PDA

View Full Version : KPI Gauge



troseberry
5 Dec 2011, 6:39 AM
***Update***
Added support for new ExtJs 4.2.0
Series - KPIGauge
- Updated to be capatible with ExtJs 4.2.0
- Updated needle configuration to allow as optional
- Apply onAnimate method to the needle, needlePivot, and value sprites to correctly redraw location on animated resize of chart.
Axis - KPIGauge
- Update "drawAxis" method to allow for axis to inherit the applied chart theme, which by default is "Base"
- Update "drawLabel" method to allow for user customized/theme styling of labels. Default library method hard codes color, font.
- set "position: 'left'" in order to allow the axis to inherit the applied chart theme. Defaults to the "Base" theme.
- if you define "position: 'gauge'" then it will use default colors and font as defined in Ext.draw.Surface



Heres a small proof of concept extension I created for the Chart's Gauge series. It allows you to specify the different slice ranges with start, end, and color. Also contains the ability to specify the needle width, color and pivot point attributes as well.

42450

Example in the attached can just be dropped in the libraryr examples directory


Ext.Loader.setConfig({
enabled: true
});
Ext.Loader.setPath('Ext.ux', 'ux');
Ext.Loader.setConfig('disableCaching', false);
Ext.require([
'Ext.chart.*',
'Ext.ux.chart.series.KPIGauge',
'Ext.ux.chart.axis.KPIGauge',
'Ext.chart.axis.Gauge', '
'Ext.chart.series.*',
'Ext.Window'
]);
Ext.onReady(function () {
Ext.create('Ext.Window', {
width: 800,
height: 400,
minWidth: 650,
minHeight: 225,
title: 'Gauge Charts',
tbar: [{
text: 'Reload Data',
handler: function () {
// Add a short delay to prevent fast sequential clicks
window.loadTask.delay(100, function () {
store1.loadData(generateData(1));
store3.loadData(generateData(1));
store4.loadData(generateData(1));
});
}
}],
layout: {
type: 'hbox',
align: 'stretch',
padding: 5
},
items: [{
xtype: 'chart',
style: 'background:#000',
animate: {
easing: 'elasticIn',
duration: 1000
},
store: store1,
insetPadding: 50,
flex: 1,
gradients: [{
id: 'gradientRed',
angle: 15,
stops: {
0: {
color: '#750000'
},
100: {
color: '#FF0000'
}
}
}, {
id: 'gradientYellow',
angle: 30,
stops: {
0: {
color: '#9D8D00'
},
100: {
color: '#FFFF00'
}
}
}, {
id: 'gradientGreen',
angle: 45,
stops: {
0: {
color: '#1C5910'
},
100: {
color: '#00ff00'
}
}
}],
axes: [{
type: 'kpigauge',
position: 'left',
minimum: 0,
maximum: 100,
steps: 10,
margin: 0,
label: {
fill: '#fff',
font: '12px Heveltica, sans-serif'
}
}],
series: [{
type: 'kpigauge',
field: 'data1',
needle: {
width: 2,
pivotFill: '#fff',
pivotRadius: 5
},
ranges: [{
from: 0,
to: 70,
color: 'url(#gradientRed)'
}, {
from: 70,
to: 90,
color: 'url(#gradientYellow)'
}, {
from: 90,
to: 100,
color: 'url(#gradientGreen)'
}],
donut: 70
}]
}, {
xtype: 'chart',
style: 'background:#fff',
animate: {
easing: 'elasticIn',
duration: 1000
},
store: store1,
insetPadding: 50,
flex: 1,
axes: [{
type: 'kpigauge',
position: 'left',
minimum: 0,
maximum: 100,
steps: 10,
margin: 0,
label: {
fill: '#333',
font: '12px Heveltica, sans-serif'
}
}],
series: [{
type: 'kpigauge',
field: 'data1',
needle: {
width: 2,
pivotFill: '#000',
pivotRadius: 5
},
ranges: [{
from: 0,
to: 70,
color: '#FF0000'
}, {
from: 70,
to: 90,
color: '#FFFF00'
}, {
from: 90,
to: 100,
color: '#00FF00'
}],
donut: 70
}]
}]
}).show();
});


