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