我以前没有在winforms中绘图的经验,在一个表单中我想要绘制ecg。或者假设一个正弦波或特定区域中的任何波函数,但我所做的是例如。表单的其余部分将是带有按钮和标签的普通表单,
有没有人愿意看完一篇教程
:)
发布于 2009-08-19 13:14:51
你有几个选择,你可以编写自己的控件,它将处理数据并呈现它。对于更复杂的图,这可能有点复杂,但基本原理总是相同的,设置X和Y值范围,然后使用GDI从左到右绘制一条线,没有什么特别的。
对于更高级的功能来说,这可能会变得有点复杂,你可以使用一些图表控件,我读过WPF post或查看codeproject.com,我记得,我看到很少有人尝试编写一些像样的图表控件,这些控件是开源的,新文章可能会用WPF编码,但你也应该找到一些更旧的东西。
编辑:
您可以找到一些有用的链接:Graph plotting lib that's main goal is to simulate ECG 或another graph plotting lib
发布于 2009-08-19 13:24:50
您需要创建自定义控件。
public class MyECGDrawer : Control{}
在其中,您将重写OnPaint事件
protect override OnPaint(PaintEventArgs pe ){}
然后在paint函数中,你可以按照你想要的方式来绘制图形,比如说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()函数。您应该能够从设计器中拖放窗体中的控件。
最后,这个类看起来就像
公共类控件: 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-19 23:06:09
我写下了下面的代码并进行了测试。它似乎做了您想做的事情,但请注意,它只是在没有延迟的循环中绘制sin(x) -即sin(x)的绘图从左边流得如此之快,以至于你几乎看不到它。但是,您可以在循环内的任何行上放置一个断点,然后使用F5单步执行循环,以查看它的工作速度很慢-假设您的流心电信号数据只会以某个固定的速度到达,所以这在您的实现中应该不是问题。
在下面的示例中,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;
}
}
一些可能对您有帮助的其他信息:
https://stackoverflow.com/questions/1299816
复制相似问题