42754

wemerson.januario
22 Dec 2011, 10:30 AM
nice work, thanks!

Muhammad Hamid
24 Feb 2012, 7:43 AM
Can you give me files which you include in your Gauge.html
ext-all.css
example.css
bootstrap.js
example-data.js

I need these files because gauges are not shown to me due to missing of these files
thank you

troseberry
26 Feb 2012, 5:46 AM
You need to download the latest ExtJs Library and just drop the files in the chart example folder and then open the gauge.html file

Muhammad Hamid
27 Feb 2012, 4:28 AM
Thanks dear

but there is issue needle view is not showing properly as in your sacreenshot and colours are not diplayed only one colour is displayed on whole gauge

JDevloper
10 Jun 2012, 9:03 AM
Hi Troseberry,

I am using your KPI gauge,But my panel has and expand/collapse capability ,show when i expand

the panel pivot is moving some where,please give me a solution....

troseberry
14 Jun 2012, 9:45 AM
Can you please post a copy of the code that your using. I have tried to duplicate any issues using a collapsible panel and it seems to be working for me with no issues.

mikegriffinn@gmail.com
26 Jul 2012, 2:32 PM
Have you done any more work on this? We're building an awesome dashboard app with an easy user UI to map grids that we create by importing spreadsheets to the widget code. It looks like your code will be a great basis for adding gauge widget. You can get and idea of what we are doing at http://www.otusanalytics.com/. We offer a free 3 dashboard instance so you can signup and check it out to get an idea of what we are doing. Thanks for posting this code!!

Aranair
30 Aug 2012, 7:54 PM
Just a quick modification/bug fix:

at about line 162, probably should set the pivot sprite's attributes again inside "if (animate)"




me.needlePivotSprite.setAttributes({
type: 'circle',
fill: me.needle.pivotFill || '#222',

radius: me.needle.pivotRadius || 7,

x: centerX,

y: centerY
});




Otherwise, the pivotSprite will just remain where it is at~


I am still figuring out why sometimes the step marks just warp out of position or disappear. Anyone figured this out?

bhupalskanwal
3 Oct 2012, 9:51 PM
Many Thanks

devtig
4 Dec 2012, 12:30 PM
Works great in ExtJS 4.1.1. Thanks!

grpbhb
10 Dec 2012, 3:49 AM
Thank you!

Syntona
4 Jan 2013, 8:39 AM
Hi,
Nice work.
and I really need this control in my application which is in Sencha Chart 2.

Please help me how to incorporate this in Sencha chart 2.

many thanks in advance.

troseberry
7 Jan 2013, 10:40 AM
I have never looked at the sencha touch charts but I will take a look

Syntona
8 Jan 2013, 3:02 AM
Hey, Thanks for your reply.

I have tried to incorporate it into Sencha-chart 2.
I have modified your code to adjust with existing SenchaChart library.

However, when i tried to add a new series type, it is still giving an error.

Uncaught Error: [Ext.create] Cannot create an instance of unrecognized class name / alias: Ext.chart.series.Kpigauge



