NPE in AxisRenderer when stacked column chart has one data item
错误信息:
I have been unable to create a simple test-case that reproduces this error, but I think a code inspection shows a problem. I've also been unable to get any help with a workaround on the Adobe forums or flexcoders.
The error is a null pointer exception when a stacked column chart has a single data item.
In AxisRenderer.as (line 2200 in sdk3.3) we find a reference to "lastLabel" which will be null if there is only one label, because it is computed as _labels[1].
Excerpt from AxisRenderer.calcStaggeredSpacing:
lastLabel = _labels[1];
if (adjustable.left == false)
{
staggeredScale = Math.min(
staggeredScale,
staggeredleftGutter / (firstLabel.width / 2));
}
if (adjustable.right == false)
{
staggeredScale = Math.min(
staggeredScale,
staggeredrightGutter / (lastLabel.width / 2)); // (me) Here's where the NPE occurs.
}
Stack Crawl:
__________
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at mx.charts::AxisRenderer/calcStaggeredSpacing()[C:\work\flex\dmv_automation\proj ects\datavisualisation\src\mx\charts\AxisRenderer.as:2200]
at mx.charts::AxisRenderer/calcRotationAndSpacing()[C:\work\flex\dmv_automation\pr ojects\datavisualisation\src\mx\charts\AxisRenderer.as:1591]
at mx.charts::AxisRenderer/adjustGutters()[C:\work\flex\dmv_automation\projects\da tavisualisation\src\mx\charts\AxisRenderer.as:1331]
at mx.charts::AxisRenderer/set gutters()[C:\work\flex\dmv_automation\projects\datavisualisation\src\mx\charts\ AxisRenderer.as:803]
at mx.charts.chartClasses::CartesianChart/updateAxisLayout()[C:\work\flex\dmv_auto mation\projects\datavisualisation\src\mx\charts\chartClasses\CartesianChart.as:2 032]
at mx.charts.chartClasses::CartesianChart/updateDisplayList()[C:\work\flex\dmv_aut omation\projects\datavisualisation\src\mx\charts\chartClasses\CartesianChart.as: 1359]
at mx.core::UIComponent/validateDisplayList()[C:\autobuild\3.3.0\frameworks\projec ts\framework\src\mx\core\UIComponent.as:6351]
at mx.managers::LayoutManager/validateDisplayList()[C:\autobuild\3.3.0\frameworks\ projects\framework\src\mx\managers\LayoutManager.as:622]
at mx.managers::LayoutManager/doPhasedInstantiation()[C:\autobuild\3.3.0\framework s\projects\framework\src\mx\managers\LayoutManager.as:695]
at Function/http://adobe.com/AS3/2006/builtin::apply()
at mx.core::UIComponent/callLaterDispatcher2()[C:\autobuild\3.3.0\frameworks\proje cts\framework\src\mx\core\UIComponent.as:8633]
at mx.core::UIComponent/callLaterDispatcher()[C:\autobuild\3.3.0\frameworks\projec ts\framework\src\mx\core\UIComponent.as:8573]
Context from AxisRenderer:
(Note: the second branch of the if statement is executing, thus adjustment.bottom is false which leads to the code path with the bug.)
public function set gutters(value:Rectangle):void
{
var correctedGutters:Rectangle = value;
// This check will rarely succeed, because _gutters
// have been tweaked to represent placement.
if (_gutters &&
_gutters.left == correctedGutters.left &&
_gutters.right == correctedGutters.right &&
_gutters.top == correctedGutters.top &&
_gutters.bottom == correctedGutters.bottom)
{
_gutters = correctedGutters;
return;
}
else
{
adjustGutters(value,
{ left: false, top: false, right: false, bottom: false });
}
}
I am building the series list dynamically, it's a stacked column chart, and for me the bug occurs when there is one series and one data point.
I haven't been able to trigger the bug with the following example, which has a similar structure to my actual code.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" xmlns:local="*">
<mx:Script>
<![CDATA[
import mx.charts.series.ColumnSeries;
import mx.charts.chartClasses.Series;
[Bindable]
public var seriesList:Array = [];
public function buildSeriesList(seriesList:Array):Array {
var chartSeries:Array = new Array();
var index:int = 0;
for each (var series:Object in seriesList) {
var columnSeries:ColumnSeries = new ColumnSeries();
columnSeries.dataProvider = series.items;
columnSeries.dataFunction = myDataFunction;
columnSeries.displayName = series.category;
chartSeries.push( columnSeries );
}
return chartSeries;
}
private function categoryProvider(seriesList:Array):Array {
if (seriesList && seriesList.length > 0)
return (seriesList[0]).items;
return null;
}
private function myDataFunction(series:Series, item:Object, fieldName:String):Object {
if(fieldName == "yValue") {
return item.value;
}
else if(fieldName == "xValue") {
return item.category;
}
else
return null;
}
public function shortCategoryLabel(source:String):String {
return source;
}
public function longCategoryLabel(source:String):String {
return source;
}
private function onRefresh(event:Event):void {
this.seriesList = [ { category: "cat1" , items: [ { category: "Default Business Unit", value:574.1 }] }];
}
]]>
</mx:Script>
<mx:Button label="Refresh" click="onRefresh(event)" />
<mx:ColumnChart height="100%"
width="100%" type="stacked" series="{this.buildSeriesList(this.seriesList)}">
<mx:horizontalAxis>
<mx:CategoryAxis id="bottomAxis2" title="Horizontal Axis"
dataProvider="{this.categoryProvider(this.seriesList)}"
categoryField="category"
/>
</mx:horizontalAxis>
<mx:verticalAxis>
<mx:LinearAxis id="leftAxis2" title="Vertical Axis"/>
</mx:verticalAxis>
<mx:verticalAxisRenderers>
<mx:AxisRenderer
placement="left" styleName="verticalAxisRenderer"
axis="{leftAxis2}" verticalAxisTitleAlignment="vertical"
/>
</mx:verticalAxisRenderers>
<mx:horizontalAxisRenderers>
<mx:AxisRenderer
placement="bottom"
axis="{bottomAxis2}" verticalAxisTitleAlignment="flippedVertical"
>
</mx:AxisRenderer>
</mx:horizontalAxisRenderers>
</mx:ColumnChart>
</mx:Application>
解决方法:
In case someone still has this problem, here a quick fix.
Add an creationComplete event to your AxisRenderer:
<mx:AxisRenderer id="horizontalAR"
creationComplete="handleHAxisRendererCreationComplete(event)"
axis="{myHAxis}" />
<Script>
private function handleHAxisRendererCreationComplete(event:FlexEvent):void
{
var axisRenderer:AxisRenderer = event.target as AxisRenderer;
axisRenderer.setStyle('canStagger', (axisRenderer.numChildren == 1) ? false : true);
}
</Script>
原文地址:https://bugs.adobe.com/jira/browse/FLEXDMV-2275
分享到:
相关推荐
Flex ColumnChart 样式设置,详细设置。
该flex应用程序演示了柱状图动态切换数据源 <mx:ColumnChart x="6" y="65" id="columnchart1" showDataTips="true" dataProvider="{list}" height="390" itemClick="onItemClick(event)"> 苹果" yField...
针对flex新手熟悉flash builde控件
Flex ColumnChart获取得焦点改变颜色
Flex ColumnChart 间隔(space)设置一方法参考实现; ChartFunc.as ChartTest.mxml
flex4 3D ColumnChart
在页面上动态创建columnchart 图表!其中也有数据的一些处理,是我这里项目中需要的。不过至少对于我这个动态创建机制还是需要的。 Dynamically created on the page columnchart Chart! Some of which also have ...
包括了Flex柱状图动态效果和不同的颜色效果,其中包括demo源代码和柱状图的源代码,非常实用 运行的时候直接双击test.html即可看到漂亮的柱状图(Flex的ColumnChart)的动态效果
NULL 博文链接:https://wuxiubing.iteye.com/blog/906805
该工程简介: 这个工程是用flex画图表...6、该工程加载的是外部数据,数据存放在一个专门的文件(data.xml)中 注:鉴于本人以前在网上下的很多demo是不完整的不能运行的,再次保证本demo是可以运行的完整工程包
提供了extjs的报表插件的用法[动态和静态皆有]
基于FLEX4多功能柱状统计图,包括了分组统计图、单项统计图...运行示例ColumnChart1时,需要根据你BigFontLegendItem类的具体位置,去修改你的MXML的legendItemClass属性,如果不想设置图例文字大小,删掉此属性即可。
当它们的数据更改时,会设置动画的ColumnChart,BarChart,LineChart和PieChart。 这些图表的数据是代表百分比的Double值数组。 为了使事情变得容易一些,有一个ChartModel可以使用Double的任何数组并将其转换为百分...
extjs为ColumnChart设置不同的颜色想必有很多朋友还是比较陌生的吧,接下来为大家详细介绍下具体设置代码,感兴趣的朋友可以参考下哈
flash builder建的actionscript项目,flash chart,现实了legend交互,多数据提示,双轴坐标,格式化坐标显示(可带单位),piechart,linechart,columnchart,combinechart(混合图表)
关于Flex中各种图形的例子 LineChart Columnchart Areachart Bubblechart Barchart 的例子 数据从后台的Java类获取 也可以从数据库获取
amCharts(.NET版)图形报表的使用实例 带VS2010工程文件 可直接运行...<cc1:ColumnChart runat="server" ID="ColumnChart1"></cc1:ColumnChart> 线型图 <cc1:LineChart runat="server" ID="LineChart1"></cc1:LineChart>
WinRTXamlToolkit.Controls.DataVisualization.Charting图形报表下自定义控件,分为单组数据图形使用SingleChart用户控件和多组数据图形使用MixedChart用户控件。传递数据集合和其它参数,让图形按需展示。 一、...