AngularJS集成HighCharts动态绘制CPU和内存变化曲线
调研了下动态曲线绘制的开源项目, HighCharts
应用在AngularJS上相对容易使用和集成,来看下在AngularJS上集成HighCharts的StockChart图表,实现动态绘制Android内存和CPU的变化曲线。
一、实现效果
先看下HightCharts CPU和内存图表显示实现效果,图表左上角可以选择显示的区间范围,1分钟、5分钟或显示全部,截图显示的是全部数据,底部栏可以拖动查看不同区间数据。
二、HighCharts集成
先到 HighCharts下载中心
下载对应的资源,这边下载的是Highcharts-Stock-8.1.2,Highcharts-Stock下载之后就不用下载Highcharts资源,Highcharts-Stock里面已经包含,也可以直接使用CDN 文件而不用下载:
// Highcharts // Highcharts Stock // Highcharts Maps // Highcharts Gantt
还可以通过 NPM 安装:
npm install highcharts --save
或者通过 Bower 安装:
bower install highcharts --save
在Highcharts-Stock-8.1.2下载完成之后,把Highcharts-Stock-8.1.2/code/highstock.js文件拷贝放到工程目录下,添加highstock.js引用声明,之后就可以在工程里面使用Highcharts:
script(src='*****/*****/highstock.js')
三、Highcharts-Stock绘制CPU曲线
直接上代码,先看下CPU图表的参数初始化:
前端界面: div(id='cpu')
JS文件,renderTo参数就是指定前端界面展示的控件id :
var chartCpuOptions = { chart: { renderTo: 'cpu' }, xAxis: [{ // currentDateIndicator: true, min: new Date().getTime(), max: new Date().getTime() + 24 * 60 * 60 * 1000 }], rangeSelector: { buttons: [{ count: 1, type: 'minute', text: '1M' }, { count: 5, type: 'minute', text: '5M' }, { type: 'all', text: 'All' }], inputEnabled: false, selected: 0 }, exporting: { enabled: true }, title: { text: 'CPU' }, series: [ { name: 'Process CPU', data: [] }, { name: 'System CPU', data: [] } ] }; var chartCpu = new Highcharts.StockChart(chartCpuOptions);
xAxis图表横坐标轴参数一定要初始化,否则会报如下异常,min和max就是指定横坐标轴的最小值和最大值,xAxis的参数说明可以参考 HighCharts API xAxis参数文档
:
Error: attribute x: Expected length, "NaN".
rangeSelector
就是图表范围选择器,这边配置1分钟、5分钟和全部显示三个类型,buttons的type参数取值可以是:”millisecond”, “second”, “minute”, “hour”, “day”, “week”, “month”, “ytd”, “all”。
exporting.enabled
是否启用导出图表按钮,默认是true,但配置了之后竟然不会显示。
title.text
配置图表显示的标题,也可以调整显示的位置。
series
配置图表显示的数据列,name参数就是鼠标移动到图表曲线的时候显示的数据列悬浮提示内容。
四、Highcharts-Stock绘制内存曲线
内存曲线图表参数的初始化也类似,前端界面:
div(id='memory')
JS文件:
var chartMemoryOptions = { chart: { renderTo: 'memory' }, xAxis: { // currentDateIndicator: true, min: new Date().getTime(), max: new Date().getTime() + 24 * 60 * 60 * 1000 }, rangeSelector: { buttons: [{ count: 1, type: 'minute', text: '1M' }, { count: 5, type: 'minute', text: '5M' }, { type: 'all', text: 'All' }], inputEnabled: false, selected: 0 }, exporting: { enabled: true }, title: { text: 'Memory' }, series: [ { name: 'Total', data: [] }, { name: 'Native', data: [] }, { name: 'Dalvik', data: [] }, { name: 'Sommap', data: [] } ] }; var chartMemory = new Highcharts.StockChart(chartMemoryOptions);
五、
Highcharts
图表数据刷新
1. CPU数据的刷新显示
cpulist和memorylist都是JSON结构的数据源:
//每次都设置最新的数据来更新图表 var cpuSize = cpulist.length; var cpuTimeStamp = new Date(parseFloat(cpulist[cpuSize - 1].time)).getTime(); chartCpu.series[0].addPoint([cpuTimeStamp, parseFloat(cpulist[cpuSize - 1].processRate)]); chartCpu.series[1].addPoint([cpuTimeStamp, parseFloat(cpulist[cpuSize - 1].systemRate)]);
//更新一次X轴的最小值和最大值,避免和初始化数据设置不一致导致图表刷新显示问题。 var hasInitCPUxAxis = false; if(!hasInitCPUxAxis){ hasInitCPUxAxis = true; chartCpu.xAxis[0].setExtremes(cpuTimeStamp - 60 * 1000, cpuTimeStamp); }
2. Memory数据的刷新显示
var memSize = memorylist.length; var memTimeStamp = new Date(parseFloat(memorylist[memSize - 1].time)).getTime(); chartMemory.series[0].addPoint([memTimeStamp, parseFloat((parseInt(memorylist[memSize - 1].totalPss) / 1024).toFixed(2))]); chartMemory.series[1].addPoint([memTimeStamp, parseFloat((parseInt(memorylist[memSize - 1].nativePss) / 1024).toFixed(2))]); chartMemory.series[2].addPoint([memTimeStamp, parseFloat((parseInt(memorylist[memSize - 1].dalvikPss) / 1024).toFixed(2))]); chartMemory.series[3].addPoint([memTimeStamp, parseFloat((parseInt(memorylist[memSize - 1].soMmapPss) / 1024).toFixed(2))]); var hasInitMemoryXAxis = false; if(!hasInitMemoryXAxis){ hasInitMemoryXAxis = true; chartMemory.xAxis[0].setExtremes(memTimeStamp - 60 * 1000, memTimeStamp); }
3. 遇到的问题
这边数据更新要注意下,
不能用
chartCpuOptions.series [
0 ]
.data.push ()的方式
,而要用
chartMemory.series [0
]
.addPoint ([
x ,
y ])
才有效。
使用不当会输出如下异常:
Uncaught TypeError: d[w].destroyElements is not a function at n.generatePoints (highstock.js:5899) at n.e.generatePoints (highstock.js:9605) at n.translate (highstock.js:5939) at n.redraw (highstock.js:6243) at highstock.js:4731 at Array.forEach () at k.Chart.redraw (highstock.js:4730) at k.Chart.setSize (highstock.js:4937) at highstock.js:4904
另外注意添加的数据点参数不能是String类型的数据,最好加下parseInt或parseFloat的转化,控制台输出的异常提示如下:
Uncaught Error: Highcharts error #14: www.highcharts.com/errors/14/ at k.Chart.e (highstock.js:98) at k.fireEvent (highstock.js:487) at k.error (highstock.js:110) at n.setData (highstock.js:5796) at n.g.updatedDataHandler (highstock.js:8923) at highstock.js:485 at k.fireEvent (highstock.js:486) at highstock.js:4709 at Array.forEach () at k.Chart.redraw (highstock.js:4707) at n.addPoint (highstock.js:6658) at Socket.dataReceiveListener (performance-monitor.js:286) at Socket.Emitter.emit (index.js:131) at Socket.onevent (socket.js:263) at Socket.onpacket (socket.js:221) at Manager.eval (index.js:21)
关于error #14的说明如下:
String value sent to series.data, expected Number This happens if using a string as a data point, for example in a setup like this: series: [{ data: ["3", "5", "1", "6"] }] Highcharts expects numerical data values. The most common reason for this error this is that data is parsed from CSV or from a XML source, and the implementer forgot to run parseFloat on the parsed value. Note: For performance reasons internal type casting is not performed, and only the first value is checked (since 2.3).
如果遇到其他问题可以到 HighCharts BBS论坛
上找答案。
六、参考资料
highcharts + angularjs + live random data example
扩展阅读:
转载请注明出处:陈文管的博客– AngularJS集成HighCharts动态绘制CPU和内存变化曲线
扫码或搜索:
文呓
微信公众号
扫一扫关注