Ext.define('Ext.chart.series.KPIGauge', {


extend: 'Ext.chart.series.Gauge',

alias: 'series.kpigauge',

type: "kpigauge",


rad: Math.PI / 180,


config: {
/**
* @cfg {String} angleField
* The store record field name to be used for the gauge angles.
* The values bound to this field name must be positive real numbers.
* This parameter is required.
*/
angleField: false,


ranges: [],


/**
* @cfg {Boolean} needle
* Use the Gauge Series as an area series or add a needle to it. Default's false.
*/
needle: false,


/**
* @cfg {Boolean/Number} donut
* Use the entire disk or just a fraction of it for the gauge. Default's false.
*/
donut: false,


/**
* @cfg {Boolean} showInLegend
* Whether to add the gauge chart elements as legend items. Default's false.
*/
showInLegend: false,


/**
* @cfg {Object} style
* An object containing styles for overriding series styles from Theming.
*/


minimum: 0,


maximum: 100,


colorSet: []
},


drawSeries: function () {


var me = this,
chart = me.getChart(),
store = chart.substore || chart.getStore(),
group = me.group,
animate = me.getChart().getAnimate(),
axis = me.getChart().getAxes().get(0),
minimum = axis && axis.getMinimum() || me.getMinimum() || 0,
maximum = axis && axis.getMaximum() || me.getMaximum() || 0,
ranges = me.getRanges(),
field = me.getAngleField() || me.field,
surface = me.getSurface(),
chartBBox = chart.chartBBox,
// rad = me.rad,
donut = +me.getDonut(),
values = {},
items = [],
seriesStyle = me.style,
colors = chart.getColorsStyle(),
colorArrayLength = colors && colors.length || 0,
cos = Math.cos,
sin = Math.sin,
enableShadows = !!chart.getShadow(),
rendererAttributes, centerX, centerY, slice, slices, sprite, value,
item, ln, record, i, j, r, slice, splitAngle, rl, startAngle, endAngle, middleAngle, sliceLength, path,
p, spriteOptions, bbox, valueAngle;




if (ranges == undefined || ranges.length <= 0) {
console.log(':((((');
}
else {
console.log('Hurrey!!!');
}


if (me.fireEvent('beforedraw', me) === false) {
return;
}


Ext.chart.series.Gauge.superclass.drawSeries.call(this);
me.setBBox();
bbox = me.bbox;


//override theme colors
if (me.getColorSet()) {
colors = me.getColorSet();
colorArrayLength = colors.length;
}


//if not store or store is empty then there's nothing to draw
if (!me.getRecordCount()) {
surface.getItems().hide(true);
return;
}


centerX = me.centerX = (chartBBox.width / 2);
centerY = me.centerY = chartBBox.height;
me.radius = Math.min(centerX, centerY);
me.slices = slices = [];
me.items = items = [];


if (!me.value) {
record = store.getAt(0);
me.value = record.get(field);
}


value = me.value;
valueAngle = -180 * (1 - (value - minimum) / (maximum - minimum));


for (r = 0, rl = ranges.length; r < rl; r++) {
splitFromAngle = -180 * (1 - (ranges[r].from - minimum) / (maximum - minimum));
splitToAngle = -180 * (1 - (ranges[r].to - minimum) / (maximum - minimum));


slices.push({
series: me,
startAngle: splitFromAngle,
endAngle: splitToAngle,
rho: me.radius,
value: value,
color: ranges[r].color
});
}


//do pie slices after.
for (i = 0, ln = slices.length; i < ln; i++) {
slice = slices[i];
sprite = group.getAt(i);
//set pie slice properties
rendererAttributes = Ext.apply({
segment: {
startAngle: slice.startAngle,
endAngle: slice.endAngle,
margin: 0,
rho: slice.rho,
startRho: slice.rho * +donut / 100,
endRho: slice.rho
}
}, Ext.apply(seriesStyle, colors && { fill: colors[i % colorArrayLength]} || {}));


item = Ext.apply({},
rendererAttributes.segment, {
slice: slice,
series: me,
storeItem: record,
index: i
});
items[i] = item;
// Create a new sprite if needed (no height)
if (!sprite) {
spriteOptions = Ext.apply({
type: "path",
group: group
}, Ext.apply(seriesStyle, colors && { fill: colors[i % colorArrayLength]} || {}));


if (enableShadows) {
Ext.apply(spriteOptions, me.getShadowOptions());
}


sprite = surface.add(Ext.apply(spriteOptions, rendererAttributes));
}
slice.sprite = slice.sprite || [];
item.sprite = sprite;
slice.sprite.push(sprite);
if (animate) {
rendererAttributes = me.getRenderer()(sprite, record, rendererAttributes, i, store);
sprite._to = rendererAttributes;
me.onAnimate(sprite, {
to: rendererAttributes
});
} else {
rendererAttributes = me.getRenderer()(sprite, record, Ext.apply(rendererAttributes, {
hidden: false
}), i, store);
sprite.setAttributes(rendererAttributes, true);
}
}


valueAngle = valueAngle * Math.PI / 180;


if (!me.needleSprite) {


me.needleSprite = me.getSurface().add({
type: 'path',
path: ['M', centerX + (me.radius * +donut / 100) * cos(valueAngle),
centerY + -Math.abs((me.radius * +donut / 100) * sin(valueAngle)),
'L', centerX + me.radius * cos(valueAngle),
centerY + -Math.abs(me.radius * sin(valueAngle))],
'stroke-width': 4,
'stroke': '#222'
});


} else {
if (animate) {
me.onAnimate(me.needleSprite, {
to: {
path: ['M', centerX + (me.radius * 0 / 100) * cos(valueAngle),
centerY + -Math.abs((me.radius * 0 / 100) * sin(valueAngle)),
'L', centerX + me.radius * cos(valueAngle),
centerY + -Math.abs(me.radius * sin(valueAngle))]
}
});
} else {
me.needleSprite.setAttributes({
type: 'path',
path: ['M', centerX + (me.radius * 0 / 100) * cos(valueAngle),
centerY + -Math.abs((me.radius * 0 / 100) * sin(valueAngle)),
'L', centerX + me.radius * cos(valueAngle),
centerY + -Math.abs(me.radius * sin(valueAngle))]
});
}
}


me.needleSprite.setAttributes({
hidden: false
}, true);


delete me.value;


me.fireEvent('draw', me);
}


});

