请问如何使用EXT JS查询数据库动态生成如下图的二维折线图?

图片说明

数据库查询只给我返回三个字段,如下图所示:
图片说明

网上的自定义插件如下图:
图片说明

 /**
 * 
 * @author LuoYu
 * @date 2012-12-04
 * 基于EXT-3.3.0开发的可以添加动态折线数的EXT.chart.DynamicLineChart插件
 * 初使化方法可以通过 new Ext.chart.DynamicLineChart(),
 * 也可以通过xtype的形式,xtype:dynamiclinechart
 * 
 */
Ext.chart.DynamicLineChart = Ext.extend(Ext.chart.LineChart,{
    initComponent : function() {
        var store = new Ext.data.Store({
            url : this.loadUrl,
            reader : new Ext.data.JsonReader()
        });
        var config = {
            store : store,
            xField: this.xField,
            series : new Array(),
            extraStyle:{  
                legend:{
                    display: 'bottom',  
                    padding: 5,  
                    font:{  
                        family: 'Tahoma',  
                        size: 13  
                    }  
                }  
            }
        };
        Ext.apply(this, config);
        Ext.apply(this.initialConfig, config);
        Ext.chart.DynamicLineChart.superclass.initComponent.apply(this, arguments);
    },
    onRender : function() {
        Ext.chart.DynamicLineChart.superclass.onRender.apply(this,arguments);
        this.store.on('load', function() {
            if (typeof (this.store.reader.jsonData.series) === 'object') {
                var series = [];
                Ext.each(this.store.reader.jsonData.series, function(serie) {
                    series.push(serie);
                });
                this.setSeries(series);
            }
        }, this);
        this.store.load();
    }
});
Ext.reg("dynamiclinechart", Ext.chart.DynamicLineChart);

网上的JSON返回格式如下图:
图片说明

 {
    'metaData':
        {
            'root':'records',   //这个record和下面那个record保持一致,名字可以随便取
            'fields':[
                {'name':'name','type':'string'},
                {'name':'views','type':'string'},
                {'name':'visits','type':'string'}
            ]
        },
    'series':
        [
            {'type': 'line',displayName: 'Good',yField: 'views'},
            {'type': 'line',displayName: 'Good',yField: 'visits'}
        ],
    'records':  //对应上面的record
        [
            {name:'Jul 07', visits: 245000, views: 300000},
            {name:'Aug 07', visits: 240000, views: 350000},
            {name:'Sep 07', visits: 355000, views: 400000},
            {name:'Oct 07', visits: 375000, views: 420000},
            {name:'Nov 07', visits: 490000, views: 450000},
            {name:'Dec 07', visits: 495000, views: 580000},
            {name:'Jan 08', visits: 520000, views: 600000},
            {name:'Feb 08', visits: 620000, views: 750000}
        ]
}

你的值相差太大了,我这里大概做了个demo,都连一起了。。数据要处理成{x:'x列值',z中存在的名称:'对应的y值'.....}此类数据加载就行了
图片说明

分为2部分,首先你要用jsp做一个服务器端,查询数据库,返回json,然后就是加载返回的json
这个可以参考:http://luoyu-ds.iteye.com/blog/1741271

图片说明

