2015-02-11 79 views
1

下面有兩個示例(A和B)。第一個,A,正確地工作,但圖表由容器管理。我覺得這不是必要的。我想直接擴展Cartesian圖表,而不是將其添加到 Container。我在第二個例子B中試圖這麼做,但我一直不成功。ExtJS5圖表 - 擴展笛卡爾圖表

示例A

該示例工作得很好。它來源於Sencha's ExtJS5 Multi-axis column chart example of their kitchen sink

Demo @ JSFiddle

var climateData = getClimateData(); 

Ext.define('ChartApp.mixins.reader.DynamicReaderMixin', { 
    extend : 'Ext.Mixin', 

    readRecords : function(data) { 
     var me = this; 
     var rootData = data; 
     console.log(data);   

     this.callParent(arguments); 
    } 
}); 

Ext.define('ChartApp.data.reader.DynamicChartReader', { 
    extend : 'Ext.data.reader.Json', 
    alias : 'widget.dynamicChartReader', 
    xtype : 'dynamicChartReader', 
    mixins : { 
     dynamicReader : 'ChartApp.mixins.reader.DynamicReaderMixin' 
    }, 
    config : { 
     xField : null 
    }, 

    readRecords : function(data) { 
     console.log('Reading records...'); 

     if (data.metaData == null) { 
      data = this.mixin.dynamicReader.readRecords.call(this, data); 
     } 

     return this.callParent([data]); 
    } 
}); 

Ext.define("ChartApp.model.Climate", { 
    extend: "Ext.data.Model", 
    fields: ["month", "high", "low", { 
     name: "highF", 
     calculate: function (b) { 
      return toFaherenheit(b.high); 
     } 
    }, { 
     name: "lowF", 
     calculate: function (b) { 
      return toFaherenheit(b.low); 
     } 
    }],  
}); 

Ext.define("ChartApp.store.Climate", { 
    extend: "Ext.data.Store", 
    alias: "store.climate", 
    model : "ChartApp.model.Climate", 
    counter: 0, 
    generateData: function() { 
     var h = this.config.data, 
      e, j, g = []; 
     for (e = 0; e < h.length; e++) { 
      g.push({ 
       month: h[e].month, 
       high: 20 + Math.random() * 20, 
       low: Math.random() * 20 
      }) 
     } 
     return g 
    }, 
    refreshData: function() { 
     this.setData(this.generateData()) 
    } 
}); 