and if i replace the existing gaugeChart drawseries function, it is working fine.
but then i am loosing original gauge series.





Ext.define('Ext.chart.series.Gauge', {


extend: 'Ext.chart.series.Series',


type: "gauge",


rad: Math.PI / 180,


config: {
/**
* @cfg {String} angleField
* The store record field name to be used for the gauge angles.
* The values bound to this field name must be positive real numbers.
* This parameter is required.
*/
angleField: false,


ranges: [],


/**
* @cfg {Boolean} needle
* Use the Gauge Series as an area series or add a needle to it. Default's false.
*/
needle: false,


/**
* @cfg {Boolean/Number} donut
* Use the entire disk or just a fraction of it for the gauge. Default's false.
*/
donut: false,


/**
* @cfg {Boolean} showInLegend
* Whether to add the gauge chart elements as legend items. Default's false.
*/
showInLegend: false,


/**
* @cfg {Object} style
* An object containing styles for overriding series styles from Theming.
*/


minimum: 0,


maximum: 100,


colorSet: []
},


constructor: function (config) {
if (!config.angleField && config.field) {
console.warn('use angleField instead');
config.angleField = config.field;
}


this.callParent(arguments);


var me = this,
chart = me.getChart(),
surface = me.getSurface();


surface.addCustomAttribute("segment", function (opt) {
return me.getSegment(opt);
});
},


//@private updates some onbefore render parameters.
initialize: function () {
var me = this;
me.callParent();
},


// @private returns an object with properties for a PieSlice.
getSegment: function (opt) {
var me = this,
rad = me.rad,
cos = Math.cos,
sin = Math.sin,
abs = Math.abs,
x = me.centerX,
y = me.centerY,
x1 = 0, x2 = 0, x3 = 0, x4 = 0,
y1 = 0, y2 = 0, y3 = 0, y4 = 0,
delta = 1e-2,
startAngle = opt.startAngle,
endAngle = opt.endAngle,
midAngle = (startAngle + endAngle) / 2 * rad,
margin = opt.margin || 0,
flag = abs(endAngle - startAngle) > 180,
auxValue = abs(endAngle % 360),
flag2 = auxValue > 90 && auxValue < 270,
a1 = Math.min(startAngle, endAngle) * rad,
a2 = Math.max(startAngle, endAngle) * rad,
singleSlice = false,
fullCircle = false;


x += margin * cos(midAngle);
y += margin * sin(midAngle);


x1 = x + opt.startRho * cos(a1);
y1 = y + opt.startRho * sin(a1);


x2 = x + opt.endRho * cos(a1);
y2 = y + opt.endRho * sin(a1);


x3 = x + opt.startRho * cos(a2);
y3 = y + opt.startRho * sin(a2);


x4 = x + opt.endRho * cos(a2);
y4 = y + opt.endRho * sin(a2);


if (abs(x1 - x3) <= delta && abs(y1 - y3) <= delta) {
singleSlice = true;
}


fullCircle = singleSlice && (abs(x2 - x4) <= delta && abs(y2 - y4) <= delta);
//Solves mysterious clipping bug with IE
if (fullCircle) {
return {
path: [
["M", x4, y4 - 1e-4],
["A", opt.endRho, opt.endRho, 0, +flag, +flag2, x4, y4],
["Z"]]
};
} else if (singleSlice) {
return {
path: [
["M", x1, y1],
["L", x2, y2],
["A", opt.endRho, opt.endRho, 0, +flag, 1, x4, y4],
["Z"]]
};
} else {
return {
path: [
["M", x1, y1],
["L", x2, y2],
["A", opt.endRho, opt.endRho, 0, +flag, 1, x4, y4],
["M", x4, y4],
["L", x3, y3],
["A", opt.startRho, opt.startRho, 0, +flag, 0, x1, y1],
["Z"]]
};
}
},


// @private utility function to calculate the middle point of a pie slice.
calcMiddle: function (item) {
var me = this,
rad = me.rad,
slice = item.slice,
x = me.centerX,
y = me.centerY,
startAngle = slice.startAngle,
endAngle = slice.endAngle,
a1 = Math.min(startAngle, endAngle) * rad,
a2 = Math.max(startAngle, endAngle) * rad,
midAngle = -(a1 + (a2 - a1) / 2),
xm = x + (item.endRho + item.startRho) / 2 * Math.cos(midAngle),
ym = y - (item.endRho + item.startRho) / 2 * Math.sin(midAngle);


item.middle = {
x: xm,
y: ym
};
},
drawSeries: function () {


var me = this,
chart = me.getChart(),
store = chart.substore || chart.getStore(),
group = me.group,
animate = me.getChart().getAnimate(),
axis = me.getChart().getAxes().get(0),
minimum = axis && axis.getMinimum() || me.getMinimum() || 0,
maximum = axis && axis.getMaximum() || me.getMaximum() || 0,
ranges = me.getRanges(),
field = me.getAngleField() || me.field,
surface = me.getSurface(),
chartBBox = chart.chartBBox,
// rad = me.rad,
donut = +me.getDonut(),
values = {},
items = [],
seriesStyle = me.style,
colors = chart.getColorsStyle(),
colorArrayLength = colors && colors.length || 0,
cos = Math.cos,
sin = Math.sin,
enableShadows = !!chart.getShadow(),
rendererAttributes, centerX, centerY, slice, slices, sprite, value,
item, ln, record, i, j, r, slice, splitAngle, rl, startAngle, endAngle, middleAngle, sliceLength, path,
p, spriteOptions, bbox, valueAngle;




if (ranges == undefined || ranges.length <= 0) {
console.log(':((((');
}
else {
console.log('Hurrey!!!');
}


if (me.fireEvent('beforedraw', me) === false) {
return;
}


Ext.chart.series.Gauge.superclass.drawSeries.call(this);
me.setBBox();
bbox = me.bbox;


//override theme colors
if (me.getColorSet()) {
colors = me.getColorSet();
colorArrayLength = colors.length;
}


//if not store or store is empty then there's nothing to draw
if (!me.getRecordCount()) {
surface.getItems().hide(true);
return;
}


centerX = me.centerX = (chartBBox.width / 2);
centerY = me.centerY = chartBBox.height;
me.radius = Math.min(centerX, centerY);
me.slices = slices = [];
me.items = items = [];


if (!me.value) {
record = store.getAt(0);
me.value = record.get(field);
}


value = me.value;
valueAngle = -180 * (1 - (value - minimum) / (maximum - minimum));


for (r = 0, rl = ranges.length; r < rl; r++) {
splitFromAngle = -180 * (1 - (ranges[r].from - minimum) / (maximum - minimum));
splitToAngle = -180 * (1 - (ranges[r].to - minimum) / (maximum - minimum));


slices.push({
series: me,
startAngle: splitFromAngle,
endAngle: splitToAngle,
rho: me.radius,
value: value,
color: ranges[r].color
});
}


//do pie slices after.
for (i = 0, ln = slices.length; i < ln; i++) {
slice = slices[i];
sprite = group.getAt(i);
//set pie slice properties
rendererAttributes = Ext.apply({
segment: {
startAngle: slice.startAngle,
endAngle: slice.endAngle,
margin: 0,
rho: slice.rho,
startRho: slice.rho * +donut / 100,
endRho: slice.rho
}
}, Ext.apply(seriesStyle, colors && { fill: colors[i % colorArrayLength]} || {}));


item = Ext.apply({},
rendererAttributes.segment, {
slice: slice,
series: me,
storeItem: record,
index: i
});
items[i] = item;
// Create a new sprite if needed (no height)
if (!sprite) {
spriteOptions = Ext.apply({
type: "path",
group: group
}, Ext.apply(seriesStyle, colors && { fill: colors[i % colorArrayLength]} || {}));


if (enableShadows) {
Ext.apply(spriteOptions, me.getShadowOptions());
}


sprite = surface.add(Ext.apply(spriteOptions, rendererAttributes));
}
slice.sprite = slice.sprite || [];
item.sprite = sprite;
slice.sprite.push(sprite);
if (animate) {
rendererAttributes = me.getRenderer()(sprite, record, rendererAttributes, i, store);
sprite._to = rendererAttributes;
me.onAnimate(sprite, {
to: rendererAttributes
});
} else {
rendererAttributes = me.getRenderer()(sprite, record, Ext.apply(rendererAttributes, {
hidden: false
}), i, store);
sprite.setAttributes(rendererAttributes, true);
}
}


valueAngle = valueAngle * Math.PI / 180;


if (!me.needleSprite) {


me.needleSprite = me.getSurface().add({
type: 'path',
path: ['M', centerX + (me.radius * +donut / 100) * cos(valueAngle),
centerY + -Math.abs((me.radius * +donut / 100) * sin(valueAngle)),
'L', centerX + me.radius * cos(valueAngle),
centerY + -Math.abs(me.radius * sin(valueAngle))],
'stroke-width': 4,
'stroke': '#222'
});


} else {
if (animate) {
me.onAnimate(me.needleSprite, {
to: {
path: ['M', centerX + (me.radius * 0 / 100) * cos(valueAngle),
centerY + -Math.abs((me.radius * 0 / 100) * sin(valueAngle)),
'L', centerX + me.radius * cos(valueAngle),
centerY + -Math.abs(me.radius * sin(valueAngle))]
}
});
} else {
me.needleSprite.setAttributes({
type: 'path',
path: ['M', centerX + (me.radius * 0 / 100) * cos(valueAngle),
centerY + -Math.abs((me.radius * 0 / 100) * sin(valueAngle)),
'L', centerX + me.radius * cos(valueAngle),
centerY + -Math.abs(me.radius * sin(valueAngle))]
});
}
}


me.needleSprite.setAttributes({
hidden: false
}, true);


delete me.value;


me.fireEvent('draw', me);
},




/**
* Sets the Gauge chart to the current specified value.
*/
setValue: function (value) {
this.value = value;
this.drawSeries();
},


// @private callback for when creating a label sprite.
onCreateLabel: Ext.emptyFn,


// @private callback for when placing a label sprite.
onPlaceLabel: Ext.emptyFn,


// @private callback for when placing a callout.
onPlaceCallout: Ext.emptyFn,


// @private handles sprite animation for the series.
onAnimate: function (sprite, attr) {
sprite.show();
Ext.chart.series.Gauge.superclass.onAnimate.apply(this, arguments);
},


isItemInPoint: function () {
return false;
},


// @private shows all elements in the series.
showAll: function () {
if (!isNaN(this._index)) {
this.getExcludes()[this._index] = false;
this.drawSeries();
}
},


/**
* Returns the color of the series (to be displayed as color for the series legend item).
* @param index {Number} Info about the item; same format as returned by #getItemForPoint
*/
getLegendColor: function (index) {
var me = this,
colors = me.getChart().getColorsStyle();
return me.getColorFromStyle(colors[index % colors.length]);
}
});



