25

財務データを表示するチャートを作成しました。とsをPathGeometry併用して接続線として表示される10000点未満を描画している間は、パフォーマンスは良好でした。しかし、今は(スクロールせずに)同時に最大100.000ポイントを表示する必要があり、すでに50.000ポイントと非常に遅いです。と思っていたのですが、基本的にはバイトストリームとして情報を格納するのと同じなのでわかりません。誰かがこれをはるかにパフォーマンスの高いものにするアイデアを持っていますか、あるいは誰かがすでに同様のことをしたことがありますか?PathFigureLineSegmentStreamGeometryPathGeometry

編集:これらのデータポイントは一度描画されると変更されないため、最適化する可能性がある場合はお知らせください(線分は現在フリーズしています)。

編集:私はStreamGeometryを試しました。グラフィックの作成には何らかの理由でさらに時間がかかりましたが、これは問題ではありません。すべてのポイントを描画した後のチャートへの描画は、以前の方法と同じくらい遅いです。WPFで処理するにはデータポイントが多すぎると思います。

編集:少し実験しましたが、WPFアンチエイリアシングサブピクセルラインを防ぐために、以前はdoubleであった座標をintに変換することで、パフォーマンスが少し向上することに気付きました。

編集:線分の数を減らすことを提案するすべての回答に感謝します。階段状の線の水平方向の解像度を最大で2倍に、単純な線の水平方向の解像度を最大で2倍に減らしましたが、パフォーマンスはかなり良好になりました。

4

9 に答える 9

19

レンダリングしようとしているポイントの数をダウンサンプリングすることを検討します。50,000ポイントのデータがあるかもしれませんが、それらすべてを画面に収めることはできないでしょう。1つのディスプレイですべてのポイントをグラフ化した場合でも、すべてを描画するには、 100,000ピクセルの水平解像度が必要です。D3Dでも、それを描くのは大変です。

2,048ピクセルのようなものが存在する可能性が高いため、グラフ化するポイントを減らして、画面に収まり、頂点が数千しかないおおよその曲線を描くこともできます。たとえば、ユーザーが10000ポイントを含む時間枠をグラフ化する場合は、グラフ化する前に、それらの10000ポイントを1000にダウンサンプリングします。単純な平均化から中央値近傍、ガウス畳み込み、(私の提案)バイキュービック補間まで、試すことができる多くの手法があります。画面解像度の1/2を超えるポイントをいくつでも描画すると、無駄になります。

ユーザーがグラフの一部を拡大すると、リサンプリングして、より高い解像度とより正確なカーブフィッティングを取得できます。

于 2009-06-04T20:13:08.540 に答える
6

ジオメトリ内の数十万の異なる頂点とベクトルの処理を開始するときは、WPF(Direct3D上に構築されているため、非常に効率的)に依存するのではなく、グラフィックスフレームワークを使用するようにグラフィックスコードを移行することを検討する必要があります。ベクターグラフィックスレンダリングでは、効率を妨げる多くの余分なオーバーヘッドが発生します)。WPF内でDirect3DとOpenGLグラフィックスレンダリングウィンドウの両方をホストすることは可能です。WPF内でのみ作業を続けるのではなく、その方向に移動することをお勧めします。

(編集:元の回答の「DirectX」を「Direct3D」に変更)

于 2009-06-04T19:48:44.347 に答える
5

この質問に遭遇したばかりですが、このスレッドで述べたように、最もパフォーマンスの高いアプローチは、WPFのビジュアルレイヤーに対してプログラミングすることかもしれません

WPFのすべてのビジュアルは、最終的にこのレイヤーに反します...したがって、これらすべての中で最も軽量なアプローチです。

詳細については、これこれを参照してください。マシューマクドナルドのC#2008の本のプロWPFの第14章にも、良いセクションがあります。

別の参考資料として...PavanPodilaの著書WPFControlDevelopmentUnleashedの第2章を参照してください。13ページで、DrawingVisualsがグラフ作成コンポーネントの優れた選択肢となる方法について説明しています。

最後に、 CharlesPetzoldがMSDNMagazineの記事を書いていることに気づきました。ここでは、(散布図に対する)全体的な(とにかく実行可能な)最良のソリューションはDrawingVisualアプローチでした。

于 2009-09-25T17:55:48.200 に答える
5

