PDA

View Full Version : Cutom ItemRenderer


StrixLa
09-10-2009, 08:37 PM
I'm trying to complete the implementation of a custom ItemRenderer on a Line Chart. I've created an .as file and am successfully importing it into the mxml file (I say successfully because intellisense is picking up on the custom class and its properties). However, when I try to compile the mxml file, I get two errors where I instantiate the custom class:

1046 - Type was not found or was not a compile-time constant: ArrowRenderer.
1180 - Call to a possibly undefined method ArrowRenderer.


<mx:Script>
<![CDATA[
import mx.charts.LegendItem;
import mx.charts.Legend;
import mx.printing.FlexPrintJob;
import mx.controls.Image;
import mx.charts.series.renderData.LineSeriesRenderData;
import mx.graphics.Stroke;
import mx.charts.series.LineSeries;
import mx.controls.Alert;
import mx.rpc.events.ResultEvent;
import mx.charts.renderers.*;
import flash.printing.PrintJob;
import mx.core.ClassFactory;
import CustomRend.ArrowRenderer;
import mx.skins.ProgrammaticSkin;

[Bindable]
private var dp:XML;

[Bindable]
private var sdp:Array;

public function Init():void {
ExternalInterface.addCallback("PrintFlexGraph",PrintGraph);
//httpService.url = "http://dev.eiglobal.net/current/eagleEnvironmental/flexgraphs/bin/lineGraph.cfm?date=4/1/2009";
httpService.url = "http://" + Application.application.parameters.path + "/flexGraphs/bin/lineGraph.cfm?type=" + Application.application.parameters.type + "&pageFrom=" + Application.application.parameters.pageFrom + "&readingType=" + Application.application.parameters.readingType + "&fromDate=" + Application.application.parameters.fromDate + "&toDate=" + Application.application.parameters.toDate + "&site=" + Application.application.parameters.site;
httpService.send();
}

public static function CreateRendererWithProperties(renderer:Class,proper ties:Object ):IFactory {
var factory:ClassFactory = new ClassFactory(renderer);
factory.properties = properties;
return factory;
}

private function LoadGraph(evt:ResultEvent):void {
dp = evt.result as XML;
sdp = new Array();
linearAxis.title = dp.yunit.@value;
panel.title = dp.panel.@value;
var legendNS:Legend = new Legend();
panel.addChild(legendNS);
//legendNS.dataProvider = lineChart;
legendNS.id = "legend";
legendNS.direction = "horizontal";
legendNS.height = 25;

//newImage = new ArrowRenderer();
for each(var item:Object in dp.site){
var ls:LineSeries;
ls = new LineSeries();
var st:Stroke;
var tmp:Array = lineChart.series;
var li:LegendItem = new LegendItem();
ls.yField = "@" + item.@name;
ls.displayName = item.@name;
st = new Stroke(item.@color, item.@weight, item.@alpha);
ls.setStyle("lineStroke", st);
if (Application.application.parameters.type == "wind speed") {
Here is the error---> var ar:ArrowRenderer = new ArrowRenderer();
var ir:ClassFactory = new ClassFactory(ar);
ir.properties = {arrayIndex: item.@name};
ls.setStyle("itemRenderer", ir);
}
tmp.push(ls)
lineChart.series = tmp;
lineChart.invalidateSeriesStyles();
if (item.@name.indexOf('Strike') < 0) {
legendNS.addChild(li);
li.label = item.@name;
li.setStyle("fill", item.@color);
}
}
}

private function MyParseFunction(s:String):void {
Alert.show(s);
//var newDate:Date = new Date(s);
//return newDate;
}

private function PrintGraph():void {
Alert.show("Printing...");
var pj:FlexPrintJob = new FlexPrintJob();
pj.start();
pj.addObject(panel, "showAll");
pj.send();
}
]]>
</mx:Script>



