This project is read-only.

Issue with Vertical Axis and Removing/Adding lines.

Jun 4, 2010 at 7:37 PM
Edited Jun 4, 2010 at 8:09 PM

Setup:

I have a chart with a Header label and a VerticalAxisTitle, and some simple CompositeDataSources in it.

 

I want to be able to remove all of the line and marker graphs within this chart, and subsequently add new ones to the chart.

I am able to do this just fine if I link the remove to one button, and the add to a separate button.  However, if I try to link both the remove, and the add lines to the same button, my Left Margin of my graph will cover half of my axis labels, every other time I click the button.  This is obviously really annoying, and I believe it has something to do with the order of the way the UI dispatcher, and the DataSource collection dispatchers are interacting at different speeds and different times.

 

This is extremely easy to reproduce, using the "PlotterLayoutSample" project in the samples/v0.2 folder, simply add another MenuItem to refresh the Chart, then call "plotter.RemoveAll(typeof(LineGraph)" followed by creating a simple data source and then calling AddLine on it...here is my refresh function:

 

 

        private void UpdateGraphData()
        {
            plotter.Children.RemoveAll(typeof(LineGraph));
            plotter.Children.RemoveAll(typeof(MarkerPointsGraph));
            const int N = 100;
            double[] x = new double[N];
            double[] cs = new double[N];
            double[] sn = new double[N];

            for (int i = 0; i < N; i++)
            {
                x[i] = i * 0.1;
                cs[i] = Math.Sin(x[i]);
                sn[i] = Math.Cos(x[i]);
            }

            // Add data sources:
            // 3 partial data sources, containing each of arrays
            var snDataSource = new EnumerableDataSource<double>(sn);
            snDataSource.SetYMapping(y => y);

            var xDataSource = new EnumerableDataSource<double>(x);
            xDataSource.SetXMapping(lx => lx);

            var csDataSource = new EnumerableDataSource<double>(cs);
            csDataSource.SetYMapping(y => y);

            // 2 composite data sources and 2 charts respectively:
            // creating composite data source
            CompositeDataSource compositeDataSource1 = new CompositeDataSource(xDataSource, snDataSource);
            //// adding graph to plotter
            ////compositeDataSource1 = (CompositeDataSource)(
            plotter.AddLineGraph(compositeDataSource1,
            new Pen(Brushes.DarkGoldenrod, 3),
            new CirclePointMarker { Size = 10, Fill = Brushes.Red },
            new PenDescription("Sin"));//.LineGraph.DataSource);

            // creating composite data source for cs values
            CompositeDataSource compositeDataSource2 = new CompositeDataSource(xDataSource, csDataSource);
            // Adding second graph to plotter
            plotter.AddLineGraph(compositeDataSource2,
            new Pen(Brushes.Blue, 3),
            new TrianglePointMarker { Size = 20, Fill = Brushes.Blue },
            new PenDescription("Cos")); 
  }

Edit: accidentally submitted...

 I tried forcing them to remove and add via the object's dispatcher, but that didn't fix it...and I've thrown multiple plotter.FitToView() calls to no avail...

Edit2: I appear to have found a workaround...

Create a list of elements to remove, after adding new ones, remove all of the old ones

 

Sep 20, 2010 at 5:36 PM

Can you explain your 'workaround' a bit more; I'm having nearly identically the same problem as you explained here.  In my code, the application itself is taking 'realtime' data and every second I need to update the current plot with the new, just-taken, data.  To do this, I create an object to hold the 'currentGraph' and then, each second, I remove that graph and add the new one.  With every other data display, I get the half-covered vertical axis labels issue you described.

Thanks for the advice!

Sep 20, 2010 at 5:49 PM

For your issue, i would recommend just using the ObservableDataSource, with the Append function to add another data point.

 

My workaround was fairly simple, all I did was loop through all of the elements of the chart and add to a list all of the elements i wanted to delete.  In my case, this was just all of the LineGraph and MarkerGraph types.

 

After adding those to a list, I added the new lines that I wanted to add.

 

Finally, I looped through all of the items in the list of items to remove, and called Chart.Children.Remove(item) so in code:

 

For Each child As IPlotterElement In chart.Children
    If TypeOf child Is LineGraph OrElse _
        TypeOf child Is MarkerPointsGraph Then
                
        RemoveList.Add(child)
    End If
Next

'Add my items

For Each child In RemoveList
    chart.Children.Remove(child)
Next

Jan 18, 2011 at 6:15 PM

thanks for the answer to this question, i was amazed there is not a removegraph method ...

i've wrapped the method you mention as follows:

 private void ClearPlotter() {
    foreach (var elem in this.plotter.Children.Where( e => e is LineGraph || e is MarkerPointsGraph).ToArray()) {
        this.plotter.Children.Remove(elem);
    }
}

Jan 21, 2011 at 3:17 AM

There is an extension method that can be used to remove graphs.  It's in the extension class PlotterChildrenCollectionExtensions

         Plotter.Children.RemoveAll<LineGraph>();            
	Plotter.Children.RemoveAll<MarkerPointsGraph>();

Grant.

Nov 8, 2011 at 9:31 AM

Hi all,

 

I have encountered the overriding tick issue too.

I fixed it using two changes:

1. when creating CompositeDataSource, first give the y axis data, and then give the x axis data - CompositeDataSource compositeDataSource1 = new CompositeDataSource(snDataSource, xDataSource);

2. I removed the y axis declaration from the XAML, I only left the X axis because it is a datetime axis.

Worked for me...

Good luck.