Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic Data Display charting: change Y axis range

Does anyone know if is there any way to change the Y axis limits on a line chart from D3?

I'm using the last version from Codeplex source... The WPF one, not the Silverlight version.

I'm plotting readings from Android sensors and the range values change quite a bit. Sometimes it's around zero and the graph looks like this:

Ranging from -0.05 to +0.05

Then the magnitude of the values changes and the Y axis is rescaled to show the entire data and the graph now looks like this:

Ranging from -0.8 to + 0.6

See how the Y values changed a lot from Picture 1 to 2.

What I want is to make the Y axis with fixed values that I choose, lets say -10 to +10. Then the graph will be plot always with the same scale.

Is there any way to do that?

The XAML code for the graph is this:

    <d3:ChartPlotter
        Name="gyroGraph"
        Margin="21,5,10,0"
        Grid.ColumnSpan="2"
        Background="White"
        Grid.Row="1"
        LegendVisibility="Collapsed"
        NewLegendVisible="False"
        MainHorizontalAxisVisibility="Collapsed"
        MainVerticalAxisVisibility="Collapsed">
        <d3:VerticalAxis
            FontSize="8" />
        <d3:Header
            Content="Angular Velocity"
            FontSize="11" />
    </d3:ChartPlotter>

Thanks and best regards, Rodrigo Basniak

like image 927
rbasniak Avatar asked Jan 18 '23 07:01

rbasniak


2 Answers

Hope it is not too late, but I encountered the same problem and found a solution in d3's forum: http://dynamicdatadisplay.codeplex.com/discussions/281164

The code was created by the d3 user 'fromDKwithlove'.

This is how you should apply the Restriction:

ViewportAxesRangeRestriction restr = new ViewportAxesRangeRestriction();
restr.YRange = new DisplayRange(-5, 105);
plotter.Viewport.Restrictions.Add(restr);

And this is the class(es) behind the code:

public class DisplayRange
{
    public double Start { get; set; }
    public double End { get; set; }

    public DisplayRange(double start, double end)
    {
        Start = start;
        End = end;
    }
}

public class ViewportAxesRangeRestriction : IViewportRestriction
{
    public DisplayRange XRange = null;
    public DisplayRange YRange = null;

    public Rect Apply(Rect oldVisible, Rect newVisible, Viewport2D viewport)
    {
        if (XRange != null)
        {
            newVisible.X = XRange.Start;
            newVisible.Width = XRange.End - XRange.Start;
        }

        if (YRange != null)
        {
            newVisible.Y = YRange.Start;
            newVisible.Height = YRange.End - YRange.Start;
        }

        return newVisible;
    }

    public event EventHandler Changed;
}
like image 129
Moobie Avatar answered Jan 21 '23 13:01

Moobie


Im not sure of the exact behaviour you want - perhaps you can clarify if necessary.
I needed a fixed initial axis at a specific value with FitToView so that when the graph out grew the intial axis the axis resized automatically from then on.
To achieve this I used a FitToViewRestriction with a DomainRestriction:

<d3:ChartPlotter.FitToViewRestrictions>
    <d3:DomainRestriction Domain="0,0,10,14000"/>
</d3:ChartPlotter.FitToViewRestrictions>

Here the Domain rect is the initial view port rect that determines the initial axis limits. Setting FitToView means that the axis will scale when the graph goes outside this initial limit.

Note however that in the version of D3 that we use (0.3.4703.0) the implimentation of DomainRestriction.Apply didn't give me the behaviour I wanted so it was necessary to modify the source code there. The file concerned is DynamicDataDisplay\v0.3.4703 - Nightly src\src\DynamicDataDisplay\ViewportRestrictions\DomainRestrictions.cs.
I modified DomainRestriction.Apply to:

public override DataRect Apply(DataRect oldDataRect, DataRect newDataRect, Viewport2D viewport) {
    return (domain.IsEmpty) ? newDataRect : DataRect.Union(newDataRect, domain);
}

Which gives the behviour I described. I think you want something similar but which only applies to the x axis. I.e you want the y to stay fixed at its initial value but you want x to scale as data comes in with FitToView. Just modify the above method and you should be able to get that behaviour.

like image 21
Ricibob Avatar answered Jan 21 '23 14:01

Ricibob