[Flex]给图表添加告警线(背景线,水平线)
有时候我们需要在图表的背景上添加上参考线,用来比较。 在<mx:backgroundElements>节点中,添加自定义的ChartElement即可。
效果图如下:
图表代码如下:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:hangge="com.hangge.*" creationComplete="init(event)"> <mx:Script> <![CDATA[ import mx.charts.chartClasses.IAxisRenderer; import mx.events.FlexEvent; private var xml:XML = <data date='2014-06-02' flag='curve' toptop='' top='65.01' bottom="40" bottombottom=""> <item value='54.6' time='00:00' /> <item value='55.0' time='00:05' /> <item value='54.4' time='00:10' /> <item value='54.6' time='00:15' /> <item value='54.8' time='00:20' /> </data> private function categoryLabelFunction(axisRenderer:IAxisRenderer, label:String):String { return " "+label+" "; } protected function init(event:FlexEvent):void { chart1.dataProvider = xml.item; vAxis.displayName = "湿度"; vAxis.maximum = 60; vAxis.minimum = 50; tt.yValue = 58; bb.yValue = 52; } ]]> </mx:Script> <mx:Canvas width="60%" height="60%" horizontalCenter="0" verticalCenter="0" backgroundColor="0xD0E0E4"> <mx:LineChart id="chart1" width="100%" height="100%" showDataTips="true"> <mx:backgroundElements> <mx:GridLines direction="horizontal"> <mx:horizontalStroke> <mx:Stroke color="0xFFFFFF" alpha="0.25"/> </mx:horizontalStroke> </mx:GridLines> <hangge:DashedLines id="tt" lineColor="0xFF0000" displayName="上上限" yMax="100" yMin="0"/> <hangge:DashedLines id="bb" lineColor="0xFF0000" displayName="下下限" yMax="100" yMin="0"/> </mx:backgroundElements> <mx:fill> <mx:SolidColor color="0x000000" alpha="0"/> </mx:fill> <mx:horizontalAxis> <mx:CategoryAxis id="hAxis" categoryField="@time" displayName="时间"/> </mx:horizontalAxis> <mx:horizontalAxisRenderers> <mx:AxisRenderer axis="{hAxis}" tickPlacement="none" minorTickPlacement="none" color="0x000000" fontSize="14" fontFamily="微软雅黑" canDropLabels="true" labelFunction="categoryLabelFunction"> <mx:axisStroke> <mx:Stroke weight="2" color="0xFFFFFF"/> </mx:axisStroke> </mx:AxisRenderer> </mx:horizontalAxisRenderers> <mx:verticalAxis> <mx:LinearAxis id="vAxis" baseAtZero="false"/> </mx:verticalAxis> <mx:verticalAxisRenderers> <mx:AxisRenderer axis="{vAxis}" tickPlacement="none" minorTickPlacement="none" fontSize="14" color="0x000000" fontFamily="微软雅黑"> <mx:axisStroke> <mx:Stroke color="0xFFFFFF" weight="2"/> </mx:axisStroke> </mx:AxisRenderer> </mx:verticalAxisRenderers> <mx:series> <mx:LineSeries id="ls" form="curve" xField="@time" yField="@value"> <mx:lineStroke> <mx:Stroke color="0x00fff5"/> </mx:lineStroke> </mx:LineSeries> </mx:series> </mx:LineChart> </mx:Canvas> </mx:Application>
使用到的DashedLines代码如下:
package com.hangge{ import flash.display.Graphics; import flash.geom.Point; import flash.text.TextField; import mx.charts.chartClasses.CartesianChart; import mx.charts.chartClasses.CartesianTransform; import mx.charts.chartClasses.ChartElement; import mx.charts.chartClasses.ChartState; import mx.charts.chartClasses.IAxis; public class DashedLines extends ChartElement { public function DashedLines() { super(); } /** * 该线对应的y值 */ private var _yValue:Number = NaN; public function get yValue():Number { return _yValue; } public function set yValue(value:Number):void { _yValue = value; invalidateDisplayList(); } /** * 该线对应的y轴最大值 */ private var _yMax:Number = NaN; public function get yMax():Number { return _yMax; } public function set yMax(value:Number):void { _yMax = value; invalidateDisplayList(); } /** * 该线对应的y轴最小值 */ private var _yMin:Number = NaN; public function get yMin():Number { return _yMin; } public function set yMin(value:Number):void { _yMin = value; invalidateDisplayList(); } /** * 实线部分的长度 * @default 10 */ public var length:Number = 10; /** * 空白部分的长度 * @default 5 */ public var gap:Number = 5; /** * 线条的宽度 * @default 1 */ public var lineThickness:Number = 1; /** * 线条的颜色 * @default 黑色 */ public var lineColor:uint = 0; private var _displayName:String; /** * 该线所对应的数值名称(平均值,最大值等等) * @default */ public function get displayName():String { return _displayName; } /** * @private */ public function set displayName(value:String):void { _displayName = value; invalidateDisplayList(); } protected var label:TextField; override protected function createChildren():void { super.createChildren(); if(!label) { label = new TextField(); label.mouseEnabled = false; addChild(label); } } override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { super.updateDisplayList(unscaledWidth, unscaledHeight); if (!chart|| chart.chartState == ChartState.PREPARING_TO_HIDE_DATA || chart.chartState == ChartState.HIDING_DATA) { return; } var g:Graphics = this.graphics; g.clear(); // 如果没有设置数据,不显示 if(isNaN(yValue)) { return; } var w:Number = unscaledWidth; var h:Number = unscaledHeight; var vAxis:IAxis = CartesianChart(this.chart).verticalAxis; var posyValue:Number = (yValue - yMin) / (yMax - yMin) * 100; // var y:Number = dataToLocal(0, yValue).y; var y:Number = dataToLocal(0, posyValue).y; var pFrom:Point = new Point(0, y); var pTo:Point = new Point(w, y); drawDashed(g, pFrom, pTo, this.length, this.gap, this.lineThickness, this.lineColor); label.text = (displayName ? (displayName + " : ") : "") + yValue; label.x = 1; label.y = y > 21 ? y - 21 : y + 1; } // 这个方法复制自LineSeries override public function dataToLocal(... dataValues):Point { var data:Object = {}; var da:Array /* of Object */ = [ data ]; var n:int = dataValues.length; if (n > 0) { data["d0"] = dataValues[0]; dataTransform.getAxis(CartesianTransform.HORIZONTAL_AXIS).mapCache(da, "d0", "v0"); } if (n > 1) { data["d1"] = dataValues[1]; dataTransform.getAxis(CartesianTransform.VERTICAL_AXIS).mapCache(da, "d1", "v1"); } dataTransform.transformCache(da,"v0","s0","v1","s1"); return new Point(data.s0 + this.x, data.s1 + this.y); } /** * 画虚线 * @param graphics 你懂的 * @param pFrom 起点 * @param pTo 终点 * @param length 实线段的长度 * @param gap 实线段的间距 * @param thickness 线的宽度 * @param color 线的颜色 */ private function drawDashed(graphics:Graphics, pFrom:Point, pTo:Point, length:Number = 5, gap:Number = 5, thickness:Number = 1, color:uint = 0):void { var max:Number = Point.distance(pFrom, pTo); var l:Number = 0; var p3:Point; var p4:Point; graphics.lineStyle(thickness, color); while (l < max) { p3 = Point.interpolate(pTo, pFrom, l / max); l += length; if (l > max) l = max; p4 = Point.interpolate(pTo, pFrom, l / max); graphics.moveTo(p3.x, p3.y) graphics.lineTo(p4.x, p4.y) l += gap; } } } }
版权声明:
作者:hangge
链接:https://news.skybyte.me/archives/78857
文章版权归作者所有,未经允许请勿转载。
THE END