Draw a line on an Extjs chart for the average of a series - extjs4

Using ExtJS4, I need to draw a straight line across a column chart indicating the average of the series. Does anyone have know of an example of this or have a suggestion on how to do it?

I usually have the average value calculated on server side and held in the store. For exmaple, My store will be:
Ext.data.Store({
fields: ['name','active','avg'],
autoLoad: true,
proxy: {
type: 'ajax',
url : '/location/to/data'
}
})
The 'avg' holds the average value. The average line is drawn using the following series configuration:
{
type: 'line',
xField: 'name',
yField: 'avg',
showMarkers: false // Ensures that markers don't show up on the line...
}

Or we can calculate it on client side like this. Here is a working sample.
var container = Ext.create('Ext.Container', {
renderTo: Ext.getBody(),
width: 600,
height: 400,
layout: 'fit',
items: {
xtype: 'cartesian',
store: {
fields: ['month', 'value'],
data: [{
month: 'January',
value: 40
}, {
month: 'February',
value: 30
}, ]
},
axes: [{
id: 'left',
type: 'numeric',
position: 'left',
fields: 'value',
grid: true,
listeners: { // this event we need.
rangechange: function (axis, range) {
var store = this.getChart().getStore();
var tmpValue = 0, ortalama = 0, idx = 0;
store.each(function (rec) {
tmpValue = rec.get('value');
ortalama = tmpValue + ortalama;
idx++;
});
ortalama = (ortalama / idx).toFixed(2);
this.setLimits({
value: ortalama,
line: {
title: {
text: 'Average: ' + ortalama + ' USD'
},
lineDash: [2, 2]
}
});
}
}
}, {
id: 'bottom',
type: 'category',
position: 'bottom',
fields: 'month'
}],
series: {
type: 'bar',
xField: 'month',
yField: 'value',
label: {
field: 'value',
display: 'outside',
orientation: 'horizontal'
}
}
}
});

Related

RallyChart with the type being pie

I am trying to connect a RallyChart using the type specifier set to pie with a Rally.data.custom.Store. When the RallyChart has the type set to column or is blank, the data shows correctly. When the type is set to pie, I get a pie with all 0%s returned.
Here's what my store looks like:
var myStore = Ext.create('Rally.data.custom.Store', {
data: mySeries,
fields: [
{ name: 'WorkItems', type: 'string' },
{ name: 'Count', type: 'int' }
]
});
Here's what my chart configuration function looks like:
_buildChart: function(myStore) {
this.myChart = Ext.create('Rally.ui.chart.Chart', {
height: 400,
store: myStore,
series: [{
type: 'pie',
name: 'Count',
dataIndex: 'Count'
}],
xField: 'WorkItems',
chartConfig: {
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
title: {
text: 'Work Breakdown in Selected Sprint'
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage}%</b>',
percentageDecimals: 1
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
color: '#000000',
connectorColor: '#000000',
formatter: function() {
return '<b>'+ this.point.name +'</b>: '+ this.percentage +' %';
}
}
}
}
}
});
this.add(this.myChart);
}
My data incoming looks like:
['Defects', 4],
['Feature A', 4]
['Feature B', 4]
Any ideas why column charts can show it, but pie cannot?
I bet this is a bug in the 2.0p5 version of the chart. We just released version 2.0rc1 of the SDK which includes a better version of the chart. The following code example shows how to create a pie with your data and Rally.ui.chart.Chart in 2.0rc1:
//from inside your app
this.add({
xtype: 'rallychart',
height: 400,
chartData: {
series: [{
type: 'pie',
name: 'Browser share',
data: [
['Defects', 4], ['Feature A', 4], ['Feature B', 4]
]
}]
},
chartConfig: {
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
xAxis: {},//must specify empty x-axis due to bug
title: {
text: 'Work Breakdown in Selected Sprint'
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage}%</b>',
percentageDecimals: 1
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
color: '#000000',
connectorColor: '#000000',
formatter: function() {
return '<b>'+ this.point.name +'</b>: '+ this.percentage +' %';
}
}
}
}
}
});
Note it is no longer necessary to create an intermediate store to pass to the chart- you can simply pass in your series as part of the chartData config.

