PDA

View Full Version : Speedometer extension?



daniel_vasilan
4 Jan 2011, 11:12 PM
Hi,
Does anyone know about a "speedometer" user extension developed with extjs ?
I've searched the forums, but couldn't find one.

Thanks
Daniel

msuresh
4 Jan 2011, 11:21 PM
How it looks, how it works, any thoughts?

daniel_vasilan
5 Jan 2011, 12:34 AM
It's used to graphically show a value reported to some minimal-optimal-maximal values.
It looks like a car speedometer, with a range of values (min-max), an arc indicator that show the current value.
Eventually, it has some coloured areas for min, optimal, max permitted values.

Ex: http://www.mrc-productivity.com/support/manual/servletmanual/Reports/speedometers.htm
(took it randomly with a short google search)

Thanks

daniel_vasilan
5 Jan 2011, 9:45 AM
I've found some Raphaeljs library for javascript drawings.
I'll test with it.

daniel_vasilan
18 Jan 2011, 1:28 AM
For who is interested in this, I made something using raphael library and the example ux.clock from sencha community.
My code is not the best and can be improved, for me it just works :)

Here is the js extension code:



/**
* @author Daniel Vasilan
* @since 17/01/2011
*/

Ext.ns('Ext.ux');

/**
* @class Ext.ux.Speed
* @extends Ext.BoxComponent
* <p>This class shows a value related to MIN-MAX values in car speedometer style. Note: Requires Raphael!
* </p>
*/
Ext.ux.Speed = Ext.extend(Ext.BoxComponent, {

/**
* @cfg {Float} minVal The minimum permitted value
* @cfg {Float} maxVal The maximum permitted value
* @cfg {Float} minOpt The minimum optimal value
* @cfg {Float} maxOpt The maximum optimal value
* @cfg {Float} currVal The current value
*/
minVal : 0,
maxVal : 100,
currVal : 0,
minOpt : 33,
maxOpt : 66,

/**
* @cfg {string} label A label ascoiated with the speedometer
*/
label : "",

// Overriding superclass template method
afterRender : function() {

this.innerEl = this.el.createChild({
cls : 'ext-ux-speed-inner'
})

// Initialize a Raphael canvas
this.canvas = Raphael(this.innerEl.dom, this.width, this.height);

this.on('resize', this.handleResize, this);

this.drawSpeed();

// Call superclass
Ext.ux.Speed.superclass.afterRender.apply(this, arguments);
},

// private
drawSpeed : function(){
var tplIndic = "M{0} {1}L{2} {3}",
tplSpeed = "M{0} {1} A200,200 0 0,1 {2},{1} v20 A200,200 0 0,0 {0},{3} z",
width = this.width,
height = this.height,
center = width/2,
brushSize = Math.ceil(width / 50),
xIndic = width * (this.currVal - this.minVal) / (this.maxVal - this.minVal),
widthMin = width * (this.minOpt - this.minVal) / (this.maxVal - this.minVal),
widthMax = width * (this.maxVal - this.maxOpt) / (this.maxVal - this.minVal),
widthOpt = width - widthMin - widthMax;

this.canvas.clear();

// draw the scale
this.canvas.path(String.format(tplSpeed, 0, 0.3*height, width, 0.3*height+20)).attr({
"stroke-width": 1,
stroke: "blue",
fill: "0-red-yellow:"+(100*widthMin)/width+"-yellow:"+(100*(widthMin+widthOpt))/width+"-green"
});

//draw the indicator
this.canvas.path(String.format(tplIndic, center, height-10, xIndic, 0.1*height)).attr({
"stroke-width": brushSize
});
this.canvas.circle(center, height-10, 5).attr({
"fill": "black"
});

//draw the text
this.canvas.text(0, 0.05*this.height, this.minVal+"-"+this.minOpt).attr({
fill: "red",
"font-size":12,
"text-anchor": "left"
});
this.canvas.text(this.width-40, 0.05*this.height, this.maxOpt+"-"+this.maxVal).attr({
fill: "green",
"font-size":12,
"text-anchor": "left"
});
this.canvas.text(center, 0.5*this.height, this.currVal).attr({
"font-size":36,
fill: "blue"
});

this.canvas.text(0, 0.8*this.height, this.label).attr({
fill: "blue",
"font-size": 16,
"text-anchor": "left"
});

},

// private
handleResize : function(me, newWidth, newHeight) {
this.canvas.setSize(this.width, this.height);
this.drawSpeed();
},

// private, clean up
onDestroy : function() {
clearInterval(this.timer);
this.canvas.clear();

// Ext.destroy(this.bgImg, this.labelEl, this.innerEl);
Ext.destroy(this.innerEl);

// Call superclass
Ext.ux.Speed.superclass.onDestroy.apply(this, arguments);
}
});

// Register the xtype for lazy rendering support
Ext.reg('ux.speed', Ext.ux.Speed);



This is how I've used it (build an array of fit-panels containing each of them a speedometer and adds these small panels to a table-panel):

var v_arSpeed = [];
for (i=0; i < pRecs.length; i++){
v_arSpeed[i] = new Ext.Panel({
layout: 'fit',
items:[
new Ext.ux.Speed({
width: 200,
height: 100,
minVal: pRecs[i].get("MIN_VAL"),
maxVal: pRecs[i].get("MAX_VAL"),
minOpt: pRecs[i].get("MIN_OPT"),
maxOpt: pRecs[i].get("MAX_OPT"),
currVal: pRecs[i].get("CRT_VAL"),
label: pRecs[i].get("KPI_DESC")
})
]
})
}
this.add(v_arSpeed);
this.doLayout();

The data is coming from a json:

{ "rows":[
{"CRT_VAL":"45","KPI_CODE":"EFF","KPI_DESC":"Efficiency","MAX_OPT":"90","MAX_VAL":"100","MIN_OPT":"70","MIN_VAL":"0"
},
{"CRT_VAL":"68","KPI_CODE":"KPI1","KPI_DESC":"Another KPI","MAX_OPT":"66","MAX_VAL":"100","MIN_OPT":"33","MIN_VAL":"0"
},
{"CRT_VAL":"40","KPI_CODE":"KPI2","KPI_DESC":"And another one","MAX_OPT":"90","MAX_VAL":"100","MIN_OPT":"30","MIN_VAL":"0"
}]}


And this is the output:

http://www.imageurlhost.com/images/js7cvloakhoo891u6n0g.png