ST-curve波形图ocx控件的试用
ST_Curve是一个专业的曲线绘制控件,只要是xy坐标系的曲线,都可绘制,纵坐标只能显示为值,横坐标可以显示为值或者时间
该控件是开源控件,
Git开源地址: https://github.com/youngwolf-project/ST_Curve
特点:
高速 / 简洁 / 便捷
如果你不知道你的数据会有多少个, 也就意味着数据是始终一个一个再增加, 那么用这个波形图表应该是最佳的选择.
import win.ui; /*DSG{{*/ var winform = win.form(text="aardio form";right=759;bottom=469) winform.add( button={cls="button";text="全屏";left=0;top=428;right=91;bottom=470;db=1;dl=1;z=2}; button2={cls="button";text="非全屏";left=101;top=428;right=192;bottom=470;db=1;dl=1;z=3}; button3={cls="button";text="设置第一个曲线属性";left=370;top=427;right=511;bottom=469;db=1;dl=1;dr=1;z=4}; button4={cls="button";text="绘制实时数据";left=522;top=428;right=613;bottom=470;db=1;dr=1;z=5}; button5={cls="button";text="清空曲线";left=228;top=433;right=347;bottom=468;db=1;dl=1;z=6}; button6={cls="button";text="绘制平移数据";left=641;top=427;right=732;bottom=469;db=1;dr=1;z=7}; picturebox={cls="picturebox";left=37;top=23;right=697;bottom=398;db=1;dl=1;dr=1;dt=1;z=1} ) /*}}*/ import console console.open() import time.ole; //我们试一下创建一个OLE时间对象 var tm = time.ole(); var stc = winform.picturebox.createEmbed("{315E7F0E-6F9C-41A3-A669-A7E9626D7CA0}"); var m_ST_Curve = stc._object //console.log( m_ST_Curve.SetMaxLength(1000, 700) ) //设置背景色 m_ST_Curve.setBackColor(0x000000); //设置 m_ST_Curve.EnableHZoom(true); //设置波形显示模式 m_ST_Curve.SetShowMode(0x80); //m_ST_Curve.SetBottomSpace(0); //m_ST_Curve.EnableFocusState(false); //设置网格线显示模式 m_ST_Curve.SetGridMode(3); //m_ST_Curve.SetBeginValue(1.34); //m_ST_Curve.SetValueStep( 2.2 ); m_ST_Curve.SetHInterval(10); //m_ST_Curve.SetTension(0.5) //设置Y轴标题 m_ST_Curve.SetUnit("温度和湿度") //m_ST_Curve.SetZoom(0); //m_ST_Curve.EnableZoom(false); //m_ST_Curve.SetMoveMode(0); //限制在一页 m_ST_Curve.LimitOnePage(true); //不显示预览 m_ST_Curve.EnablePreview(false); //不提示帮助信息 m_ST_Curve.EnableHelpTip(false); winform.button.oncommand = function(id,event){ m_ST_Curve.EnableFullScreen(true); } winform.button2.oncommand = function(id,event){ m_ST_Curve.EnableFullScreen(false); } winform.button3.oncommand = function(id,event){ //m_ST_Curve.AddLegendHelper(10,"第一条曲线",0x00CC00 , 0/*_PS_SOLID*/, 1, true); m_ST_Curve.AddLegend(10,"第一条曲线",0x00CC00 ,0/*_PS_SOLID*/,1,0x0,255,3,2,0xFF,true); } var tmId winform.button4.oncommand = function(id,event){ var tmn = tonumber(tm) var iii = 0; m_ST_Curve.DelRange2(10,0,-1,false,true); //定时器加载数据 tmId = winform.addtimer( 200, function(hwnd,msg,id,tick){ m_ST_Curve.AddMainData2(10, iii, math.random(),0, 1, true); iii++ } ) /* //手动加载数据 for(i=1;50;1){ m_ST_Curve.AddMainData2(10, tmn, math.random(),0, 1, true); tmn+= 1.0; } */ } winform.button5.oncommand = function(id,event){ winform.settimer(tmId,-1) winform.killtimer(tmId) //m_ST_Curve.DelRange2(10,0,-1,false,true); } //var tmid2; winform.button6.oncommand = function(id,event){ m_ST_Curve.AddLegend(11,"第一条曲线",0x00CC00 ,0/*_PS_SOLID*/,1,0x0,255,3,2,0xFF,true); var jjj = 0; m_ST_Curve.DelRange2(11,0,-1,false,true); tmId = winform.addtimer( 300, function(hwnd,msg,id,tick){ if(jjj> 30){ m_ST_Curve.DelRange2(11,0,1,false,true); } m_ST_Curve.AddMainData2(11, jjj, math.random(),0, 1, true); jjj++; } ) } winform.show() win.loopMessage();
有些使用波形图的场景为了美观需要去除底部那个版权文字和右侧图例那一大块区域,那么可以用下面我修改好了的这个ocx(注意里面的dll也需要的)
由于作者已经开源,所以你也可以根据自己的需求任意的更改.
去除后的效果如下:
多个波形图联动:
import win.ui; /*DSG{{*/ var winform = win.form(text="aardio form";right=1358;bottom=806) winform.add( picturebox={cls="picturebox";left=0;top=0;right=697;bottom=232;bgcolor=15780518;db=1;dl=1;dr=1;dt=1;z=1}; picturebox2={cls="picturebox";left=0;top=253;right=702;bottom=457;bgcolor=15780518;db=1;dl=1;dr=1;dt=1;z=2}; picturebox3={cls="picturebox";left=0;top=488;right=697;bottom=720;bgcolor=15780518;db=1;dl=1;dr=1;dt=1;z=3}; picturebox4={cls="picturebox";left=743;top=243;right=1359;bottom=475;bgcolor=15780518;db=1;dl=1;dr=1;dt=1;z=4} ) /*}}*/ import console console.open() import time.ole; import winex var stc = winform.picturebox.createEmbed("{315E7F0E-6F9C-41A3-A669-A7E9626D7CA0}"); var m_ST_Curve = stc._object m_ST_Curve.setBackColor(0x000000); m_ST_Curve.EnableHZoom(true); m_ST_Curve.SetShowMode(0x80); m_ST_Curve.SetGridMode(3); m_ST_Curve.SetHInterval(10); m_ST_Curve.SetUnit("温度和湿度") m_ST_Curve.LimitOnePage(true); m_ST_Curve.EnablePreview(false); m_ST_Curve.EnableHelpTip(false); m_ST_Curve.AddLegend(1,"第一条曲线",0x00CC00 ,0/*_PS_SOLID*/,1,0x0,255,3,2,0xFF,true); var stc2 = winform.picturebox2.createEmbed("{315E7F0E-6F9C-41A3-A669-A7E9626D7CA0}"); var m_ST_Curve2 = stc2._object m_ST_Curve2.setBackColor(0x000000); m_ST_Curve2.EnableHZoom(true); m_ST_Curve2.SetShowMode(0x80); m_ST_Curve2.SetGridMode(3); m_ST_Curve2.SetHInterval(10); m_ST_Curve2.SetUnit("温度和湿度") m_ST_Curve2.LimitOnePage(true); m_ST_Curve2.EnablePreview(false); m_ST_Curve2.EnableHelpTip(false); m_ST_Curve2.AddLegend(2,"第一条曲线",0x00CC00 ,0/*_PS_SOLID*/,1,0x0,255,3,2,0xFF,true); m_ST_Curve.EnableFocusState(false); m_ST_Curve2.EnableFocusState(false); //查找控件句柄 var hwnd = winex.findEx(,,'AfxWn',"") //设置联动 m_ST_Curve2.SetBuddy(hwnd, 0); for(i=1;50;1){ m_ST_Curve.AddMainData2(1, i, math.random(),0, 1, true); m_ST_Curve2.AddMainData2(2, i, math.random(),0, 1, true); } winform.show() win.loopMessage();
虽然实现了功能, 但是总感觉哪里不对, 应该是绕远路了, 按道理说自己创建的控件和窗体 ,应该有方式很容易取得这个com控件的句柄的,不需要winex这个扩展库.
科技感的背景色和线条颜色
//设置背景色 m_ST_Curve.setBackColor(0x663202); m_ST_Curve.AddLegend(11,"功率曲线",0xFFD859 ,0/*_PS_SOLID*/,1,0x0,255,3,0,0xFF,true);
批量添加波形图和曲线数据
stobj.AddLegend(10,"1曲线",0x0000cc,0,1,0,255,3/*CurveMode*/,2,0xff,true) stobj.AddLegend(11,"2曲线",0x00cc00,0,1,0,255,3/*CurveMode*/,2,0xff,true) stobj.AddLegend(12,"3曲线",0xcc0000,0,1,0,255,3/*CurveMode*/,2,0xff,true) //创建动态长度的API数组 方法三 将定长的table直接转换为数组 array = {} for(i=0;2;1){//三个曲线 for(j=1;24;1){ //每条24个点 //模拟随机数据 array[i*24 + j]={ int id = 10+i ; double x = j ; float y = 7*math.random()*10 ; word s = 0 ; _struct_aligned = 1; } } } //动态数组 data = raw.toarray( array ) //包装一下 var buff = raw.buffer(18*24*3); //拷贝数据 raw.copy(buff,data); stobj.AddMemMainData((tonumber(raw.toPointer(buff))), 18*24*3, true)
更新下: 经过jacen的指点 修改上面的查找波形图控件代码如下:
var getStCurveHwnd = function( formHwnd ){ var hView = win.findEx(formHwnd,0); if( hView ){ return win.getChild(hView); }else { return null; } } //这样使用 var m_hwnd = getStCurveHwnd( winform.picturebox.hwnd ); if(m_hwnd){ //设置联动 m_ST_Curve2.SetBuddy(m_hwnd, 0); } winform.button.oncommand = function(id,event){ if(m_hwnd){ //解除所有联动 m_ST_Curve2.SetBuddy(0, 1); //解除辅机联动, 保留主机联动 //m_ST_Curve2.SetBuddy(m_hwnd, 1); } }
下面写一写这样写思考和学习的过程:
jacen说:
你自己创建的窗口是 winform.picturebox.hwnd
com控件的窗口准确说是com控件创建的,每个com控件创建的窗口结构都不相同,有的有好几层父子窗口,所以你要根据情况自己去获取。
因为com控件创建的窗口总是你创建的窗口的子窗口,所以可以用 win.findEx,win.eachChild等函数去找。
可以参考 web.form也是这样实现的
web.form.hwndControl = { _get = function(){ owner.wait() var hView = ..win.findEx(owner.hwndEmbedding,0,"Shell DocObject View") || ..win.findEx(owner.hwndEmbedding,0,"SHELLDLL_DefView"); if( hView ) return ..win.getChild(hView); } };
波形图的简单应用示例:
这个页面创建波形, 其他界面传递参数来添加数据或者清空图形
import win.ui; /*DSG{{*/ var winform = win.form(text="aardio form";right=759;bottom=469) winform.add() /*}}*/ import thread.command; /*初始化波形图外形{{*/ var stc = winform.createEmbed("{315E7F0E-6F9C-41A3-A669-A7E9626D7CA0}"); var m_ST_Curve = stc._object; //设置背景色 m_ST_Curve.setBackColor(0x663202); //设置 m_ST_Curve.EnableHZoom(true); //设置波形显示模式 m_ST_Curve.SetShowMode(0x80); //设置网格线显示模式 m_ST_Curve.SetGridMode(3); m_ST_Curve.SetHInterval(10); m_ST_Curve.SetUnit("功率值") //限制在一页 m_ST_Curve.LimitOnePage(true); //不显示预览 m_ST_Curve.EnablePreview(false); //不提示帮助信息 m_ST_Curve.EnableHelpTip(false); m_ST_Curve.SetTension(0);//设置曲线张力 //创建识别号为11的曲线样式 m_ST_Curve.AddLegend(11,"功率曲线",0xFFD859 ,0/*_PS_SOLID*/,1,0x0,255,3,0,0xFF,true); //显示识别号为11的波形 m_ST_Curve.ShowLegend(11,0); //删除识别号为11的波形的坐标从0开始到-1(结束)中所有的点 m_ST_Curve.DelRange2(11,0,-1,false,true); /*}}*/ var index = 0; //供其他线程调用 var curveM = thread.command(); //添加数据 curveM.senddata = function(data){ m_ST_Curve.AddMainData2(11, index, data, 0, 1, true); index++; } //清空图形 curveM.clearM = function(){ m_ST_Curve.DelRange2(11,0,-1,false,true); index = 0; } winform.onClose = function(hwnd,message,wParam,lParam){ //释放函数 curveM.senddata = null; curveM.clearM = null; } winform.show(); win.loopMessage(); return winform;
分享个黑白配色界面:
import win.ui; /*DSG{{*/ var winform = win.form(text="黑白配色";right=299;bottom=239;bgcolor=16777215) winform.add() /*}}*/ var stc = winform.createEmbed("{315E7F0E-6F9C-41A3-A669-A7E9626D7CA0}"); var m_ST_Curve = stc._object; //设置背景色 m_ST_Curve.setBackColor(0xFFFFFF); m_ST_Curve.setForeColor(0x000000); m_ST_Curve.setAxisColor(0x878787); m_ST_Curve.setGridColor(0xF0F0F0); //设置 m_ST_Curve.EnableHZoom(true); //设置波形显示模式 m_ST_Curve.SetShowMode(0x80); //设置网格线显示模式 m_ST_Curve.SetGridMode(0x0F); //m_ST_Curve.SetHInterval(10); m_ST_Curve.SetUnit("") //限制在一页 m_ST_Curve.LimitOnePage(true); //不显示预览 m_ST_Curve.EnablePreview(false); //不提示帮助信息 m_ST_Curve.EnableHelpTip(false); m_ST_Curve.SetVPrecision(2); m_ST_Curve.SetHPrecision(0); //m_ST_Curve.EnableFullScreen(true); //全屏 //m_ST_Curve.SetTension(0);//设置曲线张力 m_ST_Curve.AddLegend(11,"aaa",0xC08E45 ,0/*_PS_SOLID*/,1,0x0,255,0/*CurveMode0/3*/,1,0xFF,true); m_ST_Curve.AddLegend(12,"bbb",0x4B9FFF ,0/*_PS_SOLID*/,1,0x0,255,0/*CurveMode0/3*/,1,0xFF,true); //m_ST_Curve.ShowLegend(11,0); m_ST_Curve.DelRange2(11,0,-1,false,true); m_ST_Curve.DelRange2(12,0,-1,false,true); for(i=1;300;1){ m_ST_Curve.AddMainData2(11, i, math.sin(i*0.05),0, 1, true); m_ST_Curve.AddMainData2(12, i, math.cos(i*0.15),0, 1, true); } winform.show(); win.loopMessage(); return winform;
想要在vs2022的C#中调用此ocx , 不知道为何加入不到工具箱中,那么就不能拖拽来自动生成界面代码了.
这时候就需要自己手动编写代码使用了
过程也简单, 下面是我测试使用的步骤:
需要先把ocx组件给生成vs中能用的类 , 利用vs自带的 Aximp.exe 来生成
步骤: 在vs中选择[工具]->[命令行]->[开发者命令提示]
在打开的界面中, 输入 aximp c:\st_curve.ocx 自动解析生成需要的dll
工程中引用 刚刚生成的两个dll
打开工程的设计 , 在form1上面位置添加如下代码:
private void Form1_Load(object sender, EventArgs e) { var axSTcurve1 = new AxST_CurveLib.AxST_Curve(); axSTcurve1.Dock = DockStyle.Fill; this.pictureBox1.Controls.Add(axSTcurve1); axSTcurve1.SetShowMode(0x80); //axSTcurve1.CtlBackColor=0x000000; axSTcurve1.CtlBackColor = 0xFFFFFF; axSTcurve1.CtlForeColor = 0x000000; axSTcurve1.AxisColor = 0x878787; axSTcurve1.GridColor = 0xF0F0F0; axSTcurve1.EnablePreview(false); axSTcurve1.EnableHelpTip(false); axSTcurve1.EnableHZoom(true); axSTcurve1.SetGridMode(3); axSTcurve1.LimitOnePage(true); axSTcurve1.SetVPrecision(2); axSTcurve1.SetHPrecision(0); axSTcurve1.SetHInterval(10); axSTcurve1.SetUnit("温度和湿度"); axSTcurve1.AddLegend(1, "aaa", 0xC08E45, 0/*_PS_SOLID*/, 1, 0x0, 255, 0/*CurveMode0/3*/, 1, 0xFF, true); for (int i = 0; i < 500; i++) { axSTcurve1.AddMainData(1, i.ToString(), (float)Math.Sin(i * 0.05), 0, 1, true); //axSTcurve1.AddMainData2(1, i, (float)Math.Sin(i * 0.05), 0, 1, true); } }
登录后方可回帖
绘制圆滑曲线: