How to use SmartLegend on Sencha chart - extjs

I am researching how to use smart legend on sencha chart but legend not show multi columns
I am so stupid. Please help me .
Thank all
Nguyen
Ext.onReady(function () {
var panel, chart, legend,
store = Ext.create('Ext.data.Store', {
fields: [ 'name', 'data' ],
data: [
{ name: 'Field 0', data: Math.random() * 100 },
{ name: 'Field 1', data: Math.random() * 100 },
{ name: 'Field 2', data: Math.random() * 100 },
{ name: 'Field 3', data: Math.random() * 100 },
{ name: 'Field 4', data: Math.random() * 100 },
{ name: 'Field 5', data: Math.random() * 100 },
{ name: 'Field 6', data: Math.random() * 100 },
{ name: 'Field 7', data: Math.random() * 100 },
{ name: 'Field 8', data: Math.random() * 100 },
{ name: 'Field 9', data: Math.random() * 100 },
{ name: 'Field 10', data: Math.random() * 100 },
{ name: 'Field 11', data: Math.random() * 100 },
{ name: 'Field 12', data: Math.random() * 100 }
]
});
chart = Ext.create('Ext.chart.Chart', {
renderTo: Ext.getBody(),
position: 'absolute',
id:'chart',
x: 100,
y: 100,
layout: 'fit',
width: 800,
height: 850,
animate: true,
store: store,
theme: 'Base:gradients',
animate: Ext.isIE ? false : true,
store: store,
shadow: Ext.isIE ? false : true,
legend: false,
series: [{
type: 'pie',
id : 'chart',
field: 'data',
showInLegend: true,
tips: {
trackMouse: true,
width: 140,
height: 28,
renderer: function(storeItem, item) {
// calculate and display percentage on hover
var total = 0;
store.each(function(rec) {
total += rec.get('data');
});
this.setTitle(storeItem.get('name') + ': ' + Math.round(storeItem.get('data') / total * 100) + '%');
}
},
highlight: {
segment: {
margin: 20
}
},
label: {
field: 'name',
display: 'rotate',
contrast: true,
font: '18px Arial'
}
}]
});
//chart =this.down('chart'); //panel.down('chart');
legend = chart.legend = Ext.create('Ext.ux.chart.SmartLegend', {
position: 'right',
chart: chart,
rebuild: true,
boxStrokeWidth: 1
});
chart.legend.redraw();
chart.redraw();
});

Another alternative on sencha forums: ExtJS 4 chart legend sizing

Related

Ext Js ChartsKitchenSink.view.charts.pie.Basic

I'm using this pie chart example in this link to display a pie chart.
How do I set the pie chart dynamically and refresh the pie chart?
To dynamically create chart:-
var chart = Ext.create('Ext.chart.Chart', {
xtype: 'chart',
animate: true,
store: store1,
shadow: true,
legend: {
position: 'right'
},
insetPadding: 60,
theme: 'Base:gradients',
series: [{
type: 'pie',
field: 'data1',
showInLegend: true,
donut: donut,
tips: {
trackMouse: true,
renderer: function(storeItem, item) {
//calculate percentage.
var total = 0;
store1.each(function(rec) {
total += rec.get('data1');
});
this.setTitle(storeItem.get('name') + ': ' + Math.round(storeItem.get('data1') / total * 100) + '%');
}
},
highlight: {
segment: {
margin: 20
}
},
label: {
field: 'name',
display: 'rotate',
contrast: true,
font: '18px Arial'
}
}]
});
To refresh the chart you can use store.loadData method.
Reference url
For loading dynamic data in pie char store you can use reload(),loadData() and load() methods of store.
store.reload() example
store.reload({
params : {
userid : 1234
}
});
store.load() example
store.load({
scope: this,
callback: function(records, operation, success) {
// the Ext.data.operation.Operation object
// contains all of the details of the load operation
console.log(records);
}
});
If the callback scope does not need to be set, a function can simply be passed:
store.load(function(records, operation, success) {
console.log('loaded records');
});
store.loadData() example
var data= [{
os: 'Android',
data1: 68.3
},{
os: 'Others',
data1: 1.9
}];
store.loadData(data);
In this FIDDLE, I have created a demo. Hope this will help/guide you to achieve your requirement.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
/**
* Returns a random integer between min (inclusive) and max (inclusive)
* Using Math.round() will give you a non-uniform distribution!
*/
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function createDyanmicData(store) {
store.each(rec => {
rec.set('data1', getRandomInt(20, 100));
});
}
Ext.create({
xtype: 'polar',
tbar: ['->', {
text: 'Refresh Chart',
height: 35,
padding: 5,
margin:'0 10',
style: {
background: 'green'
},
handler: function () {
createDyanmicData(this.up('polar').getStore())
}
}],
title: 'Pie Chart Example',
renderTo: Ext.getBody(),
width: '100%',
height: window.innerHeight,
interactions: 'rotate',
store: {
fields: ['os', 'data1'],
data: [{
os: 'Android',
data1: 68.3
}, {
os: 'iOS',
data1: 17.9
}, {
os: 'Windows Phone',
data1: 10.2
}, {
os: 'BlackBerry',
data1: 1.7
}, {
os: 'Others',
data1: 1.9
}]
},
series: {
type: 'pie',
xField: 'data1',
label: {
field: 'os',
display: 'inside',
calloutLine: true
},
showInLegend: true,
highlight: true,
highlightCfg: {
fill: '#ccc',
'stroke-width': 10,
stroke: '#fff'
},
tips: {
trackMouse: true,
renderer: function (storeItem, item) {
this.setTitle(storeItem.get('os') + ': ' + storeItem.get('data1') + '%');
}
}
}
});
}
});

