自定义AxisRenderer

时间:2012-05-29 19:25:27

标签: flex flex4 flex-spark flex-charting flex-charts

我正在使用LineChart横向轴CategoryAxis,我需要每个类别都有一个非常自定义格式的显示。使用CategoryAxis.LabelFunction对我的目的来说不够强大,因为它只允许自定义格式化Label对象的文本字段。特别是对于这个项目,我需要每个类别是两个不同的多行标签的网格或HGroup。左侧标签需要左对齐,右侧需要右对齐。

我尝试创建extends Groupimplements IDataRenderer的自定义类。但是,public function set data(value:Object)中定义的IDataRenderer似乎总是被赋值为AxisLabel对象,它不会传递其中的对象,只是一个字符串({{1} })


作为一个黑客替代方案,我尝试使用LabelFunction传递编码的字符串,但即使这样也会导致问题。不知何故,此代码不会在CategoryAxis上显示任何内容:

AxisLabel.text

1 个答案:

答案 0 :(得分:1)

问题似乎是GroupAxisRenderer之间的奇怪互动,以及渲染器(HGroup)具有明确的宽度/高度值(在其构造函数中设置)的事实:

在自定义渲染器上设置data后,AxisRenderer`会告诉自定义渲染器使其大小无效。

在执行此操作时,Group正确决定不执行任何操作,因为它具有明确的宽度/高度。

我做了一些修改让这个工作:

  • 仅在构造函数中设置宽度
  • 不要在子标签上设置宽度(你很可能想玩这个)
  • 使标签对象成员变量,并在create children中只创建一次(数据的setter可能会被频繁调用)

代码:

package
{
    import mx.charts.AxisLabel;
    import mx.core.IDataRenderer;
    import mx.events.FlexEvent;

    import spark.components.HGroup;
    import spark.components.Label;

    public class HeatmapAxisLabelRenderer extends HGroup implements IDataRenderer
    {
        public function HeatmapAxisLabelRenderer()
        {
            super();
            this.width=100;
        }

        private var _data:Object;

        [Bindable("dataChange")]
        public function get data():Object {
                return _data;
        }

        private var nameLabel:Label;
        private var limit:Label;

        override protected function createChildren():void
        {
            super.createChildren();
            if (!nameLabel)
            {
                nameLabel=new Label();
                nameLabel.setStyle("textAlign","left");
                limit = new Label();
                limit.setStyle("textAlign", "right");
                addElement(nameLabel);
                addElement(limit);
            }
        }

        public function set data(value:Object):void
        {
            if (_data === value)
                return;

            _data = value;
            if (value is AxisLabel && AxisLabel(value).text!=null)
            {
                var parts:Array = AxisLabel(value).text.split("|~|");
                if (parts.length == 2)
                {
                    nameLabel.text = parts[0];
                    limit.text = parts[1];
                }
            }
            else
            {
                trace("renderer bad value");
            }
            dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
        }
    }
}