工作中用到, 这里分享一下。 可以使用 amcharts 和 highcharts 在同一坐标中绘制多个对比曲线图。 当然, 对图形没有过多装饰, 可以参考 API 文档:

highcharts:   Highcharts API

amcharts:     amcharts API

0.  说明

amcharts 与 highcharts 对于数据格式的要求是不一样的。 amcharts 只需要一个 对象数组 [{'x': 1, 'y': 2, 'z': 3}, {'x':2, 'y': 4, 'z': 6}], 并指明 x ,y 轴的字段名,其它的就交给 amcharts 了; 而 highcharts 则需要对每个曲线图定义好二维数组 ,  [[1,2], [2,4]] , [[1,3], [2,6]] ; 如果要使用对象数组返回格式, 就需要进行数据抽取和重组, 以符合 highchart
的要求。

由于 javascript 所使用的标准数据格式是 JSON, 因此, 可以非常方便地进行数据拼接和组合。 也就是说, 如果要在同一坐标中绘制多个曲线图, 只需要定义一个数组, 将多个曲线图的数据加入数组即可。

实现中, 有五点需要重点说明:

a.  时间字段。 由于不同的API 返回的JSON数据中,时间的字段名不一定相同(比如有的为 time, 有的为 timestamp), 并且时间的格式有所不同(比如有的为字符串, 有的为时间戳), 为了追求灵活性, 需要使用一个日期转换函数 convertDate(chartData, timeStampFieldName, dateConvertFunc) 来统一处理。 这里统一转换为 javascript timestamp 再转化为 Date 类型, 可以兼容 Firefox 和
Chrome .  当然, 具体转换为什么类型, 要视采取的库支持决定。

b.  返回数据的格式, 主要以对象数组为主;

c.   由于要绘制任意多个曲线图, 这里也需要考虑到灵活性, 利用了 JSON 格式的灵活性, 采用循环方式加入多个曲线的配置项来实现;

d.  在实现中,尽可能基于已有库提供相同的使用接口, 这样, 就可以在多个选择中自由地切换;

e.  简单的框架性处理: 通常显示多图时, 一般会显示小图, 然后点击后显示大图。 这里, 点击小图后显示大图,最好做成框架中的处理, 客户端使用不必操心这种事情,也避免了将类似的代码分布在系统的各处。即尽量遵循“一个事实”的设计原则。

1.  返回数据格式      

{"result":{"msg":null,"code":200,"data":[{"__source__":"10.201.20.35","__time__":"1380446527","blocked":"0","plist":"1517","runq":"0","ldavg_1":"2.34","ldavg_5":"1.56","ldavg_15":"1.43","time":"Sun Sep 29 17:22:07 2013"},{"__source__":"10.201.20.35","__time__":"1380446587","blocked":"0","plist":"1524","runq":"5","ldavg_1":"2.38","ldavg_5":"1.69","ldavg_15":"1.48","time":"Sun Sep 29 17:23:07 2013"},{"__source__":"10.201.20.35","__time__":"1380446647","blocked":"0","plist":"1523","runq":"3","ldavg_1":"1.51","ldavg_5":"1.56","ldavg_15":"1.45","time":"Sun Sep 29 17:24:07 2013"}],"success":true}}

2. HTML DIV

<body>
<div id="perfcharts">
<div id="Loadperfchartdiv" style="width:100%; height:400px;" class="chartdiv"></div>
</div>
</body>

3.  使用 amcharts 绘制:  

      需要导入

<script src="../amcharts.js" type="text/javascript"></script>
<script src="../jquery-1.10.1.min.js" type="text/javascript"></script>
<script src="../drawchart.js" type="text/javascript"></script>

drawchart.js 是编写的基于 amcharts 的在同一坐标中绘制多图形的客户端接口:

/**
* 使用 amcharts 绘制时间趋势曲线图
*
* generateChart:
* chartDiv 绘图所需要的 DIV 区域名称;
* chartData 绘图所需要的数据
* chartConfig 绘图的全局配置对象
* lineConfigArray 每个曲线图的配置对象(配置Y轴)
*
*/
var globalChart = null, globalChartData = null;
function generateChart(chartDiv, chartData, chartConfig, lineConfigArray) {
console.log('begin draw chart: ' + getNow());
// SERIAL CHART
var chart = new AmCharts.AmSerialChart();
globalChart = chart;
globalChartData = chartData;
chart.pathToImages = "../resources/images/amcharts2/";
chart.zoomOutButton = {
backgroundColor: '#000000',
backgroundAlpha: 0.15
};
chart.dataProvider = chartData;
chart.categoryField = "timeStamp"; // data updated event will be fired when chart is first displayed,
// also when data will be updated. We'll use it to set some
// initial zoom
chart.addListener("dataUpdated", zoomChart); // AXES
// Category
var categoryAxis = chart.categoryAxis;
categoryAxis.parseDates = true; // in order char to understand dates, we should set parseDates to true
categoryAxis.minPeriod = "mm"; // as we have data with minute interval, we have to set "mm" here.
categoryAxis.gridAlpha = 0.07;
categoryAxis.axisColor = "#DADADA";
categoryAxis.labelFunction = function(valueText, date, categoryAxis) {
var MM = date.getMonth()+1;
var dd = date.getDate();
var hh = date.getHours();
if(hh<10) hh = '0' + hh;
var mm = date.getMinutes();
if(mm<10) mm = '0' + mm;
var ss = date.getSeconds();
return MM+'-'+dd+' '+hh+':'+mm;
} // Value
var valueAxis = new AmCharts.ValueAxis();
valueAxis.gridAlpha = 0.07;
valueAxis.title = chartConfig.title;
chart.addValueAxis(valueAxis); // GRAPH
for (var i=0; i<lineConfigArray.length;i++) {
var graph = new AmCharts.AmGraph();
graph.type = "line";
graph.title = lineConfigArray[i].title;
graph.valueField = lineConfigArray[i].valueField;
graph.lineAlpha = 1;
graph.lineColor = lineConfigArray[i].lineColor;
chart.addGraph(graph);
} // CURSOR
var chartCursor = new AmCharts.ChartCursor();
chartCursor.cursorPosition = "mouse";
chartCursor.categoryBalloonDateFormat = "MM DD JJ:NN";
chart.addChartCursor(chartCursor); // SCROLLBAR
var chartScrollbar = new AmCharts.ChartScrollbar();
chart.addChartScrollbar(chartScrollbar); // LEGEND
var legend = new AmCharts.AmLegend();
legend.marginLeft = 110;
chart.addLegend(legend); // WRITE
chart.write(chartDiv);
console.log('end draw chart: ' + getNow());
} function convertDate(chartData, timeStampFieldName, dateConvertFunc) {
for (var i=0; i<chartData.length;i++) {
var timeStamp_i = chartData[i][timeStampFieldName == null ? "timeStamp": timeStampFieldName];
if (typeof dateConvertFunc === 'function') {
chartData[i].timeStamp = dateConvertFunc(timeStamp_i);
}
else {
chartData[i].timeStamp = new Date(timeStamp_i);
}
}
return chartData;
} function zoomChart() {
globalChart.zoomToIndexes(0, globalChartData.length - 1);
}

客户端使用方法 :