package CustomRend {
import mx.skins.ProgrammaticSkin;
import flash.display.Graphics;
import mx.core.IDataRenderer;
import mx.charts.series.items.LineSeriesItem;
import flash.display.Loader;
import flash.display.*;
import flash.text.*;
import flash.net.URLRequest;
import flash.events.*;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.geom.Matrix;

public class ArrowRenderer extends mx.skins.ProgrammaticSkin
implements IDataRenderer {

public var arrayIndex:int

private var arrows:Array = ['bin/arrowS.png',
'bin/arrowSSW.png',
'bin/arrowSW.png',
'bin/arrowWSW.png',
'bin/arrowW.png',
'bin/arrowWNW.png',
'bin/arrowNW.png',
'bin/arrowNNW.png',
'bin/arrowN.png',
'bin/arrowNNE.png',
'bin/arrowNE.png',
'bin/arrowENE.png',
'bin/arrowE.png',
'bin/arrowESE.png',
'bin/arrowSE.png',
'bin/arrowSSE.png'];

private var _chartItem:LineSeriesItem;
private var loaderArray:Array;
private var bitmapArray:Array;

public function ArrowRenderer(){
loadBitmapArray();
}

private function loadBitmapArray():void {
var loader:Loader = new Loader();
loaderArray = new Array();
bitmapArray = new Array({bitmap:Bitmap});

for (var i:int = 0; i < arrows.length; i++) {
loaderArray.push(loader)
loaderArray[i].load(new URLRequest(arrows[i]));
}

}

public function get data():Object {
return _chartItem;
}

public function set data(value:Object):void {
_chartItem = value as LineSeriesItem;
invalidateDisplayList();
}

override protected function
updateDisplayList(unscaledWidth:Number,unscaledHei ght:Number):void {
super.updateDisplayList(unscaledWidth, unscaledHeight);
var g:Graphics = graphics;
g.clear();
g.beginBitmapFill(bitmapArray[arrayIndex]);
g.endFill();
}
}
}

StrixLa
09-11-2009, 03:59 PM
I've fixed the initial error. It was a problem with files not being in the proper location. Now I have a new error stating "1067 - Implicit coercion of a value of type ArrowRenderer to an unrelated type Class" at the line in the MXML file:

var ir:ClassFactory = new ClassFactory(ar);

Below is the complete MXML and AS source. The code creates a line series for each set of values over time coming from several different sources. The data source is an XML file.


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:custom="Components.*" layout="absolute" backgroundColor="white" height="300" creationComplete="Init()">

<mx:Script>
<![CDATA[
import mx.charts.LegendItem;
import mx.charts.Legend;
import mx.printing.FlexPrintJob;
import mx.controls.Image;
import mx.charts.series.renderData.LineSeriesRenderData;
import mx.graphics.Stroke;
import mx.charts.series.LineSeries;
import mx.controls.Alert;
import mx.rpc.events.ResultEvent;
import mx.charts.renderers.*;
import flash.printing.PrintJob;
import mx.core.ClassFactory;
import mx.skins.ProgrammaticSkin;

[Bindable]
private var dp:XML;

private var ar:ArrowRenderer;

public function Init():void {
ExternalInterface.addCallback("PrintFlexGraph",PrintGraph);
httpService.url = "http://" + Application.application.parameters.path + "/flexGraphs/bin/lineGraph.cfm?type=" + Application.application.parameters.type + "&pageFrom=" + Application.application.parameters.pageFrom + "&readingType=" + Application.application.parameters.readingType + "&fromDate=" + Application.application.parameters.fromDate + "&toDate=" + Application.application.parameters.toDate + "&site=" + Application.application.parameters.site;
httpService.send();
}

public static function CreateRendererWithProperties(renderer:Class,proper ties:Object ):IFactory {
var factory:ClassFactory = new ClassFactory(renderer);
factory.properties = properties;
return factory;
}

private function LoadGraph(evt:ResultEvent):void {
dp = evt.result as XML;
linearAxis.title = dp.yunit.@value;
panel.title = dp.panel.@value;
var legendNS:Legend = new Legend();
panel.addChild(legendNS);
legendNS.id = "legend";
legendNS.direction = "horizontal";
legendNS.height = 25;

//newImage = new ArrowRenderer();
for each(var item:Object in dp.site){
var ls:LineSeries;
ls = new LineSeries();
var st:Stroke;
var tmp:Array = lineChart.series;
var li:LegendItem = new LegendItem();
ls.yField = "@" + item.@name;
ls.displayName = item.@name;
st = new Stroke(item.@color, item.@weight, item.@alpha);
ls.setStyle("lineStroke", st);
if (Application.application.parameters.type == "wind speed") {
ar = new ArrowRenderer();
var ir:ClassFactory = new ClassFactory(cb);
ls.yField = "@" + item.@name + "Arrow";
ls.setStyle("itemRenderer",(ir));
}
tmp.push(ls)
lineChart.series = tmp;
lineChart.invalidateSeriesStyles();
if (item.@name.indexOf('Strike') < 0) {
legendNS.addChild(li);
li.label = item.@name;
li.setStyle("fill", item.@color);
}
}
}

private function MyParseFunction(s:String):void {
Alert.show(s);
//var newDate:Date = new Date(s);
//return newDate;
}

private function PrintGraph():void {
Alert.show("Printing...");
var pj:FlexPrintJob = new FlexPrintJob();
pj.start();
pj.addObject(panel, "showAll");
pj.send();
}
]]>
</mx:Script>