Thanks in advance

Neethi
11 Mar 2013, 9:55 PM
Can we have a render for the ranges, like 10b, 20b... 100b or 10 m, 20m.. 100m , to show larger range values.

Neethi
14 Mar 2013, 7:58 PM
I want to change the labels of the chart to white as chart background is black. I could do it for firefox and chrome using css on tspan, but couldn't do anything for IE. Does anyone have solution for this.

Cheers,
Niti

troseberry
16 Mar 2013, 3:43 PM
I updated the code to include support for resizing while animated.

troseberry
16 Mar 2013, 3:45 PM
Updated the code to also include support for applying custom styles and inherit chart theme.

The default gauge axis does not allow because it hardcodes attributes and does not use the normal chart themes.

So now if you have a different color background you can change the axis labels to use your own style or apply a theme to the chart and set the position of the axis to use the required theme config

aihua
27 Mar 2013, 6:08 AM
Hi,

There is a bug. When click 'Reload Data', the number in the chart is not right, only displayed the initial number. Maybe you should modify the handler function for 'Reload Data'.

troseberry
27 Mar 2013, 10:49 AM
I fixed the issue with reload of data and uploaded changes

rohit.advani
25 Apr 2013, 1:29 AM
Hi,

I'm relatively new to ExtJS framework and currently using version 4.1. My requirement is exactly same what is shown in the screenshot in the first comment in this thread by troseberry.

