echarts二次封装之再研究
aar里table和json格式可以相互转换,所以,echarts里用的json格式,可以由aar中的table来代替,只需要执行之前转换下。
table在aar之中是十分常见的,可以操作的空间巨大。
那么是不是可以利用这个特性来赋值和操作echarts呢
首先要解决的问题就是table中加入新的属性和覆盖老的属性问题:
import console; var option = {}; option.xAxis = table.mixin(option.xAxis,{type = "line";}); console.dumpJson(option) option.xAxis = table.mixin(option.xAxis,{boundaryGap = false;}); console.dumpJson(option) console.pause(true);
上面混入x轴一些参数,可以看出一条条来加属性是没有问题的。
于是,程序逻辑就可以很简洁了。把需要用到的属性一条条的拷贝进去就好了。
根据以上写了第一个测试程序:
import win.ui; /*DSG{{*/ var winform = win.form(text="aardio form";right=759;bottom=469) winform.add( button={cls="button";text="Button";left=678;top=412;right=763;bottom=468;z=1} ) /*}}*/ import web.json; import web.blink.form; var wbForm = web.blink.form(winform); wbForm.go("\res\echartsHtml\main.html") 绘制图表 = function(_web,optionTab){ var str ="option = " ++ web.json.stringify(optionTab,false,false) ++ ";myChart.setOption(option);"; _web.doScript(str); } x坐标轴类型设置 = function(optionTab,index){ var str = "value"; select(index) { case "数值轴" { str = "value"; } case "类目轴" { str = "category"; } case "时间轴" { str = "time"; } case "对数轴" { str = "log"; } else { } } optionTab.xAxis = table.mixin(optionTab.xAxis,{type = str}); } x坐标轴数据设置 = function(optionTab,dataTab){ optionTab.xAxis.data = table.mixin(optionTab.xAxis.data,dataTab); } y坐标轴类型设置 = function(optionTab,index){ var str = "value"; select(index) { case "数值轴" { str = "value"; } case "类目轴" { str = "category"; } case "时间轴" { str = "time"; } case "对数轴" { str = "log"; } else { } } optionTab.yAxis = table.mixin(optionTab.yAxis,{type = str}); } 系列列表类型设置 = function(optionTab,index){ var str = "line"; select(index) { case 1 { str = "line"; } case 2 { str = "bar"; } case 3 { str = "pie"; } case 4 { str = "scatter"; } else { } } optionTab.series = table.mixin(optionTab.series,{type=str}); } 系列列表数据设置 = function(optionTab,dataTab){ optionTab.series.data = table.mixin(optionTab.series.data,dataTab); } 系列列表其他属性设置 = function(optionTab,dataTab){ optionTab.series = table.mixin(optionTab.series,dataTab); } var option = {}; x坐标轴类型设置(option,"类目轴"); x坐标轴数据设置(option,{ 0 }); y坐标轴类型设置(option,"数值轴"); 系列列表类型设置(option,1); 系列列表数据设置(option,{ 0 }); 系列列表其他属性设置(option,{smooth = true}); 绘制图表(wbForm,option); var tmId = winform.addtimer( 200, function(hwnd,msg,id,tick){ if(#option.xAxis.data > 50000){ option.xAxis.data = {0}; option.series.data = {0}; }else { table.push(option.xAxis.data,option.xAxis.data[#option.xAxis.data]+1); table.push(option.series.data,math.random(0,2200)); } 绘制图表(wbForm,option); } ) winform.button.oncommand = function(id,event){ option.xAxis.data = {0}; option.series.data = {0}; } winform.show(); win.loopMessage(); return winform;
调整窗口大小时候echarts图表随着改变大小:
winform.wndproc = function(hwnd,message,wParam,lParam){ select( message ) { case 5/*_WM_SIZE*/{ //鼠标右键弹起,下面获取坐标 var str ="myChart.resize();"; wb.doScript(str); } } }
以上代码, 经过测试,发现:
用webkit的话, 如果界面最小化之后,再还原, 图表就会一片空白. 最大化的时候,不会随着改变大小
用blink的话, 就没有以上的烦恼, 但是, blink体积大, 加载图表的速度明显没有webkit快.....
小纠结....
找到了小纠结哪个问题的原因了:
就是改变窗体大小和最大最小化的时候,瞬间dojs()窗体还没来得及执行改变大小的消息,
所以,只需要异步执行改变大小的那个函数resize()就可以了.
import thread.command var msg = thread.command() msg.waitc = function(){ win.delay(1); var str ="myChart.resize();"; wb.doScript(str); } winform.wndproc = function(hwnd,message,wParam,lParam){ select( message ) { case 5/*_WM_SIZE*/{ //鼠标右键弹起,下面获取坐标 thread.command.post("waitc"); } } }
上面利用了thread.command指令来模拟异步操作, 中间延迟了1ms使窗体能执行完消息, 然后图表才开始resize()
经过测试, blink和 webkit 都没用问题了.
可以不用去纠结了...哈哈
调用C语音卡尔曼滤波
原贴地址:http://www.stm32cube.com/article/147
上图是我在aar里直接调用C语言的那个卡尔曼产生的波形.
感觉不忍直视,算法肯定调用有错误,这个aar调用c函数看来应该不像想象中那样用....
var data1string ,data2string,data3string = "{data:[","{data:[","{data:["; //aardio调用C语言函数 var code = /**** #include <stdio.h> #include <stdlib.h> long KalmanFilter(long ResrcData) { /*-------------------------------------------------------------------------------------------------------------*/ /* Q:过程噪声,Q增大,动态响应变快,收敛稳定性变坏 R:测量噪声,R增大,动态响应变慢,收敛稳定性变好 */ /*-------------------------------------------------------------------------------------------------------------*/ static long R = (int32_t)(128*1024); static long Q = (int32_t)4; static long Counter1 ; static long Counter2; static long x_last; static long p_last; // 应赋初始估计值 long x_mid; long x_now; long p_mid ; long p_now; ResrcData *= 1024; x_now = ResrcData - x_last; if(x_now < 0) { x_now *= -1; // 取绝对值 } if(x_now >= 32*1024) // 如果测量值连续比估计值大或小 相信测量值,加速迭代 { Counter1++; Counter2 = 0; if(Counter1 > 10) { R = 512;; Q = 128; } } else // 数据比较稳定,加强滤波 { Counter1 = 0; Counter2++; if(Counter2 > 10) { R = (int)(128*1024); Q = (int)4; } } x_mid = x_last; // x_last=x(k-1|k-1),x_mid=x(k|k-1) p_mid = p_last + Q; // p_mid=p(k|k-1),p_last=p(k-1|k-1),Q=噪声 // kg = p_mid/(p_mid + R); //kg为kalman filter,R为噪声 // x_now = x_mid+kg*(ResrcData - x_mid);// 估计出的最优值 x_now = x_mid + (p_mid*(ResrcData - x_mid))/(p_mid + R); // p_now = (1 - kg)*p_mid; // 最优值对应的covariance p_now = p_mid - p_mid*p_mid/(p_mid + R); // 最优值对应的covariance p_last = p_now; // 更新covariance值 x_last = x_now; // 更新系统状态值 x_now /= 1024; if((x_now > 4096)||( x_now < 0)) { x_last = ResrcData; p_now = ResrcData; x_now = ResrcData/1024; } return (int)x_now; } ****/ mainForm.button2.oncommand = function(id,event){ //mainForm.msgbox( mainForm.button2.text ); import console; import tcc; console.open() var vm = tcc( ); //创建TCC编译器 vm.compile(code); //编译C源码 //调用C函数 var data1,data2 = 0,0; for(i=1;179;1){ data1 = math.round(math.sin(math.rad(i))*500); data2 = math.round(math.sin(math.rad(i))*500) + math.random(-5, 5); var ret = vm.KalmanFilter(data2); console.log( "C函数返回值2",data1,data2, ret ) data1string = data1string ++ data1 ++ ","; data2string = data2string ++ data2 ++ ","; data3string = data3string ++ ret ++ ","; //console.more(50) } } mainForm.button3.oncommand = function(id,event){ //mainForm.msgbox( mainForm.button3.text ); var datastr; var datalist_start = "var option = { series:[" var datalist_end = "] }; myChart.setOption(option);"; datastr = datalist_start ++ data1string ++ "]},"++ data2string ++ "]},"++ data3string ++ "]}," ++ datalist_end; wbKitView.doScript(datastr); }
转换之后
/* Q:过程噪声,Q增大,动态响应变快,收敛稳定性变坏 R:测量噪声,R增大,动态响应变慢,收敛稳定性变好 */ var aar_R = 1024*10//128*1024; var aar_Q = 250//4; //让其收敛快点 var aar_Counter1 = 0 ; //aardio中必须赋值,要不然就是null var aar_Counter2 = 0 ; var aar_x_last = 0 ; var aar_p_last = 0; // 应赋初始估计值 var aar_x_mid = 0; var aar_x_now = 0; var aar_p_mid = 0 ; var aar_p_now = 100; aar_KalmanFilter = function( ResrcData){ ResrcData *= 1024; aar_x_now = ResrcData - aar_x_last; if(aar_x_now < 0) { aar_x_now = math.abs(aar_x_now); // 取绝对值 } //下面的动态判断更改R和Q被我注释掉了,是一楼中的图形就是这个导致的..变成了阶梯状 /* if(aar_x_now >= 32*1024) // 如果测量值连续比估计值大或小 相信测量值,加速迭代 { aar_Counter1++; aar_Counter2 = 0; if(aar_Counter1 > 10) { aar_R = 512;; aar_Q = 128; } } else // 数据比较稳定,加强滤波 { aar_Counter1 = 0; aar_Counter2++; if(aar_Counter2 > 10) { aar_R = 128*1024; aar_Q = 4; } } */ aar_x_mid = aar_x_last; // x_last=x(k-1|k-1),x_mid=x(k|k-1) aar_p_mid = aar_p_last + aar_Q; // p_mid=p(k|k-1),p_last=p(k-1|k-1),Q=噪声 // kg = p_mid/(p_mid + R); //kg为kalman filter,R为噪声 // x_now = x_mid+kg*(ResrcData - x_mid);// 估计出的最优值 aar_x_now = aar_x_mid + (aar_p_mid*(ResrcData - aar_x_mid))/(aar_p_mid + aar_R); // p_now = (1 - kg)*p_mid; // 最优值对应的covariance aar_p_now = aar_p_mid - aar_p_mid*aar_p_mid/(aar_p_mid + aar_R); // 最优值对应的covariance aar_p_last = aar_p_now; // 更新covariance值 aar_x_last = aar_x_now; // 更新系统状态值 aar_x_now /= 1024; if((aar_x_now > 4096)||( aar_x_now < 0)) { aar_x_last = ResrcData; aar_p_now = ResrcData; aar_x_now = ResrcData/1024; } return aar_x_now; }
同样的,把C的那个还保留着,在程序中增加了aar的卡尔曼滤波,这样也可以对比C在aar中执行是不是和直接在aar写的函数一致..
将C写的卡尔曼R和Q分别改为10*1024和4 ,将aar写的滤波RQ分别改为10*1024和250
运行后,得出以下波形
可以看出:
C函数在aar中能够很好的被支持调用,滤波中的Q值影响的确实是收敛的速度,上图汇总蓝色线是C中的Q是4, 棕色线是aar中的Q是250, 棕色的明显比蓝色的收敛的速度快
再次将两种方式的RQ中的Q都设为250的收敛速度,将aar中的R值改为1024,而C中的R值改为1024*10,运行后如下图
在C程序中再次加入滑动滤波算法:
long value_buff[10]={0}; //N相当于选定一个窗口大小,对窗口数据做平均! char i=0; char j=0; long hdfilter(long hddata) { char count; long sum=0; value_buff[j++] = hddata; i++; if(j>=10){ j = 0; } if(i>=10) { i = 9; for(count=0;count<10;count++) sum += value_buff[count]; return (long)(sum/10); }else { for(count=0;count<i;count++) sum += value_buff[count]; return (long)(sum/i); } }
调用滑动滤波,增加曲线到图中,动态效果图如下:
可以看到,滑动滤波效果和卡尔曼滤波效果差不多,某些突变比较厉害的地方卡尔曼更胜一筹.
回复#8 @google88 :
就这个文件, 其他帖子里都是用的这个.
调用html5图标控件之百度echarts - 上位机开发笔记 (chengxu.xyz)
<!doctype html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script src="js/echarts.min.js"></script> <style type="text/css"> #main { height:100% ; width:100%; position:absolute;} body { margin:0px; padding:0px; overflow:hidden;} </style> </head> <body> <!-- 为ECharts准备一个具备大小(宽高)的Dom --> <div id="main"></div> </body> </html>
登录后方可回帖
下面开始模拟下table操作,看看能不能达到效果
以上模拟了两个函数,一个写入轴的属性,一个写入轴数据,
测试了,写入,修改,删除功能