PlotChart / LineChart вертикальный линейный градиент на ряду линий - PullRequest
2 голосов
/ 06 декабря 2008

Я хочу построить компонент LineChart, где цвет линии указывает на то, насколько высоко это значение. Я должен быть в состоянии сделать эту покупку, просто используя градиентный ход (см. Ниже), но по какой-то причине градиент идет только слева направо, а свойство «угла» игнорируется. Как я мог это сделать?

    <mx:PlotChart id="bpChart" width="514" height="144" dataProvider="{measurementsXLC}"   >
    <mx:series>
        <mx:LineSeries id="bpSeries" displayName="Series 1" yField="value" xField="date" showDataEffect="fade" stroke="{lstroke}">
            <mx:lineStroke>
                <mx:LinearGradientStroke angle="270.0" weight="3"  scaleMode="vertical"  >
                    <mx:entries>
                        <mx:GradientEntry color="#ff0000" ratio="0.0"/>
                        <mx:GradientEntry color="#00ff00" ratio="1.0"/>                         
                    </mx:entries>
                </mx:LinearGradientStroke>
            </mx:lineStroke>
            <mx:itemRenderer>
                <mx:Component>
                    <mx:CircleItemRenderer >

                    </mx:CircleItemRenderer>
                </mx:Component>                 
            </mx:itemRenderer>
        </mx:LineSeries>
        <mx:LineSeries id="bpSeries2" displayName="Series 1" yField="value2" xField="date" showDataEffect="fade"  />
    </mx:series>
    <mx:horizontalAxis>
        <mx:DateTimeAxis id="dateAxis" dataUnits="milliseconds" labelUnits="days" />
    </mx:horizontalAxis>
    <mx:verticalAxis>
        <mx:LinearAxis baseAtZero="false" autoAdjust="true" interval="5" />

    </mx:verticalAxis>
</mx:PlotChart>

Ответы [ 2 ]

3 голосов
/ 01 августа 2012

После того, как я столкнулся с той же проблемой и использовал приведенное выше объяснение / пример Джеймса Хэя, я создал свой собственный LineSegmentRenderer.

По сути, я хотел, чтобы в моей линейной диаграмме был градиент сверху вниз. Я также обнаружил, что угол или, точнее, свойство поворота LinearGradientStroke не было эффективным в LineSegmentRenderer, поэтому я сделал копию ShadowLineRenderer и отредактировал его метод updateDisplayList (см. Код ниже).

В этом методе updateDisplayList для свойства LineSeries lineStroke установлено значение LinearGradientStroke, поэтому я мог бы использовать записи цвета обводки, которые установлены в модуле MXML «вызывающий» / lineChart, где также задан вес обводки.

Я обнаружил, что важной частью создания градиента сверху вниз является использование GradientBox при определении lineGradientStyle. Для градиента сверху вниз свойство вращения GradientBox установлено в PI / 2 (эквивалентно 90 градусам). Вероятно, можно получить это свойство поворота (используя преобразование градусов в радианы) из свойства поворота штриха (которое можно установить в свойстве LineSeries LineSeries), чтобы вы могли избежать жесткого кодирования свойства поворота в этом рендерере, но вместо этого сделать его настраиваемым параметром при использовании этого пользовательского рендерера.

См. Код:

        override protected function updateDisplayList(unscaledWidth:Number,
                                                  unscaledHeight:Number):void
    {
        super.updateDisplayList(unscaledWidth, unscaledHeight);

        var stroke:LinearGradientStroke = getStyle("lineStroke");
        var form:String = getStyle("form");
        var gradientBoxMatrix:Matrix = new Matrix();
        gradientBoxMatrix.createGradientBox(unscaledWidth,0.9*(unscaledHeight),Math.PI/2,0,-0.05*(unscaledHeight));
        graphics.clear();
        graphics.lineStyle(stroke.weight,0);

        graphics.lineGradientStyle(GradientType.LINEAR,[stroke.entries[0].color,stroke.entries[1].color],[1,1],[0,255],gradientBoxMatrix);

        graphics.moveTo(_lineSegment.items[_lineSegment.start].x,_lineSegment.items[_lineSegment.start].y);
        graphics.lineTo(_lineSegment.items[_lineSegment.end].x,_lineSegment.items[_lineSegment.end].y);
    }
1 голос
/ 20 января 2009

Я ожидаю, что вам потребуется создать пользовательский lineSegmentRenderer для диаграммы серии линий. Текущий lineSegmentRenderer является ShadowLineRenderer. Не решая саму всю проблему, я создал бы новый класс на основе ShadowLineRenderer и изменил метод updateDisplayList, чтобы нарисовать линию точно так, как вам нужно. Затем измените свойство lineSegmentRenderer вашей серии строк, чтобы использовать этот рендерер.

Если это поможет, мне пришлось сделать очень похожую вещь, но с AreaRenderer. Градиент области должен был быть основан на итоговой диаграмме, а не окрашивать полный градиент для любой отображаемой области (например, с помощью обычного AreaRenderer, если область только покрывает первые 20% оси y, она все еще использовала полный градиент, который был нежелательной особенностью для моего проекта). Вот решение моей проблемы, где я создал свой собственный AreaRenderer и обновил метод updateDisplayList:

override protected function updateDisplayList(unscaledWidth:Number,
                                                  unscaledHeight:Number):void
    {
        super.updateDisplayList(unscaledWidth, unscaledHeight);

        var fill:IFill = GraphicsUtilities.fillFromStyle(getStyle("areaFill"));
        var stroke:IStroke = getStyle("areaStroke");
        var form:String = getStyle("form");

        var g:Graphics = graphics;
        g.clear();

        if (!_area)
            return;

        var boundary:Array /* of Object */ = _area.filteredCache;
        var n:int = boundary.length;
        if (n <= 1)
            return;

        var xMin:Number;
        var xMax:Number = xMin = boundary[0].x;
        var yMin:Number;
        var yMax:Number = yMin = boundary[0].y;

        var i:int;
        var v:Object;

        for (i = 0; i < n; i++)
        {
            v = boundary[i];

            xMin = Math.min(xMin, v.x);
            yMin = Math.min(yMin, v.y);
            xMax = Math.max(xMax, v.x);
            yMax = Math.max(yMax, v.y);

            if (!isNaN(v.min))
            {
                yMin = Math.min(yMin, v.min);
                yMax = Math.max(yMax, v.min);
            }
        }

        if (fill)
            fill.begin(g, new Rectangle(0, 0, unscaledWidth, unscaledHeight));

        GraphicsUtilities.drawPolyLine(g, boundary, 0, n,
                                        "x", "y", stroke, form);

        g.lineStyle(0,0,0); 

        if(boundary[0].element.minField != null && boundary[0].element.minField != "")
        {
            g.lineTo(boundary[n - 1].x, boundary[n - 1].min);       

            GraphicsUtilities.drawPolyLine(g, boundary, n - 1, -1,
                                            "x", "min", noStroke, form, false);
        }
        else
        {
            g.lineTo(boundary[n - 1].x, _area.renderedBase);        
            g.lineTo(boundary[0].x, _area.renderedBase);
        }

        g.lineStyle(0, 0, 0);
        g.lineTo(boundary[0].x, boundary[0].y);

        g.endFill();
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...