Cannot bind filters on Ext.chart.CartesianChart

I am new to Ext JS working on Sencha 6.5(Ext js 6.2), while running my code I am getting error as :
Ext.mixin.Bindable.applyBind(): Cannot bind filters on Ext.chart.CartesianChart - missing a setFilters method.
The chart in tab1 works fine. Further what I am trying to do is, binding the selection from combo box in tab2 to cartesian chart in next tab, I am getting the error. Can any one help please, Thanks in advance, my code is :
Store : 2FAData.js
Ext.define('LICApp.store.2FAData', {
extend: 'Ext.data.Store',
alias: 'store.2fa-data',
storeId: 'myStore',
requires: [
'Ext.data.reader.Xml'
],
autoLoad: false, // Set it to false
fields: ['name','cnt', 'zone'],
proxy: {
type: 'rest',
cors: 'true',
url : 'http://localhost:8080/UserManagement/rest/BiodataController/bio',
method: 'POST',
reader: {
type: 'xml',
record: 'biodata',
rootProperty: 'biodatas'
}
}
});
Basic.js
Ext.define('LICApp.view.charts.bar3d.Basic', {
extend: 'Ext.tab.Panel',
xtype: 'bar-basic-3d',
controller: 'bar-basic-3d',
requires: [
'Ext.chart.theme.Muted',
'LICApp.store.2FAData',
'LICApp.store.Chartdata'
],
//width: 1300,
layout: 'anchor',
defaults: { anchor: '-30' },
referenceHolder: true,
viewModel: true,
config: {
value: false
},
items: [{
xtype: 'cartesian',
title: 'Consolidated View',
reference: 'chart',
theme: 'Muted',
width: '100%',
height: 700,
legend: {
docked: 'right'
},
animation: Ext.isIE8 ? false : {
easing: 'backOut',
duration: 500
},
store: {type: 'chartdata',autoLoad:true},
insetPadding: 40,
flipXY: true,
axes: [{
type: 'numeric3d',
position: 'bottom',
grid: true,
minimum: 0,
//maximum: 100,
//majorTickSteps: 10,
renderer: 'onAxisLabelRender1'
}, {
type: 'category3d',
position: 'left',
grid: true
}],
series: [{
type: 'bar3d',
fullStack: false,
title: [ 'Concurrencia Enabled', 'eFeap Enabled', 'Authorised Users', 'Biometric Enrolled Users', 'Total Devices Issued', 'Total No. of Employees'],
xField: 'zone',
yField: [ 'data1', 'data2', 'data3', 'data4', 'data5', 'data6'],
axis: 'bottom',
stacked: false,
highlight: true,
tooltip: {
trackMouse: true,
renderer: 'onSeriesTooltipRender1'
}
}],
sprites: [{
type: 'text',
text: '2FA Biometric Progress - Zonewise comparison',
fontSize: 22,
width: 100,
height: 30,
x: 450, // the sprite x position
y: 20 // the sprite y position
},
{
type: 'text',
text: 'Source: 2FA Data Server',
fontSize: 10,
x: 12,
y: 695
}]
},
{
xtype: 'combobox',
title : 'Zone Selection',
reference: 'zone',
fieldLabel: 'Choose Zone',
store: {
type: 'chartdata',autoLoad:true
},
valueField: 'zone',
displayField: 'zone',
publishes: 'value',
typeAhead: true,
queryMode: 'local',
triggerAction: 'all',
emptyText: 'Select a Zone...',
selectOnFocus: true,
//width: 300,
indent: true,
renderTo: Ext.getBody(),
listeners: {
select: 'onZoneSelected'
}
},
{
xtype: 'cartesian',
itemId: 'zchart',
title: 'Zonewise View',
flipXY: true,
reference: 'chart',
width: '100%',
height: 500,
insetPadding: '40 40 30 40',
innerPadding: '3 0 0 0',
theme: {
type: 'muted'
},
store: {
type: '2fa-data', autoLoad :true
},
bind: {
visible: '{zone.value}',
filters: {
property: 'zone',
value: '{zone.value}'
}
},
animation: {
easing: 'easeOut',
duration: 500
},
interactions: ['itemhighlight'],
axes: [{
type: 'numeric3d',
renderer: 'onAxisLabelRender',
title: 'Number of Employees',
grid: {
odd: {
fillStyle: 'rgba(245, 245, 245, 1.0)'
},
even: {
fillStyle: 'rgba(255, 255, 255, 1.0)'
}
}
}, {
type: 'category3d',
position: 'left',
label: {
textAlign: 'right'
},
grid: true
}],
series: [{
type: 'bar3d',
xField: 'name',
yField: 'cnt',
style: {
minGapWidth: 10
},
highlight: true,
label: {
field: 'cnt',
display: 'insideEnd',
renderer: 'onSeriesLabelRender'
},
tooltip: {
trackMouse: true,
renderer: 'onSeriesTooltipRender'
}
}],
sprites: [{
type: 'text',
text: '2FA Biometric - Zonewise Progress Chart',
fontSize: 22,
width: 100,
height: 30,
x: 40, // the sprite x position
y: 20 // the sprite y position
}, {
type: 'text',
text: 'Source: 2FA Data Server',
fontSize: 10,
x: 12,
y: 490
}]
}
]
});
BasicController.js
Ext.define('LICApp.view.charts.bar3d.BasicController', {
extend: 'Ext.app.ViewController',
alias: 'controller.bar-basic-3d',
onAxisLabelRender: function (axis, label, layoutContext) {
return Ext.util.Format.number(layoutContext.renderer(label) );
},
onSeriesLabelRender: function (v) {
return Ext.util.Format.number(v);
},
onSeriesTooltipRender: function (tooltip, record, item) {
var formatString = '0,000 ';
tooltip.setHtml(record.get('name') + ': ' +
Ext.util.Format.number(record.get('cnt'), formatString));
},
onPreview: function () {
if (Ext.isIE8) {
Ext.Msg.alert('Unsupported Operation', 'This operation requires a newer version of Internet Explorer.');
return;
}
var chart = this.lookupReference('chart');
chart.preview();
},
onItemSelected: function (sender, record) {
var zone = sender.getValue();
Ext.toast('You selected : ' + zone);
var store = Ext.getStore('myStore');
Ext.Ajax.request({
url: 'http://localhost:8080/UserManagement/rest/BiodataController/bio?zone='+zone,
timeout: 60000,
method: 'GET',
scope: this,
reader: {
type: 'xml',
record: 'biodata',
rootProperty: 'biodatas'
},
success: function(resp, request) {
var data = console.log(resp.responseText);
var myView = Ext.getCmp('zchart');
Ext.MessageBox.alert('Success', 'Data return from the server: '+ resp.responseText);
store.reLoad();//reload will be called, when AJAX call is successful.
/*
if ( window.DOMParser ) { // Standard
tmp = new DOMParser();
xml = tmp.parseFromString( resp.responseText , "text/xml" );
} else { // IE
xml = new ActiveXObject( "Microsoft.XMLDOM" );
xml.async = "false";
xml.loadXML( resp.responseText );
}
*/
autoLoad:true;
//store.load(resp.responseText);
//console.log(myView);
//store.setData(resp.responseText);
},
failure: function(resp, opts) {
},
callback: function(options, success, resp) {
}
});
},
onCombo1Selected: function (sender, record) {
var zone = sender.getValue();
Ext.toast('You selected : ' + zone );
},
onCombo2Selected: function (sender, record) {
var divn = sender.getValue();
Ext.toast('You selected : ' + divn + '-' + record.get('donm'));
},
onCombo3Selected: function (sender, record) {
var bran = sender.getValue();
Ext.toast('You selected : ' + record.get('bran'));
},
onZoneSelected: function (sender, record) {
var zone = sender.getValue();
Ext.toast('You selected : ' + zone );
},
// Controller entries for stacked bar
onAxisLabelRender1: function (axis, label, layoutContext) {
// Custom renderer overrides the native axis label renderer.
// Since we don't want to do anything fancy with the value
// ourselves except appending a '%' sign, but at the same time
// don't want to loose the formatting done by the native renderer,
// we let the native renderer process the value first.
return layoutContext.renderer(label) ;
},
onSeriesTooltipRender1: function (tooltip, record, item) {
var fieldIndex = Ext.Array.indexOf(item.series.getYField(), item.field),
zone = item.series.getTitle()[fieldIndex];
tooltip.setHtml(zone + ' of ' + record.get('zone') + ': ' +
record.get(item.field) + ' out of ' + record.get('data6') + ' Total');
},
onColumnRender1: function (v) {
return v ;
}
// Ends here
});
This won't work the way you want it to.
The Cartesian Graph doesn't have it's own filtering mechanism and thus you can't trigger the filter via data binding. (Correct me if I'm wrong, but as far as I know, you can't set child elements' properties such as the store's filter property via data-binding)
You'll have to take the oldschool route and set the filters by hand in the ComboBox's Listener like this:
onZoneSelected: function (sender, record) {
var zone = sender.getValue();
Ext.toast('You selected : ' + zone );
var zchart = sender.up().getComponent('#zchart');
zchart.store.setFilters([{property: 'zone', value: zone}]);
},