这是返回的JSON格式样例

 <html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Line Chart</title>
    <link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
    <script type="text/javascript" src="../../ext-all.js"></script>
    <script>
        Ext.onReady(function () {
            ////////////////////////////////////////////数据,服务器生成此类数据就行,和你数据库结构一样,直接序列化为json格式字符串复制给给对应的变量
            data = [{ x: '06:00', y: 123, z: '1#干式变压器' },
       { x: '13:00', y: 4, z: '1#干式变压器' },
       { x: '18:00', y: 0.99, z: '1#干式变压器' },
       { x: '20:00', y: 0.99, z: '1#干式变压器' },
       { x: '22:30', y: 0.99, z: '1#干式变压器' },
       { x: '06:00', y: 543, z: '2#干式变压器' },
       { x: '13:00', y: 5, z: '2#干式变压器' },
       { x: '18:00', y: 0.97, z: '2#干式变压器' },
       { x: '20:00', y: 0.96, z: '2#干式变压器' },
       { x: '22:30', y: 0.97, z: '2#干式变压器' },
       { x: '06:00', y: 0.97, z: '3#干式变压器' },
       { x: '13:00', y: 7, z: '3#干式变压器' },
       { x: '18:00', y: 0.97, z: '3#干式变压器' },
       { x: '20:00', y: 0.96, z: '3#干式变压器' },
       { x: '22:30', y: 0.97, z: '3#干式变压器' }]
            ////////////////////////////////////////////
            //数据转换 z/y数据整合
            fields = ['x']//store的列
            series = []//chart的series配置
            mydata = []//处理后store加载的值,和fields对应,变为[{x:'时间',z的值:'对应的y'...更多z的值对应y}]这种格式
            maxLineName = ''; maxY = 0;//记录y最大值,以便获取最大值的z值作为chart的y轴
            kvZ = {}//记录fields是否已经压入过唯一的z值
            var arrColor = ['red', 'blue', 'green', 'yellow', 'gray']//每条轴的颜色,如果很多继续扩展这个数组,要不超过5条颜色会重复
            for (var i = 0; i < data.length; i++) {
                lineName = data[i].z;
                if (maxLineName == '') { maxLineName = lineName; maxY = data[i].y }
                else if (data[i].y > maxY) { maxLineName = lineName; maxY = data[i].y }
                if (!kvZ[lineName]) {
                    kvZ[lineName] = true;
                    color = arrColor[fields.length%arrColor.length]
                    fields.push(lineName)
                    series.push((function (lineName) {
                        return {
                            type: 'line',
                            axis: 'left',
                            xField: 'x',
                            yField: lineName,
                            style: { fill: color, stroke: color, 'stroke-width': 3 },
                            markerConfig: { type: 'circle', size: 4, radius: 4, 'stroke-width': 0, fill: color, stroke: color },
                            tips: {
                                trackMouse: true,
                                width: 80,
                                height: 40,
                                renderer: function (storeItem, item) {
                                    console.log(lineName)
                                    this.setTitle(storeItem.get('x'));
                                    this.update(storeItem.get(lineName));
                                }
                            }
                        }
                    })(lineName));
                }
            }
            kvT = {}
            function fillExist(arr, x, v, attr) {
                for (var i = 0; i < arr.length; i++) if (arr[i].x == x) { arr[i][attr] = v; break; }
            }
            for (var i = 0; i < data.length; i++) {
                x = data[i].x
                if (kvT[x]) fillExist(mydata, x, data[i].y, data[i].z);
                else {
                    item = { x: data[i].x };
                    for (attr in kvZ) item[attr] = attr == data[i].z ? data[i].y : 0
                    mydata.push(item)
                    kvT[x] = true;
                }
            }


            mystore = Ext.create('Ext.data.JsonStore', {
                fields: fields,
                data: mydata
            });
            Ext.create('Ext.chart.Chart', {
                renderTo: document.body,
                xtype: 'chart',
                legend: { position: 'right' },
                animate: false,
                store: mystore, height: 300, width: 600,
                insetPadding: 30,
                axes: [
                    { type: 'Numeric', minimum: 0, position: 'left', fields: [maxLineName], title: true, grid: true },
                    { type: 'Category', position: 'bottom', fields: ['x'], title: true }],
                series: series
            });

        })
    </script>
</head>
    <body id="docbody">
    </body>
</html>