AmCharts.ready(function () {

                    var drawLoadperf = function() {
$.ajax({
dataType: "json",
url: httpPrefix + '/controllers/sls/obtainNcLoad',
data: 'Category=load_log_index&' + params,
success: function(data) {
var chartData = convertDate(data.result.data, "time");
generateChart('Loadperfchartdiv', chartData,
{'title': 'Load'},
[{'title':'load_1', 'valueField': 'ldavg_1', 'lineColor': '#ff0000'},
{'title':'load_5', 'valueField': 'ldavg_5', 'lineColor': '#00ff00'},
{'title':'load_15', 'valueField': 'ldavg_15', 'lineColor': '#0000ff'}]);
}
});
}
}

amcharts 效果图:

4.  使用 highcharts 绘制:

需要导入:

<script src="../jquery-1.10.1.min.js" type="text/javascript"></script>
<script src="../highcharts.js" type="text/javascript"></script>
<script src="../drawchart_highcharts.js" type="text/javascript"></script>

drawchart_highcharts.js 是基于 highcharts 的在同一坐标中绘制多个图形的客户端接口。点击可以放大显示,再点击则还原到原来的视图。

/**
* 使用 highcharts 绘制时间趋势曲线图
*
* generateChart:
* chartDiv 绘图所需要的 DIV 区域名称;
* chartData 绘图所需要的数据
* chartConfig 绘图的全局配置对象
* lineConfigArray 每个曲线图的配置对象(配置Y轴)
*
*/
Highcharts.setOptions({
global: {
useUTC: false
},
lang: {
resetZoom: '还原视图'
} });
function generateChart(chartDiv, chartData, chartConfig, lineConfigArray) {
var chartObj = {
chart: {
zoomType: 'x',
events: {
// 点击图表后在指定区域 zoomUpDiv 放大显示
click: null
}
},
// 去掉 highcharts.com 链接
credits: {
enabled: false,
text: ''
},
plotOptions: {
series: {
// 去掉点的marker, 使图形更美观
marker: {
enabled: false,
states: {
hover: {
enabled: true
}
}
}
}
},
series: [],
xAxis: {
type: 'datetime',
dateTimeLabelFormats: {
hour: '%m-%d %H:%M'
}
},
yAxis: {
title: {
text: ''
},
min: 0
},
tooltip: {
crosshairs: true,
shared: true,
formatter: function() { // 当鼠标悬停图表上时, 格式化提示信息
var tipText = '<b>' + Highcharts.dateFormat('%m-%d %H:%M', this.x) + '</b>';
$.each(this.points, function(i, point) {
tipText += '<br/>'+ point.series.name +': '+ point.y;
});
return tipText;
}
},
title: {
// 不显示图表标题
text: null
}
};
// 在同一坐标中绘制多个曲线图
for (var i=0; i<lineConfigArray.length;i++) {
var subseries = {
name: lineConfigArray[i].title,
data: extract(chartData, lineConfigArray[i].valueField),
color: lineConfigArray[i].lineColor
};
chartObj.yAxis.title.text = chartConfig.title;
chartObj.series.push(subseries);
}
// 点击图表后在指定区域 zoomUpDiv 放大显示
chartObj.chart.events.click = function(event) {
var zoomUpDiv = $('#zoomUpDiv');
if (zoomUpDiv != null) {
$('#zoomUpDiv').css('display', 'block');
$('.chartdiv').css('display', 'none');
chartObj.chart.events.click = function(event) {
$('#zoomUpDiv').css('display', 'none');
$('.chartdiv').css('display', 'block');
};
$('#zoomUpDiv').highcharts(chartObj);
}
};
$("#"+chartDiv).highcharts(chartObj); } /**
* 指定后台返回的时间字段为 timeStampFieldName , 若不指定则默认为 timeStamp ,
* 并利用自定义回调函数 dateConvertFunc 统一为时间戳进行处理
*/
function convertDate(chartData, timeStampFieldName, dateConvertFunc) {
for (var i=0; i<chartData.length;i++) {
var timeStamp_i = chartData[i][timeStampFieldName == null ? "timeStamp": timeStampFieldName];
if (typeof dateConvertFunc === 'function') {
// 如果给定了自定义的时间转换回调函数, 则使用该函数
chartData[i].timeStamp = dateConvertFunc(timeStamp_i);
}
else if (typeof timeStamp_i === 'number') {
// 适用于时间戳
chartData[i].timeStamp = timeStamp_i;
}
else {
// 适用于格式 "Sun Sep 29 17:24:07 2013", "2013-09-29 17:23:09"
chartData[i].timeStamp = new Date(timeStamp_i);
}
}
return chartData;
} /**
* 从 chartData 中抽取出 valueField 数据
*/
function extract(chartData, valueField) {
var valueData = [];
var i=0, len = chartData.length;
for (i=0; i<len; i++) {
valueData.push([chartData[i].timeStamp, parseFloat(chartData[i][valueField])]);
}
return valueData;
}

客户端使用:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>宿主机性能状态曲线图</title>
<script src="../jquery-1.10.1.min.js" type="text/javascript"></script>
<script src="../highcharts.js" type="text/javascript"></script>
<script src="../drawchart_highcharts.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="../resources/css/chart.css" />
<script type="text/javascript"> $(document).ready(function () { var iframeurl = parent.document.getElementById("ncperf").src
var params = iframeurl.substring(iframeurl.lastIndexOf('?')+1);
$(function () { var drawLoadperf = function() {
$.ajax({
dataType: "json",
url: httpPrefix + '/controllers/sls/obtainNcLoad',
data: 'Category=load_log_index&' + params,
success: function(data) {
var chartData = convertDate(data.result.data, "time");
generateChart('Loadperfchartdiv', chartData,
{'title': 'Load'},
[{'title':'load_1', 'valueField': 'ldavg_1', 'lineColor': '#f58220'},
{'title':'load_5', 'valueField': 'ldavg_5', 'lineColor': '#00ff00'},
{'title':'load_15', 'valueField': 'ldavg_15', 'lineColor': '#0000ff'}]);
}
});
} var drawCpuperf = function() {
$.ajax({
dataType: "json",
url: httpPrefix + '/controllers/sls/obtainNcCpuUsage',
data: 'Category=dom0_log_index&' + params,
success: function(data) {
var chartData = convertDate(data.result.data, "time");
generateChart('CpuUsageperfchartdiv', chartData,
{'title': 'Cpu 使用率(%)'},
[{'title':'usr', 'valueField': 'usr', 'lineColor': '#f58220'},
{'title':'sys', 'valueField': 'sys', 'lineColor': '#00ff00'},
{'title':'idle', 'valueField': 'idle', 'lineColor': '#0000ff'},
{'title':'iowait', 'valueField': 'iowait', 'lineColor': '#ffe600'}]);
}
});
} var drawNetworkperf = function() {
$.ajax({
dataType: "json",
url: httpPrefix + '/controllers/sls/obtainNcNetworkflow',
data: 'Category=netflow_log_index&' + params,
success: function(data) {
var chartData = convertDate(data.result.data, "time");
generateChart('Networkflowchartdiv', chartData,
{'title': '网络流量 (KB/s)'},
[{'title': 'RECV_BYTES', 'valueField': 'rxkB', 'lineColor': '#f58220'},
{'title': 'TRAN_BYTES', 'valueField': 'txkB', 'lineColor': '#00ff00'}]);
}
}); } var drawIoperf = function() {
$.ajax({
dataType: "json",
url: httpPrefix + '/controllers/sls/obtainNcIoperf',
data: 'Category=iostat_log_index&' + params,
success: function(data) {
var chartData = convertDate(data.result.data, "time");
generateChart('Iorwperfchartdiv', chartData,
{'title': 'io读写 (KB/s)'},
[{'title': 'read_iops', 'valueField': 'rkB_s', 'lineColor': '#f58220'},
{'title': 'write_iops', 'valueField': 'wkB_s', 'lineColor': '#00ff00'}]); generateChart('Ioutilchartdiv', chartData,
{'title': 'io利用率 (%)'},
[{'title': 'ioutil', 'valueField': 'util', 'lineColor': '#f58220'}]);
}
});
} // 间隔 一段时间 后发送下一个异步请求, 避免服务端线程竞争导致错误
setTimeout(drawCpuperf, 500);
setTimeout(drawNetworkperf, 2000);
setTimeout(drawIoperf, 3500);
drawLoadperf();
}); }); // $document </script>
</head> <body>
<div id="zoomUpDiv"></div>
<div id="perfcharts">
<div id="Loadperfchartdiv" class="chartdiv"></div>
<div id="CpuUsageperfchartdiv" class="chartdiv"></div>
<div id="Networkflowchartdiv" class="chartdiv"></div>
<div id="Iorwperfchartdiv" class="chartdiv"></div>
<div id="Ioutilchartdiv" class="chartdiv"></div>
</div>
</body> </html>

样式文件: chart.css

* {font-family: 微软雅黑, 宋体, san-serif!important}

.chartdiv {
float: left;
margin: 5px 15px 5px 10px;
width: 45%;
height: 150px;
} #zoomUpDiv {
display: none;
position: absolute;
top: 20px;
left: 10px;
margin: 10px 15px 10px 10px;
width: 95%;
height: 80%;
z-index:;
}