Ext.define('ChartApp.view.charts.column.MultiAxis', { 
    extend: 'Ext.container.Container', 
    xtype: 'column-multi-axis', 

    width: 650, 
    height: 500, 

    initComponent: function() { 
     var me = this; 

     var highSeries = { 
      type: 'line', 
      xField: 'month', 
      yField: ['highF'], 
      yAxis: 'fahrenheit-axis', 
      style: { 
       lineWidth: 2, 
       fillStyle: '#115fa6', 
       strokeStyle: '#115fa6', 
       fillOpacity: 0.6, 
       miterLimit: 3, 
       lineCap: 'miter' 
      }, 
      colors : [ '#115fa6' ], 
      title : ['High'], 
      tooltip: { 
       trackMouse: true, 
       style: 'background: #444; color: #FFF', 
       renderer: function(storeItem, item) { 
        var title = item.series.getTitle()[0]; 
        this.setHtml(title + ' for ' 
         + storeItem.get('month') + ': ' 
         + storeItem.get(item.field).toFixed(2) + '°'); 
       } 
      } 
     }, 
     lowSeries = Ext.apply({}, { 
      yField: ['lowF'], 
      style: { 
       lineWidth: 2, 
       fillStyle: '#ff8800', 
       strokeStyle: '#884400', 
       fillOpacity: 0.6, 
       miterLimit: 3, 
       lineCap: 'miter' 
      }, 
      colors : [ '#ff8800' ], 
      title : ['Low'], 
     }, highSeries); 

     me.items = [{ 
      xtype: 'cartesian', 
      legend : { 
       hidden : true 
      }, 
      store: { 
       type: 'climate', 
       reader: { 
        xtype : 'dynamicChartReader' 
       } 
      }, 
      insetPadding: 10, 
      innerPadding: { 
       left: 20, 
       right: 20 
      }, 
      interactions: 'crosszoom', 
      axes: [{ 
       type: 'numeric', 
       id: 'fahrenheit-axis', 
       adjustByMajorUnit: true, 
       position: 'left', 
       titleMargin: 20, 
       minimum: 32, 
       grid: true, 
       title: { 
        text: 'Temperature in °F', 
        fontSize: 14 
       }, 
       listeners: { 
        rangechange: function (range) { 
         var cAxis = this.getChart().getAxis('celsius-axis'); 
         if (cAxis) { 
          cAxis.setMinimum(toCelcius(range[0])); 
          cAxis.setMaximum(toCelcius(range[1])); 
         } 
        } 
       } 
      }, { 
       id: 'celsius-axis', 
       type: 'numeric', 
       titleMargin: 20, 
       position: 'right', 
       title: { 
        text: 'Temperature in °C', 
        fontSize: 14, 
        fillStyle: 'red' 
       } 
      }, { 
       id: 'months-axis', 
       type: 'category', 
       position: 'bottom', 
       title: { 
        text: 'Months' 
       } 
      }, { 
       position: 'top', 
       linkedTo: 'months-axis', 
       title: { 
        text: 'Climate data for Redwood City, California', 
        fontSize: 16, 
        fillStyle: 'green' 
       }, 
       titleMargin: 20 
      }], 
      series: [ highSeries, lowSeries ] 
     }]; 

     this.callParent(); 
    }, 

    getChart : function() { 
     return this.down('cartesian'); 
    }, 

    getStore : function() { 
     return this.getChart().getStore(); 
    }, 

    getLegendStore : function() { 
     return this.getChart().getLegendStore(); 
    } 
}); 

Ext.define('ChartApp.chart.Legend', { 
    extend : 'Ext.chart.Legend', 
    xtype: 'extendedlegend', 
    docked : 'left', 

    tpl: [ 
     '<div class="', Ext.baseCSSPrefix, 'legend-container">', 
     '<tpl for=".">', 
     '<div class="', Ext.baseCSSPrefix, 'legend-item">', 
     '<input type="checkbox" class="', Ext.baseCSSPrefix, 'legend-item-check" checked="true" />', 
     '<span ', 
     'class="', Ext.baseCSSPrefix, 
     'legend-item-marker {[ values.disabled ? Ext.baseCSSPrefix + \'legend-inactive\' : \'\' ]}" ', 
     'style="background:{mark};">', 
     '</span>{name}', 
     '</div>', 
     '</tpl>', 
     '</div>' 
    ], 

    initComponent : function() { 
     var me = this; 

     me.callParent(arguments); 
    }, 

    onItemClick: function (record, item, index, e) { 
     var target = e.getTarget(); 
     var disabled = record.get('disabled'); 

     if (this.isCheckBox(target)) { 
      target.checked = !disabled; 
      console.log(target.checked); 
      this.callParent(arguments); 
     } 
    }, 

    isCheckBox : function(element) { 
     return element && element.tagName.toLowerCase() === 'input' && element.type === 'checkbox'; 
    } 
}); 

