Extjs4 中Line chart使用Ajax数据源绘图

    技术2022-06-10  46

    在ExtJS 4 LiveAnimated.html 例子中,动态绘制了曲线图,很是漂亮,例子中是用前端javascript生成的测试数据来绘图,如果用ajax的方式从后台取数据去绘图,出现了曲线无法绘制(坐标轴已绘制)的问题,结果如下:

    代码如下:

      Ext.require('Ext.chart.*');function Content(ncId, ipAddress) { var nowTime = new Date(); var intervalId = -1; var arrayCount = 30; var step = 1; var storeLength = ""; var generateData = (function() { var data = [], i = 0, date = nowTime; min = Math.min, max = Math.max, random = Math.random; return function() { Ext.Ajax.request({ url: 'getVMUsedMemory.php', params: {ncId:ncId, ipAddress: ipAddress}, success: function(response, options){ var jsonData = Ext.decode(response.responseText); //data = data.slice(); if(data.length == arrayCount){ data.shift(); //remove the first data of array } data.push({ date: new Date(jsonData.date), usedMemory: parseInt(jsonData.usedMemory/1024) }); } }); return data.slice(); }; })(); var store = Ext.create('Ext.data.JsonStore', { fields: ['date', 'usedMemory'], data: generateData() }); Ext.create('Ext.Window', { width: 800, height: 600, hidden: false, maximizable: true, title: 'Live Animated Chart', renderTo: Ext.getBody(), layout: 'fit', items: [{ xtype: 'chart', style: 'background:#fff', id: 'chartCmp', store: store, animate: true, axes: [{ type: 'Numeric', grid: true, minimum: 0, maximum: 8192, position: 'left', fields: ['usedMemory'], title: 'Memory of used(MB)', grid: { odd: { fill: '#dedede', stroke: '#ddd', 'stroke-width': 0.5 } } }, { type: 'Time', position: 'bottom', fields: 'date', title: 'Day', step: [Ext.Date.SECOND, 1], dateFormat: 'i:s',groupBy: 'year,month,day,hour,minute,second',//aggregateOp: 'sum', constrain: true, fromDate: Ext.Date.add(nowTime, Ext.Date.SECOND, 1), toDate: Ext.Date.add(nowTime, Ext.Date.SECOND, 30), grid: true }], series: [{ type: 'line', axis: 'left', xField: 'date', yField: 'usedMemory', label: { display: 'none', field: 'usedMemory', renderer: function(v) { return v >> 0; }, 'text-anchor': 'middle' }, markerConfig: { radius: 5, size: 5 } }] }], listeners: { afterrender: function() { var chart = Ext.getCmp('chartCmp'); var timeAxis = chart.axes.get(1);intervalId = setInterval(function() { var gs = generateData(); var toDate = timeAxis.toDate, lastDate = gs[gs.length - 1].date, markerIndex = chart.markerIndex || 0; if (+toDate < +lastDate) { markerIndex = 1; timeAxis.toDate = lastDate; timeAxis.fromDate = Ext.Date.add(Ext.Date.clone(timeAxis.fromDate), Ext.Date.SECOND, step); chart.markerIndex = markerIndex; } store.loadData(gs); storeLength += store.data.items.length;}, step*1000); }, destroy: function(){ clearInterval(intervalId); } } });}Ext.onReady(function () {var con = new Content("10.0.21.1");});

    分析代码,没有发现缺陷,但一直无法绘制曲线,后来跟踪代码到 Ext.chart.axis.Time中,发现了问题所在:Ext在绘制图形时,先绘制了Time时间轴。绘制时间轴时,首先为chart对象创建了substore,它与store的结构一样,先看看drawSeries这个函数的代码(Ext.chart.series.Line)

    //Ext.chart.series.LinedrawSeries: function() {var me = this,chart = me.chart,store = chart.substore || chart.store, ……} 

    从代码中可以看出drawSeries使用的数据源是chart.substore和chart.store “逻辑或”,逻辑或的结果是“第一个不为空就是第一个,第一个为空就是第二个”,而此时的substore不为null,因此绘制曲线的数据源也是substore,而substore的数据与时间轴的刻度一一对应,constrainDates( Ext.chart.axis.Time)函数中生成了substore的数据,从下面的代码可以看出,其数据来源与store有关。

    var getRecordByDate = (function() { var index = 0, l = store.getCount(); return function(date) { var rec, recDate; for (; index < l; index++) { rec = store.getAt(index); recDate = rec.get(field); if (+recDate > +date) { return false; } else if (+recDate == +date) { return rec; } } return false; }; })(); 

     

    时间轴可以绘制出来,但曲线就是不能绘制出来,经过查找,发现substore中的usedMemory的值全部为false,此为问题所在。上面的代码是从store中查找date字段,如果2个时间相等,则将rec的数据返回给substore。

     

    关注for循环中的else if 部分,发现没有任何两个时间相等,所以substore中的usedMemory的值全部为false。ajax返回的数据格式为{"usedMemory":163576,"date":"2011 05 31 22:11:02"} ,不相等的原因在于nowtime中含有微秒值,而ajax返回值中无微秒值,所以 else if (+recDate == +date) 永远不成立,找到问题所在后,解决十分简单,将nowtime中的微秒值去除,可以使用nowTime.setMilliseconds(0);

     

     

    经验:时间值的比较可以采用如下方式:

    date = new Date();

    +date操作可直接将date转换为int值,两个Date类型的比较,一定要注意精度(秒、微秒)!


    最新回复(0)