I'm migrating ExtJs 3 application to ExtJs 4. One of the component that I need to change is a chart that has series of bars and lines on it. It displays the data for previous and current years. Beside the chart there is a checkbox "Compare to previous year". When it checked all line series should be visible and hidden when it is not checked.
In ExtJs 3 I did this task by setting visibility:hidden for series styles this way: chart.setSeriesStyles(...). But in ExtJs 4 this function is absent and I can't find any other way to hide series on demand.
Here is the code of my chart:
var store = Ext.create('Ext.data.Store', {
fields: [
'month','data1','data2','data3','prev_data1','prev_data2','prev_data3'
],
proxy: {
type: 'ajax',
url: '/getmonthlystats.php'
}
});
this.statChart = Ext.create('Ext.chart.Chart', {
flex: 1,
store: store,
axes: [{
type: 'Numeric',
position: 'left',
minimum: 0,
maximum: 100,
fields: [
'data1',
'data2',
'data3',
'prev_data1',
'prev_data2',
'prev_data3'
],
label: {
renderer: Ext.util.Format.numberRenderer('0,0')
},
grid: true
},{
type: 'Category',
position: 'bottom',
fields: ['month'],
label: {
rotate: {
degrees: 315
}
}
}],
series: [{
type: 'column',
yField: ['data1','data2','data3'],
xField: 'month'
},
{
type: 'line',
yField: 'prev_data1',
xField: 'month'
},{
type: 'line',
yField: 'prev_data2',
xField: 'month'
},{
type: 'line',
yField: 'prev_data3',
xField: 'month'
}]
});
So, the lines prev_data1, prev_data2, prev_data3 should be shown or hidden when needed (depending on the checkbox state). Does anyone know the way to do that?
Thanx.
Try this (sample from my code):
handler: function (checkbox, checked) {
if (checked)
chart.series.getAt(index).showAll();
else
chart.series.getAt(index).hideAll();
}
For ExtJS 4.2.x
If you use 'legend' with your charts, this code will be better for you:
var chart = Ext.getCmp(chartId);
var series = chart.series.getAt(seriesIndex);
if (value) {
series.showInLegend = true;
series.showAll();
} else {
series.showInLegend = false;
series.hideAll();
}
chart.redraw();
Related
I have an ExtJS Chart,
The chart doesn't draw lines between the dots...
this is my config:
{
title: 'Chart',
layout: 'fit',
items: [
{
xtype: 'chart',
itemId: 'chart',
animate: true,
store: me.IndexStatusStore,
axes: [
{
type: 'Numeric',
position: 'left',
fields: ['docsPerSec'],
label: {
renderer: function (v) {
return Ext.util.Format.number(v, '0');
}
},
title: 'Documents per second',
grid: true,
minimum: 0
},
{
type: 'Category',
position: 'bottom',
fields: ['now'],
title: 'Time running',
//minimum: 0 start time
label: {
renderer: function (v) {
return Ext.util.Format.date(new Date(v), 'H:i:s');
}
}
}
],
series: [
{
type: 'line',
axis: 'left',
xField: 'now',
yField: 'docsPerSec'
}
]
}
]
}
The chart is drawing the points correctly but the lines between them are missing. It might be worth mentioning that on an interval I update store's data, the chart updates automatically.
I've found the issue... It was my data. The first record had a very high value. It seems like the chart can't handle that. The reason why this high value was present was a miscalculation in the speed and it stayed like that because I kept the first record.
I have a jsonstore
var rankingStore = new Ext.data.JsonStore({
url: './get-ranking-stats.php',
root: 'item',
fields: ['name', 'click', 'foto','pdf', 'gid', 'type'],
baseParams: {end: getToday(), start: getOneWeekBefore(), typ: 'all'},
autoLoad: true
})
and column chart based on it:
var statis2 = new Ext.Panel({
title: 'Ranking',
width: '60%',
height: 500,
items: {
xtype: 'columnchart',
store: rankingStore,
xField: 'name',
id: 'mainChart2',
yField: 'click',
extraStyle: {
xAxis: {
labelRotation: -90
}
},
series: [{
type: 'column',
displayName: 'Click counter',
yField: 'click',
style: {
mode: 'stretch',
color:0x99BBE8
}
}]
}
});
All coulms have the same colour. What I want is to heve different colours based on 'type' value from jsonstore. How to create rule like that?
user before render event of chart after that u add own custom color in chart.
beforerender: function(chart, record, index, series){
if(record.data.type=="Somthing"){
// add own custom css
}
},
Similar to this post in the Sencha forums, how do I get the labels in this (image below) to show up vertically and line up with the grid? Seems like this should be charting basics, but maybe I missed something.
Here is the jsFiddle with the code: http://jsfiddle.net/wilsjd/kg6Ps/8/
Ext.require('Ext.chart.*');
Ext.require(['Ext.Window', 'Ext.fx.target.Sprite', 'Ext.layout.container.Fit', 'Ext.window.MessageBox']);
Ext.define('CPI', {
extend: 'Ext.data.Model',
fields: [{
name: 'ReportingPeriod',
type: 'string'
}, {
name: 'PeriodAmount',
type: 'decimal'
}, {
name: 'CumulativeAmount',
type: 'decimal'
}]
});
var store1 = Ext.create('Ext.data.Store', {
model: 'CPI',
data: [{
ReportingPeriod: 'Period1',
PeriodAmount: 1,
CumulativeAmount: 1.2,
Target: 1
}, {
ReportingPeriod: 'Period2',
PeriodAmount: 1.2,
CumulativeAmount: .2,
Target: 1
}, {
ReportingPeriod: 'Period9',
PeriodAmount: 1.5,
CumulativeAmount: 0.8,
Target: 1
}]
});
var chart = Ext.create('Ext.chart.Chart', {
style: 'background:#fff',
animate: true,
theme: 'Category1',
store: store1,
width: 300,
height: 300,
renderTo: 'chart',
axes: [{
type: 'Numeric',
position: 'left',
fields: ['PeriodAmount', 'CumulativeAmount'],
title: 'CPI'
},{
type: 'Category',
position: 'bottom',
fields: ['ReportingPeriod'],
title: 'Reporting Period',
label : {
rotation:{degrees:270}
}
}],
series: [{
type: 'column',
axis: 'left',
xField: 'ReportingPeriod',
yField: 'PeriodAmount',
renderer: function(sprite, record, attr, index, store) {
var value = 0;
if(record.get('PeriodAmount')>=1){
value = 0;
}else{
value = 1;
}
var color = ['rgb(127, 255, 127)',
'rgb(255, 0, 50)'
][value];
return Ext.apply(attr, {
fill: color
});
}
}, {
type: 'line',
axis: 'left',
xField: 'ReportingPeriod',
yField: 'CumulativeAmount',
markerConfig: {
type: 'circle',
size: 4,
radius: 4,
'stroke-width': 0,
}
}]
});
chart.show();
I changed rotation to rotate and it works.
label:{
rotate:{degrees:270}
}
Per usual, the people at sencha's forum are as helpful as a punch to the throat: http://www.sencha.com/forum/showthread.php?156746-line-chart-time-axis-label-rotate-issue&p=678586&viewfull=1#post678586
It appears to be set via dy attribute in the html:
<tspan x="96" dy="3.75">Period1</tspan>
Altering dy will move the h-pos left or right. Unfortunately, there doesn't seem to be an inbuilt way to do it though.
Bottom line: it might be a bug (as a dev mentions in the above link -- but helpfully doesn't expand upon).
Suppose I have some data that I want to display on an Ext.js bar chart and I want my data to revolve around a custom value, "1.0" for example, on the y-axis (versus traditionally "0.0").
Meaning, the picture below has negative values represented with inverted bars, I would like values less than "1.0" to show as an inverted bar on the chart.
Is there a setting that I can set to acheive this? If so, would it be in the series and the axis definition? Maybe the chart itself?
The code for the chart displayed is below:
Ext.require('Ext.chart.*');
Ext.require(['Ext.Window', 'Ext.fx.target.Sprite', 'Ext.layout.container.Fit', 'Ext.window.MessageBox']);
Ext.define('CPI', {
extend: 'Ext.data.Model',
fields: [{
name: 'ReportingPeriod',
type: 'string'
}, {
name: 'CPI_P',
type: 'decimal'
}, {
name: 'CPI_C',
type: 'decimal'
}]
});
var store1 = Ext.create('Ext.data.Store', {
model: 'CPI',
data: [{
ReportingPeriod: 'Period1',
CPI_P: '1.9',
CPI_C: '1.2'
}, {
ReportingPeriod: 'Period2',
CPI_P: '1.2',
CPI_C: '1.1'
}, {
ReportingPeriod: 'Period3',
CPI_P: '0.1',
CPI_C: '0.5'
}, {
ReportingPeriod: 'Period4',
CPI_P: '-0.5',
CPI_C: '0.6'
}, {
ReportingPeriod: 'Period5',
CPI_P: '-0.9',
CPI_C: '0.8'
}, {
ReportingPeriod: 'Period6',
CPI_P: '-1.0',
CPI_C: '-0.6'
}, {
ReportingPeriod: 'Period7',
CPI_P: '-1.1',
CPI_C: '-0.7'
}, {
ReportingPeriod: 'Period8',
CPI_P: '-1.5',
CPI_C: '-0.8'
}]
});
var chart = Ext.create('Ext.chart.Chart', {
style: 'background:#fff',
animate: true,
theme: 'Category1',
store: store1,
width: 300,
height: 300,
renderTo: 'chart',
axes: [{
type: 'Numeric',
position: 'left',
fields: ['CPI_P', 'CPI_C'],
title: 'CPI',
grid: true
}, {
type: 'Category',
position: 'bottom',
fields: ['ReportingPeriod'],
title: 'Reporting Period'
}],
series: [{
type: 'column',
axis: 'left',
xField: 'ReportingPeriod',
yField: 'CPI_P',
markerConfig: {
type: 'cross',
size: 3
},
renderer: function(sprite, record, attr, index, store) {
var value = (record.get('CPI_P') >> 2) % 2;
var color = ['rgb(213, 70, 121)',
'rgb(44, 153, 201)'
][value];
return Ext.apply(attr, {
fill: color
});
}
}]
});
chart.show();
UPDATE
If I add a minimum to y-axis I get closer (sort of)
...
axes: [{
type: 'Numeric',
position: 'left',
fields: ['CPI_P', 'CPI_C'],
title: 'CPI',
grid: true,
minimum: 1,
}....
It's the right idea, because the bars now are relevant to the number 1, but I obviously need to keep the bars on the graph.
What has seemed to work is subtracting 1 from my data and adding 1 to the labels.
axes: [{
type: 'Numeric',
position: 'left',
grid: true,
maximum: 1.0, //will render to 2.0
fields: ['PeriodAmount', 'CumulativeAmount'],
label:{
renderer:function(v){
return (v+1).toFixed(2);
}
}
}...]
This is a viable work around for me, but I wouldn't consider this an elegant answer since it isn't very configurable for custom values. For example, changing this to -1 or 2 would require more work than just changing a simple setting.
I'm kind of stuck with this thing. What I want to do is to give each bar on a sencha chart a different color. This is what I have so far:
And this is my code for it:
Ext.setup({
tabletStartupScreen: 'tablet_startup.jpg',
phoneStartupScreen: 'phone_startup.jpg',
tabletIcon: 'icon-ipad.png',
phoneIcon: 'icon-iphone.png',
glossOnIcon: false,
onReady: function() {
Ext.regModel('Retail', {
fields: [
{name: 'id', type: 'string'},
{name: 'quantity', type: 'int'}
]
});
var retailStore = new Ext.data.JsonStore({
model: 'Retail',
proxy: {
type: 'ajax',
url: 'getData.php',
reader: {
type: 'json',
}
},
autoLoad: true
});
console.log(retailStore);
new Ext.chart.Panel({
id: 'chartCmp',
title: 'Stock Example',
fullscreen: true,
dockedItems: {
xtype: 'button',
iconCls: 'shuffle',
iconMask: true,
ui: 'plain',
dock: 'left'
},
items: {
cls: 'stock1',
theme: 'Demo',
legend: {
position: {
portrait: 'right',
landscape: 'top'
},
labelFont: '17px Arial'
},
interactions: [{
type: 'panzoom',
axes: {
left: {
maxZoom: 2
},
bottom: {
maxZoom: 4
}
}
}],
animate: false,
store: retailStore,
axes: [{
type: 'Numeric',
position: 'bottom',
fields: ['quantity'],
title: 'Quantity'
}, {
type: 'Category',
position: 'left',
fields: ['id'],
title: 'Products'
}],
series: [{
type: 'bar',
axis: 'right',
xField: 'id',
yField: ['quantity'],
}]
}
});
}});
I know there should be some way to "cheat" the chart by adding an extra dimension to it, just as it is done here:
http://dev.sencha.com/deploy/touch-charts-1.0.0/examples/Bar/
There each year represents a new product. I'd like to do the same with mine, each product representing a different dimension.
You can use the renderer function of a serie. You just have to change attributes.fill to the color you want for each bar. Here is an example : http://bl.ocks.org/3511876 and the code :
Ext.setup({
onReady: function() {
var data = [];
for (var i = 0; i < 10; i++) {
data.push({
x: i,
y: parseInt(Math.random() * 100)
});
}
var colors = ['blue', 'yellow', 'red', 'green', 'gray'];
var store = new Ext.data.JsonStore({
fields: ['x', 'y'],
data: data
});
var chart = new Ext.chart.Chart({
store: store,
axes: [{
type: 'Category',
fields: ['x'],
position: 'left'
}, {
type: 'Numeric',
fields: ['y'],
position: 'bottom'
}],
series: [{
type: 'bar',
xField: 'x',
yField: 'y',
axis: 'bottom',
renderer: function(sprite, record, attributes, index, store) {
attributes.fill = colors[index%colors.length];
return attributes;
}
}]
});
new Ext.chart.Panel({
fullscreen: true,
chart: chart
});
chart.redraw();
}
});