highcharts动态曲线的实现
Highcharts是一个非常成熟的绘制图表的前端库,由纯JS编写。能够很方便的在实际项目中添加有交互性的图表,并且免费提供给个人学习、个人网站和非商业用途使用。目前HighCharts支持的图表类型有曲线图、区域图、柱状图、饼状图、散状点图和综合图表。
HighCharts的UI设计非常优美,由于使用纯JS编写,所以不需要像Flash和Java那样需要插件才可以运行,而且运行速度较快。最重要的是,HighCharts还有很好的兼容性,能够兼容当前主流的浏览器。详细的文档,可以参考:www.highcharts.com.
下面,我将分享使用highcharts在实际项目中绘制动态曲线图的例子,先上代码:
QtAvgCostChartPanel = function() {
this.plot;
var scope = this;
//获取Provider(应用名)
var appArr2store = buildCombo.getApp();
//当Provider App默认值为search时,按search加载Service Name、Service MethodName及providerHost默认的下拉框列表
//获取ProviderHost
var providerArr2store = buildCombo.getProvider('search');
//获取service(服务名)
var serviceArr2store = buildCombo.getService('search');
//初始化service methodName(服务方法名)
var methodArr2store = new Ext.data.ArrayStore({
fields:['methodName','methodName']
});
this.toolBar = [ '-', 'Provider App:', {
id : 'providerApp_QtAvg',
xtype : 'combo',
width : 155,
listWidth : 200,
value : 'search',//设置默认值
store : appArr2store,
valueField : 'appCode',
displayField : 'appCode',
selectOnFocus : true,
mode : 'local',
triggerAction : 'all',
listeners:{
'select': function(){
//选择App的值,可以级联确定service及providerHost下拉框列表
var appValue = this.getRawValue();
Ext.getCmp('providerHost_QtAvg').store.removeAll(); //清除缓存数据
Ext.getCmp('serviceName_QtAvg').store.removeAll(); //清除缓存数据
Ext.getCmp('serviceMethodName_QtAvg').store.removeAll(); //清除缓存数据
//当重新选择时,清空各下拉框显示值及原始值
Ext.getCmp('serviceName_QtAvg').clearValue();
Ext.getCmp('serviceMethodName_QtAvg').clearValue();
Ext.getCmp('providerHost_QtAvg').clearValue();
//获取service(服务名)
var serviceArr2store = buildCombo.getService(appValue);
//重新加载数据(local)
Ext.getCmp('serviceName_QtAvg').store.loadData(serviceArr2store);
//获取ProviderHost
var providerArr2store = buildCombo.getProvider(appValue);
//重新加载数据(local)
Ext.getCmp('providerHost_QtAvg').store.loadData(providerArr2store);
scope.query();
}
}
}, '-','Provider Host:', {
id : 'providerHost_QtAvg',
xtype : 'combo',
width : 155,
listWidth : 180,
store : providerArr2store,
valueField : 'hosts',
displayField : 'hosts',
selectOnFocus : true,
mode : 'local',
triggerAction : 'all',
listeners:{
'select': function(){
scope.query();
}
}
}, '-','Service Name:', {
id : 'serviceName_QtAvg',
xtype : 'combo',
width : 155,
listWidth : 280,
store : serviceArr2store,
valueField : 'service',
displayField : 'service',
selectOnFocus : true,
mode : 'local',
triggerAction : 'all',
listeners:{
'select': function(){
var appValue = Ext.getCmp('providerApp_QtAvg').getRawValue();
var selectedValue = this.getRawValue();
Ext.getCmp('serviceMethodName_QtAvg').store.removeAll(); //清除缓存数据
//当重新选择时,清空各下拉框显示值及原始值
Ext.getCmp('serviceMethodName_QtAvg').clearValue();
//获取service nameMethod(服务方法名)
var methodArr2store = buildCombo.getServiceMethod(appValue,selectedValue);
//重新加载数据(local)
Ext.getCmp('serviceMethodName_QtAvg').store.loadData(methodArr2store);
scope.query();
}
}
}, '-','Service MethodName:', {
id : 'serviceMethodName_QtAvg',
xtype : 'combo',
width : 155,
listWidth : 420,
store : methodArr2store,
valueField : 'methodName',
displayField : 'methodName',
selectOnFocus : true,
mode : 'local',
triggerAction : 'all',
listeners:{
'select': function(){
scope.query();
}
}
}, '-',{
iconCls : 'ms-query',
xtype : 'button',
text : "查找",
handler : this.query,
scope : this
}];
this.reportPanel = new Ext.BoxComponent(
{
border : false,
autoEl : {
tag : 'div',
html : "<div id='QtAvgCostChartDiv' style='width:80%;height:90%;'></div>"
},
anchor : 'none -24'
});
QtAvgCostChartPanel.superclass.constructor.call(this, {
id : 'QtAvgCostChart',
title : '平均耗时',
margins : '0 0 5 5',
cmargins : '0 5 5 5',
closable : true,
tbar : this.toolBar,
bbar : this.bottomBar,
layout : 'fit',
autoScroll : true,
items : [this.reportPanel],
listeners : {
'beforedestroy' : function(){
clearInterval(this.reVal);
}
}
});
};
Ext.extend(QtAvgCostChartPanel, Ext.Panel, {
query : function() {
var param = {
providerApp : Ext.getCmp("providerApp_QtAvg").getRawValue(),
providerHost : Ext.getCmp("providerHost_QtAvg").getRawValue(),
serviceName : Ext.getCmp("serviceName_QtAvg").getRawValue(),
serviceMethodName : Ext.getCmp("serviceMethodName_QtAvg").getRawValue()
};
clearInterval(this.reVal);
this.draw("quarterAnalystService", "getMemoMinsAvgCost" , param);
},
init : function() {
this.draw("quarterAnalystService", "getMemoMinsAvgCost" , {});
},
draw : function(service, method ,param){
var me = this;
Highcharts.setOptions({
global : {
useUTC: false
}
});
var chart,
maxMinData = {},
params = Ext.encode({s : service, m : method, p : param});
$('#QtAvgCostChartDiv').highcharts({
chart : {
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events : {
load : function(){
var series = this.series[0];
var loadData = function(){
maxMinData = {};
$.ajax({
type : "post",
url : "ajax.do",
data : {rmi : params},
async : false,
success : function(response){
if(!Ext.isEmpty(response)){
var xdata = response['xdata'],
ydata = response['ydata'],
others = response['others'];
for(var i = 0, len = xdata.length; i<len; i++){
maxMinData[xdata[i]] = others[i];//保存最大值最小值
var x = xdata[i], y = ydata[i];
var isShift = series.data.length >= 15;//防止数据过大,造成浏览器崩溃
series.addPoint([x,y], true, isShift);
}
}
}
});
}
loadData();//首次加载数据
me.reVal = setInterval(loadData, 30000);//动态获取数据,并保存返回值
}
}
},
title : {
text: '平均耗时实时监控'
},
xAxis : {
type: 'category'
},
yAxis : {
title : {
text : '平均耗时/ms'
},
min : 0,
plotLines : [{
value : 0,
width : 1,
color: '#808080'
}]
},
tooltip : {
formatter : function(){
var max_min = maxMinData[this.point.name] && maxMinData[this.point.name].split(',');
if(!max_min){
return '<b>'+ this.series.name +
'</b><br/>'+this.point.name+
'<br />'+'平均值 :'+this.y +
'<br />'+'最大值 :'+ 0 +
'<br />'+'最小值 :'+ 0 ;
}
return '<b>'+ this.series.name +
'</b><br/>'+this.point.name+
'<br />'+'平均值 :'+this.y +
'<br />'+'最大值 :'+max_min[0]+
'<br />'+'最小值 :'+max_min[1];
}
},
legend : {
enabled : false
},
exporting : {
enabled : false
},
credits : {
enabled : false
},
series : [{
name : '平均耗时',
data : []
}]
});
}
});
Ext.reg("QtAvgCostChart", QtAvgCostChartPanel);
上面是一个平均耗时的代码,使用了Extjs,关键的绘图代码是方法draw : function(service, method ,param){},在load事件中,使用了jquery的ajax方法同步取数据,因为后面要用到这些数据,故而使用了同步方法。其中:
var isShift = series.data.length >= 15;//防止数据过大,造成浏览器崩溃
这里是因为每次均获取15分钟的数据,故此,当图中数据大于15个,将会删除最前面的数据点。动态加载的方法是loadData,每半分钟刷新一次。效果如下: