4

I am using oxyplot scatterline to load thousands of datapoints(around 60000 per each plotModel). It takes 2.5 seconds to update the plot view model. But I takes extra 5 seconds to render the visuals. How to improve the render speed?

In the View, it is a list view which DataTemplate is OxyPlot. Each plot is binding to a PlotModel.

In the ViewModel, we get datum from database vie the Entity Framework and update each plot model

View Code:

<ListView Grid.Column="1" ItemsSource="{Binding ArchiveRoutePlotModels , UpdateSourceTrigger=PropertyChanged, Mode=OneWay}">
    <ListView.ItemTemplate>
         <DataTemplate>
              <oxyPlot:PlotView Height="300" Width="1000" Model="{Binding RouteModel}">
              </oxyPlot:PlotView>
         </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

ViewModel Code:

    private void LoadArchiveJobRoutesMethod(string uuid)
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        if (ArchiveRoutePlotModels.Count() > 0)
        {
            ArchiveRoutePlotModels.Clear();
        }
        using (ArchiveEntities _archiveSource = new ArchiveEntities())
        {

            _archiveSource.Loggings.Where(i => i.UUID == uuid).ToList().GroupBy(p => p.RouteId, (p, v) => new
            {
                RouteId = p,
                MeasureList = v,
            }).ToList().ForEach(p =>
            {
                App.Current.Dispatcher.Invoke((Action)delegate
                {
                    this.ArchiveRoutePlotModels.Add(new RoutePlotModel()
                    {
                        RouteId = (int)p.RouteId,
                        Minimum = (int)p.MeasureList.First().Id,
                        Maximum = (int)p.MeasureList.Last().Id,
                        RouteModel = new PlotModel()
                        {
                        }
                    });
                    this.ArchiveRoutePlotModels.Last().RouteModel.Axes.Add(new LinearAxis()
                    {
                        Position = AxisPosition.Bottom,
                        Unit = "Interval",
                        Minimum = p.MeasureList.First().Id,
                        Maximum = p.MeasureList.Last().Id
                    });
                    this.ArchiveRoutePlotModels.Last().RouteModel.Axes.Add(new LinearAxis()
                    {
                        Position = AxisPosition.Left,
                        Unit = "mm",
                        Minimum = -25,
                        Maximum = 100,
                        IsZoomEnabled = false
                    });
                    this.ArchiveRoutePlotModels.Last().RouteModel.Series.Add(new ScatterSeries()
                    {
                        Title = "Route " + p.RouteId.ToString(),
                        DataFieldX = "Index",
                        DataFieldY = "Y",
                        Background = OxyColors.Transparent,
                        IsVisible = true,
                    });
                    (this.ArchiveRoutePlotModels.Last().RouteModel.Series[0] as ScatterSeries).Points.AddRange(p.MeasureList.Select(m => new ScatterPoint(m.Id, (double)m.Value / 1000000 < 80.0 ? (double)m.Value / 1000000 : 80)).ToList());
                });
            });
            sw.Stop();
        }
        SystemPrompt = "OxyPlot Archive Plot Model Loading: " + sw.ElapsedMilliseconds + "ms ; Memory Usage" + (Process.GetCurrentProcess().WorkingSet64 / (1024 *1024)) + "MB";
    }
Yuzhe Zhou
  • 157
  • 2
  • 11
  • UpdateSourceTrigger can be left out in your xaml. The ToList() might hurt performance. Code would me more readable imo if you used local variables for the RoutePlotModel and ScatterSeries. Regarding the drawing speed look into using the decimator feature of oxyplot. For the why the update is slow I'd try to divide and conquer: time different parts of your update, the slowness might not be related to oxyplot but with the handling of your date before you hand it over to oxyplot. – Herman Mar 08 '18 at 11:32
  • I seriously doubt there's really any reason to add that many points to a chart. Consider filtering it for the purposes of data visualization. If you don't need to show it "real-time", then you can also dynamically bind on demand, meaning, first add your data to your collection THEN bind it to your view. – jsanalytics Mar 22 '18 at 08:03
  • `OxyPlot` here seen rendering 193,000+ points in only 152 milliseconds. So, your 5,000 milliseconds figure needs a reality check. [Look here](https://imgur.com/wUKtraT). – jsanalytics Mar 22 '18 at 08:49
  • 2
    @jsanalytics can you, please show code example? – SolderingIronMen Dec 06 '18 at 20:06
  • @SolderingIronMen sorry i no longer have this sample... – jsanalytics Dec 08 '18 at 08:32

0 Answers0