11

WPF でリアルタイム データを折れ線グラフとしてレンダリングする適切な方法を見つけようとしています。リアルタイムとは、実際には、約 40Hz のレートでデータを生成する USB デバイスから収集されるデータを意味します。複数 (最大 7 つ) のデータ ストリームがあり、非同期で 40Hz で読み取っています。

私は 2 つの既製のソリューション (WPF Toolkit チャートと Swordfish チャート) を使用してみましたが、Dynamic Data Visualization コンポーネントをほとんど調べましたが、フォーラムでいくつかのコメントを読んだ後、あきらめました。既製のチャート作成ソリューションは静的チャートを対象としているようで、実際には Windows タスク マネージャーに似たものが必要です。はるかに高速で、データ ポイントがはるかに多いだけです。

現在、私はこれまでで最もうまく機能しているように見える独自のソリューションを展開しましたが、それからより良いパフォーマンスを得ることができるように思われるため、何かが欠けていると感じています.

要件は、スライディング ウィンドウで約 10000 ポイントの一定の範囲を処理できる必要があることです。新しいデータが (40Hz で) 入ってくると、古いデータは可視範囲の左側に押し出されます。そして、このレートを少なくとも 20 ~ 30 分間維持する必要があります (データ ストリームあたり合計約 75 ~ 100,000 ポイント)。

私の現在のカスタム実装は、Shape から継承し、DefinigGeometry に StreamingGeometry を使用するコンポーネントに基づいています。デバイスから入ってくるデータはキューを介してコンポーネントに渡され、固有の「バースト効果」によりパフォーマンスが向上し、デキュー操作の後、コンポーネントは無効になります。

だから、私の質問は、私は正しい道を進んでいますか、それとも完全に間違っていますか? WPF でこのようなデータの視覚化を実現する最も効率的な方法は何ですか? どんな助けやヒントも大歓迎です。

4

4 に答える 4

5

前述のように、これを行う WPF の「標準」の方法では、必要なパフォーマンスが得られません。いくつかの無料の商用製品を試してみましたが、必要なものが得られなかったので、次の方法を試してみました。

  1. WPF ジオメトリの使用。
  2. Direct2D の使用。

どちらもまったくパフォーマンスがありませんでした。

私が知っていることの 1 つは、WPF が画像 (BitmapSource) のレンダリングに適していることです。そのため、その方向に進み、WriteableBitmapEx を使用して WriteableBitmap にグラフを描画し、それを渡すことにしました...

WriteableBitmapEx ライブラリの問題の 1 つは、GDI などの描画機能があまりないことです。では、なぜ GDI を使用しないのでしょうか。正しくやれば違いはありません。

例:

    public void BeginDraw()
    {
        _writeable_bitmap = new WriteableBitmap((int)Math.Max(_size.Width, 1), 
        (int)Math.Max(_size.Height, 1), 96.0, 96.0, PixelFormats.Pbgra32, null);

        _gdi_bitmap = new System.Drawing.Bitmap(_writeable_bitmap.PixelWidth, 
        _writeable_bitmap.PixelHeight,_writeable_bitmap.BackBufferStride,
        System.Drawing.Imaging.PixelFormat.Format32bppPArgb,
        _writeable_bitmap.BackBuffer);

        _writeable_bitmap.Lock();

        _g = System.Drawing.Graphics.FromImage(_gdi_bitmap);
        _g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

        _g.Clear(System.Drawing.Color.Transparent);
    }

    public void DrawSeries(IEnumerable<System.Drawing.PointF> points)
    {
        _g.DrawCurve(dataSeries.GdiPen, points.ToArray());
    }

    public void EndDraw()
    {
        _writeable_bitmap.AddDirtyRect(new Int32Rect(0, 0, 
        _writeable_bitmap.PixelWidth, _writeable_bitmap.PixelHeight));
        _writeable_bitmap.Unlock();

        var cloned = _writeable_bitmap.Clone();
        cloned.Freeze();

        Dispatcher.BeginInvoke(new Action((() =>
        {
            Image = cloned;
        })));

        _g.Dispose();
    }

ご覧のとおり、「特別なトリック」を使用して、GDI を使用してグラフィックをネイティブ WPF BitmapSource に直接描画しています。

これが適切な測定方法であるかどうかはわかりませんが、この方法を使用して、非常にまともな結果を得ることができました。

  • 10 億を超えるデータ ポイント。
  • 5FPSのリフレッシュレート。
  • 100hz でプッシュされる 10,000 個の新しいデータ ポイント。
  • i7 Core ラップトップで 10% の CPU。
  • WPF UI とレンダリング スレッドは、他の操作を完全に自由に実行できます。

私は、まさにそれを行うオープン ソース ライブラリ RealTimeGraphX (WPF および UWP 用) の作成者です。 https://github.com/royben/RealTimeGraphX

実際の折れ線シリーズを除く残りのグラフ コンポーネントは、標準の WPF コントロールと形状を使用して作成されるため、簡単にカスタマイズおよび操作できます。

于 2019-02-08T14:46:52.953 に答える
4

開示: 私は ABT Software を所有しており、 SciChartを開発し、さらにWriteableBitmapExオープン ソース ライブラリに貢献しています。

残念ながら、あなたは何も見逃していません。WPF/Silverlight のリテイン モード レンダリング エンジンは、この種の作業ではパフォーマンスが低下します。私は Windows フォームから WPF にアップグレードされた多くのシステムに取り組んできましたが、クライアントはこの「GPU アクセラレーション」フレームワークのレンダリング パフォーマンスにひどく失望しました。

とにかく、方法はあります。即時モード レンダリングを使用します。WriteableBitmap または InteropBitmap クラスを確認してください。私が貢献したRene Schulteによる WriteableBitmapExと呼ばれる優れたオープン ソース ライブラリがあります。WriteableBitmapEx は、ビットマップに直接描画するためのいくつかの低レベルの描画関数 (GDI スタイル) を提供します。これにより、優れたパフォーマンスと少ないメモリ フットプリントが実現します (MS の凝ったフレームワークは、適切に最適化された for ループとバイト配列へのポインタによって打ち負かされます)。

探している特定のサード パーティのグラフ コンポーネントである場合は、SciChartを試してください。SciChart は、私自身が開発したコンポーネントで、超高性能の WPF または Silverlight 科学/株価チャートのギャップを埋めようとしています。独自のリサンプリング アルゴリズムを使用して、描画前にデータセットを削減し、即時モード レンダリング、およびオブジェクト プーリングやリソースの再利用などのその他の最適化を多数実行することで、非常に大きなデータセットのスムーズなリフレッシュ レートと少ないメモリ フットプリントを実現します。

上記のリンクのパフォーマンス デモをクリックします (Silverlight 4 が必要です)。現在、SciChart は約 5FPS (ターゲット ハードウェアによって異なります) で 1,000,000 データポイントをレンダリングできます。これは 1 秒あたり 5,000,000 データポイントに相当します。商用ライセンスは 2012 年第 1 四半期に利用可能になります。

于 2011-12-21T12:19:58.923 に答える
2

WPF のリテイン モード レンダリングでは、特にこれらの描画に多くのオブジェクトが含まれている場合に、カスタム チャートや画像の描画/再描画が難しくなります。

私が WPF でできる最速の描画は、WritableBitmap を使用し、それを WritePixels の呼び出しで満たすことです。これはオプションかもしれません。PathGeometries を使用してキャンバスに描画して作成したチャートの描画速度を大幅に上回りました。

より速い中間点があるかどうかに興味があります。

于 2010-03-25T17:44:39.233 に答える