<mx:HTTPService id="httpService" resultFormat="e4x" result="LoadGraph(event)"/>

<mx:Style>
@font-face {
fontFamily: labelFont;
src:url("arial.ttf");
}
LineChart{
fontFamily: labelFont;
}
</mx:Style>

<mx:Panel id="panel" height="300" width="100%">
<mx:LineChart id="lineChart" height="225" width="100%" showDataTips="true" dataProvider="{dp.reading}">
<mx:backgroundElements>
<mx:GridLines direction="horizontal"/>
</mx:backgroundElements>

<mx:seriesFilters>
<mx:Array/>
</mx:seriesFilters>

<mx:verticalAxis>
<mx:LinearAxis id="linearAxis" baseAtZero="true"/>
</mx:verticalAxis>

<mx:horizontalAxis>
<mx:CategoryAxis id="catAxis" categoryField="@time"/>
</mx:horizontalAxis>

<mx:horizontalAxisRenderer>
<mx:AxisRenderer axis="{catAxis}" canDropLabels="true" labelRotation="90"/>
</mx:horizontalAxisRenderer>
</mx:LineChart>
</mx:Panel>
</mx:Application>



package {
import flash.display.*;
import flash.events.*;
import flash.text.*;
import mx.core.ClassFactory;
import mx.charts.series.items.LineSeriesItem;
import mx.core.IDataRenderer;
import mx.skins.ProgrammaticSkin;

public class ArrowRenderer extends ProgrammaticSkin
implements IDataRenderer {

[Bindable]
[Embed(source="/bin/arrowS.png")]
private var arrowS:Class;

[Bindable]
[Embed(source="/bin/arrowN.png")]
private var arrowN:Class;

private var _chartItem:LineSeriesItem;

public function ArrowRenderer() {

}

public function get data():Object {
return _chartItem;
}

public function set data(value:Object):void {
_chartItem = value as LineSeriesItem;
invalidateDisplayList();
}

override protected function
updateDisplayList(unscaledWidth:Number,unscaledHei ght:Number):void {
super.updateDisplayList(unscaledWidth, unscaledHeight);
var g:Graphics = graphics;
g.clear();
var bitmap:BitmapData

if (_chartItem.yValue > 2) {
bitmap = new arrowS().bitmapData;
}
else {
bitmap = new arrowN().bitmapData;
}

g.clear();
g.beginBitmapFill(bitmap);
g.endFill();
}
}

}


Everywhere I've looked this is the proper way to implement a custom itemRenderer. What am I missing?