i try to do the Spie example in Ext JS 5 but it didnt work

Here is my code i dont know why it didnt work ..the error in the console is
[W] [Ext.Loader] Synchronously loading 'widget.polar'; consider adding Ext.require('widget.polar') above Ext.onReady Util.js?_dc=1404383474396:692
GET http://localhost/widget/polar.js?_dc=1404383480019 404 (Not Found) bootstrap.js:558
Uncaught Error: [Ext.create] Unrecognized class name / alias: widget.polar ClassManager.js?_dc=1404383474396:1405
[E] [Ext.Loader] Some requested files failed to load. Util.js?_dc=1404383474396:692
Object
Util.js?_dc=1404383474396:698
console.trace() Util.js?_dc=1404383474396:704
log Util.js?_dc=1404383474396:704
Ext.apply.raise Error.js?_dc=1404383474396:186
Ext.apply.onLoadFailure Loader.js?_dc=1404383474396:649
(anonymous function) bootstrap.js:728
Uncaught Error: [Ext.Loader] Some requested files failed to load. Error.js?_dc=1404383474396:103
im just trying to create an Spie like in the example :http://dev.sencha.com/ext/5.0.0/examples/kitchensink/?charts=true#pie-custom
Ext.define('App.view.main.Main', {
extend: 'Ext.container.Container',
requires: 'App.view.main.TabPanel',
xtype: 'app-main',
controller: 'main',
viewModel: {
type: 'main'
},
layout: {
type: 'border'
},
items: [
{
region: 'center',
xtype: 'customtabpanel'
}]
});
and input it into my TAB .... i dunno why didnt work
app/view/main/TabPanel.js
Ext.define('App.view.main.TabPanel', {
extend: 'Ext.tab.Panel',
xtype: 'customtabpanel',
requires:['App.view.main.Pie'],
ui: 'navigation',
tabPosition: 'left',
tabRotation: 0,
tabBar: {
border: false
},
items: [{
title: 'Active Tab 1',
html: 'Active Link One',
xtype: 'pie-custom',
}, {
title: 'Active Tab 2',
html: 'Active Link Two'
}, {
title: 'Active Tab 3',
html: 'Active Link Three'
}, {
title: 'Active Tab 4',
html: 'Active Link Four'
}]
});
app/view/main/Pie.js
Ext.define('App.view.main.Pie', {
extend: 'Ext.Panel',
xtype: 'pie-custom',
// <example>
bodyStyle: 'background: transparent !important',
layout: {
type: 'vbox',
pack: 'center'
},
// </example>
width: 650,
initComponent: function() {
var me = this;
//<example>
me.tbar = [
'->',
{
text: 'Preview',
handler: function() {
me.down('polar').preview();
}
}
];
//</example>
me.items = [{
xtype: 'polar',
width: '100%',
height: 500,
store: {type: 'device-market-share'},
insetPadding: 30,
innerPadding: 20,
legend: {
docked: 'bottom'
},
interactions: ['rotate', 'itemhighlight'],
sprites: [{
type: 'text',
text: 'Pie Charts - Custom Slice Sizing',
font: '22px Helvetica',
width: 100,
height: 30,
x: 40, // the sprite x position
y: 20 // the sprite y position
}, {
type: 'text',
text: 'Data: IDC Predictions - 2017',
font: '10px Helvetica',
x: 12,
y: 425
}, {
type: 'text',
text: 'Source: Internet',
font: '10px Helvetica',
x: 12,
y: 435
}],
series: [{
type: 'pie',
animation: {easing: 'easeOut', duration: 500},
angleField: 'data1', // bind angle span to visits
lengthField: 'data2', // bind pie slice length to views
clockwise: false,
highlight: {
margin: 20
},
label: {
field: 'os', // bind label text to name
display: 'outside',
font: '14px Arial'
},
style: {
strokeStyle: 'white',
lineWidth: 1
},
tooltip: {
trackMouse: true,
renderer: function(storeItem, item) {
this.setHtml(storeItem.get('os') + ': ' + storeItem.get('data1') + '%');
}
}
}]
//<example>
}, {
style: 'padding-top: 10px;',
xtype: 'gridpanel',
columns : {
defaults: {
sortable: false,
menuDisabled: true
},
items: [
{ text: 'OS', dataIndex: 'os' },
{ text: 'Market Share', dataIndex: 'data1', width: 150, renderer: function(v) { return v + '%'; } },
{ text: 'Growth', dataIndex: 'data2', width: 150, renderer: function(v) { return v + '%'; } }
]
},
store: {type: 'device-market-share'},
width: '100%'
//</example>
}];
this.callParent();
}
});
can you help me out why is this error happen ???
Try to add "ext-charts" to "requires" section of your app.json in line 42