But when I try to render this sample code, I don't see anything on the browser. On debugging, it gives me problem saying "Failed to load resource: the server responded with a status of 404 (Not Found) -
http://localhost:8080/testJs/ux/chart/axis/KPIGauge.js" and same error I'm getting for KPIGauge.js file in Series folder.

Basically, what I have done, I have created one .js file (GaugeChart.js) which contains the same code as mentioned by trosberry in this thread and from this file, we are importing (Ext.Require) KPIGauge.js file and I'm getting the above mentioned problem probably because I'm not inheriting it in right way.

Can someone in this thread please assist me with right approach ?

Regards,
Rohit

dillu5c5
15 May 2014, 6:33 AM
Hi all.
Please suggest me a way to show up the legend in the gauge chart. I've used the plugin which you gave but I need to show 3 legends in the box but couldn't make it out using showInLengend: true with field config under series.

Expecting a reply

troseberry
19 May 2014, 6:28 PM
The legends have never worked with the KPI Gauge. I believe it has to do with the range config which is different than the way the normal gauge value is set. I will see if I can adjust the getLegendColor method.

dillu5c5
19 May 2014, 6:39 PM
Hi troseberry,
Thanks for the reply I also need some help with respect to animation for the gauge chart. Right now the animation is applied only for the first range, is there a way to animate all segments of the gauge?:-/

