老牌开源波形图控件,尽管有些简陋,几年来仍被大量转载。超过数千人从项目中有所收获。
野比这几年忙于个人事务和回答网友疑问,一直未能抽出时间维护,深感遗憾。
Nobi's StatusChart - 野比的状态波形图控件
作者:野比 (conmajia@gmail.com)
封面图片为野比原创,请勿未经允许私自引用
从构思到实现
野比 著
背景
目前比较流行的 WinForm 程序设计都会提供形象的可视化数据流动记录功能,
如 FlashGet 及其衍生软件的悬浮窗网速监视图,Windows 任务管理器的 CPU、内存使用图等。
构思
为了在我们自己的程序中实现这种效果,就需要研究、分析它们的原理,掌握其规律,然后加以实现。
很明显,从软件可重用性以及各种随之而来的好处考虑,我们要求将这个“波形显示”效果做成一个控件(Control)。
分析
还是以 FlashGet 的悬浮窗和 Windows 任务管理器作为研究对象。仔细观察它们的工作方式,发现它们有以下的共同点:
- 在右边更新当前的波形值
- 更新后的波形不消失,而是整体向左平移
- 可以设置波形颜色、更新速度等
而通过深入研究,发现二者不同点如下:
- 不同的显示方式,有曲线显示和直方图显示
- 有无定位网格
- 各部分颜色可自定义
设计
通过分析,可以决定如下:凡是二者共同点,加以重点实现;凡二者不同之处,通过设置属性(Property)进行更改。最后绘制时,基于所设置的属性,使用共同方法加以实现。
因此自定义属性如下:
- BackColor(重写基类属性)
- Enabled(重写)
- ForeColor(重写)
- GridColor 网格颜色
- GridHeight 网格每格高度
- GridShiftting 是否平移网格
- GridWidth 网格每格宽度
- Interval 波形刷新间隔(单位:毫秒)
- Mode 波形显示方式(曲线/直方图)
- Range 数值范围
- ShifttingIncrement 向左平移增量
- Value 当前值
控件因为要定时更新,因此具有一个内部的 Timer 对其进行定时,其 Interval 由控件的 Interval 属性指定。
对于此自定义控件,需要每次更新时在其 OnPaint() 事件中对整个控件进行绘制。绘制顺序为:背景 - 网格 - 波形,如此保证所有部分均正确画出且无遮挡。
从波形看,很明显,我们需要一个长度至少等于波形控件宽度的数组来存放每时刻波形的值,因此可以确定这个数组是和控件绘图画布宽度一致的。
算法
绘图最重要的是算法部分,如何计算如网格位置,如何将图形整体平移,如何设置波形值是本控件的重点和难点部分。
计算网格位置,以上面的 ShifttingIncrement 为 offset 参数传入
-
-
floatdiv;
-
floatpos=0F;
-
-
-
div=(float)w/(float)gridWidth+1;
-
for(inti=0;i<(int)div;i++)
-
{
-
pos+=gridWidth;
-
g.DrawLine(penGrid,pos-offset,0,pos-offset,h);
-
}
-
-
div=(float)h/(float)gridHeight;
-
pos=0F;
-
for(inti=0;i<(int)div;i++)
-
{
-
pos+=gridHeight;
-
g.DrawLine(penGrid,0,pos,w,pos);
-
}
对于波形,传入其波形值数组作为参数
-
-
intlen=w;
-
-
if(chartMode==StatusChart.ChartMode.Histogram)
-
{
-
for(inti=0;i<len;i++)
-
{
-
g.DrawLine(p,i,h-val[i],i,h);
-
}
-
g.DrawLine(p,len,h-val[len-1],len,h);
-
}
-
else
-
{
-
len--;
-
for(inti=0;i<len;i++)
-
{
-
g.DrawLine(p,i,h-val[i],i+1,h-val[i+1]);
-
}
-
len++;
-
g.DrawLine(p,len-1,h-val[len-2],len,h-val[len-1]);
-
}
如何平移,是一个难点,需要在内部定时器的 Tick() 事件中加以处理
-
-
-
if(gridShiftting)
-
{
-
iOffset+=gridShifttingIncrement;
-
iOffset%=gridWidth;
-
}
-
-
-
-
intlen=w;
-
for(inti=0;i<len;i++)
-
{
-
-
if(i<len-1)
-
{
-
val[i]=val[i+1];
-
}
-
else
-
{
-
val[len-1]=currentValue;
-
-
}
-
}
-
-
Invalidate();
最后引发控件的 Invalidate() 方法使控件重绘自身。
效果
最后的控件运行效果如下图所示:(用的随机数做数据,所以感觉乱跳)
(全文完)
分享到:
相关推荐
野比的状态波形图控件 Nobi.StatusChart.dll http://bbs.bccn.net/viewthread.php?tid=210440&page=1#pid1254128
波形显示控件Nobi.StatusChart.dll C#类库,引用,然后网上查资料,这里不细讲用法
Nobi's Somatosensory Game:Catch the Brick 野比的体感游戏:抓住板砖,利用摄像头游戏,需要Emgu CV支持。
数据可视化,大屏,移动报表,数据中台,WEB应用的微代码NoBI(No Only BI)开发平台。简单, 敏捷, 高效, 通用化, 高度可定制化, 让你的项目瞬间档次提升。完全真正打通前后端, 支持图形数据联动,筛选,钻取, 支持几乎常见...
dgsw-nobi-association DGSW学生会开放室
"com.nobi.roundedcorners": "https://github.com/kirevdokimov/Unity-UI-Rounded-Corners.git" Unity包 从获取.unitypackage 如何使用 相同的圆度 使用Image将ImageWithRoundedCorners附加到游戏对象 创建新材料 ...
Mastering React [PDF+EPUB+NOBI+CODE] Adam Horton, Ryan Vice February 2016 Book Description React stands out in the web framework crowd through its approach to composition. This approach yields ...
完整版的qt-sdk-win不是分卷,,,因为其他人都是分卷我用的时候特别难受,所以整理出来分享给大家
用于编写在线词典的英英词库,华清远见课程可用 a indef art one abacus n.frame with beads that slide along parallel rods, used for teaching numbers to children, and (in some countries) for counting ...