How to use HTML tags in a Chart Legend?

How can use HTML tags in a chart legend while using title to apply custom legend text?
If we apply something like this title:['Your<b>New</b><br />Label'] the tags are just written as plain text.
Ext.application({
name: 'Fiddle',
launch: function () {
var store = Ext.create('Ext.data.JsonStore', {
fields: ['name', 'data', 'data2'],
data: [{
'name': 'metric one',
'data': 10,
'data2': 2
}, {
'name': 'metric two',
'data': 27,
'data2': 5
}]
});
Ext.create('Ext.chart.Chart', {
renderTo: Ext.getBody(),
width: 500,
height: 300,
animate: true,
store: store,
legend: {
position: 'right'
},
axes: [{
type: 'Numeric',
position: 'left',
fields: ['data', 'data2'],
label: {
renderer: Ext.util.Format.numberRenderer('0,0')
},
title: 'Sample Values',
grid: true,
minimum: 0
}, {
type: 'Category',
position: 'bottom',
fields: ['name'],
title: 'Sample Metrics'
}],
series: [{
type: 'column',
axis: 'left',
highlight: true,
stacked: true,
tips: {
trackMouse: true,
width: 140,
height: 28,
renderer: function (storeItem, item) {
this.setTitle(storeItem.get('name') + ': ' + storeItem.get('data') + ' $');
}
},
label: {
display: 'insideEnd',
'text-anchor': 'middle',
field: 'data',
renderer: Ext.util.Format.numberRenderer('0'),
orientation: 'vertical',
color: '#333'
},
xField: 'name',
yField: ['data', 'data2'],
title: ['Your<b>New</b><br />Label']
}]
});
}
});