troseberry
20 May 2014, 5:17 AM
can you give me an example of what data your wanting to show in the legend?

dillu5c5
21 May 2014, 5:27 AM
Hi Trooseberry,
Please post some sample where I could have the legend to be displayed. I tried to get the legends but its coming undefined. Also the animations were coming for the first range of values. The code I'm using is

var gaugeChart = Ext4.create('Ext.chart.Chart', {
renderTo:renderToId,
anchor:'100%',
width: chartWidth,
height: chartHeight,
xtype: 'chart',
store: chartStore,
legend: {
position: 'right',
boxStroke: 0,
labelFont: '10px Arial'
},
animate: Ext.isIE ? false : {
easing: 'easeInOut',
duration: 1000
},
axes: [{
type: 'kpigauge',
position: 'left',
title:titleName,
minimum: 0,
maximum: 100,
steps: 10,
margin:-5,
label: {
fill: '#000',
font: 'bold 12px Arial'
}

}],
series: [{
type: 'kpigauge',
showInLegend: true,
store: chartStore,
needle: {
width: 2,
pivotFill: '#000',
pivotRadius: 5,
animate:true
},
ranges:setRange,
highlight: true,
highlight: {
segment: {
margin: 20
}
},
field:xCol,
yField: xCol,
donut: 60

}]
});
My data will be of the form

