- 浏览: 7264 次
- 性别:
- 来自: 珠海
最新评论
-
grzrt:
不错,学习下
重新编译charts.swf,显示charts上面的值,增加右键菜单 -
sunjilu05:
好强!学习中!
重新编译charts.swf,显示charts上面的值,增加右键菜单 -
vishare:
终于找到我想要了的...谢谢分享
重新编译charts.swf,显示charts上面的值,增加右键菜单 -
yanxianggt:
楼主可有方法改变Y轴坐标的起始值
每次都从0开始,造成图形的 ...
重新编译charts.swf,显示charts上面的值,增加右键菜单
在ext3.0中,增加了flash图表的部分,可以让报表更加的赏心悦目。但是其中也有些缺憾,比如stackbar,columnbar 等,里面的值不能直接显示在相应的位置,必须鼠标移动到上面才行。本以为有什么机关咱不知道,但是在yahoo的论坛上,yui的开发人员明确的回答,yui-chart没有这样的功能,咱就只能自己动手了。
ext3.0中的charts.swf用的是yui-chart,我试验了两个版本2.6和2.8,2.8无法显示。2.6比较好的兼容了。到这里下载2.6的源码http://yuilibrary.com/downloads/。解压缩后,取出其中的chart目录。
再说说编译工具的问题吧,为了解决能调试的问题,找了很多的工具,但是现在还是没有能解决,目前只能是黑盒修改,也就是说无法跟踪调试,只能自己在里面写点信息,然后显示出来,看看是否达到了目的。我用的是flex3.0。其实用flashdevelop也可以的。
用flex3.0新建一个as的工程,然后将chart目录下的文件拷贝到该目录一下,或者应用chart目录。修改build.xml的输出路径(output)和编译工具的路径(flexbin),其他的可以不管.
对于stackbar 和columnbar,显示值的位置是不同的,因为一个是横向的柱子,一个是纵向的柱子,对于横向的,值是显示在bar里面的,纵向的,值是显示在bar上面的。下面分别就针对这两种类型的bar,进行说明,原理差不多。带中文备注的是增加的.
打开单元com.yahoo.astra.fl.charts.series.ColumnSeries.as找到draw方法
打开单元com.yahoo.astra.fl.charts.series.BarSeries.as找到draw方法
增加右键菜单的功能是因为我想在鼠标移动到某个柱子上面,可以有相应的交互。其实用EXT的menu也可以实现,但是会有响应的问题,也就是说会发生点击不准,响应失败的问题,而用flash的右键,则不会产生这种问题,而且更加的好看。响应的修改方法如下:
打开Charts.as.
首先在flash中增加方法,可以接受JS传来的右键菜单名:找到方法initializeComponent,在其中加入
//custom ExternalInterface.addCallback("setMenuInfo",setMenuInfo)
实现setMenuInfo方法
增加Charts的本地变量_menuInfo
这样flash就能接受菜单信息了。接受到菜单信息后,就可以建立菜单了。建立菜单我是安排在数据显示的时候,因为想这种只是针对series的右键菜单,必须在Series中生成,而且是针对每个Series创建。
com.yahoo.astra.fl.series.Series.as是ColumnSeries和BarSeries的基类,所以在这里就可以解决掉问题。
加入菜单对象
private var _lastItem:Object;//鼠标当前停留的item对象,利用以下方法进行获取
在Charts的setDataProvider方法中加入
EXT的JS修改如下
重载Ext.chart.StackedBarChart 的refresh方法,
增加函数 ,可以由点中flash右键菜单的时候调用
function executeFlashMenu(dataItem,itemIndex){}
组织菜单对象,然后传入至flash
ext3.0中的charts.swf用的是yui-chart,我试验了两个版本2.6和2.8,2.8无法显示。2.6比较好的兼容了。到这里下载2.6的源码http://yuilibrary.com/downloads/。解压缩后,取出其中的chart目录。
再说说编译工具的问题吧,为了解决能调试的问题,找了很多的工具,但是现在还是没有能解决,目前只能是黑盒修改,也就是说无法跟踪调试,只能自己在里面写点信息,然后显示出来,看看是否达到了目的。我用的是flex3.0。其实用flashdevelop也可以的。
用flex3.0新建一个as的工程,然后将chart目录下的文件拷贝到该目录一下,或者应用chart目录。修改build.xml的输出路径(output)和编译工具的路径(flexbin),其他的可以不管.
对于stackbar 和columnbar,显示值的位置是不同的,因为一个是横向的柱子,一个是纵向的柱子,对于横向的,值是显示在bar里面的,纵向的,值是显示在bar上面的。下面分别就针对这两种类型的bar,进行说明,原理差不多。带中文备注的是增加的.
打开单元com.yahoo.astra.fl.charts.series.ColumnSeries.as找到draw方法
override protected function draw():void { super.draw(); //if we don't have data, let's get out of here if(!this.dataProvider) { return; } //grab the axes var cartesianChart:CartesianChart = this.chart as CartesianChart; var valueAxis:IOriginAxis = cartesianChart.verticalAxis as IOriginAxis; var otherAxis:IAxis = cartesianChart.horizontalAxis; var verticalAxisTitle:IAxis=cartesianChart.verticalAxis;//获取X轴的相关信息 if(!valueAxis) { throw new Error("To use a ColumnSeries object, the vertical axis of the chart it appears within must be an IOriginAxis."); return; } var allSeriesOfType:Array = ChartUtil.findSeriesOfType(this, cartesianChart); var markerSizes:Array = []; var totalMarkerSize:Number = this.calculateTotalMarkerSize(otherAxis, markerSizes); var seriesIndex:int = allSeriesOfType.indexOf(this); var markerSize:Number = markerSizes[seriesIndex] as Number; var xOffset:Number = this.calculateXOffset(valueAxis, otherAxis, markerSizes, totalMarkerSize, allSeriesOfType); var startValues:Array = []; var endValues:Array = []; var itemCount:int = this.length; for(var i:int = 0; i < itemCount; i++) { var originValue:Object = this.calculateOriginValue(i, valueAxis, allSeriesOfType); var originPosition:Number = valueAxis.valueToLocal(originValue); var position:Point = IChart(this.chart).itemToPosition(this, i); var value:Object=IChart(this.chart).itemToAxisValue(this,i,verticalAxisTitle,false);//根据X轴来获取当前柱子的值 var marker:DisplayObject = this.markers[i] as DisplayObject; marker.x = position.x + xOffset; marker.width = markerSize; var caption:TextField=new TextField ();//创建一个TextField,也可以用Label等代替 caption.y=-20;//这里的x,y是相对于柱子来说的,所以要显示在上面,必须为负值 caption.x=-10; caption.text=String(value);//显示值 UIComponent(marker).addChild(caption);//增加这个对象 //if we have a bad position, don't display the marker if(isNaN(position.x) || isNaN(position.y)) { this.invalidateMarker(ISeriesItemRenderer(marker)); } else if(this.isMarkerInvalid(ISeriesItemRenderer(marker))) { //initialize the marker to the origin marker.y = originPosition; marker.height = 0; if(marker is UIComponent) { (marker as UIComponent).drawNow(); } this.validateMarker(ISeriesItemRenderer(marker)); } //stupid Flash UIComponent rounding! position.y = Math.round(position.y); originPosition = Math.round(originPosition); var calculatedHeight:Number = originPosition - position.y; if(calculatedHeight < 0) { calculatedHeight = Math.abs(calculatedHeight); position.y = Math.round(originPosition); //always put the marker on the origin marker.y = position.y; } startValues.push(marker.y, marker.height); endValues.push(position.y, calculatedHeight); } //handle animating all the markers in one fell swoop. if(this._animation) { this._animation.removeEventListener(AnimationEvent.UPDATE, tweenUpdateHandler); this._animation.removeEventListener(AnimationEvent.COMPLETE, tweenUpdateHandler); this._animation = null; } //don't animate on livepreview! if(this.isLivePreview || !this.getStyleValue("animationEnabled")) { this.drawMarkers(endValues); } else { var animationDuration:int = this.getStyleValue("animationDuration") as int; var animationEasingFunction:Function = this.getStyleValue("animationEasingFunction") as Function; this._animation = new Animation(animationDuration, startValues, endValues); this._animation.addEventListener(AnimationEvent.UPDATE, tweenUpdateHandler); this._animation.addEventListener(AnimationEvent.COMPLETE, tweenUpdateHandler); this._animation.easingFunction = animationEasingFunction; } }
打开单元com.yahoo.astra.fl.charts.series.BarSeries.as找到draw方法
override protected function draw():void { super.draw(); this.graphics.clear(); //if we don't have data, let's get out of here if(!this.dataProvider) { return; } this.graphics.lineStyle(1, 0x0000ff); //grab the axes var cartesianChart:CartesianChart = this.chart as CartesianChart; var valueAxis:IOriginAxis = cartesianChart.horizontalAxis as IOriginAxis; var otherAxis:IAxis = cartesianChart.verticalAxis; var horizontalAxis:IAxis=cartesianChart.horizontalAxis;//获取Y轴的信息 if(!valueAxis) { throw new Error("To use a BarSeries object, the horizontal axis of the chart it appears within must be an IOriginAxis."); return; } var markerSizes:Array = []; var allSeriesOfType:Array = ChartUtil.findSeriesOfType(this, this.chart as IChart); var totalMarkerSize:Number = this.calculateTotalMarkerSize(otherAxis, markerSizes); var seriesIndex:int = allSeriesOfType.indexOf(this); var markerSize:Number = markerSizes[seriesIndex] as Number; var yOffset:Number = this.calculateYOffset(valueAxis, otherAxis, markerSizes, totalMarkerSize, allSeriesOfType); var startValues:Array = []; var endValues:Array = []; var itemCount:int = this.length; for(var i:int = 0; i < itemCount; i++) { var originValue:Object = this.calculateOriginValue(i, valueAxis, allSeriesOfType); var originPosition:Number = valueAxis.valueToLocal(originValue); var value:Object=IChart(this.chart).itemToAxisValue(this,i,horizontalAxis,false);//根据Y轴信息来获取值 var position:Point = IChart(this.chart).itemToPosition(this, i); var marker:DisplayObject = this.markers[i] as DisplayObject; marker.y = position.y + yOffset; marker.height = markerSize; var caption:TextField=new TextField ();//创建一个对象 caption.y=1; caption.x=position.x/2;//显示在柱子的中间 caption.text=String(value);//显示值 UIComponent(marker).addChild(caption);//加入对象 //if we have a bad position, don't display the marker if(isNaN(position.x) || isNaN(position.y)) { this.invalidateMarker(ISeriesItemRenderer(marker)); } else if(this.isMarkerInvalid(ISeriesItemRenderer(marker))) { //initialize the marker to the origin marker.x = originPosition; marker.width = 0; if(marker is UIComponent) { (marker as UIComponent).drawNow(); } this.validateMarker(ISeriesItemRenderer(marker)); } //stupid Flash UIComponent rounding! position.x = Math.round(position.x); originPosition = Math.round(originPosition); var calculatedWidth:Number = originPosition - position.x; if(calculatedWidth < 0) { calculatedWidth = Math.abs(calculatedWidth); position.x = Math.round(originPosition); //always put the marker on the origin marker.x = position.x; } startValues.push(marker.x, marker.width); endValues.push(position.x, calculatedWidth); } //handle animating all the markers in one fell swoop. if(this._animation) { this._animation.removeEventListener(AnimationEvent.UPDATE, tweenUpdateHandler); this._animation.removeEventListener(AnimationEvent.COMPLETE, tweenUpdateHandler); this._animation = null; } //don't animate on livepreview! if(this.isLivePreview || !this.getStyleValue("animationEnabled")) { this.drawMarkers(endValues); } else { var animationDuration:int = this.getStyleValue("animationDuration") as int; var animationEasingFunction:Function = this.getStyleValue("animationEasingFunction") as Function; this._animation = new Animation(animationDuration, startValues, endValues); this._animation.addEventListener(AnimationEvent.UPDATE, tweenUpdateHandler); this._animation.addEventListener(AnimationEvent.COMPLETE, tweenUpdateHandler); this._animation.easingFunction = animationEasingFunction; } }
增加右键菜单的功能是因为我想在鼠标移动到某个柱子上面,可以有相应的交互。其实用EXT的menu也可以实现,但是会有响应的问题,也就是说会发生点击不准,响应失败的问题,而用flash的右键,则不会产生这种问题,而且更加的好看。响应的修改方法如下:
打开Charts.as.
首先在flash中增加方法,可以接受JS传来的右键菜单名:找到方法initializeComponent,在其中加入
//custom ExternalInterface.addCallback("setMenuInfo",setMenuInfo)
实现setMenuInfo方法
public function setMenuInfo(value:String):void{ var info:Object = JSON.decode(value as String); _menuInfo=info; }
增加Charts的本地变量_menuInfo
protected var _menuInfo:Object; public function get MenuInfo():Object{ return this._menuInfo; }
这样flash就能接受菜单信息了。接受到菜单信息后,就可以建立菜单了。建立菜单我是安排在数据显示的时候,因为想这种只是针对series的右键菜单,必须在Series中生成,而且是针对每个Series创建。
com.yahoo.astra.fl.series.Series.as是ColumnSeries和BarSeries的基类,所以在这里就可以解决掉问题。
加入菜单对象
private var _menuInfo:Object; public function get menuInfo():Object{ return this._menuInfo; } public function set menuInfo(value:Object):void{ this._menuInfo=value; build_right_click_menu(); } private function onContextMenuHandler(event:ContextMenuEvent):void { } private function build_right_click_menu(): void { //本函数主要的难点在于鼠标对象的获取 var cm:ContextMenu = new ContextMenu(); cm.addEventListener(ContextMenuEvent.MENU_SELECT, onContextMenuHandler); cm.hideBuiltInItems(); var items:Array=this._menuInfo.items as Array; for (var i:int=0;i<items.length;i++){ var item:String=items[i]; var fs:ContextMenuItem = new ContextMenuItem(item); fs.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT,function doSomething(e:ContextMenuEvent):void { //获取当前Series不能用this,用如下方法,可以获取当前的Series var ser:Series=Series(e.contextMenuOwner); //获取当前菜单序号 var index:int=-1; for (var j:int=0;j<(ser._menuInfo.items as Array).length;j++){ if (ser._menuInfo.items[j]==ContextMenuItem(e.currentTarget).caption) index=j; } if(ExternalInterface.available){ var param:String=JSON.encode(_lastItem);//将对象编码为字符串 ExternalInterface.call("executeFlashMenu",param,index); }////执行JS函数 }); cm.customItems.push( fs ); } // OFC CREDITS this.contextMenu = cm; }
private var _lastItem:Object;//鼠标当前停留的item对象,利用以下方法进行获取
protected function markerRollOverHandler(event:MouseEvent):void { var itemRenderer:ISeriesItemRenderer = ISeriesItemRenderer(event.currentTarget); var index:int = this.itemRendererToIndex(itemRenderer); var item:Object = this.dataProvider[index]; _lastItem=item; var rollOver:ChartEvent = new ChartEvent(ChartEvent.ITEM_ROLL_OVER, index, item, itemRenderer, this); this.dispatchEvent(rollOver); }
在Charts的setDataProvider方法中加入
public function setDataProvider(value:Array):void { var dataProvider:Array = []; var seriesCount:int = value.length; var seriesStyles:Array = []; for(var i:int = 0; i < seriesCount; i++) { var dataFromJavaScript:Object = value[i]; var currentData:ISeries = this.chart.dataProvider[i] as ISeries; var seriesType:Class = SeriesSerializer.shortNameToSeriesType(dataFromJavaScript.type ? dataFromJavaScript.type : this.type); var series:ISeries; if(currentData && getDefinitionByName(getQualifiedClassName(currentData)) == seriesType) { //reuse the series if possible because we want animation series = SeriesSerializer.readSeries(dataFromJavaScript, currentData); } else { series = SeriesSerializer.readSeries(dataFromJavaScript); } dataProvider[i] = series; series.menuInfo=this._menuInfo;//将菜单信息赋值给每个柱子对象 //this is where we parse the individual series styles, and we convert them //to the format the chart actually expects. //we fill in with defaults for styles that have not been specified if(dataFromJavaScript.style) { seriesStyles.push(dataFromJavaScript.style); } else seriesStyles.push(null); }
EXT的JS修改如下
重载Ext.chart.StackedBarChart 的refresh方法,
refresh : function(){ if (this.store==undefined) { return ; } var styleChanged = false; // convert the store data into something YUI charts can understand var data = [], rs = this.store.data.items; for(var j = 0, len = rs.length; j < len; j++){ data[j] = rs[j].data; } var Number=40; //this.setHeight(Number*rs.length); //make a copy of the series definitions so that we aren't //editing them directly. var dataProvider = []; var seriesCount = 0; var currentSeries = null; var i = 0; if(this.series){ seriesCount = this.series.length; for(i = 0; i < seriesCount; i++){ currentSeries = this.series[i]; var clonedSeries = {}; for(var prop in currentSeries){ if(prop == "style" && currentSeries.style !== null){ clonedSeries.style = Ext.encode(currentSeries.style); styleChanged = true; //we don't want to modify the styles again next time //so null out the style property. // this causes issues // currentSeries.style = null; } else{ clonedSeries[prop] = currentSeries[prop]; } } dataProvider.push(clonedSeries); } }else { } if(seriesCount > 0){ for(i = 0; i < seriesCount; i++){ currentSeries = dataProvider[i]; if(!currentSeries.type){ currentSeries.type = this.type; } currentSeries.dataProvider = data; } } else{ dataProvider.push({type: this.type, dataProvider: data}); } if (this.menuTitles!='')//增加menuTitles属性 { this.swf.setMenuInfo(this.menuTitles);//调用flash的setMenuInfo方法 } try{ this.swf.setDataProvider(dataProvider); }catch(e){ } }
//增加属性 menuTitles:'', setMenuInfo:function(infoStr){ //设置菜单值 this.menuTitles=infoStr; }
增加函数 ,可以由点中flash右键菜单的时候调用
function executeFlashMenu(dataItem,itemIndex){}
组织菜单对象,然后传入至flash
var items=new Array(); for (var i=0;i<menuInfo.items.length ;i++ ) { items.push(menuInfo.items[i].text); } var menus=new Object(); menus.items=items; stackedBarChart.setMenuInfo(Ext.util.JSON.encode(menus));
评论
4 楼
grzrt
2012-03-08
不错,学习下
3 楼
sunjilu05
2010-09-24
好强!学习中!
2 楼
vishare
2010-09-10
终于找到我想要了的...谢谢分享
1 楼
yanxianggt
2010-05-18
楼主可有方法改变Y轴坐标的起始值
每次都从0开始,造成图形的变化趋势太小
根本没有使用价值
每次都从0开始,造成图形的变化趋势太小
根本没有使用价值
相关推荐
Charts.swf可能是一个预编译的Flex图表组件示例,用于展示如何在Flex应用中创建和使用各种图表。在Flex中,开发者可以利用mx.charts或spark.charts包下的类来创建各种图形,如柱状图、折线图、饼图等,这些图表通常...
在压缩包文件"flex chart"中,可能包含了示例代码、FLA文件(Flash的工程文件)以及编译后的SWF文件,供你直接运行和学习。通过这些资源,你可以更深入地理解如何在Flex 4.5中实现单线和双线线性图表,以及如何根据...
在Flex中,我们可以使用`mx.charts.ColumnChart`类来创建柱状图。这个类提供了丰富的自定义选项,包括颜色、样式、动画效果等,以满足各种需求。 首先,我们来看`library.swf`文件。这是一个包含预编译的Flex组件库...
在Flex中,雷达图(也称为蜘蛛图或网络图)通常通过使用mx.charts.RadarChart类来创建。RadarChart类提供了一系列属性和方法,允许开发者定制图表的外观和行为,包括轴的数量、刻度间隔、数据系列的样式以及交互性等...
这对于动态数据的展示特别重要,因为它允许开发者在不重新编译SWF的情况下更新图表数据。 4. **Using dynamic data with charts**:动态数据是Amchart的一个关键特性。这里会教用户如何利用XML或者JSON数据源实时...
4. `FlexMxmlServlet`和`FlexSwfServlet`的初始化参数`load-on-startup`决定了它们在服务器启动时的加载顺序,`FlexMxmlServlet`先于`FlexSwfServlet`加载,因为MXML编译必须在SWF检索之前完成。 配置完成后,你...
2. 编译Flex应用:将Flex源代码编译为SWF文件。 3. 集成到Web Dynpro:在Web Dynpro中嵌入SWF文件,通过FlexBridge实现与Java控制器的通信。 4. 数据交换:利用LiveCycle Data Services ES或Web服务在Flex和SAP后端...
3. **explorer.swf**:这是一个SWF文件,即ShockWave Flash文件,它是Flex编译后的可执行文件,包含实际的Flex应用程序。通过Flash Player或AIR运行时,用户可以在浏览器或桌面环境中运行这个SWF,体验Flex应用的...
- 最后编译生成SWF文件,可在Flash Player中运行。 3. **关键点**: - **Controls**是可交互的组件,如按钮、文本框等。 - **Containers**是包含和管理其他组件的对象,如Panel、Canvas。 - **Effects**为组件...
2. **bin-debug目录:** 编译后的*.swf文件将默认存储在此目录下。 #### 五、Flex开发模式 1. **设计模式:** 提供了“所见即所得”的开发方式,开发者可以直接在设计面板上添加和调整控件。 2. **代码编写模式:*...