The documentation on printing in Flex is pretty sparse. There are some unrealistically simple examples and no treatment of real printing situations, apart from an interesting article (in the Flex 4.5 doco in this case) called using a print-specific output format. It would be great to see more comprehensive examples along this line involving other objects. For example, what about printing charts? This is a nightmare because if you add the chart to your print template you lose the chart from your page and have to re-add it (what a hack!), but if you try to make a copy of the chart as described in this link, the data disappears from the chart! The code below demonstrates it. One interesting side-effect is that after you print and the data disappears from your chart, you can still hover over the empty chart and get the dataTips pop up! :-)
(Solution after the code)
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="800"
height="600">
<fx:Script>
<![CDATA[
import mx.charts.LineChart;
import mx.printing.FlexPrintJob;
import mx.collections.ArrayCollection;
[Bindable]
public var expensesAC:ArrayCollection = new ArrayCollection( [
{ Month: "Jan", Profit: 2000, Expenses: 1500, Amount: 450 },
{ Month: "Feb", Profit: 1000, Expenses: 200, Amount: 600 },
{ Month: "Mar", Profit: 1500, Expenses: 500, Amount: 300 },
{ Month: "Apr", Profit: 1800, Expenses: 1200, Amount: 900 },
{ Month: "May", Profit: 2400, Expenses: 575, Amount: 500 } ]);
protected function button1_clickHandler(event:MouseEvent):void {
var printJob:FlexPrintJob = new FlexPrintJob();
if (printJob.start()) {
var lc:LineChart = new LineChart();
lc.height = mlc.height;
lc.width = mlc.width;
lc.dataProvider = mlc.dataProvider;
lc.series = mlc.series;
lc.seriesFilters = mlc.seriesFilters;
lc.horizontalAxis = mlc.horizontalAxis;
lc.verticalAxis = mlc.verticalAxis;
addElement(lc);
printJob.addObject(lc);
printJob.send();
removeElement(lc);
}
}
]]>
</fx:Script>
<s:HGroup>
<mx:LineChart id="mlc" dataProvider="{expensesAC}" showDataTips="true">
<mx:horizontalAxis>
<mx:CategoryAxis categoryField="Month"/>
</mx:horizontalAxis>
<mx:series>
<mx:LineSeries yField="Profit" form="curve" displayName="Profit"/>
<mx:LineSeries yField="Expenses" form="curve" displayName="Expenses"/>
<mx:LineSeries yField="Amount" form="curve" displayName="Amount"/>
</mx:series>
</mx:LineChart>
<s:Button label="print" click="button1_clickHandler(event)"/>
</s:HGroup>
</s:WindowedApplication>
This caused myself and a colleague some serious head-scratching. Eventually I resorted to using the AlivePDF library, whereupon I discovered the same behaviour! This gave me hope because I realised it wasn't just a bug in the Flex PrintJob class.
The problem is that when you print or do whatever you do with the new chart, it makes some changes to its series. As you have passed it an array of references to Series objects (not copies), it is acting on the same series that the original chart uses. It is these changes that muck up your original chart. I actually thought I had checked this because I tried making a new series array by copying the old series array - but of course even if you copy a bunch of references to objects into a totally new array, they are still references to the same objects! So what you need to do is loop through the series array, creating a new Series object for each source object and applying any relevant properties to it. Something like this:
private function createSeries(sourceSeries:Array):void {
for each (var sourceSerie:LineSeries in sourceSeries) {
var newSerie:LineSeries = new LineSeries();
newSerie.xyz = sourceSerie.xyz;
newSeries.push(newSerie);
}
}
Then you set your new chart series to the newSeries array. Yay!
Add new comment