admin管理员组文章数量:1322180
I'm using Extjs 4 with the MVC architecture.
I have a python script that outputs this Json Data :
{
"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"
}
}
I want the fields of my MetaData to be used as the chart series, so I have a store like this :
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'
}
And to add series to the chart I did this :
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();
But It's not working, I think the fields array is always empty... Any help would be appreciated:
I'm using Extjs 4 with the MVC architecture.
I have a python script that outputs this Json Data :
{
"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"
}
}
I want the fields of my MetaData to be used as the chart series, so I have a store like this :
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'
}
And to add series to the chart I did this :
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();
But It's not working, I think the fields array is always empty... Any help would be appreciated:
Share Improve this question edited Jul 21, 2014 at 22:42 Ben 1,36817 silver badges42 bronze badges asked Sep 27, 2013 at 14:56 salameysalamey 3,82110 gold badges40 silver badges71 bronze badges 2- Could you find any solution to your question? – Dhairya Vora Commented Feb 26, 2014 at 5:28
- please paste your code on fiddle with dummy json – Man Programmer Commented Jul 22, 2014 at 10:18
2 Answers
Reset to default 7 +25Swapping or reloading a store would be easy, however you'd have a very hard time reconfiguring axes and series a posteriori... Ext's chart just don't support that. It would be possible to replace the axis in the myChart.axes
collection, and same for series, and then with a careful study of the code, replace remove the existing sprites, etc. However that's a fool's path since, for once your code will be very fragile against future evolutions of Ext's chart code (which happen), and second there is a far more easier and reliable solution. That is creating a new chart, remove the old one, put the new one in its place, and pouf! The user won't see the difference.
You're not giving a lot of information about your code, so I'll work a solution out of the Bar chart example.
First, you need to fix your store:
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'
}
});
Then, let's enrich your response a bit in order to minimize the prior client-side knowledge of the model to none. I've added a totalField
and a categoryField
to the metaData
node, that we'll use for the axis and series:
{
"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"
}
}
Please, notice that the proxy will catch the metaData
in the response automatically and reconfigure its store's (implicit) model accordingly... so you don't need your gloubiboulga to do it yourself. It is also worth noting that the reader will keep a copy of the raw response data in its rawData
property; that will be useful to get the custom information we've added.
Now that we have a proper store that will receive a detailed response, let's use it:
new Proj.store.ChartData({
listeners: {
load: replaceChart
}
});
That will trigger the replaceChart
method, that will create a brand new chart from the meta and data given by the server and destroy and replace the old one. Here's the function:
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 plete.
}
Try to clear lines cache of unused series:
Ext.Array.each(chart.series.items, function(item){
if(!item.items.length){
item.line = null;
}
});
本文标签: javascriptdynamically changing chart series extjs 4Stack Overflow
版权声明:本文标题:javascript - dynamically changing chart series extjs 4 - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742113537a2421363.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论