none
Große Datenmengen in mschart einlesen RRS feed

  • Frage

  • Moin,

    ich habe eine große Datenmenge, die ich an eine FastLineSeries übergeben muss (z.B. 100000 Punkte). Die Methode AddXY ist zwar schon nicht sehr langsam, aber die schleppt ja auch eine Menge Allozierungs- und Indizierungsarbeit mit sich rum.

    Gibt es einen direkten Zugriff auf das Wertearray? Bei TeeChart für Delphi habe ich eine Eigenschaft FastLineSeries.YValues.Value, das ist ein Verweis auf das WerteArray der Y-Werte.  Dasselbe für X-Werte. Da können komplette Wertearrays übergeben werden.

    Ausserdem kann ich mit BeginUpdate und EndUpdate die Events lahmlegen und verhindern, dass Windows während der Werteübergabe versucht, neu zu zeichnen.

    Gibt es vergleichbare Möglichkeiten mit dem mschart?

    Grüße, Messie

     

    P.S. Visual Studio 2010, WinForms, .net 4


    bin neu hier...
    Dienstag, 1. März 2011 15:35

Antworten

  • Hallo Messie,

    > Ich habe eine große Datenmenge, die ich an eine FastLineSeries übergeben muss (z.B. 100000 Punkte).

    Das Chart-Steuerelement ist nicht für die Bearbeitung riesiger Datenmengen ausgelegt.  Mußt Du denn wirklich soviele Daten anzeigen? Wie groß ist den Dein Chart?

    > Die Methode AddXY ist zwar schon nicht sehr langsam, aber die schleppt ja auch eine Menge Allozierungs- und Indizierungsarbeit mit sich rum.

    Mir ist keine Methode bekannt, wie man einer Serie eine DataPointCollection direkt zuweisen könnte (außer über den Umweg über DataPoint(series)), aber folgender Code wurde auf meinem Test-Rechner in etwa 300 ms ausgeführt:

    using System;
    using System.Diagnostics;
    using System.Windows.Forms;
    using System.Windows.Forms.DataVisualization.Charting;
    
    namespace WindowsFormsApplication1
    {
      public partial class Form1 : Form
      {
        public Form1()
        {
          InitializeComponent();
        }
    
        private void buttonTest_Click(object sender, EventArgs e)
        {
          const int pointsCount = 100000;
          const int seriesCount = 1;
    
          Random rand = new Random(DateTime.Now.Millisecond);
    
          int[,] dataX = new int[seriesCount, pointsCount];
          double[,] dataY = new double[seriesCount, pointsCount];
    
          for (int seriesIndex = 0; seriesIndex < seriesCount; seriesIndex++)
          {
            for (int pointsIndex = 0; pointsIndex < pointsCount; pointsIndex++)
            {
              dataX[seriesIndex, pointsIndex] = pointsIndex + 1;
              dataY[seriesIndex, pointsIndex] = rand.NextDouble();
            }
          }
    
          Stopwatch sw = Stopwatch.StartNew();
          chart1.Series.Clear();
    
          for (int seriesIndex = 0; seriesIndex < seriesCount; seriesIndex++)
          {
            Series series = new Series { ChartType = SeriesChartType.FastLine };
            series.Points.SuspendUpdates();
    
            for (int pointIndex = 0; pointIndex < pointsCount; pointIndex++)
            {
              series.Points.AddXY(dataX[seriesIndex, pointIndex],
                        dataY[seriesIndex, pointIndex]);
            }
    
            chart1.Series.SuspendUpdates();
            chart1.Series.Add(series);
          }
    
          chart1.Invalidate();
    
          this.Text = String.Format("{0}ms", sw.ElapsedMilliseconds);
        }
      }
    }

    Vielleicht hilft Dir das weiter. Ich habe gerade wenig Zeit, aber wenn ich die hätte, würde ich einen Profiler drüber laufen lassen und schauen, was sich irgendwie noch optimieren läßt.

    Gruß
    Marcel

    Donnerstag, 3. März 2011 17:31
    Moderator