Flex4 用LineChart实现实时曲线图,并在其中添加自定义的虚线水平线

本示例首先是为了显示实时曲线。然后呢,要显示个水平线,比如我要显示一个变量的变化过程,但它有一个标准值,就可以用该种方式。

示例:

[flash=600,500]https://dl.dropbox.com/u/38216791/flex/samples/runtimeChart/samples.swf[/flash]

然后是代码:
先看Application:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:chartClasses="lip.charts.chartClasses.*">

<fx:Script>
<![CDATA[
import lip.utils.DateFormatter;

import mx.collections.ArrayCollection;
import mx.utils.ObjectProxy;

private static const DELAY:int = 1000;

private static const MAX_COUNT:int = 10;

[Bindable]
private var ac:ArrayCollection;

private var timer:Timer;

protected function startCalc(event:MouseEvent):void
{
if(!timer)
{
timer = new Timer(DELAY);
timer.addEventListener(TimerEvent.TIMER, timer_timerHandler);
}
timer.start();
}

protected function stopCalc(event:MouseEvent):void
{
if(timer)
timer.stop();

ac = null;
}

protected function timer_timerHandler(event:TimerEvent):void
{
var now:Date = new Date();
var nowTime:String;

if(!ac)
{
ac = new ArrayCollection();
now.setTime(now.time - 1000 * MAX_COUNT);
for (var i:int = 0; i < MAX_COUNT; i++)
{
nowTime = DateFormatter.getInstance().formatTime(now);
ac.addItem(new ObjectProxy({time:nowTime, gas:0}));
now.setTime(now.time + 1000);
}

}

nowTime = DateFormatter.getInstance().formatTime(now);
var item:ObjectProxy = new ObjectProxy({time:nowTime, gas:Math.round(Math.random() * 100) * .01});

if(ac.length < 10)
{
ac.addItem(item);
}
else
{
ac.removeItemAt(0);
ac.addItem(item);
}

trace(item.time, ":", item.gas);
}

protected function changeDashedLine(event:MouseEvent):void
{
nn = Math.round((Math.random() / 5 + 0.8) * 100) * .01;
}

]]>
</fx:Script>

<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
<mx:SeriesInterpolate id="effect" duration="1000" />
<fx:Number id="nn">0.3</fx:Number>
</fx:Declarations>

<s:Panel width="600" height="500" title="测试实时曲线">
<s:controlBarContent>
<s:HGroup width="100%" height="20" horizontalAlign="center" verticalAlign="middle">
<s:Button label="start" click="startCalc(event)"/>
<s:Button label="stop" click="stopCalc(event)"/>
<s:Button label="change dashed line" click="changeDashedLine(event)"/>
</s:HGroup>
</s:controlBarContent>
<mx:LineChart id="chart" width="500" height="400" horizontalCenter="0" showDataTips="true"
verticalCenter="0" dataProvider="{ac}" >
<mx:backgroundElements>
<mx:GridLines gridDirection="both"/>
<chartClasses:DashedLines lineColor="0xFF0000" yValue="{nn}"/>
</mx:backgroundElements>

<mx:horizontalAxis>
<mx:CategoryAxis categoryField="time" displayName="Time" title="时间" />
</mx:horizontalAxis>

<mx:verticalAxis>
<mx:LinearAxis minimum="0" maximum="1"/>
</mx:verticalAxis>

<mx:series>
<mx:LineSeries displayName="瓦斯" xField="time" yField="gas" form="curve"/>
</mx:series>
</mx:LineChart>

</s:Panel>
</s:Application>


接下来是里面的DashedLines:

package lip.charts.chartClasses
{
import flash.display.Graphics;
import flash.geom.Point;

import lip.utils.GraphicUtils;

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();
}

private var _yValue:Number = NaN;

/**
* 该线对应的y值
*/
public function get yValue():Number
{
return _yValue;
}

/**
* @private
*/
public function set yValue(value:Number):void
{
_yValue = 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
{
// TODO Auto Generated method stub
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 y:Number = dataToLocal(0, yValue).y;

var pFrom:Point = new Point(0, y);
var pTo:Point = new Point(w, y);

GraphicUtils.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);
}
}
}


还有其中用到的GraphicUtils.drawDashed()方法:


package lip.utils
{
import flash.display.Graphics;
import flash.geom.Point;

/**
* 一些绘图相关的方法
* @author lip
*/
public class GraphicUtils
{
public function GraphicUtils()
{
}


/**
* 画虚线
* @param graphics 你懂的
* @param pFrom 起点
* @param pTo 终点
* @param length 实线段的长度
* @param gap 实线段的间距
* @param thickness 线的宽度
* @param color 线的颜色
*/
public static 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;
}
}
}
}


代码不太多,就不详细解释了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值