How to change color of bar in column chart in extjs4.1

can anybody tell how to change color of bar in column chart .I have tried with style but its not working
style : {
fill : ['red', 'green'],
width : 30
},
Thanks
Use color renderer function for series onReady method like this on custom example;
Ext.onReady(function () {
var chart = Ext.create('Ext.chart.Chart', {
xtype: 'chart',
animate: true,
style: 'background:#fff',
shadow: false,
store: store1,
axes: [{
type: 'Numeric',
position: 'bottom',
fields: ['data1'],
label: {
renderer: Ext.util.Format.numberRenderer('0,0')
},
title: 'Number of Hits',
minimum: 0
}, {
type: 'Category',
position: 'left',
fields: ['name'],
title: 'Month of the Year'
}],
series: [{
type: 'bar',
axis: 'bottom',
label: {
display: 'insideEnd',
field: 'data1',
renderer: Ext.util.Format.numberRenderer('0'),
orientation: 'horizontal',
color: '#333',
'text-anchor': 'middle',
contrast: true
},
xField: 'name',
yField: ['data1'],
//color renderer
renderer: function(sprite, record, attr, index, store) {
var fieldValue = Math.random() * 20 + 10;
var value = (record.get('data1') >> 0) % 5;
var color = ['rgb(213, 70, 121)',
'rgb(44, 153, 201)',
'rgb(146, 6, 157)',
'rgb(49, 149, 0)',
'rgb(249, 153, 0)'][value];
return Ext.apply(attr, {
fill: color
});
}
}]
});
var win = Ext.create('Ext.Window', {
width: 800,
height: 600,
minHeight: 400,
minWidth: 550,
hidden: false,
maximizable: true,
title: 'Bar Renderer',
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'
});
}
});
}
}, {
text: 'Reload Data',
handler: function() {
store1.loadData(generateData());
}
}],
items: chart
});
});
Good Luck!

Two charts in the same panel overlap each other. Why?

I am trying to put 2 charts next to each other, just like the Yearly view in the example EnergyApp. My code I use for initiating the charts and putting them into the Panel is as follows:
var salesChart = new Ext.Panel({
title: 'Sales',
iconCls: 'line',
cls: 'chartpanel',
layout: {
type: 'hbox',
align: 'stretch'
},
items: [{
flex: 1,
xtype: 'chart',
cls: 'sales',
store: StoreDemo.stores.SalesStore,
shadow: true,
animate: true,
interactions: [{
type: 'iteminfo',
listeners: {
show: function(interaction, item, panel) {
// Can be used to pop-up more information or to load drill down chart
}
}
}, {
type: 'panzoom',
axes: ['bottom']
}],
axes: [{
type: 'Numeric',
position: 'left',
minimum: 0,
maximum: 1000,
fields: ['total'],
label: {
renderer: function(v) {
return v.toFixed(0);
}
},
title: 'Total'
},
{
type: 'Category',
position: 'bottom',
fields: ['month'],
label: {
renderer: function(v) {
return Date.monthNames[(v - 1) % 12];
}
},
title: 'Month of the Year'
}],
series: [{
type: 'column',
axis: 'left',
highlight: true,
label: {
field: 'total'
},
xField: 'month',
yField: 'total'
}, {
type: 'line',
highlight: {
size: 7,
radius: 7
},
fill: true,
axis: 'left',
smooth: true,
label: {
field: 'forecast'
},
xField: 'month',
yField: 'forecast'
}]
}, {
flex: 1,
xtype: 'chart',
cls: 'sales-forecast',
store: StoreDemo.stores.SalesForecastStore,
shadow: true,
animate: true,
interactions: [{
type: 'iteminfo',
listeners: {
show: function(interaction, item, panel) {
// Can be used to pop-up more information or to load drill down chart
}
}
}, {
type: 'panzoom',
axes: ['bottom']
}],
axes: [{
type: 'Numeric',
position: 'left',
minimum: 0,
maximum: 1000,
fields: ['total'],
label: {
renderer: function(v) {
return v.toFixed(0);
}
},
title: 'Total (Forecast)'
},
{
type: 'Category',
position: 'bottom',
fields: ['month'],
label: {
renderer: function(v) {
return Date.monthNames[(v - 1) % 12];
}
},
title: 'Month of the Year'
}],
series: [{
type: 'column',
axis: 'left',
highlight: true,
label: {
field: 'total'
},
xField: 'month',
yField: 'total'
}]
}]
});
StoreDemo.views.ChartView = new Ext.TabPanel({
tabBar: {
dock: 'top',
layout: {
pack: 'center'
}
},
ui: 'light',
cardSwitchAnimation: {
type: 'slide'
},
items: [salesChart]
});
The two charts overlap, but only the data, not the axes. Here is a screenshot from Chrome 14 (it also happens on Chrome 16 and Safari 5):
You can see that the right chart is empty since the data is displayed behind the left chart.
The same thing happens for 3 charts. I tried to set a fixed width and height instead of a flex number, but then the charts completely disappeared.
I searched Google and this forum and didn't find any topic to help me (I also read the articles in the Sencha Learn, and of course the source of the EnergyApp).
Your help is very appreciated.
Ofir
You can try to set the layout of items that under the panel as 'fit'.

