2

私はwinformsでプロットした経験がありません。ある形式では、ecgをプロットしたいと思います。または、特定の領域の正弦波または任意の波動関数を言うことができますが、私がしているのは心電図です。フォームの残りの部分は、ボタンとラベルが付いた通常のフォームになります。

チュートリアルで誰もが十分に親切になれますか

:)

4

4 に答える 4

2

選択肢はほとんどありません。データを処理してレンダリングする独自のコントロールを作成できます。より複雑なプロットの場合、少し複雑になる可能性がありますが、基本は常に同じで、X値とY値の範囲を設定してから、GDIを使用して左から右に線を引くだけです。
これはより高度な機能では少し複雑になる可能性があるため、いくつかのチャートコントロールを使用できます。この投稿を読むか、codeproject.comを確認します。オープンソースである、適切なチャートコントロールを作成する試みはほとんど見られませんでした。 、新しい記事はおそらくWPFでコーディングされますが、古いものも見つける必要があります。
編集:
あなたが役に立つと思うことができるいくつかのリンク:主な目標はECGをシミュレートすることであるグラフプロットlibまたはlibをプロットする別のグラフ

于 2009-08-19T13:14:51.033 に答える
1

以下を書いてテストしました。それはあなたが望むことをしているように見えますが、遅延のないループで sin(x) をプロットしているだけであることに注意してください。ただし、ループ内の任意の行にブレークを設定し、F5 キーを押してループをステップ実行して、ゆっくりと動作することを確認できます。おそらく、ストリーミング ECG データは一定の速度でしか到着しないため、実装では問題になりません。 .

以下では、monitor は winforms フォームの PictureBox です。それ以外はすべてローカルです。

private void drawStream(){
  const int scaleX = 40;
  const int scaleY = 40;
  Point monitorTopLeft = new Point(0, 0);
  Point MonitorTopLeftMinus1 = new Point(-1, 0);

  int halfX = monitor.Width / 2;
  int halfY = monitor.Height / 2;
  Size size = new Size(halfX + 20, monitor.Height);

  Graphics g = monitor.CreateGraphics();
  g.TranslateTransform(halfX, halfY);
  g.ScaleTransform(scaleX, scaleY);
  g.Clear(Color.Black);
  g.ResetClip();

  float lastY = (float)Math.Sin(0);
  float y = lastY;
  Pen p = new Pen(Color.White, 0.01F);
  float stepX = 1F / scaleX;

  for (float x = 0; x < 10; x += stepX) {
    g.CopyFromScreen(monitor.PointToScreen(monitorTopLeft), MonitorTopLeftMinus1, size, CopyPixelOperation.SourceCopy);
    y = (float)Math.Sin(x);
    g.DrawLine(p, -stepX, lastY, 0, y);
    lastY = y;
  }
}

役に立つかもしれないいくつかの追加情報:

  1. ピクチャ ボックスの原点は、左上隅から始まります。TranslateTransform を使用すると、原点を平行移動 (移動) できます。例では、画像ボックスの幅の半分と高さの半分だけ移動します。
  2. ScaleTransform は、ピクチャ ボックスの倍率を変更します。ピクチャ ボックスの描画に使用されるペンの幅も拡大することに注意してください。これが、ペンの幅が 0.01 に設定されている理由です。
  3. CopyFromScreen は bitblt を実行します。そのソース ポイントは画面に対して相対的であり、移動先はピクチャ ボックスに対して相対的であり、移動する四角形のサイズは変換 (追加したスケール変換や平行移動変換など) を無視します。
  4. DrawLine メソッドの X 座標は -stepx と 0 であることに注意してください。すべての描画は基本的に y 軸 (つまり x = 0) で行われ、次に CopyFromScreen が描画された部分を左に移動し、左に「流れる」ようにします。 .
于 2009-08-19T23:06:08.647 に答える
1

カスタム コントロールを作成する必要があります。

public class MyECGDrawer : Control{}

その中で、OnPaint イベントをオーバーライドします

protect override OnPaint(PaintEventArgs pe ){}

次に、ペイント関数で、グラフィックを好きなように描画します。sin(x) としましょう。

// refresh background
pe.Graphics.FillRectangle( Brushes.White, 0, 0, Width, Height );
int prevX = -1, prevY = -1;
for(int x = 0; x < Width; x++ )
{
    if( prevX >= 0 )
    {
        pe.Graphics.DrawLine( Pens.Black, prevX, prevY, x, Math.sin(x) );
    }
    prevX = x;
    prevY = Math.sin(x);
}

ECG を強制的に再描画するには、コントロールで .Invalidate() 関数を呼び出します。デザイナーからフォームにコントロールをドラッグ アンド ドロップできる必要があります。

最終的に、クラスは次のようになります

public class MyECGDrawer : コントロール{}

その中で、OnPaint イベントをオーバーライドします

public class MyECGDrawer : Control
{
protect override OnPaint(PaintEventArgs pe )
{
   // refresh background
    pe.Graphics.FillRectangle( Brushes.White, 0, 0, Width, Height );
    int prevX = -1, prevY = -1;
    for(int x = 0; x < Width; x++ )
    {
        if( prevX >= 0 )
            pe.Graphics.DrawLine( Pens.Black, prevX, prevY, x, Math.sin(x) );
        prevX = x;
        prevY = Math.sin(x);
    }
}
}
于 2009-08-19T13:24:49.750 に答える
0

これを学習経験として行っている場合を除き、ここで入手できる無料の Microsoft Chart Controls for .NET を参照することを検討してください。

http://www.microsoft.com/downloads/details.aspx?FamilyID=130f7986-bf49-4fe5-9ca8-910ae6ea442c&displaylang=en#QuickInfoContainer

そうは言っても、自分で作成したい場合は、次のガイドラインを提供します.

  1. フォームに直接レンダリングするのではなく、プロット レンダリングをカプセル化するユーザー コントロールを作成します。
  2. コントロールで、レンダリングするデータを取得/設定するプロパティを公開し、レンダリングを制御するその他のプロパティ (スケーリング、パン、色など) を追加します。
  3. コントロールで、OnPaint メソッドをオーバーライドするか、Paint イベントのイベント ハンドラーを作成します。これらのメソッドには、Graphics オブジェクトをプロパティとして含む PaintEventArgs オブジェクトが渡されます。Graphics オブジェクトのメソッドは、コントロールを描画する必要がある場合に、点や線などをコントロールにレンダリングするために使用されます。ほとんどの描画操作には、ペン (輪郭/線) またはブラシ (塗りつぶし領域) が必要です。これらの操作にはストック オブジェクト (Pens.Black や Brushes.Red など) を使用することも、独自のオブジェクトを作成することもできます (ドキュメントを参照)。独自のオブジェクトを作成する場合は、それらを使用した後に破棄してください (たとえば、"using" ステートメントを使用するか、Dispose を呼び出します)。

GDI+ に関する優れた書籍が 2 冊あります。深く入りたい場合は、1つを選択することをお勧めします。

于 2009-08-19T13:25:20.653 に答える