-
17 Oct 2012 1:58 PM #1
how to dynamicaly create multiple line in a extjs chart throuhg a json
how to dynamicaly create multiple line in a extjs chart throuhg a json
hi,
i have been trying to dynamicaly create multiple lin in a extjs 4 char through a json without success...
as u can see in the code below ..
the model and store data will have to be changed ..
i really don't see how it could be done...
basically the user can choose any number of customer which will return a json that will be use to create the line ..
any help is welcome...
var store = new Ext.data.ArrayStore({
id: 'graphStore',
autoLoad: true,
proxy: new Ext.data.HttpProxy({
type: 'ajax',
method: 'GET',
url: 'data/resources/jsons/graph.json',
//url: 'data/resources/jsons/graphNested.json',
//url: '../Services/NukeappsSiteWebService.asmx/GetJsonStructure',
reader: {
type: 'json',
root: 'data'
}
}),
fields: [
{ name: 'visits', type: 'int' },
{ name: 'month', type: 'string' }
],
listeners: {
beforeload: function (store, operation, opts) {
currentCount++;
operation.params = {
currentCount: currentCount
};
},
load: function (store, records) {
for (var i = 0; i < records.length; i++) {
var visits = records[i].get('visits');
visitsRecord = records.length;
this.visit = records.length;
console.log(visits);
if (i == records.length - 1) console.log(visitsRecord);
}
}
}
});
console.log('number of visits --> ' + this.visit);
me.lineChart = Ext.create('Ext.chart.Chart', {
style: 'background:#fff',
animate: true,
store: store,
shadow: true,
axes: [{
type: 'Numeric',
minimum: 0,
position: 'left',
fields: ['visits'],
title: 'Number of Visits',
minorTickSteps: 1
}, {
type: 'Category',
position: 'bottom',
fields: ['month'],
title: 'Month of the Year'
}],
series: [{
type: 'line',
highlight: {
size: 7,
radius: 7
},
tips: {
trackMouse: true,
width: 140,
height: 28,
renderer: function (storeItem, item) {
this.setTitle(storeItem.get('month') + ': ' + storeItem.
get('visits') + ' visits');
}
},
axis: 'left',
xField: 'month',
yField: 'visits'
}]
});
-
23 Oct 2012 5:42 AM #2Sencha - Senior Forum Manager
- Join Date
- Mar 2007
- Location
- St. Louis, MO
- Posts
- 33,684
- Vote Rating
- 435
When asking for help please post your code within the BBCode CODE tags so that it's legible.
Mitchell Simoens @SenchaMitch
Sencha Inc, Senior Forum Manager
________________
http://www.JSONPLint.com - Source to lint your JSONP!
Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
https://github.com/mitchellsimoens
Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/
Need more help with your app? Hire Sencha Services services@sencha.com
Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is almost in print!
When posting code, please use BBCode's CODE tags.
-
26 Oct 2012 12:15 PM #3
The code below is the solution...
i m dynamically creating a chart.
first i have a panel that has an empty chat.
i then grab the data from the store and create a new store from the old store ...
i then use those new value to dynamically assign chart.axes and chart.series
to the empty chart
Code:// this is the solution Ext.define('Insight.view.portal.GraphChart', { extend: 'Ext.panel.Panel', alias: 'widget.portal-GraphChart', id: "pnlGraphChart", title: "Insight.view.portal.GraphChart", constructor: function (config) { var me = this; var store = Ext.create('Insight.store.Graph'); //------------------------------------------------------------------------------------------ // since the load is asynchronous - i need to use the callback function to update the chart store.load({ scope: this, callback: function (records, operation, success) { //here the store has been loaded so you can use what functions you like debugger; store.update(records, operation); } }); //-------------------------------------------------------------------------------------------------- me.chart = Ext.create('Ext.chart.Chart', { id: 'mainchart', xtype: 'chart', style: 'background:#fff', animate: true, store: store, shadow: true, theme: 'Category1', legend: { position: 'right' } }); //--------------------------------------------------------------------------------------------------- config = config || {}; Ext.applyIf(config, { dockedItems: [ { width: 400, height: 400, layout: 'border', defaults: { xtype: 'panel' }, items: [{ title: 'Insight.view.portal.Graph', region: 'center', width: '100%', items: [me.chart], layout: 'fit' }] } ] }); me.callParent([config]); } }); Ext.define('Insight.model.Graph', { extend: 'Ext.data.Model', fields: [ { name: 'month', type: 'string' }, { name: 'Name', type: 'string' }, { name: 'Number', type: 'int' } ] }); Ext.define('Insight.store.Graph', { extend: 'Ext.data.Store', id: 'graphStore', model: 'Insight.model.Graph', remoteSort: false, remoteFilter: false, remoteGroup: false, folderSort: false, autoLoad: true, field: ['month', 'Name', 'Number'], proxy: { type: 'ajax', method: 'GET', url: 'data/resources/jsons/graphMultiple.json', reader: { type: 'json', root: 'data' } }, update: function (records, operation) { var DataStore = new Array(); var oldarray = this.GetMonthData(records); // New Data - remodeled Data for updating the new store var DataStore = oldarray.slice(); // New model - remodeled Model for updating the new store var field_customer = this.getCustomer(records); var DataModel = [ { name: 'month', type: 'string' } ]; for (var a = 0; a < field_customer.length; a++) { DataModel.push({ name: field_customer[a], type: 'int' }); } // New Store - remodeled Store for new Chart var Chart_Store = this.getStore(DataStore, DataModel); debugger; // UPDATING THE CHART //0- Getting the Chart var cmp = Ext.getCmp('mainchart'); //1- updating the Store cmp.store = Chart_Store; debugger; //2- updating the Chart.axes cmp.axes.add({ type: 'Numeric', minimum: 0, position: 'left', fields: field_customer, //<---axes[0].fields needs to be updated title: 'Number of Hits', minorTickSteps: 1, grid: { odd: { opacity: 1, fill: '#ddd', stroke: '#bbb', 'stroke-width': 0.5 } } }); cmp.axes.add({ type: 'Category', position: 'bottom', fields: ['month'], title: 'Month of the Year' }); ; //3-updating Chart.series for (var b = 0; b < field_customer.length; b++) { cmp.series.add({ type: 'line', highlight: { size: 7, radius: 7 }, tips: { trackMouse: true, width: 140, height: 28, renderer: function (storeItem, item) { this.setTitle(storeItem.get('month') + ': ' + storeItem. get(field_customer[b]) + ' '); // <--- setTitle needs to be updated } }, axis: 'left', xField: 'month', yField: field_customer[b] //<--- each series needs to be updated }); } }, GetMonthData: function (records) { var january = new Array(); var january_count = 1; var january_record = 10; var february = new Array(); var february_count = 1; var february_record = 11; for (var y = 0; y < records.length; y++) { if (records[y].data.month == 'January' && y < records.length && (january_record + january_count + 1) < records.length && records[january_record + january_count + 1].data.month == 'January') { january[0] = 'January'; january[1] = records[0].data.Number; january[january_count + 1] = records[january_record + january_count + 1].data.Number; january_count++; january_record = january_record + 10; } if (y == 24) debugger; if (records[y].data.month == 'February' && y < records.length && (february_record + february_count + 1) < records.length && records[february_record + february_count + 1].data.month == 'February') { february[0] = 'February'; february[1] = records[1].data.Number; february[february_count + 1] = records[february_record + february_count + 1].data.Number; february_count++; february_record = february_record + 10; } } var data = new Array(); data[0] = january; data[1] = february; var x = data; debugger; return data; }, getStore: function (jsonData, modelVar) { var new_store = Ext.create('Ext.data.ArrayStore', { id: 'new_store', autoLoad: true, data: jsonData, fields: modelVar }); return new_store; }, getCustomer: function (records) { var customers = new Array(); var month_counter = 11; var customer_count = 0; var name; for (var z = 0; z < records.length; z++) { if (z % month_counter == 0 && name != records[z].data.Name || month_counter % z == 0 && name != records[z].data.Name) { customers[customer_count] = records[z].data.Name; customer_count++; name = records[z].data.Name; } } var name_customers = new Array(); name_customers = customers; return name_customers; } });
-
16 Nov 2012 12:55 PM #4
UPDATE AND Better explanation on how to build a dynamic chart line
UPDATE AND Better explanation on how to build a dynamic chart line
hi t0ad999,
the code that you got is for a static chart.
Dynamic Chart Line
------------------------
(1) See the data from the database in the store.records
------------------------------------------------------------------
the thing that you must notice is that since u re using a proxy and ajax
within your store that data is being process asynchronously ...
meaning that an background Thread will be use to get the data right away ... thus allowing the browser not to freeze while waiting to get the data....
at the time the chart is created , your store do not have a hold of the data... and this is why if u use a debugger; call , right after u telling your store to get data from the database, your store records will be empty.
now if you look down here at my view , i have used a call back fuction... meaning that as soon as the data is loaded , this call back function will be called.
(2) CREATE a dynamic value for the chart lineCode:Ext.define('Insight.view.forwarding.kpi.KpiMultiLine', { extend: 'Ext.panel.Panel', alias: 'widget.forwarding-kpi-KpiMultiLine', measure: '', groupBy: '', initComponent: function () { var me = this; var yearId = Core.context.get('yearId'); var customerId = Core.context.get('customerId'); var customer = Core.context.get('customer'); var hierarchy = Core.context.get('hierarchy'); var title = customer + ' [' + customerId + ']'; var levelId = 0; me.store = Ext.create('Insight.store.forwarding.KpiMultiLine'); me.cboMeasure = Ext.create('Insight.view.forwarding.measure.Combo'); me.cboHierarchy = Ext.create('Insight.view.forwarding.Hierarchy.Combo'); if (me.measure == null || me.measure == '') me.measure = 'ToplineRev'; Core.mask(Core.masks.load); me.store.load({ scope: this, params: { yearId: yearId, customerId: customerId, hierarchy: hierarchy, levelId: levelId }, callback: function (records, operation, success) { //here the store has been loaded so records are not empty var groupBy = ''; me.store.update(records, me.measure, groupBy); Core.unmask(); } }); var config = { layout: { type: 'vbox', align: 'stretch' }, items: [ { id: 'mainchart', flex: 1, xtype: 'chart', style: 'background:#fff', animate: true, store: me.store, shadow: true, autoSize: true, theme: 'Category1', legend: { position: 'right' } } ], dockedItems: [ { xtype: 'toolbar', dock: 'top', items: [me.cboMeasure, me.cboHierarchy] } ] }; Ext.apply(me, config); me.callParent(arguments); } });
-----------------------------------------------
the code below is very simple.
basically I'm creating a new store, a new model based of
the value a got from the store in section(1).
Then i add axes and series to the chart int the main view.
after that i refresh the chart and redraw it.
i improved my code a bit so do take a look at it below,
shoot me an email if your are having further issues...
TO ANSWERS YOUR QUESTION IN ONE SENTENCE?
YOU NEED TO YOUR CALLBACK ...
Code:Ext.define('Insight.store.forwarding.KpiMultiLine', { extend: 'Ext.data.Store', model: 'Insight.model.forwarding.KpiMultiLine', autoLoad: false, remoteSort: true, remoteFilter: true, remoteGroup: true, /* Update panel main chart with axes and series along with a new store --------------------------------------------------------------------- since the main chart is empty--> empty axes and empty series we will get the data from the records and create axes and series from it */ update: function (records, measure, groupBy) { if (groupBy != '') groupBy = ' group By ' + groupBy; // get all y axis var field_Kpi = this.getKpis(records); // set up dataStore var dataStore = new Array(); var oldarray = this.getMonthData(records, measure, field_Kpi); // New data - remodeled Data for updating the new store var dataStore = oldarray.slice(); // New model - remodeled Model for updating the new store var dataModel = [ { name: 'month', type: 'string' } ]; for (var a = 0; a < field_Kpi.length; a++) { dataModel.push({ name: field_Kpi[a], useNull: true }); } // New Store - remodeled Store for new Chart var chart_Store = this.getStore(dataStore, dataModel); // UPDATING THE CHART //0- Getting the Chart var cmp = Ext.getCmp('mainchart'); cmp.surface.removeAll(); //1- updating the Store cmp.store = chart_Store; //2- updating the Chart.axes cmp.axes.add({ type: 'Numeric', minimum: 0, position: 'left', fields: field_Kpi, //<---axes[0].fields needs to be updated title: measure + groupBy, minorTickSteps: 1, grid: { odd: { opacity: 1, fill: '#ddd', stroke: '#bbb', 'stroke-width': 0.5 } } }); cmp.axes.add({ type: 'Category', position: 'bottom', fields: ['month'], title: 'Month of the Year' }); //3-updating Chart.series if (cmp.series.items.length > 0) { cmp.series.clear(); // clear all series } for (var b = 0; b < field_Kpi.length; b++) { cmp.series.add({ type: 'line', highlight: { size: 7, radius: 7 }, tips: { trackMouse: true, width: 140, height: 28, renderer: function (storeItem, item) { var c = 0; for (var t = 0; t < field_Kpi.length; t++) { if (cmp.series.keys[t] == item.series.seriesId) c = t; } this.setTitle(field_Kpi[c] + ' / ' + storeItem.get('month') + ': ' + storeItem.get(field_Kpi[c])); // <--- setTitle needs to be updated } }, axis: 'left', xField: 'month', yField: field_Kpi[b] //<--- each series needs to be updated and fomated }); } //4- redraw the chart cmp.redraw(); }, //return store.data getMonthData: function (records, measure, kpis) { /* Data Format Example we re looking for: { [ {'January' , 4875 , 3587}, {'February' , 3854 , 2489}, {'March' , 2358 , 4965}, {'April' , 5693 , 1684}, {'May' , 6751 , 2943}, {'June' , 5231 , 1846}, {'July' , 8721 , 4662}, {'August' , 8642 , 9712}, {'September', 7231 , 6847}, {'October' , 5642 , 5222}, {'November' , 8642 , 7304}, {'December' , 6154 , 5651} ] } */ var months = { january: ['January'], february: ['February'], march: ['March'], april: ['April'], may: ['May'], june: ['June'], july: ['July'], august: ['August'], september: ['September'], october: ['October'], november: ['November'], december: ['December'] } if (measure == '') measure = 'ToplineRev'; var dataMonth = new Array(); var dataMeasure = new Array(); var tempMonth = new Array(); var tempMeasure = new Array(); var count = 0; var x; /* categorize data for each kpis from 0 to 11 For each array (january to december) kpis [n]... dataMonth [n-kpis] [n-month]...forkpis [n] , datamonth [n] = {month:january ... december}... -> dataMonth[n-kpis].length = customers.length -> dataMonth[n-kpis][n-month].length = 12 dataMeasure [n-kpis] [n-measure]...for kpis [n] , datameasure [n] = {measure:54454...586454}... -> 12 element for each array -> dataMeasure [n-kpis].length = customers.length -> dataMeasure [n-kpis][n-measure].length = 12 */ for (var line = 0; line < kpis.length; line++) { tempMonth = []; tempMeasure = []; count = 0; for (x = 0; x < records.length; x++) { if (kpis[line] == records[x].data.Name) { dataName = records[x].data.Name; tempMonth[count] = records[x].data.Month; tempMeasure[count] = records[x].get(measure); dataMonth[line] = tempMonth; dataMeasure[line] = tempMeasure; count++; } } } // create a store.data for (var k = 0; k < kpis.length; k++) { for (var g = 0; g < 12; g++) { // January data if (dataMonth[k][g] == 'January') { months.january[k + 1] = dataMeasure[k][g]; } // February Data if (dataMonth[k][g] == 'February') { months.february[k + 1] = dataMeasure[k][g]; } // March Data if (dataMonth[k][g] == 'March') { months.march[k + 1] = dataMeasure[k][g]; } // April data if (dataMonth[k][g] == 'April') { months.april[k + 1] = dataMeasure[k][g]; } // May Data if (dataMonth[k][g] == 'May') { months.may[k + 1] = dataMeasure[k][g]; } // June Data if (dataMonth[k][g] == 'June') { months.june[k + 1] = dataMeasure[k][g]; } // July data if (dataMonth[k][g] == 'July') { months.july[k + 1] = dataMeasure[k][g]; } // August Data if (dataMonth[k][g] == 'August') { months.august[k + 1] = dataMeasure[k][g]; } // September Data if (dataMonth[k][g] == 'September') { months.september[k + 1] = dataMeasure[k][g]; } // October data if (dataMonth[k][g] == 'October') { months.october[k + 1] = dataMeasure[k][g]; } // November Data if (dataMonth[k][g] == 'November') { months.november[k + 1] = dataMeasure[k][g]; } // December Data if (dataMonth[k][g] == 'December') { months.december[k + 1] = dataMeasure[k][g]; } } } var data = new Array(); data[0] = months.january; data[1] = months.february; data[2] = months.march; data[3] = months.april; data[4] = months.may; data[5] = months.june; data[6] = months.july; data[7] = months.august; data[8] = months.september; data[9] = months.october; data[10] = months.november; data[11] = months.december; return data; }, // retore a store getStore: function (jsonData, modelVar) { var new_store = Ext.create('Ext.data.ArrayStore', { id: 'new_store', autoLoad: true, data: jsonData, fields: modelVar }); return new_store; }, // return chart.axes.fields---y axis // add a kpi name when the previous kpi name is different to the next kpi name // select * Distinct KpiLine-name from records getKpis: function (records) { var kpis = new Array(); var kpi_count = 0; var name; for (var z = 0; z < records.length; z++) { if (z == 0) { kpis[kpi_count] = records[z].data.Name; kpi_count++; name = records[z].data.Name } if (z > 0) { if (name != records[z].data.Name) { kpis[kpi_count] = records[z].data.Name; kpi_count++; name = records[z].data.Name; } } } return kpis; } }


Reply With Quote