highcharts  效果图

使用 amcharts 和 highcharts 绘制多曲线时间趋势图的通用方法的更多相关文章

  1. 使用highcharts绘制美观的燃尽图

    使用highcharts绘制美观的燃尽图 助教在博客中介绍了两种绘制燃尽图的方法,但是我们组在使用时发现有些任务不适合写进issue,而且网站生成的燃尽图不是很美观,因此我们打算使用其他方法自己绘制燃 ...

  2. HighCharts画时间趋势图,标示区以及点击事件操作

    最近在用HighCharts画趋势图,如果按照设计文档上来画那太复杂了,于是根据自己多年的经验改动了设计文档,添加了highcharts的标示区,然而我也发现,最后一次画highchart趋势图还是在 ...

  3. 使用highcharts实现无其他信息纯趋势图实战实例

    使用highcharts实现无其他信息纯趋势图实战实例 Highcharts去掉或者隐藏掉y轴的刻度线yAxis : { gridLineWidth: 0, labels:{ //enabled:fa ...

  4. Echarts 曲线数少于图例数解决方法

    在上一篇文章 Echarts 多曲线“断点”问题解决方法 中说到了Angular 项目中要使用 Echarts 的方法. 说明了自己解决当“每一条曲线的横坐标不相同”时,在各条曲线上,它们的值采用数组 ...

  5. 根据GSVA结果绘制不同组的趋势图

    首先需要将GSVA的矩阵结果转换成如下格式: 然后使用如下代码进行作图 infile <- "draw_pre_violin_heatmap.txt" data <- ...

  6. Excel应该这么玩——7、我是预言家:绘制趋势图

    让我们先看一个场景:你是公司销售部的员工,你手里有公司最近几年的销售额相关的数据,经理希望你预测下个月的销售额.盯着一堆数据,你或许会想到画一张XY坐标图,然后将每个月份的销售额标定为一个坐标.但是下 ...

  7. 使用python和pygame绘制繁花曲线

    前段时间看了一期<最强大脑>,里面展示了各种繁花曲线组合成的非常美丽的图形,一时心血来潮,想尝试自己用代码绘制繁花曲线,想怎么组合就怎么组合. 真实的繁花曲线使用一种称为繁花曲线规的小玩意 ...

  8. Highcharts绘制曲线图小结

    Higcharts绘制曲线图很好用! 虽然说Highcharts官网有API 刚接触这个领域,学有心得,理解不到位之处希望大家多多指教! 项目绘制的曲线是:平均水位随时间的变化而改变的水情走势图. 主 ...

  9. highcharts绘制股票k线

    借助highcharts绘制股票k线: 后台通过websocket没个一定时间下发最新数据,然后重新绘制k线; 开发文档: https://api.highcharts.com/highcharts/ ...

随机推荐

  1. python requests模块中返回时间elapsed解析

    一.问题: Python 中requests库在发送http请求时相当方便好用,但在使用时一直受一个问题困扰,怎么才能查看请求时长呢? 自己写时间函数再相减?NO,这个方法肯定不行. 二.解决: 好吧 ...

  2. Linux at 定时任务

    命令格式:at[参数][时间]  请注意系统时间是UTC 命令功能:在一个指定的时间执行一个指定任务,只能执行一次.假如该时间已过去,那么就放在第二天执行. /var/spool/mail/这里是任务 ...

  3. Transient修饰符的使用

    如果一个类没有继承Serilizable接口,那么它就不能被序列化,写入文件的时候会报异常.如果一个类继承了Serilizable接口,那么这个类的所有属性和方法都可以自动被序列化,而现实中我们又希望 ...

  4. background-size:100% 100% 时 background-position: % 失效

    背景知识: background-size background-position 难题: background-size 为 100% 100% 时,background-position 部分失效 ...

  5. 线性DP总结(LIS,LCS,LCIS,最长子段和)

    做了一段时间的线性dp的题目是时候做一个总结 线性动态规划无非就是在一个数组上搞嘛, 首先看一个最简单的问题: 一,最长字段和 下面为状态转移方程 for(int i=2;i<=n;i++) { ...

  6. hadoop2.x编译安装

    Build instructions for Hadoop (Hadoop 编译安装,参考hadoop源码包中BUILDING.txt文档) ----------------------------- ...

  7. android udev

    http://www.freesoftwaremagazine.com/articles/drivers_linux http://blog.csdn.net/jianchi88/article/de ...

  8. 【Loadrunner】Error -26601: Decompression function 错误解决、27728报错解决方案

       一. Error -26601: Decompression function 错误解决 Action2.c(30): Error -26601: Decompression function ...

  9. 【Python】详解Python多线程Selenium跨浏览器测试

    前言 在web测试中,不可避免的一个测试就是浏览器兼容性测试,在没有自动化测试前,我们总是苦逼的在一台或多台机器上安装N种浏览器,然后手工在不同的浏览器上验证主业务流程和关键功能模块功能,以检测不同浏 ...

  10. 怎么设置输入的EditText字母自己主动大写

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/t80t90s/article/details/25048917 复于: 2013-09-06 09: ...