2

MsChart を使用して時間に対してポイントをプロットするプロジェクトに取り組んでいます。私の問題は、時間が進むにつれて MsChart の速度が低下することです。毎秒127ポイント更新しています。(128Hz) これは私の最悪のケースです。時間スケールと間隔が固定されています。私が観察したのは、ポイントの更新ごとに MsCHart が完全なグラフを再描画することです (これはオーバーヘッドです)。これを一部の更新または新しいポイントのみの更新に変更するオプションはありますか?

前もって感謝します。

4

1 に答える 1

1

ChartArea の一部だけを更新する方法がわかりません。ただし、チャートを最適化するためにいくつかのヒントを使用します。

  • まず、シリーズに表示するために最も最適化された ChartType を使用します

列挙:

SeriesChartType.FastLine
SeriesChartType.FastPoint
  • また、新しいポイントを追加する前に、 Series コレクションに.SuspendUpdates()and.ResumeUpdates()メソッドを適用します。

例:

myChart.Series.SuspendUpdates();

// Adding points
...

myChart.Series.ResumeUpdates();
  • また、X 軸の最小最大範囲を調整して、すべてのポイントのサブセットのみを表示すると役立つ場合があります。

十分でない場合は、要件が MsChart の機能を超えている可能性があります。

この場合、ZedGraphライブラリに切り替えることをお勧めします。古いものですが、フットプリントとパフォーマンスの点で今でも最高であり、決してがっかりすることはありません.


編集

ZedGraph が悪い結果を出したことに驚いたので、仕様に合わせて最善を尽くす簡単で汚いzedgraph サンプルをここに置きます。

  • RollingPointPairList (特殊な FIFO ポイント リスト) で 3600 の 128hz ドットを処理します。
  • 1秒ごとにグラフに128ドットを追加します

Form_Load イベントにコピーして貼り付けて、試してみてください。ランダムな値を使用し、開始時にチャート全体を表示するため、一見非常に見苦しく見えるかもしれません。

ただし、マウスの選択とホイールを使用してズームするか、Ctrl キーを押しながらクリックしてマウスを動かしてパンし、パフォーマンスが期待どおりかどうかを確認します。

var fq = 128; // Freq in hz
var maxDuration = 3600; // max duration in s

var zg1 = new ZedGraphControl();
zg1.Dock = DockStyle.Fill;
this.Controls.Add(zg1);

var myPane = zg1.GraphPane;
myPane.XAxis.Type = AxisType.Date;
myPane.XAxis.Scale.Format = "yyyy/MM/dd HH:mm:ss.mmm";

var list = new RollingPointPairList(maxDuration * fq);

var ran = new Random();
var getRandomValue = new Func<double, double, double>((min, max) => ran.NextDouble() * (max - min) + min);

var ts = DateTime.Now;

for (var i = 0; i < list.Capacity; i++)
{
    list.Add(new XDate(ts), getRandomValue(50d, -50d));
    ts = ts.AddMilliseconds(1000d / fq);
}

var myCurve = new LineItem("dots", list, Color.Red, SymbolType.None, 1);
myCurve.Line.IsOptimizedDraw = true;
myPane.CurveList.Add(myCurve);

zg1.AxisChange();
zg1.Invalidate();

var z = new Timer();
z.Interval = 1000;
z.Tick += (s, ev) =>
    {
        var points = myCurve.Points as RollingPointPairList;
        for (var i = 0; i < fq; i++)
        {
            points.Add(new XDate(ts), getRandomValue(50d, -50d));
            ts = ts.AddMilliseconds(1000d / fq);
        }

        zg1.Invalidate();
    };

z.Start();
于 2013-02-22T06:48:30.427 に答える