Fully update pie chart using ExtJS 4.2.0 and external datasource - extjs

I am currently creating a "drill-down" style pie chart, where clicking on a "slice" should update the pie chart with data within that slice.
Imagine for example an E-commerce report which shows sales by top level categories:
Shirts - $10,000
Pants - $8,000
Shoes - $3,500
Then clicking on the "Shirts" slice would display detailed information about sales in the Shirts category:
T-Shirts - $7,000
Polo Shirts - $2,000
Tank Tops - $1,000
I have a basic example here using a data source that returns random information:
http://jsfiddle.net/informationarchitech/BrMeh/
Ext.onReady(function () {
var level = 1;
Ext.define('Report', {
extend: 'Ext.data.Model',
fields: [{
name: 'category',
type: 'string'
}, {
name: 'purchases',
type: 'string'
}],
});
var store = Ext.create('Ext.data.Store', {
id: 'store',
model: 'Report',
autoLoad: true,
proxy: {
type: 'jsonp',
url: 'http://informationarchitech.com/demos/rand.php',
reader: {
root: 'content',
}
}
});
Ext.create('Ext.chart.Chart', {
renderTo: Ext.getBody(),
width: 500,
height: 350,
animate: true,
store: store,
series: [{
listeners: {
itemmousedown: function (obj) {
level++;
store.getProxy().url = 'http://informationarchitech.com/demos/rand.php?parent=' + obj.storeItem.data['category'] + '&level=' + level;
store.load();
}
},
type: 'pie',
angleField: 'purchases',
showInLegend: true,
label: {
field: 'category',
display: 'rotate',
contrast: true,
font: '18px Arial'
}
}]
});
});
As you can see, clicking on a slice results in inconsistent behavior. Sometimes it seems to update correctly, but often it seems to somehow be merging or overwriting the previous data.
I have tried every "clear," "update," "reset" method I can find, on the chart, the store, etc, and nothing I have tried seems to successfully "fully" update the pie chart with the new data. Can anyone tell me what I am doing wrong?

Related

EXTJS Pass data to another JS store

I am new to EXTJS. I am developing application using EXTJS 4.2. I have grid that shows list of Unix server details. I have 2 JS one is serverdetails.js that shows all the servers in the grid and another one is pie.js that shows pie chart. My requirement is when I select server from the grid that is in ServerDetails.js and click on button it goes to dao layer to get server details, Now this server details I have to passed on to Pie chart Js Ext.data.Store object. How do I pass these server details to Pie chart JS?
Below is my code.
On the grid I have dashboard button that shows the pie chart for selected row in the grid. below is the code for that.
showDashBoard : function(button) {
var grid = Ext.ComponentQuery.query('serverdetailslist')[0];
var sm = grid.getSelectionModel();
var rs = sm.getSelection();
if (!rs.length) {
Ext.Msg.alert('Info', 'No Server Details Selected');
return;
}else{
dashBoardServerDetail = rs[0].getData();
var url = '/TechnologyTrackPortal/dashboard/loadDashBoard.action';
Ext.Ajax.request({
url : url,
method : 'POST',
jsonData: dashBoardServerDetail,
success: function(response){
var iResult = response.responseText;
Ext.create('resources.script.Pie');
}
});
}
}
response.responseText give me data in jason format. Now how do I pass this jason dat to pie.js file. Below is my pie.js file
Ext.onReady(function () {
Ext.define('DashBoardModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'title', type: 'string'},
{name: 'size', type: 'string'}
]
});
var store = Ext.create('Ext.data.Store', {
storeId : 'DashBoardStoreId',
model : 'DashBoardModel',
fields : ['title', 'size'],
autoLoad: false,
autoSync: true
});
var chart = Ext.create('Ext.chart.Chart', {
alias : 'widget.dashBoardPieChart',
title : 'Technology Portal',
store : store,
theme: 'Base:gradients',
legend: {
position: 'bottom'
},
series: [
{
type: 'pie',
angleField: 'size',
showInLegend: true,
label: {
field: 'title',
display: 'outside',
font: '12px Arial',
calloutLine: true
},
highlight: {
segment: {
margin: 20
}
},
label: {
field: 'title',
display: 'rotate',
contrast: true,
font: '18px Arial'
},
tips: {
trackMouse: true,
width: 120,
renderer: function(storeItem, item) {
this.setTitle(storeItem.get('title') + ': ' + storeItem.get('size') + '%');
}
}
}
]
});
var panel1= Ext.create('widget.panel', {
// extend : 'widget.panel',
width: 800,
height: 600,
title: 'Server',
alias : 'widget.dashBoardForm',
renderTo: Ext.getBody(),
layout: 'fit',
tbar: [{
text: 'Save Chart',
handler: function() {
Ext.MessageBox.confirm('Confirm Download', 'Would you like to download the chart as an image?', function(choice){
if(choice == 'yes'){
chart.save({
type: 'image/png'
});
}
});
}
}],
items: chart
});
I hope I am clear with my points.
Thanks
Sach
You need to see this as one app, one memoryspace, that the code is separated in two .js files makes not much difference, they both have to be loaded in your main html, asp, php or whatever. In that memoryspace you can reference each others variables and objects if they were declared before. The easiest way to accomplish what you ask is to have one store and use that for both views. So load the data in the store in your ServerDetails.js and have the chart use this same store.
I have some ExtJs apps that do that but they are for version 3.3.1 and not at my disposal for the moment. Hope this helps.

Using Highcharts in ExtJS 4.2.2

I try to use Highcharts i ExtJS.
I wrote my app.js:
Ext.onReady(function () {
Ext.define('myModel', {
extend: 'Ext.data.Model',
fields: [{ name: 'month' }, { name: 'value' }]
});
Ext.define('myStore', {
extend: 'Ext.data.Store',
model: 'myModel',
data: [{
month: '1',
value: 1
}, {
month: '2',
value: 12
}]
});
var sto = Ext.create('myStore');
var win = new Ext.create('Ext.window.Window', {
layout: 'fit',
width: 480,
height: 320,
items: [{
xtype: 'highchart',
series: [{
dashStyle: 'DashDot',
dataIndex: 'value'
}],
xField: 'month',
store: sto,
chartConfig: {
chart: {
type: 'spline'
},
title: {
text: 'A simple graph'
}
}
}]
}).show();
});
The page loaded without errors, but there is no any chart on the form.
I checked, some elements were added in DOM, but I can't see it on the form.
Importantly, that the elements, which were added don't contain the SVG components, they are only DIVs (empty DIVs) with id like: 'highchart-1010-north-handle'.
It is my first highchart sample in ExtJS.
I use this as an example, but result was equal - no errors, but no any charts on the form too.
Did I do something wrong?
I shared full example.

Infinite Grid only 1 column Issues

Here is the JS fiddle where I just copy pasted the sample example given by ExtJS and Kept only 1 column and that too locked. In this scenario we have 2 errors :
Its making continuous calls to backend till it gets last result. We
can check in fiddler that the calls are getting posted to backend
continously till the last page.
I am not able to scroll(vertical) in grid
Is it bug from ExtJS 4.2.1 Infinite Grid ? is there a solution ?
If we add 1 more column unlocked then its working fine (It will make only 1 request to backend and on scroll it will make next request depending on the scroller position)
Below is the same code :
Ext.onReady(function () {
Ext.define('ForumThread', {
extend: 'Ext.data.Model',
fields: [
'title', 'forumtitle', 'forumid', 'username', {
name: 'replycount',
type: 'int'
}, {
name: 'lastpost',
mapping: 'lastpost',
type: 'date',
dateFormat: 'timestamp'
},
'lastposter', ' ', 'threadid']
});
// create the Data Store
var store = Ext.create('Ext.data.Store', {
id: 'store',
model: 'ForumThread',
//remoteGroup: true,
// allow the grid to interact with the paging scroller by buffering
buffered: true,
leadingBufferZone: 300,
pageSize: 50,
proxy: {
// load using script tags for cross domain, if the data in on the same domain as
// this page, an Ajax proxy would be better
type: 'jsonp',
url: 'http://www.sencha.com/forum/remote_topics/index.php',
reader: {
root: 'topics',
totalProperty: 'totalCount'
}
},
autoLoad: true,
listeners: {
// This particular service cannot sort on more than one field, so if grouped, disable sorting
beforeprefetch: function (store, operation) {}
}
});
var grid = Ext.create('Ext.grid.Panel', {
width: 700,
height: 500,
collapsible: true,
title: 'ExtJS.com - Browse Forums',
store: store,
loadMask: true,
// grid columns
columns: [{
id: 'last',
text: "Last Post",
locked: true,
dataIndex: 'lastpost',
width: 130,
renderer: Ext.util.Format.dateRenderer('n/j/Y g:i A'),
sortable: true,
groupable: false
}],
renderTo: Ext.getBody()
});
});

Extjs grid cant get store buffered working