Setting the reader on a extjs store

I have a store on extjs4 that return a list of objects, and i want to set the reader property to be able to count the elements so i can use paging afterward.
For reference, the example that extjs use already comes with a count property(totalCount) and the type of object listed(topics), while mine dont have it, just the list.
for reference:
example
Also, in my code the grid doesnt recognize the limit of results per page, but the paging toolbar does:
var sm = Ext.create('Ext.selection.CheckboxModel');
Ext.define('Cliente', {
extend: 'Ext.data.Model',
fields: [{
name: 'ID',
type: 'int'
}, {
name: 'Nome',
type: 'string'
}, {
name: 'Email',
type: 'string'
}, {
name: 'RazaoSocial',
type: 'string'
}, {
name: 'TipoDeCliente',
type: 'string'
}],
idProperty: 'ID'
});
var store = Ext.create('Ext.data.Store', {
pageSize: 3,
model: 'Cliente',
remoteSort: true,
proxy: {
type: 'ajax',
url: 'http://localhost:4904/Cliente/ObterClientes',
extraParams: {
nome: '',
tipopessoa: '',
email: '',
cpf: '',
estado: '',
cidade: '',
cep: ''
},
reader: {
type: 'json',
root: 'data'
},
simpleSortMode: true
},
sorters: [{
property: 'Email',
direction: 'DESC'
}]
});
var pluginExpanded = true;
var grid = Ext.create('Ext.grid.Panel', {
width: 500,
height: 250,
title: 'Array Grid',
store: store,
selModel: sm,
loadMask: true,
viewConfig: {
id: 'gv',
trackOver: false,
stripeRows: false
},
columns: [{
id: 'gridid',
text: "ID",
dataIndex: 'ID',
hidden: true
}, {
text: 'Nome',
width: 150,
sortable: true,
dataIndex: 'Nome'
}, {
text: 'Tipo de Cliente',
width: 100,
sortable: true,
dataIndex: 'TipoDeCliente'
}, {
text: 'Email',
width: 150,
sortable: true,
dataIndex: 'Email'
}],
bbar: Ext.create('Ext.PagingToolbar', {
store: store,
displayInfo: true,
displayMsg: 'Exibindo clientes {0} - {1} of {2}',
emptyMsg: "Nenhum cliente"
}),
renderTo: 'clientes',
});
store.loadPage(1);
The store needs the total count to calculate the paging parameters and to show the total. Your server side implementation must change to add that count with your data.
Also load the data like this store.load(); instead of loadPage.
EDIT: you also have an extra comma here: renderTo: 'clientes', I would suggest running your code through JSLint.

extjs4 render component in tab panel