もう1つのアイデアは、動的に作成したDrawingImageに設定されたSourceプロパティでImageコントロールを使用することです。

WPF Control DevelopmentUnleashedのPavanPodilaによると、このアプローチは、インタラクティブ性を必要としない何千ものビジュアルがある場合に非常に役立ちます。詳細については、彼の本の25ページをご覧ください。

これは古いスレッドですが、MouseUp()イベントを使用することで、上記のメソッドとの対話性を実現できることは言及する価値があると思いました。画像のビューポートのサイズ、画像の解像度、およびマウスの位置がわかります。たとえば、UserControl_SizeChangedイベントにアタッチされたタイマーを介してコレクションactualScreenPointsを維持できます。

    double xworth = viewport.ActualWidth / (XEnd - XStart);
    double xworth = viewport.ActualHeight / (YEnd - YStart);
    List<Point> actualScreenPoints = new List<Point>(); 
    for (var i = 0; i < points.Count; i++)
    {
        double posX = points[i].X * xworth;
        double posY = points[i].Y * yworth;
        actualScreenPoints.Add(posX, posY);
    }

そして、MouseUp()イベントが発生したら、コレクション内のポイントのいずれかが+-2px以内にあるかどうかを確認します。特定のポイントにMouseUpがあります。

于 2013-01-18T01:15:16.497 に答える
4

どれだけうまくスケーリングできるかはわかりませんが、WPF(WindowsFormsPresenter内のWinFormsコントロール)でZedGraphを使用してある程度の成功を収めています。まだ誰も言及していないことに驚いています。現在のプロジェクトで使用する予定がない場合でも、一見の価値があります。

ZedGraph

幸運を!

于 2009-06-11T19:56:08.090 に答える
3

WPFフレームワークにとどまっている間に高速になる可能性がある唯一の方法は、カスタムコントロールでOnRenderをオーバーライドすることだと思います。次に、ジオメトリを永続化されたシーンに直接レンダリングして、ビューの外にあるものをカリングできます。ユーザーが一度にデータセットのごく一部しか見ることができない場合は、カリングだけで十分である可能性があります。

これだけ多くのデータポイントがあるため、データセット全体が表示されているときにユーザーが完全な詳細を表示できる可能性はほとんどありません。したがって、フルビューのデータセットを単純化してから、ズームインした場合に、より詳細なビューを表示することを検討することも価値があります。

編集:また、StreamGeometryを試してみてください。存在する理由はすべてパフォーマンスであり、試してみるまでわかりません。

于 2009-06-04T19:55:07.423 に答える
1

これは非常に良い質問であり、「100,000個の個別のポイントを含む画面をユーザーが実際に使用したり、ビジネス上の決定を下したりできるか」という疑問が根底にあります。

GUI設計哲学のベストプラクティスに従うと、答えは「いいえ」になります。これにより、アプリケーションの要件を満たすための別の方法がないかどうかを疑問視することになります。

スクロールせずに画面に100,000ポイントを表示するという誠実なケースがある場合は、オフスクリーンバッファを使用するのが最善の方法です。必要に応じてそのビットマップをウィンドウ/ページに叩き込むよりも、画像をビットマップに合成します。このように、重い持ち上げは1回だけ実行され、その後は、ウィンドウを描画する必要があるたびにハードウェアアクセラレーションを使用できます。

お役に立てれば。

于 2009-06-11T19:49:52.537 に答える
0

私はWPF(免責事項)を使用していませんが、パフォーマンスの問題は、コードがすべてのデータに滑らかな曲線を合わせようとしているためであり、必要な時間は、データポイント。

これが見た目で許容できるかどうかはわかりませんが、各ポイントを最後のポイントに直線で接続してデータをグラフ化してみてください。これにより、グラフ化までの時間がデータポイントの数に比例するようになり、グラフの数と同じ数のポイントを使用すると、とにかくまったく同じように見える可能性があります。

于 2009-06-04T20:12:04.267 に答える
0

もう1つのアイデアは、動的に作成したDrawingImageに設定されたSourceプロパティでImageコントロールを使用することです。

WPF Control DevelopmentUnleashedのPavanPodilaによると、このアプローチは、インタラクティブ性を必要としない何千ものビジュアルがある場合に非常に役立ちます。詳細については、彼の本の25ページをご覧ください。

于 2009-10-17T00:00:14.437 に答える