Ext.define('ChartApp.components.ChartContainer', { 
    extend : 'Ext.container.Container', 
    alias : 'widget.chartcontainer', 
    referenceHolder: true, 
    height : 600, 
    width : 800, 
    layout: 'border', 
    items: [{ 
     region : 'west', 
     title : 'Legend', 
     items : [{ 
      xtype : 'extendedlegend', 
      reference : 'chartLegend', 
     }], 
     width : 180, 
     minHeight : 550, 
     collapsible : true, 
     collasped : false, 
     split : true, 
     animCollapse : true 
    }, { 
     region : 'center', 
     reference : 'chartWrapper', 
     layout : 'fit', 
     margins : '5 5 0 0', 
     items : [{ 
      xtype : 'column-multi-axis', 
      reference : 'chart', 
      layout : 'fit' 
     }] 
    }], 

    initComponent : function() { 
     var me = this; 

     me.callParent(arguments); 

     var chart = me.lookupReference('chart'); 
     chart.getStore().loadData(climateData); 

     var legend = me.lookupReference('chartLegend'); 
     legend.setStore(chart.getLegendStore()); 
    } 
}); 

Ext.onReady(function() { 
    Ext.create('Ext.panel.Panel', { 
     title : 'Dual Axis Example', 
     layout : 'fit', 
     items : [{ 
      xtype : 'chartcontainer' 
     }], 
     renderTo: Ext.getBody(), 
    }); 
}); 

function toCelcius(faherenheit) { 
    return (faherenheit - 32)/1.8; 
}; 

function toFaherenheit(celcius) { 
    return (celcius * 1.8) + 32; 
}; 

function getClimateData() { 
    return [ 
     { month: "Jan", high: 14.7, low: 5.6 }, 
     { month: "Feb", high: 16.5, low: 6.6 }, 
     { month: "Mar", high: 18.6, low: 7.3 }, 
     { month: "Apr", high: 20.8, low: 8.1 }, 
     { month: "May", high: 23.3, low: 9.9 }, 
     { month: "Jun", high: 26.2, low: 11.9 }, 
     { month: "Jul", high: 27.7, low: 13.3 }, 
     { month: "Aug", high: 27.6, low: 13.2 }, 
     { month: "Sep", high: 26.4, low: 12.1 }, 
     { month: "Oct", high: 23.6, low: 9.9 }, 
     { month: "Nov", high: 17.0, low: 6.8 }, 
     { month: "Dec", high: 14.7, low: 5.8 } 
    ]; 
} 

實施例B

在這個例子中column-multi-axis直接延伸的cartesian圖表。出於某種原因,我不知道在chartcontainerinitComponent中,在致電this.callParent()之後,商店仍然是圖表上的配置。

Demo @ JSFiddle

var climateData = getClimateData(); 

Ext.define('ChartApp.mixins.reader.DynamicReaderMixin', { 
    extend : 'Ext.Mixin', 

    readRecords : function(data) { 
     var me = this; 
     var rootData = data; 
     console.log(data);   

     this.callParent(arguments); 
    } 
}); 

Ext.define('ChartApp.data.reader.DynamicChartReader', { 
    extend : 'Ext.data.reader.Json', 
    alias : 'widget.dynamicChartReader', 
    xtype : 'dynamicChartReader', 
    mixins : { 
     dynamicReader : 'ChartApp.mixins.reader.DynamicReaderMixin' 
    }, 
    config : { 
     xField : null 
    }, 

    readRecords : function(data) { 
     console.log('Reading records...'); 

     if (data.metaData == null) { 
      data = this.mixin.dynamicReader.readRecords.call(this, data); 
     } 

     return this.callParent([data]); 
    } 
}); 

Ext.define("ChartApp.model.Climate", { 
    extend: "Ext.data.Model", 
    fields: ["month", "high", "low", { 
     name: "highF", 
     calculate: function (b) { 
      return toFaherenheit(b.high); 
     } 
    }, { 
     name: "lowF", 
     calculate: function (b) { 
      return toFaherenheit(b.low); 
     } 
    }],  
}); 