How to edit cell in grid panel in Ext JS 3.4?

Is it possible to make cell editable in ext js 3.4 gridpanel?
If yes please reply me how?
This is the code I tried,
var fm = Ext.form;
var grid = new Ext.grid.EditorGridPanel({
height: 500,
renderTo: Ext.getBody(),
width: 800,
loadMask: false,
viewConfig: {
emptyText: 'No data to display'
},
selModel: checkboxselection,
tbar: mainGridToolbar,
clicksToEdit: 1,
store: cartStore,
listeners: {
afteredit: function(o) {
var pos = o.record.get('POS');
var quantity = o.value;
}
},
columns: [
checkboxselection,
{
header: "quantity",
align: 'right',
dataIndex: 'QUANTITY',
sortable: true,
editor: new fm.TextField({
allowBlank: false
})
}
]
});
Edit
You are missing the plugin line... (I never heard of a EditorGridPanel, but I am on 4.x and may be mistaken at this point)
plugins: new Ext.ux.grid.RowEditor({saveText: 'Update'});
Origin
Use the Row Editor Plugin for these. You can specify for each cell if it should be editable or not.
You should really take look at the examples that comes along with the library! These lines can be found under ext-3.4.0\examples\grid\row-editor.js
Ext.onReady(function(){
Ext.QuickTips.init();
var Employee = Ext.data.Record.create([{
name: 'name',
type: 'string'
}, {
name: 'email',
type: 'string'
}, {
name: 'start',
type: 'date',
dateFormat: 'n/j/Y'
},{
name: 'salary',
type: 'float'
},{
name: 'active',
type: 'bool'
}]);
// hideous function to generate employee data
var genData = function(){
var data = [];
var s = new Date(2007, 0, 1);
var now = new Date(), i = -1;
while(s.getTime() < now.getTime()){
var ecount = Ext.ux.getRandomInt(0, 3);
for(var i = 0; i < ecount; i++){
var name = Ext.ux.generateName();
data.push({
start : s.clearTime(true).add(Date.DAY, Ext.ux.getRandomInt(0, 27)),
name : name,
email: name.toLowerCase().replace(' ', '.') + '#exttest.com',
active: true,
salary: Math.floor(Ext.ux.getRandomInt(35000, 85000)/1000)*1000
});
}
s = s.add(Date.MONTH, 1);
}
return data;
}
var store = new Ext.data.GroupingStore({
reader: new Ext.data.JsonReader({fields: Employee}),
data: genData(),
sortInfo: {field: 'start', direction: 'ASC'}
});
var editor = new Ext.ux.grid.RowEditor({
saveText: 'Update'
});
var grid = new Ext.grid.GridPanel({
store: store,
width: 600,
region:'center',
margins: '0 5 5 5',
autoExpandColumn: 'name',
plugins: [editor],
view: new Ext.grid.GroupingView({
markDirty: false
}),
tbar: [{
iconCls: 'icon-user-add',
text: 'Add Employee',
handler: function(){
var e = new Employee({
name: 'New Guy',
email: 'new#exttest.com',
start: (new Date()).clearTime(),
salary: 50000,
active: true
});
editor.stopEditing();
store.insert(0, e);
grid.getView().refresh();
grid.getSelectionModel().selectRow(0);
editor.startEditing(0);
}
},{
ref: '../removeBtn',
iconCls: 'icon-user-delete',
text: 'Remove Employee',
disabled: true,
handler: function(){
editor.stopEditing();
var s = grid.getSelectionModel().getSelections();
for(var i = 0, r; r = s[i]; i++){
store.remove(r);
}
}
}],
columns: [
new Ext.grid.RowNumberer(),
{
id: 'name',
header: 'First Name',
dataIndex: 'name',
width: 220,
sortable: true,
editor: {
xtype: 'textfield',
allowBlank: false
}
},{
header: 'Email',
dataIndex: 'email',
width: 150,
sortable: true,
editor: {
xtype: 'textfield',
allowBlank: false,
vtype: 'email'
}
},{
xtype: 'datecolumn',
header: 'Start Date',
dataIndex: 'start',
format: 'm/d/Y',
width: 100,
sortable: true,
groupRenderer: Ext.util.Format.dateRenderer('M y'),
editor: {
xtype: 'datefield',
allowBlank: false,
minValue: '01/01/2006',
minText: 'Can\'t have a start date before the company existed!',
maxValue: (new Date()).format('m/d/Y')
}
},{
xtype: 'numbercolumn',
header: 'Salary',
dataIndex: 'salary',
format: '$0,0.00',
width: 100,
sortable: true,
editor: {
xtype: 'numberfield',
allowBlank: false,
minValue: 1,
maxValue: 150000
}
},{
xtype: 'booleancolumn',
header: 'Active',
dataIndex: 'active',
align: 'center',
width: 50,
trueText: 'Yes',
falseText: 'No',
editor: {
xtype: 'checkbox'
}
}]
});
var cstore = new Ext.data.JsonStore({
fields:['month', 'employees', 'salary'],
data:[],
refreshData: function(){
var o = {}, data = [];
var s = new Date(2007, 0, 1);
var now = new Date(), i = -1;
while(s.getTime() < now.getTime()){
var m = {
month: s.format('M y'),
employees: 0,
salary: 0,
index: ++i
}
data.push(m);
o[m.month] = m;
s = s.add(Date.MONTH, 1);
}
store.each(function(r){
var m = o[r.data.start.format('M y')];
for(var i = m.index, mo; mo = data[i]; i++){
mo.employees += 10000;
mo.salary += r.data.salary;
}
});
this.loadData(data);
}
});
cstore.refreshData();
store.on('add', cstore.refreshData, cstore);
store.on('remove', cstore.refreshData, cstore);
store.on('update', cstore.refreshData, cstore);
var chart = new Ext.Panel({
width:600,
height:200,
layout:'fit',
margins: '5 5 0',
region: 'north',
split: true,
minHeight: 100,
maxHeight: 500,
items: {
xtype: 'columnchart',
store: cstore,
url:'../../resources/charts.swf',
xField: 'month',
yAxis: new Ext.chart.NumericAxis({
displayName: 'Employees',
labelRenderer : Ext.util.Format.numberRenderer('0,0')
}),
tipRenderer : function(chart, record, index, series){
if(series.yField == 'salary'){
return Ext.util.Format.number(record.data.salary, '$0,0') + ' total salary in ' + record.data.month;
}else{
return Ext.util.Format.number(Math.floor(record.data.employees/10000), '0,0') + ' total employees in ' + record.data.month;
}
},
// style chart so it looks pretty
chartStyle: {
padding: 10,
animationEnabled: true,
font: {
name: 'Tahoma',
color: 0x444444,
size: 11
},
dataTip: {
padding: 5,
border: {
color: 0x99bbe8,
size:1
},
background: {
color: 0xDAE7F6,
alpha: .9
},
font: {
name: 'Tahoma',
color: 0x15428B,
size: 10,
bold: true
}
},
xAxis: {
color: 0x69aBc8,
majorTicks: {color: 0x69aBc8, length: 4},
minorTicks: {color: 0x69aBc8, length: 2},
majorGridLines: {size: 1, color: 0xeeeeee}
},
yAxis: {
color: 0x69aBc8,
majorTicks: {color: 0x69aBc8, length: 4},
minorTicks: {color: 0x69aBc8, length: 2},
majorGridLines: {size: 1, color: 0xdfe8f6}
}
},
series: [{
type: 'column',
displayName: 'Salary',
yField: 'salary',
style: {
image:'../chart/bar.gif',
mode: 'stretch',
color:0x99BBE8
}
}]
}
});
var layout = new Ext.Panel({
title: 'Employee Salary by Month',
layout: 'border',
layoutConfig: {
columns: 1
},
width:600,
height: 600,
items: [chart, grid]
});
layout.render(Ext.getBody());
grid.getSelectionModel().on('selectionchange', function(sm){
grid.removeBtn.setDisabled(sm.getCount() < 1);
});
});

Resources