2013-09-27 4 views
0

Я использую Extjs 4 с архитектурой MVC.динамически меняющаяся серия диаграмм extjs 4

У меня есть сценарий питона, который выводит этот JSon данные:

{ 
"data": [ 
    { 
     "inAnalysis": 3, 
     "inQuest": 2, 
     "inDevelopment": 6, 
     "total": 12, 
     "inValidation": 1, 
     "Month": 1303 
    }, 
    { 
     "inAnalysis": 1, 
     "total": 5, 
     "Month": 1304, 
     "inDevelopment": 4 
    } 
], 
"success": true, 
"metaData": { 
    "fields": [ 
     { 
      "name": "inAnalysis" 
     }, 
     { 
      "name": "inQuest" 
     }, 
     { 
      "name": "inDevelopment" 
     }, 
     { 
      "name": "inValidation" 
     }, 
     { 
      "name": "isDuplicate" 
     }, 
     { 
      "name": "New" 
     }, 
     { 
      "name": "total" 
     } 
    ], 
    "root": "data" 
} 

}

Я хочу поле моих МЕТАДАННЫХ, которые будут использоваться в качестве серии графика, поэтому у меня есть магазин, как это:

Ext.define('Proj.store.ChartData', { 
extend: 'Ext.data.Store', 
autoload: true, 
proxy: { 
    type: 'ajax', 
    url : 'data/getParams.py', 
    reader: new Ext.data.JsonReader({ 
     fields:[] 
    }), 
    root: 'data' 
} 

И добавить серию к графике я сделал это:

var chart = Ext.widget('drawchart'); 
var fields = []; 

chartStore.each(function (field) { 
    fields.push(Ext.create('Ext.data.Field', { 
     name: field.get('name') 
    })); 
}); 
chartModel.prototype.fields.removeAll(); 
chartModel.prototype.fields.addAll(fields); 

var series = []; 
for (var i = 1; i < fields.length; i++) { 
    var newSeries = new Ext.chart.BarSeries({ 
     type: 'column', 
     displayName: fields[i].name, 
     xField: ['Month'], 
     yField: fields[i].name, 
     style: { 
      mode: 'stretch', 
      color: this.chartColors[i + 1] 
     } 
    }); 
    series.push(newSeries); 
    chart.series = series; 
}; 

chart.bindStore(chartStore); 
chart.redraw(); 
chart.refresh(); 

Но это не работает, я думаю, что массив полей всегда пусто ... Любая помощь будет оценена:

+0

Не могли бы вы найти какое-либо решение на свой вопрос? –

+0

вставьте свой код на скрипке с dummy json –

ответ

7

подкачка или перегрузочные магазин будет легко, но вы бы очень трудное время перенастройки осей и серии posteriori ... Диаграмма Ext просто не поддерживает это. Можно было бы заменить ось в коллекции myChart.axes, и то же самое для серий, а затем при тщательном изучении кода замените удаляемые существующие спрайты и т. Д. Однако это путь глупого, поскольку на этот раз ваш код будет очень хрупкие против будущих изменений кода диаграммы Ext (что происходит), а во-вторых, гораздо более легкое и надежное решение. Это создает новую диаграмму, удаляет старую, кладет новую на свое место и пуфу! Пользователь не увидит разницы.

Вы не даете много информации о своем коде, поэтому я смогу решить проблему из Bar chart example.

Во-первых, вам нужно исправить ваш магазин:

Ext.define('Proj.store.ChartData', { 
    extend: 'Ext.data.Store', 
    //autoload: true, 
    autoLoad: true, // there was a type in there 
    fields: [], // was missing 
    proxy: { 
     type: 'ajax', 
     url : 'data/getParams.py', 
     // better to inline the proxy (lazy init) 
     reader: { 
      type: 'json' 
      ,root: 'data' // and root is an option of the reader, not the proxy 
     } 
//  reader: new Ext.data.JsonReader({ 
//   fields:[] 
//  }), 
//  root: 'data' 
    } 
}); 

Тогда давайте обогатить ваш ответ немного для того, чтобы свести к минимуму перед стороне клиента знания модели никто. Я добавил totalField и categoryField к metaData узел, который мы будем использовать для оси и серии:

{ 
    "data": [ 
     { 
      "inAnalysis": 3, 
      "inQuest": 2, 
      "inDevelopment": 6, 
      "total": 12, 
      "inValidation": 1, 
      "Month": 1303 
     }, 
     { 
      "inAnalysis": 1, 
      "total": 5, 
      "Month": 1304, 
      "inDevelopment": 4 
     } 
    ], 
    "success": true, 
    "metaData": { 
     "totalField": "total", 
     "categoryField": "Month", 
     "fields": [ 
      { 
       "name": "Month" 
      }, 
      { 
       "name": "inAnalysis" 
      }, 
      { 
       "name": "inQuest" 
      }, 
      { 
       "name": "inDevelopment" 
      }, 
      { 
       "name": "inValidation" 
      }, 
      { 
       "name": "isDuplicate" 
      }, 
      { 
       "name": "New" 
      }, 
      { 
       "name": "total" 
      } 
     ], 
     "root": "data" 
    } 
} 

Пожалуйста, обратите внимание, что прокси-сервер будет ловить metaData в ответ автоматически и перенастроить его магазина (неявной) модели ... так что вам не нужна ваша gloubiboulga, чтобы сделать это самостоятельно. Также стоит отметить, что читатель сохранит копию необработанных ответов в свойстве rawData; это будет полезно для получения пользовательской информации, которую мы добавили.

Теперь, когда у нас есть правильный магазин, который будет получать подробный ответ, давайте использовать его:

new Proj.store.ChartData({ 
    listeners: { 
     load: replaceChart 
    } 
}); 

Это вызовет replaceChart метод, который будет создавать новую диаграмму из мета- и данных, заданного сервер и уничтожить и заменить старый. Вот функция:

function replaceChart(chartStore) { 

    // Grab the name of the total & category fields as instructed by the server 
    var meta = chartStore.getProxy().getReader().rawData.metaData, 
     totalField = meta.totalField, 
     categoryField = meta.categoryField; 

    // Build a list of all field names, excluding the total & category ones 
    var fields = Ext.Array.filter(
     Ext.pluck(chartStore.model.getFields(), 'name'), 
     function(field) { 
      return field !== categoryField && field !== totalField; 
     } 
    ); 

    // Create a pimping new chat like you like 
    var chart = Ext.create('Ext.chart.Chart', { 
     store: chartStore, 
     legend: true, 
     axes: [{ 
      type: 'Numeric', 
      position: 'bottom', 
      fields: [totalField] 
     }, { 
      type: 'Category', 
      position: 'left', 
      fields: [categoryField] 
     }], 
     series: [{ 
      type: 'bar', 
      axis: 'bottom', 
      label: { 
       display: 'insideEnd', 
       field: fields 
      }, 
      xField: categoryField, 
      yField: fields, 
      stacked: true // or not... like you want! 
     }] 
    }); 

    // Put it in the exact same place as the old one, that will trigger 
    // a refresh of the layout and a render of the chart 
    var oldChart = win.down('chart'), 
     oldIndex = win.items.indexOf(oldChart); 
    win.remove(oldChart); 
    win.insert(oldIndex, chart); 

    // Mission complete. 
} 
0

Попробуйте очистить кэш линии неиспользованного серии:

Ext.Array.each(chart.series.items, function(item){ 
      if(!item.items.length){ 
       item.line = null; 
      } 
     }); 
+0

Ответ на этот пост уже получил щедрость от нескольких лет назад - просьба указать небольшую дополнительную информацию о том, почему это полезный ответ в контексте сообщения и доступного ответа. – wahwahwah

Смежные вопросы