扩展arcgis flex symbol 显示报表功能,显示饼状图和柱状图,非用infoSymbol实现(三)

来源:互联网 发布:ditto软件 编辑:程序博客网 时间:2024/06/05 08:07

有博友问我这个什么怎么实现,我之前忘记贴代码了,虽然flex这个鬼东西离我们而去了,但是不乏还是有人用这个,就当怀念一下flex(早已拥抱了h5),我就翻箱倒柜找了半天程序,贴一个初级版本给大家参考,其实很简单。代码写的烂,烂番茄就不要扔了。目录结构是这样的:



第一个是柱状图,第二个是饼状图,第三个是调用

/***************************************************** * @创建者:liuyy * @创建时间:2014-1-11 * @功能描述:扩展arcgis flex symbol自定义符号,主要是展示柱状图,生成图例 * ***************************************************/package platform.symbol{import com.esri.ags.Map;import com.esri.ags.geometry.Geometry;import com.esri.ags.geometry.MapPoint;import com.esri.ags.symbols.Symbol;import flash.display.GradientType;import flash.display.Graphics;import flash.display.SpreadMethod;import flash.display.Sprite;import flash.events.MouseEvent;import flash.filters.DropShadowFilter;import flash.geom.Matrix;import flash.text.TextField;import flash.text.TextFieldAutoSize;import flash.text.TextFieldType;import flash.text.TextFormat;import mx.core.UIComponent;import core.util.ColorUtils;import platform.symbol.supportClasses.ColumnSeries;import platform.symbol.supportClasses.ColumnTip;public class ColumnSymbol extends Symbol{public function ColumnSymbol(){super();format.font = "LatoBlack";format.size = 13;format.align="center";format.bold=true;}private var shadow:DropShadowFilter = new DropShadowFilter(0,0,0xecf0f5,0.7,5,5);/** * 每根柱子的宽度 */public var columnWidth:Number=18;/** * 柱子底部的连接线是否可见 */public var lineSpriteVisible:Boolean = false;/** * 柱子底部的连接线颜色 */public var lineSpriteColor:uint = 0x555555;/** * 柱子颜色 */public var columnColor:uint = 0x3698ff;/** * 柱子边框颜色 */public var borderColor:uint = ColorUtils.Silver;/** * 柱子底部的连接线厚度 */public var lineSpriteThickness:int = 1;/** * 提示框是否已经显示 */public var isTipShown:Boolean=false;/** * 数字标注是否已经显示 */public var isLabelShown:Boolean=false;/** * 数字标注颜色 */public var labelColor:uint=0x000000;/** * 是否显示边框 */public var isBorderShown:Boolean=false;/** * 是否是多根柱子 */public var isMulti:Boolean=false;/** * 圆角 */public var ellipseNumber:Number=0;/** * 图例 */private var legend:UIComponent = new UIComponent();/** * 字体样式 */private var format:TextFormat = new TextFormat();/** * 重写父类Symbol的draw方法 */override public function draw(sprite:Sprite, geometry:Geometry, attributes:Object, map:Map):void{try{sprite.filters=[shadow];if (geometry.type==Geometry.MAPPOINT){//坐标转换,地理坐标转屏幕坐标var sx:Number = toScreenX(map, (geometry as MapPoint ).x);var sy:Number = toScreenY(map, (geometry as MapPoint ).y);}var data:Array = attributes.data;var i:int=0;var total:Number=0;var halfLineSpriteWidth:Number = data.length*columnWidth/2;//trace("data:"+data.length);//绘制饼图的各个部分for each(var d:Object in data){format.color = labelColor;total=total+Number(d.value);//trace("total:"+total);var val:Number = Number(d.value);var height:Number = Number(d.height);if(height<2){break;}var startX:Number = sx-halfLineSpriteWidth+i*columnWidth;var startY:Number = sy-d.height;//绘制柱子beginvar series:ColumnSeries=new ColumnSeries();series.sortNum = i;series.seriesNum = data.length;series.addEventListener(MouseEvent.MOUSE_OVER,seriesMouseOverHandler);series.addEventListener(MouseEvent.MOUSE_OUT,seriesMouseOutHandler);series.centerX = startX+columnWidth/2;if(val<0){series.centerY = sy+d.height;}else{series.centerY = sy-d.height;}series.color = d.color;if(d.name){series.msg =attributes.name+"\n"+d.value.toFixed(2)+"\n"+d.name;}else{series.msg =attributes.name+"\n"+d.value.toFixed(2);}////if(data.length>1)//{//series.graphics.beginFill(d.color,1);//}//else//{//series.graphics.beginFill(columnColor,1);//}////series.graphics.beginGradientFill(GradientType.RADIAL, [d.color, 0xED1C24], [1, 1], [0x00, 0xff], null, SpreadMethod.REFLECT); //if(height>0)//{//if(isBorderShown)//{//series.graphics.lineStyle(2,borderColor);//}//else//{//series.graphics.lineStyle(0,borderColor);//}//}//series.graphics.drawRoundRect(startX,startY,columnWidth,d.height,ellipseNumber,ellipseNumber);////series.graphics.drawRect(startX,startY,columnWidth,d.height);//series.graphics.endFill();//绘制柱子end//底部圆series.graphics.clear();series.graphics.lineStyle(1,0xffffff,0.65);  series.graphics.beginFill(d.color);  series.graphics.drawEllipse(startX,sy-columnWidth*0.25,columnWidth,columnWidth * 0.5); //柱子series.graphics.lineStyle(1,0xffffff,0.65);series.graphics.beginFill(d.color);series.graphics.drawRect(startX,startY,columnWidth,d.height);  //遮盖柱子边框的圆series.graphics.lineStyle(1,0xffffff,0);  series.graphics.beginFill(d.color);  series.graphics.drawEllipse(startX,sy-columnWidth*0.25,columnWidth,columnWidth * 0.5); //顶部圆series.graphics.lineStyle(1,0xffffff,0.65);  series.graphics.beginFill(d.color);  series.graphics.drawEllipse(startX,sy-d.height-columnWidth*0.25,columnWidth,columnWidth * 0.5);series.graphics.endFill();  sprite.addChild(series);if(val!=0&&isLabelShown&&data.length<2){if(data.length==1){var quarterTxt:TextField = new TextField();  quarterTxt.type = TextFieldType.DYNAMIC;quarterTxt.wordWrap=true;quarterTxt.autoSize=TextFieldAutoSize.LEFT;quarterTxt.text=d.value;quarterTxt.setTextFormat(format);quarterTxt.x = startX-columnWidth/2-20;quarterTxt.y = sy-d.height-25;//quarterTxt.width = columnWidth*2+40;  quarterTxt.height = 20;quarterTxt.alpha=0.8;quarterTxt.autoSize=TextFieldAutoSize.NONE;quarterTxt.border=false;quarterTxt.borderColor=columnColor;quarterTxt.background = false;  quarterTxt.backgroundColor = 0xffffff;sprite.addChild(quarterTxt);}else{var quarterTxt:TextField = new TextField();  quarterTxt.type = TextFieldType.DYNAMIC;quarterTxt.autoSize=TextFieldAutoSize.LEFT;quarterTxt.wordWrap=true;quarterTxt.text=d.value;quarterTxt.setTextFormat(format);quarterTxt.x = startX;quarterTxt.y = sy-d.height-20;//quarterTxt.width = columnWidth;  quarterTxt.height = 15;quarterTxt.alpha=0.8;quarterTxt.autoSize=TextFieldAutoSize.NONE;quarterTxt.border=true;quarterTxt.borderColor=columnColor;quarterTxt.background = true;  quarterTxt.backgroundColor = 0xffffff;sprite.addChild(quarterTxt);}}i++;}//trace(total);if(lineSpriteVisible&&total>0){var lineSprite:Sprite=new Sprite();lineSprite.graphics.lineStyle(lineSpriteThickness,lineSpriteColor,1);//lineSprite.graphics.moveTo(sx-halfLineSpriteWidth+1,sy);//lineSprite.graphics.lineTo(sx+halfLineSpriteWidth-1,sy)lineSprite.graphics.moveTo(sx-halfLineSpriteWidth-7,sy-5);lineSprite.graphics.lineTo(sx-halfLineSpriteWidth-7,sy);lineSprite.graphics.lineTo(sx+halfLineSpriteWidth+7,sy)lineSprite.graphics.lineTo(sx+halfLineSpriteWidth+7,sy-5)sprite.addChild(lineSprite);}//legend.addChild(sprite);}catch(e:Error){}}/** * 鼠标放到柱状图上,显示提示点和提示信息 */private function seriesMouseOverHandler(event:MouseEvent):void{if(!isTipShown){var series:ColumnSeries = event.currentTarget as ColumnSeries;var tipPoint:Sprite = new Sprite();var g:Graphics = tipPoint.graphics;var tipPointShadow:DropShadowFilter = new DropShadowFilter(0,0,0xFFFFFF,1,5,5);tipPoint.filters=[tipPointShadow];g.clear();g.lineStyle(2, series.color);g.beginFill(0xffffff);g.drawCircle(series.centerX,series.centerY,3);g.endFill();series.addChild(tipPoint);var tooltip:ColumnTip = new ColumnTip(series.msg,series.color,series.centerX,series.centerY,series.sortNum,series.seriesNum,100,60);series.addChildAt(tooltip,0);isTipShown=true;}}/** * 鼠标离开柱状图,移除提示点和提示信息 */private function seriesMouseOutHandler(event:MouseEvent):void{var series:ColumnSeries = event.currentTarget as ColumnSeries;while(series.numChildren>0){series.removeChildAt(0);}isTipShown=false;}override public function createSwatch(width:Number=50, height:Number=50, shape:String=null):UIComponent{return legend;}/*****************************************************************************************************/override public function destroy(sprite:Sprite):void{sprite.graphics.clear();}override public function clear(sprite:Sprite):void{sprite.graphics.clear();sprite.x = 0;sprite.y = 0;while(sprite.numChildren>0){sprite.removeChildAt(0);}}}}
/***************************************************** * @创建者:liuyy * @创建时间:2014-01-01 * @功能描述:自定义PieSymbol的扇形 * ***************************************************/package platform.symbol.supportClasses{import flash.display.Sprite;public class ColumnSeries extends Sprite{public function ColumnSeries(){super();}/** * 提示信息 */public var msg:String;/** * sprite的父容器 */public var owner:Sprite;/** * 颜色 */public var color:uint;/** * 饼图中心坐标x */public var centerX:Number;/** * 饼图中心坐标y */public var centerY:Number;/** * 柱子数量 */public var seriesNum:int;/** * 左右排列顺序 */public var sortNum:int;}}


饼状图:
/***************************************************** * @创建者:liuyy * @创建时间:2014-1-11 * @功能描述:扩展arcgis flex symbol自定义符号,主要是展示饼图,生成图例 * ***************************************************/package platform.symbol{import com.esri.ags.Map;import com.esri.ags.geometry.Geometry;import com.esri.ags.geometry.MapPoint;import com.esri.ags.symbols.Symbol;import flash.display.Graphics;import flash.display.Sprite;import flash.events.MouseEvent;import flash.filters.DropShadowFilter;import platform.symbol.supportClasses.PieSeries;import platform.symbol.supportClasses.Tip;public class PieSymbol extends Symbol{public function PieSymbol(){super();}/** * 半径,默认是20 */public var radius:Number = 20;/** * 重写父类Symbol的draw方法 */override public function draw(sprite:Sprite, geometry:Geometry, attributes:Object, map:Map):void{if (geometry.type==Geometry.MAPPOINT){//坐标转换,地理坐标转屏幕坐标var sx:Number = toScreenX(map, (geometry as MapPoint ).x);var sy:Number = toScreenY(map, (geometry as MapPoint ).y);//获取饼图各个值的总和var data:Array = attributes.data;var startAngle:Number=0.0;var totalVal:Number=0.0;for each(var pie:Object in data){var pieVal:Number = Number(pie.value);totalVal=totalVal+pieVal;}//绘制背景if(totalVal>0){var backgroud:Sprite = new Sprite();backgroud.graphics.clear();backgroud.graphics.beginFill(0x5B8C3E,0.3);backgroud.graphics.drawCircle(sx,sy,radius+5);backgroud.graphics.endFill();sprite.addChild(backgroud);}//绘制饼图的各个部分for each(var d:Object in data){var val:Number = Number(d.value);var series:PieSeries = new PieSeries();series.msg=attributes.name+"\n"+d.name+":"+d.value;series.owner=sprite;var g:Graphics = series.graphics;g.clear();g.lineStyle(1,0xffffff);g.beginFill(d.color);var angle:Number = 360*val/totalVal;series.angle=angle;series.startAngle = startAngle;series.centerX=sx;series.centerY=sy;series.color = d.color;drawWedge(g, sx, sy, radius, angle,startAngle);g.endFill();series.addEventListener(MouseEvent.MOUSE_OVER,pieMouseOverHandler);series.addEventListener(MouseEvent.MOUSE_OUT,pieMouseOutHandler);sprite.addChild(series);//var shadow:DropShadowFilter = new DropShadowFilter(0,0,0,0.6,8,8);//series.filters = [shadow];startAngle+=angle;}}}/** * 鼠标放到饼图上,显示提示点和提示信息 */private function pieMouseOverHandler(event:MouseEvent):void{var series:PieSeries = event.currentTarget as PieSeries;var angle:Number = series.startAngle+series.angle/2;var arc:Number =angle/180*Math.PI;var x:Number = series.centerX+radius*Math.cos(arc);var y:Number = series.centerY-radius*Math.sin(arc);var tipPoint:Sprite = new Sprite();var g:Graphics = tipPoint.graphics;var tipPointShadow:DropShadowFilter = new DropShadowFilter(0,0,0xFFFFFF,1,5,5);tipPoint.filters=[tipPointShadow];g.clear();g.lineStyle(2, series.color);g.beginFill(0xffffff);g.drawCircle(x,y,3);g.endFill();series.addChild(tipPoint);var tooltip:Tip = new Tip(series.msg,series.color,angle,x,y,100,50);series.addChildAt(tooltip,0);}/** * 鼠标离开饼图,移除提示点和提示信息 */private function pieMouseOutHandler(event:MouseEvent):void{var series:PieSeries = event.currentTarget as PieSeries;while(series.numChildren>0){series.removeChildAt(0);}}/** <p>功能:绘制扇形相应函数。</p> <p>参数:target:Graphics 目标对象的graphics</p> <p>参数:x:Number 中心点坐标x</p> <p>参数:y:Number 中心点坐标y</p> <p>参数:radius:Number 半径</p> <p>参数:arc:Number 弧度</p> <p>参数:startAngle:Number 起始角度</p> <p>参数:yRadius:Number y轴距离</p> <p>返回值:无</p> */private function drawWedge(target:Graphics, x:Number, y:Number, radius:Number, arc:Number, startAngle:Number=0, yRadius:Number=0):void{if (yRadius == 0){yRadius = radius;}target.moveTo(x, y);var segAngle:Number, theta:Number, angle:Number, angleMid:Number, segs:Number, ax:Number, ay:Number, bx:Number, by:Number, cx:Number, cy:Number;if (Math.abs(arc) > 360){arc = 360;}segs = Math.ceil(Math.abs(arc) / 45);segAngle = arc / segs;theta = -(segAngle / 180) * Math.PI;angle = -(startAngle / 180) * Math.PI;if (segs > 0){ax = x + Math.cos(startAngle / 180 * Math.PI) * radius;ay = y + Math.sin(-startAngle / 180 * Math.PI) * yRadius;target.lineTo(ax, ay);for (var i:int = 0; i < segs; ++i){angle += theta;angleMid = angle - (theta / 2);bx = x + Math.cos(angle) * radius;by = y + Math.sin(angle) * yRadius;cx = x + Math.cos(angleMid) * (radius / Math.cos(theta / 2));cy = y + Math.sin(angleMid) * (yRadius / Math.cos(theta / 2));target.curveTo(cx, cy, bx, by);}target.lineTo(x, y);}}override public function destroy(sprite:Sprite):void{sprite.graphics.clear();}override public function clear(sprite:Sprite):void{sprite.graphics.clear();sprite.x = 0;sprite.y = 0;while(sprite.numChildren>0){sprite.removeChildAt(0);}}}}

/*****************************************************
 * @创建者:liuyy
 * @创建时间:2014-01-01
 * @功能描述:自定义PieSymbol的扇形
 * ***************************************************/
package platform.symbol.supportClasses
{
import flash.display.Sprite;

public class PieSeries extends Sprite
{
public function PieSeries()
{
super();
}
/**
* 提示信息
*/
public var msg:String;
/**
* sprite的父容器
*/
public var owner:Sprite;
/**
* 颜色
*/
public var color:uint;
/**
* 绘制的角度
*/
public var angle:Number;
/**
* 绘制的起始角度
*/
public var startAngle:Number;
/**
* 饼图中心坐标x
*/
public var centerX:Number;
/**
* 饼图中心坐标y
*/
public var centerY:Number;
}
}

调用

/** <p>功能:在地图上创建chart</p> <p>参数:data String类型</p> <p>返回值:无</p> */private function createChart(data:String):void{clearMap();var result:Object = JSONUtil.decode(data);var pointCollecton:ArrayCollection = new ArrayCollection(result.data as Array);var points:Multipoint=new Multipoint();for each(var obj:Object in pointCollecton.toArray()){var g:Graphic=new Graphic(new MapPoint(obj.x,obj.y,map.spatialReference),null,obj);chartGraphicsLayer.add(g);points.addPoint(g.geometry as MapPoint);switch(result.type){case ChartSymbol.COLUMN:g.symbol = columnSymbol;break;case ChartSymbol.PIE:g.symbol = pieSymbol;break;}if(!chartSymbolLegendDG.dataProvider&&result) {chartSymbolLegendDG.dataProvider=new ArrayCollection(obj.data as Array);//trace(JSONUtil.encode(chartSymbolLegendDG.dataProvider));}}if(points.points.length>1) map.extent=points.extent.expand(2);}
数据:

var data:String='{"type":"column","data":[{"name":"北京人口数","x":120,"y":31,"data":[{"name":"item1","value":123.0,"color":1035328.0,"height":0.0},{"name":"item2","value":59.0,"color":1.5564081E7,"height":0.0},{"name":"item3","value":10.0,"color":1.534699E7,"height":0.0},{"name":"item4","value":99.5,"color":4485831.0,"height":0.0}]}]}';
调用:

this.createChart(data);

当然你也可以用queryTask之类的查询图层,然后给symbol也行,不过得严格最受数据结构约定


 
阅读全文
0 0
原创粉丝点击