你好,这是所有的JS代码,ajax请求数据库返回数据跟你的格式是一样的,但是页面出现这个错误,如下图,:
图片说明
错误对应到的是我的这一行,请问您知道是哪里出问题了吗....:
图片说明

        var powerStore = Ext.create('Ext.data.JsonStore', {
        fields: ['x','y','z'],
        autoLoad: false,
        proxy: {
            type: 'ajax',
            url: Eap.contextPath + '/eap/scripts/run-script/smartassets-index-Power.gson',
            reader: {
                type: 'json',
                root: 'models'
                    }
                }
            });

            var fields = ['x']; 
            var series = [];                                            //轴线配置
            var mydata = [];                                            //存放整理后的Store
            var maxLineName = '';                                       //记录Z最大值
            var maxY = 0;                                               //记录y最大值,以便获取最大值的z值作为chart的y轴
            var kvZ = {};                                               //记录fields是否已经压入过唯一的z值
            var arrColor = ['red', 'blue', 'green', 'yellow', 'gray'];  //每条轴线的颜色,如果很多就继续扩展这个数组,不然超过5条,颜色会重复

        powerStore.load({
            scope: this,
            callback: function(records, operation, success) {
                for (var i = 0; i < records.length; i++) {
                    lineName = records[i].get('z');
                    if (maxLineName == '') {
                        maxLineName = lineName; 
                        maxY = records[i].get('y');
                    }
                    if (!kvZ[lineName]) {
                        kvZ[lineName] = true;
                        color = arrColor[fields.length%arrColor.length]
                        fields.push(lineName)
                        series.push((function (lineName) {
                        return {
                            type: 'line',
                            axis: 'left',
                            xField: 'x',
                            yField: lineName,
                            style: { fill: color, stroke: color, 'stroke-width': 3 },
                            markerConfig: { type: 'circle', size: 4, radius: 4, 'stroke-width': 0, fill: color, stroke: color },
                            tips: {
                                trackMouse: true,
                                width: 80,
                                height: 40,
                                renderer: function (storeItem, item) {
                                    this.setTitle(storeItem.get('x'));
                                    this.update(storeItem.get(lineName));
                                }
                            }
                        }
                    })(lineName));
                }
              }

            kvT = {}
            function fillExist(arr, x, v, attr) {
                for (var i = 0; i < arr.length; i++) if (arr[i].x == x) { 
                    arr[i][attr] = v; 
                    break; 
                    }
            }

            for (var i = 0; i < records.length; i++) {
                x = records[i].get('x')
                if(kvT[x]){
                    fillExist(mydata, x, records[i].get('y'), records[i].get('z'));
                    }
                else {
                    item = { x: records[i].get('x') };
                    for (attr in kvZ) item[attr] = attr == records[i].get('z') ? records[i].get('y') : 0
                    mydata.push(item)
                    kvT[x] = true;
                    }
                 }        
           }
        });

    console.log(fields)
    console.log(mydata)

    var newStore = Ext.create('Ext.data.JsonStore', {
             fields: fields,
             data: mydata
            });

    var powerPortlet = Ext.create({
             legend: { position: 'right' },
             xtype: 'cartesian',
             width: 300,
             height: 250,
             store: newStore,
             axes: [
                    { type: 'Numeric', minimum: 0, position: 'left', fields: [maxLineName], title: true, grid: true },
                    { type: 'Category', position: 'bottom', fields: ['x'], title: true }],
             series: series
            });

    var powerPanel = Ext.create('Ext.panel.Panel', {
        id: 'powerPortlet',
        multiSelect: true,
        layout: 'fit',
        border: 0,
        items:[powerPortlet],
        viewConfig: {
            stripeRows: true,
            enableTextSelection: true
        },
        refreshPortlet: function() {
            newStore.load();
        }

图片说明

数据格式如图....

图片说明

图片说明
图片说明

加上一个日期过滤条件,数据就对应不上了......
图片说明

完整JS代码如下图:

    var powerStore = Ext.create('Ext.data.JsonStore', {
        fields: ['x','y','z'],
        autoLoad: false,
        proxy: {
            type: 'ajax',
            url: Eap.contextPath + '/eap/scripts/run-script/smartassets-index-Power.gson',
            reader: {
                type: 'json',
                root: 'models'
                    }
                }
            });
            var DatePower;
            var newStore;
            var powerCart;
            var fields = ['x']; 
            var series = [];                                            //轴线配置
            var mydata = [];                                            //存放整理后的Store
            var maxLineName = '';                                       //记录Z最大值
            var maxY = 0;                                               //记录y最大值,以便获取最大值的z值作为chart的y轴
            var kvZ = {};                                               //记录fields是否已经压入过唯一的z值
            var arrColor = ['red', 'blue', 'green', 'yellow', 'gray'];  //每条轴线的颜色,如果很多就继续扩展这个数组,不然超过5条,颜色会重复

        powerStore.load({
            scope: this,
            callback: function(records, operation, success) {
                for (var i = 0; i < records.length; i++) {
                    lineName = records[i].get('z');
                    if (maxLineName == '') {
                        maxLineName = lineName; 
                        maxY = records[i].get('y');
                    }
                    if (!kvZ[lineName]) {
                        kvZ[lineName] = true;
                        color = arrColor[fields.length%arrColor.length]
                        fields.push(lineName)
                        series.push((function (lineName) {
                        return {
                            type: 'line',
                            axis: 'left',
                            xField: 'x',
                            yField: lineName,
                            style: { stroke: color, 'stroke-width': 2 },
                         marker: {
                              type: 'diamond',
                              animation: {
                                  duration: 200
                              }
                         },
                         highlight: {
                              scaling: 1,
                              rotationRads: Math.PI / 4
                         },
                         tooltip: {
                                  trackMouse: true,
                                  renderer: function (tooltip, record, item) {
                                      var store = record.store
                                      tooltip.setHtml('<div style="text-align: center; font-weight: bold">' + record.get(lineName)*100 + '%</div>');
                                 }
                              }
                        }
                    })(lineName));
                }
              }

            //遍历方法
            kvT = {}
            function fillExist(arr, x, v, attr) {
                for (var i = 0; i < arr.length; i++) if (arr[i].x == x) { 
                    arr[i][attr] = v; 
                    break; 
               }
            }
            //遍历后台传过来的元store数组 获取需要的数据格式放入mydata
            for (var i = 0; i < records.length; i++) {
                x = records[i].get('x')
                if(kvT[x]){
                    fillExist(mydata, x, records[i].get('y'), records[i].get('z'));
                    }
                else {
                    item = { x: records[i].get('x') };
                    for (attr in kvZ) item[attr] = attr == records[i].get('z') ? records[i].get('y') : 0
                    mydata.push(item)
                    kvT[x] = true;
                    }
                 }        
             //创建一个新的store
            newStore = Ext.create('Ext.data.JsonStore', {
                fields: fields,
                data: mydata
             });
            //折线坐标图
            powerCart = Ext.create({
                //renderTo: document.body,
                legend: { position: 'right' },
                xtype: 'cartesian',
                width: 400,
                height: 300,
                store: newStore,
                axes: [{ 
                type: 'numeric', 
                minimum: 0, 
                position: 'left', 
                fields: [maxLineName], 
                title: true, 
                grid: true 
                },{ 
                type: 'category', 
                position: 'bottom', 
                fields: ['x'], 
                title: true
                }],
                series: series
                });

          DatePower = new Ext.form.DateField({
              name : 'DatePower',
              editable:true, 
              Width : 100,
              format : 'Y-m-d',
              emptyText : '年/月/日',
              id : 'DatePower',
              listeners: { 
                  change:function(me, newValue, oldValue, eOpts){
                  powerStore.removeAll();
                  powerStore.proxy.extraParams = {};
                  powerStore.proxy.extraParams['bydate'] = [Ext.Date.format(newValue,'Y-m-d')];
                  powerStore.load();
                  }
                }
              })
                toolbarPow.add(DatePower);
                powerPanel.remove(powerCart);
                powerPanel.add(powerCart);
           }
        });

    var toolbarPow = Ext.create("Ext.Toolbar", {
        width: 200,
        items: []
        });

    var powerPanel = Ext.create('Ext.panel.Panel', {
        id: 'powerPortlet',
        multiSelect: true,
        layout: {
        type:'vbox',
        align: 'stretch'
        },
        layout: 'fit',
        border: 0,
        items:[],
        tbar:toolbarPow,
        viewConfig: {
            stripeRows: true,
            enableTextSelection: true
        },
        refreshPortlet: function() {
            powerStore.reload();
        }
       });

我现在加了个日期选择条件,返回的数据当然是不一样的,但是我的折线要怎么才能对应上呢?

图片说明

图片说明
最新截图:
问题就出在这里,通过调试发现records 是最新的,但是mydata还是之前的.......