Ext.define("ChartApp.store.Climate", { 
    extend: "Ext.data.Store", 
    alias: "store.climate", 
    model : "ChartApp.model.Climate", 
    counter: 0, 
    generateData: function() { 
     var h = this.config.data, 
      e, j, g = []; 
     for (e = 0; e < h.length; e++) { 
      g.push({ 
       month: h[e].month, 
       high: 20 + Math.random() * 20, 
       low: Math.random() * 20 
      }) 
     } 
     return g 
    }, 
    refreshData: function() { 
     this.setData(this.generateData()) 
    } 
}); 

Ext.define('ChartApp.view.charts.column.MultiAxis', { 
    extend: 'Ext.chart.CartesianChart', 
    xtype: 'column-multi-axis', 

    width: 650, 
    height: 500, 

    initComponent: function() { 
     var me = this; 

     var highSeries = { 
      type: 'line', 
      xField: 'month', 
      yField: ['highF'], 
      yAxis: 'fahrenheit-axis', 
      style: { 
       lineWidth: 2, 
       fillStyle: '#115fa6', 
       strokeStyle: '#115fa6', 
       fillOpacity: 0.6, 
       miterLimit: 3, 
       lineCap: 'miter' 
      }, 
      colors : [ '#115fa6' ], 
      title : ['High'], 
      tooltip: { 
       trackMouse: true, 
       style: 'background: #444; color: #FFF', 
       renderer: function(storeItem, item) { 
        var title = item.series.getTitle()[0]; 
        this.setHtml(title + ' for ' 
         + storeItem.get('month') + ': ' 
         + storeItem.get(item.field).toFixed(2) + '°'); 
       } 
      } 
     }, 
     lowSeries = Ext.apply({}, { 
      yField: ['lowF'], 
      style: { 
       lineWidth: 2, 
       fillStyle: '#ff8800', 
       strokeStyle: '#884400', 
       fillOpacity: 0.6, 
       miterLimit: 3, 
       lineCap: 'miter' 
      }, 
      colors : [ '#ff8800' ], 
      title : ['Low'], 
     }, highSeries); 

     Ext.apply(me, { 
      legend : { 
       hidden : true 
      }, 
      store: { 
       type: 'climate', 
       reader: { 
        xtype : 'dynamicChartReader' 
       } 
      }, 
      insetPadding: 10, 
      innerPadding: { 
       left: 20, 
       right: 20 
      }, 
      interactions: 'crosszoom', 
      axes: [{ 
       type: 'numeric', 
       id: 'fahrenheit-axis', 
       adjustByMajorUnit: true, 
       position: 'left', 
       titleMargin: 20, 
       minimum: 32, 
       grid: true, 
       title: { 
        text: 'Temperature in °F', 
        fontSize: 14 
       }, 
       listeners: { 
        rangechange: function (range) { 
         var cAxis = this.getChart().getAxis('celsius-axis'); 
         if (cAxis) { 
          cAxis.setMinimum(toCelcius(range[0])); 
          cAxis.setMaximum(toCelcius(range[1])); 
         } 
        } 
       } 
      }, { 
       id: 'celsius-axis', 
       type: 'numeric', 
       titleMargin: 20, 
       position: 'right', 
       title: { 
        text: 'Temperature in °C', 
        fontSize: 14, 
        fillStyle: 'red' 
       } 
      }, { 
       id: 'months-axis', 
       type: 'category', 
       position: 'bottom', 
       title: { 
        text: 'Months' 
       } 
      }, { 
       position: 'top', 
       linkedTo: 'months-axis', 
       title: { 
        text: 'Climate data for Redwood City, California', 
        fontSize: 16, 
        fillStyle: 'green' 
       }, 
       titleMargin: 20 
      }], 
      series: [ highSeries, lowSeries ] 
     }); 

     this.callParent(); 
    } 
}); 