As you might notice, I'm a newbie in extjs; I have managed to do some stuff myself but the truth is that I don't understand certain things.
I have this tree on the left side, and a content panel with a tab panel on the right side. Basically what I want is to load different options (calling different components) on the tab panel when the user clicks on the tree on the left side. Right now, when the user clicks on the first of the options, it displays the components that are related to that option on the content panel. (I'm sure is not the most elegant way of showing this, but at least for now it works) however, my problem is the fact that the components doesn't seem to load in the right tab, once it loads, even if I change tabs the components stay in the same place.
I have tried using the rbac.tabs.doLayout(); after reading some topics here in the forum, with no success.
I really appreciate the help you guys can give me so i can point in the right direction.
Here is my code:
rbac.userPanel = Ext.create('role.formUserRbac');
rbac.grid = Ext.create('role.gridUserRbac');
rbac.tabsShowPanel = Ext.define('mainPanel',{
extend:'Ext.panel.Panel',
border:'false',
initComponent: function() {
this.callParent();
},
items:[rbac.userPanel,rbac.grid]
});
tabsShowPanel = Ext.create('rbac.tabsShowPanel');
function test(nameTab,des){
rbac.addTab(true,nameTab);
console.log(des);
if (des=='users'){
//console.log(rbac.tabs.addDocked(rbac.testPanel));
rbac.tabs.addDocked(tabsShowPanel)
}
}
Ext.define('treeModel', {
extend: 'Ext.data.Model',
fields: [
{mapping: 'id', name: 'id', type: 'string'},
{mapping: 'text', name: 'text', type: 'string'},
{mapping: 'descripcion', name: 'descripcion', type: 'string'},
]
})
rbac.TreeStore = Ext.create('Ext.data.TreeStore', {
proxy: {
type: 'ajax',
url: 'service.php',
extraParams: {
accion:'loadtree'
},
reader: {
type: 'json',
root: 'nodes',
}
},
autoLoad:true,
sorters: [{
property: 'id',
direction: 'ASC'
},{
property: 'id',
direction: 'ASC'
}],
root: {
id: 0,
expanded: true
},
model:'treeModel'
});
rbac.treePanel = Ext.create('Ext.tree.Panel', {
id: 'tree-panel',
title: 'Navegaci\u00f3n',
region:'west',
split: true,
height: 360,
width: 180,
minSize: 150,
rootVisible: false,
autoScroll: true,
collapsible: true,
collapseMode: 'mini',
store: rbac.TreeStore
});
var currentItem;
rbac.tabs = Ext.create('Ext.tab.Panel', {
resizeTabs: true,
enableTabScroll: true,
defaults: {
autoScroll:true,
bodyPadding: 10
},
items: [{
title: 'Men\u00FA Principal',
iconCls: 'tabs',
closable: false
}]
});
rbac.addTab = function (closable,tabName) {
rbac.tabs.add({
title: tabName,
iconCls: 'tabs',
closable: !!closable
}).show();
//rbac.tabs.doLayout();
}
rbac.treePanel.getSelectionModel().on('select', function(selModel, record) {
if (record.get('leaf')) {
var des = record.data.descripcion;
var nameTab = record.data.text;
test(nameTab,des);
}
});
rbac.contentPanel = {
id: 'content-panel',
region: 'center',
layout: 'card',
margins: '2 5 5 0',
activeItem: 0,
border: false,
items: [rbac.tabs],
};
rbac.panel = Ext.create('Ext.Viewport', {
layout: 'border',
title: 'Ext Layout Browser',
items: [{
xtype: 'box',
id: 'header',
region: 'north',
html: '<img src="images/test.png"/>',
height: 70
},{
layout: 'border',
id: 'layout-browser',
region:'center',
border: false,
split:true,
margins: '2 0 5 5',
width: 275,
minSize: 100,
maxSize: 500,
items: [rbac.treePanel, rbac.contentPanel]
}],
renderTo: Ext.getBody()
});
Solved:
rbac.addTab = function (closable,tabName) {
return rbac.tabs.add({
title: tabName,
iconCls: 'tabs',
closable: !!closable
});
}
function test(nameTab,des){
var newTab = rbac.addTab(true,nameTab);
rbac.tabs.setActiveTab(newTab);
if (des=='users'){
newTab.add(tabsShowPanel)
}
}