I have a large dataset (over 80k records). So I am trying to implement buffer but I couldn't get it work. If I include buffered configuration I am getting error object doesn't support this property. When I remove it, works ok but of course it takes forever to load the data.
Here is my code
Ext.Loader.setConfig({
enabled: true,
disableCaching: false
});
Ext.require(['Ext.data.*', 'Ext.grid.*',
'Ext.grid.plugin.BufferedRenderer', 'Ext.ux.grid.FiltersFeature']);
Ext.define('Borrower', {
extend: 'Ext.data.Model',
fields: [{
name: 'Name',
type: 'string'
}, {
name: 'Num',
type:
'string'
}]
});
Ext.onReady(function () {
var store = Ext.create('Ext.data.Store', {
autoLoad: false,
model: 'Borrower',
pageSize: 100,
buffered: true, // getting error object doestn support this property in extjs-all-debug.js
proxy: {
type: 'rest',
url: 'borrBuff.xsp/byName',
reader: {
type: 'json',
root: 'items'
}
}
});
var filters = {
ftype: 'filters',
encode: false,
local: true
};
var grid = Ext.create('Ext.grid.Panel', {
id: 'testgrid',
store: store,
features: [filters],
plugins: 'bufferedrenderer',
columns: [{
text: 'Borr Name',
dataIndex: 'Name',
filterable: true
}, {
text: 'Number',
dataIndex: 'Num'
}]
});
})
Opening the grid in a window on button click
var grid = Ext.getCmp('testgrid');
var win = Ext.create('Ext.Window', {
title: 'Grid Filters Example',
height: 400,
width: 700,
modal: true,
layout: 'fit',
items: grid
}).show();
grid.getStore().load();
Just couldnt figure out what I am doing wrong. Appreciate any help in fixing this issue.
Is there any reason to fetch all the data from server?
I'd recommend using data paging with all the pros, speed being the first one (and some cons too). If you choose to use an infinite grid, it will work well. In fact the basic idea behind infinite grid is fetching data in chunks (data paging in other words).
Filtering works without any problems with this scenario, see sample. It's usually handled by server, which is built to do this kind of tasks.

Extjs 4 how to return xml data with additional information from server to extjs controller?

I hope someone helps me out.
I want to load my grid with xml file's data, locally.
I created model,store and grid. I load the store in render event of grid.
The problem is,
Store is loaded but the grid is still empty. I looked at the grid at console, and grids items contains the loaded data, but grid doesnt contain the data on the screen.
Here is the model
Ext.define('BTOM.model.test.test', {
extend: 'Ext.data.Model',
fields: [
{ name: 'id', type: 'string' },
{ name: 'name', type: 'string' },
{ name: 'phone', type: 'string' }
]
});
Here is the store
Ext.define('BTOM.store.test.test', {
extend: 'Ext.data.Store',
model: 'BTOM.model.test.test',
autoLoad: false,
proxy: {
type: 'memory',
reader: {
type: 'xml',
root: 'users',
record: 'user'
}
}
});
And the grid
Ext.define('BTOM.view.test.test', {
extend: 'Ext.grid.Panel',
store: 'BTOM.store.test.test',
alias: 'widget.test',
title: 'Test',
initComponent: function () {
this.columns =
[
{ header: "Id", width: 120, dataIndex: 'id', sortable: false },
{ header: "Name", width: 180, dataIndex: 'name', sortable: false },
{ header: "Phone", width: 115, dataIndex: 'phone', sortable: false}
];
this.callParent(arguments);
},
});
And where I load the store is
render: function (grid, eOpts) {
var store = grid.getStore();
var data =
'<?xml version="1.0" encoding="utf-8"?>' +
'<users> ' +
'<user><id>1</id><name>Bll QASD</name><phone>333 2211</phone></user> ' +
'<user><id>2</id><name>Asd QWF</name><phone>444 2211</phone></user> ' +
'<user><id>3</id><name>Zas QWE</name><phone>555 2211</phone></user> ' +
'</users>';
var dataXml = (new DOMParser()).parseFromString(data, 'text/xml');
console.log(dataXml);
store.loadRawData(dataXml, true);
console.log(grid);
}
dataXML document is created without problem.
grid seems to contain the data (by firebug, I can see)
but datagrid is empty, doesnt show the data!
Ok, the error is that you are defining the store but not creating it.
So the grid just has the name of the store but it expects a store instance,
or is that some thing you have missed in the code snippet above.
I used the same code and here is a running example:
https://fiddle.sencha.com/#fiddle/oel

Resources