Ext.define('ChartApp.chart.Legend', { 
    extend : 'Ext.chart.Legend', 
    xtype: 'extendedlegend', 
    docked : 'left', 

    tpl: [ 
     '<div class="', Ext.baseCSSPrefix, 'legend-container">', 
     '<tpl for=".">', 
     '<div class="', Ext.baseCSSPrefix, 'legend-item">', 
     '<input type="checkbox" class="', Ext.baseCSSPrefix, 'legend-item-check" checked="true" />', 
     '<span ', 
     'class="', Ext.baseCSSPrefix, 
     'legend-item-marker {[ values.disabled ? Ext.baseCSSPrefix + \'legend-inactive\' : \'\' ]}" ', 
     'style="background:{mark};">', 
     '</span>{name}', 
     '</div>', 
     '</tpl>', 
     '</div>' 
    ], 

    initComponent : function() { 
     var me = this; 

     me.callParent(arguments); 
    }, 

    onItemClick: function (record, item, index, e) { 
     var target = e.getTarget(); 
     var disabled = record.get('disabled'); 

     if (this.isCheckBox(target)) { 
      target.checked = !disabled; 
      console.log(target.checked); 
      this.callParent(arguments); 
     } 
    }, 

    isCheckBox : function(element) { 
     return element && element.tagName.toLowerCase() === 'input' && element.type === 'checkbox'; 
    } 
}); 

Ext.define('ChartApp.components.ChartContainer', { 
    extend : 'Ext.container.Container', 
    alias : 'widget.chartcontainer', 
    referenceHolder: true, 
    height : 600, 
    width : 800, 
    layout: 'border', 
    items: [{ 
     region : 'west', 
     title : 'Legend', 
     items : [{ 
      xtype : 'extendedlegend', 
      reference : 'chartLegend', 
     }], 
     width : 180, 
     minHeight : 550, 
     collapsible : true, 
     collasped : false, 
     split : true, 
     animCollapse : true 
    }, { 
     region : 'center', 
     reference : 'chartWrapper', 
     layout : 'fit', 
     margins : '5 5 0 0', 
     items : [{ 
      xtype : 'column-multi-axis', 
      reference : 'chart', 
      layout : 'fit' 
     }] 
    }], 

    initComponent : function() { 
     var me = this; 

     me.callParent(arguments); 

     var chart = me.lookupReference('chart'); 

     console.log(chart.getStore()); // Still a config 

     chart.getStore().loadData(climateData); 

     var legend = me.lookupReference('chartLegend'); 
     legend.setStore(chart.getLegendStore()); 
    } 
}); 

Ext.onReady(function() { 
    Ext.create('Ext.panel.Panel', { 
     title : 'Dual Axis Example', 
     layout : 'fit', 
     items : [{ 
      xtype : 'chartcontainer' 
     }], 
     renderTo: Ext.getBody(), 
    }); 
}); 

function toCelcius(faherenheit) { 
    return (faherenheit - 32)/1.8; 
}; 

function toFaherenheit(celcius) { 
    return (celcius * 1.8) + 32; 
}; 

function getClimateData() { 
    return [ 
     { month: "Jan", high: 14.7, low: 5.6 }, 
     { month: "Feb", high: 16.5, low: 6.6 }, 
     { month: "Mar", high: 18.6, low: 7.3 }, 
     { month: "Apr", high: 20.8, low: 8.1 }, 
     { month: "May", high: 23.3, low: 9.9 }, 
     { month: "Jun", high: 26.2, low: 11.9 }, 
     { month: "Jul", high: 27.7, low: 13.3 }, 
     { month: "Aug", high: 27.6, low: 13.2 }, 
     { month: "Sep", high: 26.4, low: 12.1 }, 
     { month: "Oct", high: 23.6, low: 9.9 }, 
     { month: "Nov", high: 17.0, low: 6.8 }, 
     { month: "Dec", high: 14.7, low: 5.8 } 
    ]; 
} 

回答

0

商店還不存在在這一點上 - 不如說沒有嘗試運行setStore()呢。如果你真的需要它,試着打電話:

chart.setStore(chart.getStore()); 

這應該調用負責創建存儲的底層setter的方法。