3

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.

peterh
  • 11,875
  • 18
  • 85
  • 108
DayTimeCoder
  • 4,294
  • 5
  • 38
  • 61

1 Answers1

1

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";
David Mear
  • 2,254
  • 2
  • 13
  • 21
  • Well yes sure ,I had already downloaded that source code ,But I don't know Actionscript ,but I will try :) – DayTimeCoder Mar 06 '13 at 19:00
  • I have updated the question ,I'm trying your suggestion right now. – DayTimeCoder Mar 06 '13 at 19:10
  • +1 for the json tip , `Line extends Base` and you are asking me to modify `LineBase.as` I'm a little confuse here ,tell me how to modify for json ,please bear with me as I'm the Actionscript Noob :) – DayTimeCoder Mar 06 '13 at 19:44
  • I've edited my answer to be a bit more comprehensive. You will need to edit the .NET library as well (so that's LineBase.**cs**, in the dot-net-library/... folder. It's a bit more involved, but I'm guessing from your handle that you know more .NET than me! – David Mear Mar 06 '13 at 19:54
  • Dont worry about .Net I can handle that ! :) ,Just help me cross the Actionscript bridge ! – DayTimeCoder Mar 06 '13 at 19:56
  • Shud I replace `solid_line()` function with your code or fit it within somewhere solid_line() function ? – DayTimeCoder Mar 06 '13 at 20:02
  • You can just replace the whole of `solid_line()` with that code. – David Mear Mar 06 '13 at 20:04
  • It didnt worked :/ , I successfully recompiled the .swf after code changes and modified the .Net library and tested on the test project but Boundry colors didnt showed up ,the json produced did have the boundry information like `"boundary": 5, "colour": "#CC3399"` – DayTimeCoder Mar 06 '13 at 20:24
  • in the `Line.as` the code is `this.props.get_colour('alt-colour')` but in the json the data is `"boundary": 5, "colour": "#CC3399"`, don't you find it awkward ? ,I think json should use the `alt-colour` key 'instead of 'colour' – DayTimeCoder Mar 06 '13 at 20:29
  • You definitely should have an `alt-colour` property in the json somewhere. It looks like adding the `Boundary` property worked okay, have you done anything differently with `AltColour`? Even so, the alternative colour would default to black, so maybe the old swf is still cached too? – David Mear Mar 06 '13 at 20:31
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/25721/discussion-between-dotnetsoldier-and-david-mear) – DayTimeCoder Mar 06 '13 at 20:42