Question

I am using Open Flash Charts v2. I have been trying to make Conditional line graph. But I couldn't find any straight forward way, example or any class for producing Conditional charts.

Example of Conditional Graph Example of Conditional Graph

So I thought to use some techniques to emulate conditional graph ,I made separate Line object for values above limit range and then this line is used to overlap the plotted line.

This techniques works some what ok ,but there are problems with it,

  1. How to color or place the conditional colored line exactly above the limit.
  2. Remove tooltip and dot from limit line.
  3. Tooltip of conditional line(red) and plotted line(green) are both shown ,I only need tooltip of green line.

Conditional Line Graph Problem illustrated flash chart

Source Code: // C#

    var chart = new OpenFlashChart.OpenFlashChart();
    var data1 = new List<double?> { 1, 3, 4, 5, 2, 1, 6, 7 };//>4=
    var overlap = new List<double?> { null, null, 4, 5, null, null, null, null };
    var overlap2 = new List<double?> { null, null, null, null, null, null, 6, 7 };
    var limitData = new List<double?> { 4, 4, 4, 4, 4, 4, 4, 4 };

    var line1 = new Line();
    line1.Values = data1;
    //line1.HaloSize = 0;
    line1.Width = 2;
    line1.DotSize = 5;
    line1.DotStyleType.Tip = "#x_label#<br>#val#";
    line1.Colour = "#37c855";
    line1.Tooltip = "#val#";

    var overLine = new Line();
    overLine.Values = overlap;
    //overLine.HaloSize = 0;
    overLine.Width = 2;
    overLine.DotSize = 5;
    overLine.DotStyleType.Tip = "#x_label#<br>#val#";
    overLine.Colour = "#d81417";
    overLine.Tooltip = "#val#";

    var overLine2 = new Line();
    overLine2.Values = overlap2;
    //overLine2.HaloSize = 0;
    overLine2.Width = 2;
    overLine2.DotSize = 5;
    //overLine2.DotStyleType.Tip = "#x_label#<br>#val#";
    //overLine2.DotStyleType.Type = DotType.DOT;
    overLine2.Colour = "#d81417";
    overLine2.Tooltip = "#val#";

    var limit = new Line();
    limit.Values = limitData;
    limit.Width = 2;
    limit.Colour = "#ff0000";
    limit.HaloSize = -1;
    limit.DotSize = -1;
    // limit.DotStyleType.Tip = "";
    limit.DotStyleType.Type = null;
    //limit.Tooltip = "";

    chart.AddElement(line1);
    chart.AddElement(overLine);
    chart.AddElement(overLine2);
    chart.AddElement(limit);

    chart.Y_Legend = new Legend("Experiment");
    chart.Title = new Title("Conditional Line Graph");
    chart.Y_Axis.SetRange(0, 10);
    chart.X_Axis.Labels.Color = "#e43456";
    chart.X_Axis.Steps = 4;
    chart.Tooltip = new ToolTip("#val#");
    chart.Tooltip.Shadow = true;
    chart.Tooltip.Colour = "#e43456";
    chart.Tooltip.MouseStyle = ToolTipStyle.CLOSEST;
    Response.Clear();
    Response.CacheControl = "no-cache";
    Response.Write(chart.ToPrettyString());
    Response.End();

Note:

I have already downloaded the OFC (Open Flash Charts) source ,If I modify the OFC Line.as source than how would I be able to generate json for the changed graph ? ,b/c I'm currently using .Net library for the json generation for OFC charts,please do let me know this also.

Update:

I have modified the source code on the advice of David Mears I'm using FlashDevelop for ActionScript.

P.S: I'm open for ideas if another library can do this job.

Was it helpful?

Solution

If you don't mind a little rebuilding, you can get the source of OFC here and modify the Line.solid_line() method in open-flash-chart/charts/Line.as to do this fairly easily.

In order to set the extra chart details through JSON using the .NET library, you'll also have to modify OpenFlashChart/LineBase.cs to add alternative colour and boundary properties. I'm not hugely familiar with .NET, but based on the existing properties you might add something like this:

private double boundary;
private string altcolour;

[JsonProperty("boundary")]
public virtual double Boundary
{
    set { this.boundary = value; }
    get { return this.boundary; }
}
[JsonProperty("alt-colour")]
public virtual string AltColour
{
    set { this.altcolour = value; }
    get { return this.altcolour; }
}

Then I believe the following should work in Line.as:

public function solid_line(): void {

    var first:Boolean = true;
    var i:Number;
    var tmp:Sprite;
    var x:Number;
    var y:Number;

    var last_e:Element;
    var ratio:Number;

    for ( i=0; i < this.numChildren; i++ ) {
        // Step through every child object.

        tmp = this.getChildAt(i) as Sprite;

        // Only include data Elements, ignoring extra children such as line masks.
        if( tmp is Element )
        {
            var e:Element = tmp as Element;

            if( first )
            {
                if (this.props.get('alt-colour') != Number.NEGATIVE_INFINITY) {
                    if (e._y >= this.props.get_colour('boundary'))
                    {
                        // Line starts below boundary, set alt line colour.
                        this.graphics.lineStyle( this.props.get_colour('width'), this.props.get_colour('alt-colour') );
                    }
                    else
                    {
                        // Line starts above boundary, set normal line colour.
                        this.graphics.lineStyle( this.props.get_colour('width'), this.props.get_colour('colour') );
                    }
                }

                // Move to the first point.
                this.graphics.moveTo(e.x, e.y);
                x = e.x;
                y = e.y;
                first = false;
            }
            else
            {
                if (this.props.get('alt-colour') != Number.NEGATIVE_INFINITY) {
                    if (last_e._y < this.props.get_colour('boundary') && e._y >= this.props.get_colour('boundary'))
                    {
                        // Line passes below boundary. Draw first section and switch to alt colour.
                        ratio = (this.props.get_colour('boundary') - last_e._y) / (e._y - last_e._y);
                        this.graphics.lineTo(last_e.x + (e.x - last_e.x) * ratio, last_e.y + (e.y - last_e.y) * ratio);
                        this.graphics.lineStyle( this.props.get_colour('width'), this.props.get_colour('alt-colour') );
                    }
                    else if (last_e._y >= this.props.get_colour('boundary') && e._y < this.props.get_colour('boundary'))
                    {
                        // Line passes above boundary. Draw first section and switch to normal colour.
                        ratio = (this.props.get_colour('boundary') - last_e._y) / (e._y - last_e._y);
                        this.graphics.lineTo(last_e.x + (e.x - last_e.x) * ratio, last_e.y + (e.y - last_e.y) * ratio);
                        this.graphics.lineStyle( this.props.get_colour('width'), this.props.get_colour('colour') );
                    }
                }

                // Draw a line to the next point.
                this.graphics.lineTo(e.x, e.y);
            }

            last_e = e;
        }

    }

    if ( this.props.get('loop') ) {
        // close the line loop (radar charts)
        this.graphics.lineTo(x, y);
    }
}

With the new open-flash-chart.swf, you should be able to just set your new properties on line1:

line1.Boundary = 4;
line1.AltColour = "#d81417";
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top