{Abcd,Vendor 1,Jun-2011,50.0,80,90}
where 50.0 is the xCol {value plotted}, 80 and 90 are the ranges.:-| PFA the screenshots
4906849069

troseberry
22 May 2014, 6:38 AM
There are a few problems with a legend on the Gauge. The first is there is no more than one series to show in the legend so there is no way to show multiple entries unless the Legend class itself is overridden. The second issues is that the "getLegendColors" method of the series.Gauge class needs to be overridden to include the proper color ranges(colorSet) used from the KPIGauge series's ranges config. But you still run into issue #1. By default it will use the default chart series theme to pick the color but the label is coded to pull directly from the field "name".

You could use a label config on the series to specify the correct field to display as the first and only series legend item's label



series: [{
type: 'kpigauge',
field: 'data1',
label: {
field: 'MyTitleField'
},
showInLegend: true,
needle: {
width: 2,
pivotFill: '#000',
pivotRadius: 5
},
ranges: [{
from: 0,
to: 70,
color: 'url(#gradientRed)'
}, {
from: 70,
to: 90,
color: 'url(#gradientYellow)'
}, {
from: 90,
to: 100,
color: 'url(#gradientGreen)'
}],
donut: 70
}]


In all honesty, I am not sure you will be able to accomplish what you want by modifying the KPIGauge extension because of the way the legend is created and that there is only one series.

dillu5c5
22 May 2014, 10:49 AM
Hi troseberry,
First of all thanks a ton for the excellent and elaborate answer.
I got the concept will try to include one series legend.

Now I need help on animation. The animation is being applied to the first segment alone. Any idea on that??

prabha_86
8 Jun 2014, 10:59 PM
Hi ,
I'm a newbie and can anyone of you please let me know in steps how to make use of KPIGauge in sencha architect 3 EXT JS to show multi colors variants.Thanks in advance

troseberry
13 Jun 2014, 10:40 AM
Sorry I have never used Architect and do not know how components integrate.

hparekh
18 Jun 2014, 8:24 AM
I am new to Sencha and I was wondering if anyone could show me how to use the KPI Gauge.
I have the KPI Gauge in the toolbox but when I try to use it, it doesn't work.
Thank you in advance for the help.

nareshKM
30 Jul 2014, 5:35 PM
Is there a way to hide the axes numbers and the gauge value in the chart?

troseberry
31 Jul 2014, 9:16 AM
To hide the axis lines and values you can override

drawAxis: function () {}

inside the axes config. This essentially overrides the function that creates all those elements.

Unfortunately there is no config to get rid of the value label as it is part of the needle component. You could always modify the KPIGauge series class and add in a showValue config type of option to the needle configuration that will check to see if it should create that sprite.

michael_jr
21 Aug 2014, 6:06 AM
Thank you... very good tutorial !!!

;)