RGraph = window.RGraph || {isRGraph:
true
};
RGraph.Odometer =
function
(conf)
{
if
(
typeof
conf === 'object
'
&& typeof conf.value !== '
undefined
'
&& typeof conf.id === '
string
') {
var id = conf.id
var canvas = document.getElementById(id);
var min = conf.min;
var max = conf.max;
var value = conf.value;
var parseConfObjectForOptions = true; // Set this so the config is parsed (at the end of the constructor)
} else {
var id = conf;
var canvas = document.getElementById(id);
var min = arguments[1];
var max = arguments[2];
var value = arguments[3];
}
this.id = id;
this.canvas = canvas;
this.context = this.canvas.getContext ? this.canvas.getContext("2d", {alpha: (typeof id === '
object
' && id.alpha === false) ? false : true}) : null;
this.canvas.__object__ = this;
this.type = '
odo
';
this.isRGraph = true;
this.min = RGraph.stringsToNumbers(min);
this.max = RGraph.stringsToNumbers(max);
this.value = RGraph.stringsToNumbers(value);
this.currentValue = null;
this.uid = RGraph.CreateUID();
this.canvas.uid = this.canvas.uid ? this.canvas.uid : RGraph.CreateUID();
this.colorsParsed = false;
this.coordsText = [];
this.original_colors = [];
this.firstDraw = true; // After the first draw this will be false
/**
* Compatibility with older browsers
*/
//RGraph.OldBrowserCompat(this.context);
this.properties =
{
'
chart.background.border
': '
black
',
'
chart.background.color
': '
#eee',
'chart.background.lines.color
': '
#ddd',
'chart.centerx
': null,
'
chart.centery
': null,
'
chart.radius
': null,
'
chart.value.text
': false,
'
chart.value.text.decimals
': 0,
'
chart.needle.color
': '
black
',
'
chart.needle.width
': 2,
'
chart.needle.head
': true,
'
chart.needle.tail
': true,
'
chart.needle.type
': '
pointer
',
'
chart.needle.extra
': [],
'
chart.needle.triangle.border
': '
#aaa',
'chart.text.size
': 12,
'
chart.text.color
': '
black
',
'
chart.text.font
': '
Segoe UI, Arial, Verdana, sans-serif
',
'
chart.text.accessible
': false,
'
chart.text.accessible.overflow
': '
visible
',
'
chart.text.accessible.pointerevents
': true,
'
chart.green.max
': max * 0.75,
'
chart.red.min
': max * 0.9,
'
chart.green.color
': '
Gradient(white:
#0c0)',
'chart.yellow.color
': '
Gradient(white:
#ff0)',
'chart.red.color
': '
Gradient(white:
#f00)',
'chart.label.area
': 35,
'
chart.gutter.left
': 25,
'
chart.gutter.right
': 25,
'
chart.gutter.top
': 25,
'
chart.gutter.bottom
': 25,
'
chart.title
': '
',
'
chart.title.background
': null,
'
chart.title.hpos
': null,
'
chart.title.vpos
': null,
'
chart.title.font
': null,
'
chart.title.bold
': true,
'
chart.title.x
': null,
'
chart.title.y
': null,
'
chart.title.halign
': null,
'
chart.title.valign
': null,
'
chart.contextmenu
': null,
'
chart.linewidth
': 1,
'
chart.shadow.inner
': false,
'
chart.shadow.inner.color
': '
black
',
'
chart.shadow.inner.offsetx
': 3,
'
chart.shadow.inner.offsety
': 3,
'
chart.shadow.inner.blur
': 6,
'
chart.shadow.outer
': false,
'
chart.shadow.outer.color
': '
black
',
'
chart.shadow.outer.offsetx
': 3,
'
chart.shadow.outer.offsety
': 3,
'
chart.shadow.outer.blur
': 6,
'
chart.annotatable
': false,
'
chart.annotate.color
': '
black
',
'
chart.scale.decimals
': 0,
'
chart.scale.point
': '
.
',
'
chart.scale.thousand
': '
,
',
'
chart.zoom.factor
': 1.5,
'
chart.zoom.fade.
in
': true,
'
chart.zoom.fade.out
': true,
'
chart.zoom.hdir
': '
right
',
'
chart.zoom.vdir
': '
down
',
'
chart.zoom.frames
': 25,
'
chart.zoom.delay
': 16.666,
'
chart.zoom.shadow
': true,
'
chart.zoom.background
': true,
'
chart.zoom.action
': '
zoom
',
'
chart.resizable
': false,
'
chart.resize.handle.adjust
': [0,0],
'
chart.resize.handle.background
': null,
'
chart.units.pre
': '
',
'
chart.units.post
': '
',
'
chart.border
': false,
'
chart.border.color1
': '
#BEBCB0',
'chart.border.color2
': '
#F0EFEA',
'chart.border.color3
': '
#BEBCB0',
'chart.tickmarks
': true,
'
chart.tickmarks.highlighted
': false,
'
chart.tickmarks.big.color
': '
#999',
'chart.zerostart
': false,
'
chart.labels
': null,
'
chart.units.pre
': '
',
'
chart.units.post
': '
',
'
chart.value.units.pre
': '
',
'
chart.value.units.post
': '
',
'
chart.key
': null,
'
chart.key.background
': '
white
',
'
chart.key.position
': '
graph
',
'
chart.key.shadow
': false,
'
chart.key.shadow.color
': '
#666',
'chart.key.shadow.blur
': 3,
'
chart.key.shadow.offsetx
': 2,
'
chart.key.shadow.offsety
': 2,
'
chart.key.position.gutter.boxed
':false,
'
chart.key.position.x
': null,
'
chart.key.position.y
': null,
'
chart.key.halign
': '
right
',
'
chart.key.color.shape
': '
square
',
'
chart.key.rounded
': true,
'
chart.key.text.size
': 10,
'
chart.key.colors
': null,
'
chart.key.text.color
': '
black
',
'
chart.adjustable
': false,
'
chart.clearto
': '
rgba(0,0,0,0)
'
}
/*
* Translate half a pixel for antialiasing purposes - but only if it hasn'
t beeen
* done already
*/
if
(!
this
.canvas.__rgraph_aa_translated__) {
this
.context.translate(0.5,0.5);
this
.canvas.__rgraph_aa_translated__ =
true
;
}
var
RG = RGraph,
ca =
this
.canvas,
co = ca.getContext(
'2d'
),
prop =
this
.properties,
pa2 = RG.path2,
win = window,
doc = document,
ma = Math
if
(RG.Effects &&
typeof
RG.Effects.decorate ===
'function'
) {
RG.Effects.decorate(
this
);
}
this
.set =
this
.Set =
function
(name, value)
{
var
value = arguments[1] ||
null
;
if
(arguments.length === 1 &&
typeof
name === 'object
') {
RG.parseObjectStyleConfig(this, name);
return this;
}
/**
* This should be done first - prepend the property name with "chart." if necessary
*/
if (name.substr(0,6) != '
chart.
') {
name = '
chart.
' + name;
}
// Convert uppercase letters to dot+lower case letter
while(name.match(/([A-Z])/)) {
name = name.replace(/([A-Z])/, '
.
' + RegExp.$1.toLowerCase());
}
if (name == '
chart.needle.style
') {
alert('
[RGRAPH] The RGraph property chart.needle.style has changed to chart.needle.color
');
}
if (name == '
chart.needle.thickness
') {
name = '
chart.needle.width
';
}
if (name == '
chart.value
') {
this.value = value;
return;
}
prop[name] = value;
return this;
};
/**
* A getter
*
* @param name string The name of the property to get
*/
this.get =
this.Get = function (name)
{
/**
* This should be done first - prepend the property name with "chart." if necessary
*/
if (name.substr(0,6) != '
chart.
') {
name = '
chart.
' + name;
}
// Convert uppercase letters to dot+lower case letter
while(name.match(/([A-Z])/)) {
name = name.replace(/([A-Z])/, '
.
' + RegExp.$1.toLowerCase());
}
if (name == '
chart.value
') {
return this.value;
}
return prop[name.toLowerCase()];
};
/**
* Draws the odometer
*/
this.draw =
this.Draw = function ()
{
/**
* Fire the onbeforedraw event
*/
RG.FireCustomEvent(this, '
onbeforedraw
');
/**
* Set the current value
*/
this.currentValue = this.value;
/**
* No longer allow values outside the range of the Odo
*/
if (this.value > this.max) {
this.value = this.max;
}
if (this.value < this.min) {
this.value = this.min;
}
/**
* This is new in May 2011 and facilitates indiviual gutter settings,
* eg chart.gutter.left
*/
this.gutterLeft = prop['
chart.gutter.left
'];
this.gutterRight = prop['
chart.gutter.right
'];
this.gutterTop = prop['
chart.gutter.top
'];
this.gutterBottom = prop['
chart.gutter.bottom
'];
// Work out a few things
this.radius = Math.min(
(ca.width - this.gutterLeft - this.gutterRight) / 2,
(ca.height - this.gutterTop - this.gutterBottom) / 2
)
- (prop['
chart.border
'] ? 25 : 0);
this.diameter = 2 * this.radius;
this.centerx = ((ca.width - this.gutterLeft- this.gutterRight) / 2) + this.gutterLeft;
this.centery = ((ca.height - this.gutterTop - this.gutterBottom) / 2) + this.gutterTop;
this.range = this.max - this.min;
this.coordsText = [];
/**
* Move the centerx if the key is defined
*/
if (prop['
chart.key
'] && prop['
chart.key
'].length > 0 && ca.width > ca.height) this.centerx = 5 + this.radius;
if (typeof(prop['
chart.centerx
']) == '
number
') this.centerx = prop['
chart.centerx
'];
if (typeof(prop['
chart.centery
']) == '
number
') this.centery = prop['
chart.centery
'];
/**
* Allow custom setting of the radius
*/
if (typeof(prop['
chart.radius
']) == '
number
') {
this.radius = prop['
chart.radius
'];
if (prop['
chart.border
']) {
this.radius -= 25;
}
}
/**
* Parse the colors for gradients. Its down here so that the center X/Y can be used
*/
if (!this.colorsParsed) {
this.parseColors();
// Don'
t want to
do
this
again
this
.colorsParsed =
true
;
}
co.lineWidth = prop[
'chart.linewidth'
];
this
.DrawBackground();
this
.DrawLabels();
this
.DrawNeedle(
this
.value, prop[
'chart.needle.color'
]);
if
(prop[
'chart.needle.extra'
].length > 0) {
for
(
var
i=0; i<prop[
'chart.needle.extra'
].length; ++i) {
var
needle = prop[
'chart.needle.extra'
][i];
this
.DrawNeedle(needle[0], needle[1], needle[2]);
}
}
if
(prop[
'chart.key'
] && prop[
'chart.key'
].length > 0) {
var
colors = [prop[
'chart.needle.color'
]];
if
(prop[
'chart.needle.extra'
].length > 0) {
for
(
var
i=0; i<prop[
'chart.needle.extra'
].length; ++i) {
var
needle = prop[
'chart.needle.extra'
][i];
colors.push(needle[1]);
}
}
RG.DrawKey(
this
, prop[
'chart.key'
], colors);
}
if
(prop[
'chart.contextmenu'
]) {
RG.ShowContext(
this
);
}
if
(prop[
'chart.resizable'
]) {
RG.AllowResizing(
this
);
}
RG.InstallEventListeners(
this
);
if
(
this
.firstDraw) {
this
.firstDraw =
false
;
RG.fireCustomEvent(
this
,
'onfirstdraw'
);
this
.firstDrawFunc();
}
RG.FireCustomEvent(
this
,
'ondraw'
);
return
this
;
};
this
.exec =
function
(func)
{
func(
this
);
return
this
;
};
this
.drawBackground =
this
.DrawBackground =
function
()
{
co.beginPath();
if
(prop[
'chart.shadow.outer'
]) {
RG.setShadow(
this
, prop[
'chart.shadow.outer.color'
], prop[
'chart.shadow.outer.offsetx'
], prop[
'chart.shadow.outer.offsety'
], prop[
'chart.shadow.outer.blur'
]);
}
var
backgroundColor = prop[
'chart.background.color'
];
co.fillStyle = backgroundColor;
co.arc(
this
.centerx,
this
.centery,
this
.radius, 0.0001, RG.TWOPI,
false
);
co.fill();
RG.noShadow(
this
);
co.strokeStyle =
'#666'
;
co.arc(
this
.centerx,
this
.centery,
this
.radius, 0, RG.TWOPI,
false
);
co.fillStyle = backgroundColor;
co.arc(
this
.centerx,
this
.centery,
this
.radius, 0, RG.TWOPI,
false
);
co.fill();
if
(prop[
'chart.tickmarks'
]) {
co.beginPath();
co.strokeStyle =
'#bbb'
;
for
(
var
i=0; i<=360; i+=3) {
co.arc(
this
.centerx,
this
.centery,
this
.radius, 0, i / 57.3,
false
);
co.lineTo(
this
.centerx,
this
.centery);
}
co.stroke();
}
co.beginPath();
co.lineWidth = 1;
co.strokeStyle =
'black'
;
co.fillStyle = backgroundColor;
co.strokeStyle = backgroundColor;
co.arc(
this
.centerx,
this
.centery,
this
.radius - 5, 0, RG.TWOPI,
false
);
co.fill();
co.stroke();
co.beginPath();
co.strokeStyle = prop[
'chart.background.lines.color'
];
for
(
var
i=0; i<360; i+=18) {
co.arc(
this
.centerx,
this
.centery,
this
.radius, 0, RG.degrees2Radians(i),
false
);
co.lineTo(
this
.centerx,
this
.centery);
}
co.stroke();
co.beginPath();
co.strokeStyle = prop[
'chart.background.border'
];
co.arc(
this
.centerx,
this
.centery,
this
.radius, 0, RG.TWOPI,
false
);
co.stroke();
if
(prop[
'chart.shadow.inner'
]) {
co.beginPath();
RG.SetShadow(
this
, prop[
'chart.shadow.inner.color'
], prop[
'chart.shadow.inner.offsetx'
], prop[
'chart.shadow.inner.offsety'
], prop[
'chart.shadow.inner.blur'
]);
co.arc(
this
.centerx,
this
.centery,
this
.radius - prop[
'chart.label.area'
], 0, RG.TWOPI, 0);
co.fill();
co.stroke();
RG.NoShadow(
this
);
}
var
greengrad = prop[
'chart.green.color'
];
if
(prop[
'chart.tickmarks.highlighted'
]) {
co.beginPath();
co.lineWidth = 5;
co.strokeStyle = greengrad;
co.arc(
this
.centerx,
this
.centery,
this
.radius - 2.5,
-1 * RG.HALFPI,
(((prop[
'chart.green.max'
] -
this
.min)/ (
this
.max -
this
.min)) * RG.TWOPI) - RG.HALFPI,
0);
co.stroke();
co.lineWidth = 1;
}
co.beginPath();
co.fillStyle = greengrad;
co.arc(
this
.centerx,
this
.centery,
this
.radius - prop[
'chart.label.area'
],
0 - RG.HALFPI,
(((prop[
'chart.green.max'
] -
this
.min)/ (
this
.max -
this
.min)) * RG.TWOPI) - RG.HALFPI,
false
);
co.lineTo(
this
.centerx,
this
.centery);
co.closePath();
co.fill();
var
yellowgrad = prop[
'chart.yellow.color'
];
if
(prop[
'chart.tickmarks.highlighted'
]) {
co.beginPath();
co.lineWidth = 5;
co.strokeStyle = yellowgrad;
co.arc(
this
.centerx,
this
.centery,
this
.radius - 2.5, (
((prop[
'chart.green.max'
] -
this
.min) / (
this
.max -
this
.min)) * RG.TWOPI) - RG.HALFPI,
(((prop[
'chart.red.min'
] -
this
.min) / (
this
.max -
this
.min)) * RG.TWOPI) - RG.HALFPI,
0);
co.stroke();
co.lineWidth = 1;
}
co.beginPath();
co.fillStyle = yellowgrad;
co.arc(
this
.centerx,
this
.centery,
this
.radius - prop[
'chart.label.area'
],
( ((prop[
'chart.green.max'
] -
this
.min) / (
this
.max -
this
.min)) * RG.TWOPI) - RG.HALFPI,
( ((prop[
'chart.red.min'
] -
this
.min) / (
this
.max -
this
.min)) * RG.TWOPI) - RG.HALFPI,
false
);
co.lineTo(
this
.centerx,
this
.centery);
co.closePath();
co.fill();
var
redgrad = prop[
'chart.red.color'
];
if
(prop[
'chart.tickmarks.highlighted'
]) {
co.beginPath();
co.lineWidth = 5;
co.strokeStyle = redgrad;
co.arc(
this
.centerx,
this
.centery,
this
.radius - 2.5,(((prop[
'chart.red.min'
] -
this
.min) / (
this
.max -
this
.min)) * RG.TWOPI) - RG.HALFPI,RG.TWOPI - RG.HALFPI,0);
co.stroke();
co.lineWidth = 1;
}
co.beginPath();
co.fillStyle = redgrad;
co.strokeStyle = redgrad;
co.arc(
this
.centerx,
this
.centery,
this
.radius - prop[
'chart.label.area'
],
(((prop[
'chart.red.min'
] -
this
.min) / (
this
.max -
this
.min)) * RG.TWOPI) - RG.HALFPI,
RG.TWOPI - RG.HALFPI,
false
);
co.lineTo(
this
.centerx,
this
.centery);
co.closePath();
co.fill();
if
(prop[
'chart.border'
]) {
var
grad = co.createRadialGradient(
this
.centerx,
this
.centery,
this
.radius,
this
.centerx,
this
.centery,
this
.radius + 20);
grad.addColorStop(0, prop[
'chart.border.color1'
]);
grad.addColorStop(0.5, prop[
'chart.border.color2'
]);
grad.addColorStop(1, prop[
'chart.border.color3'
]);
co.beginPath();
co.fillStyle = grad;
co.strokeStyle =
'rgba(0,0,0,0)'
co.lineWidth = 0.001;
co.arc(
this
.centerx,
this
.centery,
this
.radius + 20, 0, RG.TWOPI, 0);
co.arc(
this
.centerx,
this
.centery,
this
.radius - 2, RG.TWOPI, 0, 1);
co.fill();
}
co.lineWidth = prop[
'chart.linewidth'
];
if
(prop[
'chart.title'
]) {
RG.DrawTitle(
this
,
prop[
'chart.title'
],
this
.centery -
this
.radius,
null
,
prop[
'chart.title.size'
] ? prop[
'chart.title.size'
] : prop[
'chart.text.size'
] + 2);
}
if
(!prop[
'chart.tickmarks.highlighted'
]) {
for
(
var
i=18; i<=360; i+=36) {
co.beginPath();
co.strokeStyle = prop[
'chart.tickmarks.big.color'
];
co.lineWidth = 2;
co.arc(
this
.centerx,
this
.centery,
this
.radius - 1, RG.degrees2Radians(i), RG.degrees2Radians(i+0.01),
false
);
co.arc(
this
.centerx,
this
.centery,
this
.radius - 7, RG.degrees2Radians(i), RG.degrees2Radians(i+0.01),
false
);
co.stroke();
}
}
};
this
.drawNeedle =
this
.DrawNeedle =
function
(value, color)
{
var
length = arguments[2] ? arguments[2] :
this
.radius - prop[
'chart.label.area'
];
co.fillStyle =
'#999'
;
co.beginPath();
co.moveTo(
this
.centerx,
this
.centery);
co.arc(
this
.centerx,
this
.centery, 10, 0, RG.TWOPI,
false
);
co.fill();
co.closePath();
co.fill();
co.fillStyle = color
co.strokeStyle =
'#666'
;
co.beginPath();
co.moveTo(
this
.centerx,
this
.centery);
co.arc(
this
.centerx,
this
.centery, 8, 0, RG.TWOPI,
false
);
co.fill();
co.closePath();
co.stroke();
co.fill();
if
(prop[
'chart.needle.type'
] ==
'pointer'
) {
co.strokeStyle = color;
co.lineWidth = prop[
'chart.needle.width'
];
co.lineCap =
'round'
;
co.lineJoin =
'round'
;
co.beginPath();
co.beginPath();
co.moveTo(
this
.centerx,
this
.centery);
if
(prop[
'chart.needle.tail'
]) {
co.arc(
this
.centerx,
this
.centery,
20,
(((value /
this
.range) * 360) + 90) / (180 / RG.PI),
(((value /
this
.range) * 360) + 90 + 0.01) / (180 / RG.PI),
false
);
}
co.arc(
this
.centerx,
this
.centery,
length - 10,
(((value /
this
.range) * 360) - 90) / (180 / RG.PI),
(((value /
this
.range) * 360) - 90 + 0.1 ) / (180 / RG.PI),
false
);
co.closePath();
}
else
if
(prop[
'chart.needle.type'
] ==
'triangle'
) {
co.lineWidth = 0.01;
co.lineEnd =
'square'
;
co.lineJoin =
'miter'
;
co.beginPath();
co.fillStyle = prop[
'chart.needle.triangle.border'
];
co.arc(
this
.centerx,
this
.centery, 11, (((value /
this
.range) * 360)) / 57.3, ((((value /
this
.range) * 360)) + 0.01) / 57.3, 0);
co.arc(
this
.centerx,
this
.centery, 11, (((value /
this
.range) * 360) + 180) / 57.3, ((((value /
this
.range) * 360) + 180) + 0.01)/ 57.3, 0);
co.arc(
this
.centerx,
this
.centery, length - 5, (((value /
this
.range) * 360) - 90) / 57.3, ((((value /
this
.range) * 360) - 90) / 57.3) + 0.01, 0);
co.closePath();
co.fill();
co.beginPath();
co.arc(
this
.centerx,
this
.centery, 15, 0, RG.TWOPI, 0);
co.closePath();
co.fill();
co.beginPath();
co.strokeStyle =
'black'
;
co.fillStyle = color;
co.arc(
this
.centerx,
this
.centery, 7, (((value /
this
.range) * 360)) / 57.3, ((((value /
this
.range) * 360)) + 0.01) / 57.3, 0);
co.arc(
this
.centerx,
this
.centery, 7, (((value /
this
.range) * 360) + 180) / 57.3, ((((value /
this
.range) * 360) + 180) + 0.01)/ 57.3, 0);
co.arc(
this
.centerx,
this
.centery, length - 13, (((value /
this
.range) * 360) - 90) / 57.3, ((((value /
this
.range) * 360) - 90) / 57.3) + 0.01, 0);
co.closePath();
co.stroke();
co.fill();
co.beginPath();
co.arc(
this
.centerx,
this
.centery, 7, 0, RG.TWOPI, 0);
co.closePath();
co.fill();
}
co.stroke();
co.fill();
co.beginPath();
co.fillStyle = color;
co.arc(
this
.centerx,
this
.centery, prop[
'chart.needle.type'
] ==
'pointer'
? 7 : 12, 0.01, RG.TWOPI,
false
);
co.fill();
if
(prop[
'chart.needle.head'
] && prop[
'chart.needle.type'
] ==
'pointer'
) {
co.lineWidth = 1;
co.fillStyle = color;
co.lineJoin =
'miter'
;
co.lineCap =
'butt'
;
co.beginPath();
co.arc(
this
.centerx,
this
.centery, length - 5, (((value /
this
.range) * 360) - 90) / 57.3, (((value /
this
.range) * 360) - 90 + 0.1) / 57.3,
false
);
co.arc(
this
.centerx,
this
.centery,
length - 20,
RG.degrees2Radians( ((value /
this
.range) * 360) - (length < 60 ? 80 : 85) ),
RG.degrees2Radians( ((value /
this
.range) * 360) - (length < 60 ? 100 : 95) ),
1);
co.closePath();
co.fill();
}
co.beginPath();
co.fillStyle =
'gray'
;
co.moveTo(
this
.centerx,
this
.centery);
co.arc(
this
.centerx,
this
.centery,2,0,6.2795,
false
);
co.closePath();
co.fill();
};
this
.drawLabels =
this
.DrawLabels =
function
()
{
var
size = prop[
'chart.text.size'
];
var
font = prop[
'chart.text.font'
];
var
centerx =
this
.centerx;
var
centery =
this
.centery;
var
r =
this
.radius - (prop[
'chart.label.area'
] / 2);
var
start =
this
.min;
var
end =
this
.max;
var
decimals = prop[
'chart.scale.decimals'
];
var
labels = prop[
'chart.labels'
];
var
units_pre = prop[
'chart.units.pre'
];
var
units_post = prop[
'chart.units.post'
];
co.beginPath();
co.fillStyle = prop[
'chart.text.color'
];
if
(labels) {
for
(
var
i=0; i<labels.length; ++i) {
RG.Text2(
this
, {
'font'
:font,
'size'
:size,
'x'
:centerx + (Math.cos(((i / labels.length) * RG.TWOPI) - RG.HALFPI) * (
this
.radius - (prop[
'chart.label.area'
] / 2) ) ),
'y'
:centery + (Math.sin(((i / labels.length) * RG.TWOPI) - RG.HALFPI) * (
this
.radius - (prop[
'chart.label.area'
] / 2) ) ),
'text'
: String(labels[i]),
'valign'
:
'center'
,
'halign'
:
'center'
,
'tag'
:
'labels'
});
}
}
else
{
RG.Text2(
this
, {
'font'
:font,
'size'
:size,
'x'
:centerx + (0.588 * r ),
'y'
:centery - (0.809 * r ),
'text'
:RG.number_format(
this
, (((end - start) * (1/10)) + start).toFixed(decimals), units_pre, units_post),
'halign'
:
'center'
,
'valign'
:
'center'
,
'angle'
:36,
'tag'
:
'scale'
});
RG.Text2(
this
, {
'font'
:font,
'size'
:size,
'x'
:centerx + (0.951 * r ),
'y'
:centery - (0.309 * r),
'text'
:RG.number_format(
this
, (((end - start) * (2/10)) + start).toFixed(decimals), units_pre, units_post),
'halign'
:
'center'
,
'valign'
:
'center'
,
'angle'
:72,
'tag'
:
'scale'
});
RG.Text2(
this
, {
'font'
:font,
'size'
:size,
'x'
:centerx + (0.949 * r),
'y'
:centery + (0.31 * r),
'text'
:RG.number_format(
this
, (((end - start) * (3/10)) + start).toFixed(decimals), units_pre, units_post),
'halign'
:
'center'
,
'valign'
:
'center'
,
'angle'
:108,
'tag'
:
'scale'
});
RG.Text2(
this
, {
'font'
:font,
'size'
:size,
'x'
:centerx + (0.588 * r ),
'y'
:centery + (0.809 * r ),
'text'
:RG.number_format(
this
, (((end - start) * (4/10)) + start).toFixed(decimals), units_pre, units_post),
'halign'
:
'center'
,
'valign'
:
'center'
,
'angle'
:144,
'tag'
:
'scale'
});
RG.Text2(
this
, {
'font'
:font,
'size'
:size,
'x'
:centerx,
'y'
:centery + r,
'text'
:RG.number_format(
this
, (((end - start) * (5/10)) + start).toFixed(decimals),units_pre, units_post),
'halign'
:
'center'
,
'valign'
:
'center'
,
'angle'
:180,
'tag'
:
'scale'
});
RG.Text2(
this
, {
'font'
:font,
'size'
:size,
'x'
:centerx - (0.588 * r ),
'y'
:centery + (0.809 * r ),
'text'
:RG.number_format(
this
, (((end - start) * (6/10)) + start).toFixed(decimals), units_pre, units_post),
'halign'
:
'center'
,
'valign'
:
'center'
,
'angle'
:216,
'tag'
:
'scale'
});
RG.Text2(
this
, {
'font'
:font,
'size'
:size,
'x'
:centerx - (0.949 * r),
'y'
:centery + (0.300 * r),
'text'
:RG.number_format(
this
, (((end - start) * (7/10)) + start).toFixed(decimals), units_pre, units_post),
'halign'
:
'center'
,
'valign'
:
'center'
,
'angle'
:252,
'tag'
:
'scale'
});
RG.Text2(
this
, {
'font'
:font,
'size'
:size,
'x'
:centerx - (0.951 * r),
'y'
:centery - (0.309 * r),
'text'
:RG.number_format(
this
, (((end - start) * (8/10)) + start).toFixed(decimals), units_pre, units_post),
'halign'
:
'center'
,
'valign'
:
'center'
,
'angle'
:288,
'tag'
:
'scale'
});
RG.Text2(
this
, {
'font'
:font,
'size'
:size,
'x'
:centerx - (0.588 * r ),
'y'
:centery - (0.809 * r ),
'text'
:RG.number_format(
this
, (((end - start) * (9/10)) + start).toFixed(decimals), units_pre, units_post),
'halign'
:
'center'
,
'valign'
:
'center'
,
'angle'
:324,
'tag'
:
'scale'
});
RG.Text2(
this
, {
'font'
:font,
'size'
:size,
'x'
:centerx,
'y'
:centery - r,
'text'
: prop[
'chart.zerostart'
] ? RG.number_format(
this
,
this
.min.toFixed(decimals), units_pre, units_post) : RG.number_format(
this
, (((end - start) * (10/10)) + start).toFixed(decimals), units_pre, units_post),
'halign'
:
'center'
,
'valign'
:
'center'
,
'tag'
:
'scale'
});
}
co.fill();
if
(prop[
'chart.value.text'
]) {
co.strokeStyle =
'black'
;
RG.Text2(
this
, {
'font'
:font,
'size'
:size+2,
'x'
:centerx,
'y'
:centery + size + 15,
'text'
:String(prop[
'chart.value.units.pre'
] +
this
.value.toFixed(prop[
'chart.value.text.decimals'
]) + prop[
'chart.value.units.post'
]),
'halign'
:
'center'
,
'valign'
:
'center'
,
'bounding'
:
true
,
'boundingFill'
:
'white'
,
'tag'
:
'value.text'
});
}
};
this
.getShape =
function
(e) {};
this
.getValue =
function
(e)
{
var
mouseXY = RG.getMouseXY(e)
var
angle = RG.getAngleByXY(
this
.centerx,
this
.centery, mouseXY[0], mouseXY[1]);
angle += RG.HALFPI;
if
(mouseXY[0] >=
this
.centerx && mouseXY[1] <=
this
.centery) {
angle -= RG.TWOPI;
}
var
value = ((angle / RG.TWOPI) * (
this
.max -
this
.min)) +
this
.min;
return
value;
};
this
.getObjectByXY =
function
(e)
{
var
mouseXY = RG.getMouseXY(e);
var
radius = RG.getHypLength(
this
.centerx,
this
.centery, mouseXY[0], mouseXY[1]);
if
(
mouseXY[0] > (
this
.centerx -
this
.radius)
&& mouseXY[0] < (
this
.centerx +
this
.radius)
&& mouseXY[1] > (
this
.centery -
this
.radius)
&& mouseXY[1] < (
this
.centery +
this
.radius)
&& radius <=
this
.radius
) {
return
this
;
}
};
this
.adjusting_mousemove =
this
.Adjusting_mousemove =
function
(e)
{
if
(prop['chart.adjustable
'] && RG.Registry.Get('
chart.adjusting
') && RG.Registry.Get('
chart.adjusting
').uid == this.uid) {
this.value = this.getValue(e);
RG.clear(ca);
RG.redrawCanvas(ca);
RG.fireCustomEvent(this, '
onadjust
');
}
};
/**
* This method returns the appropriate angle for a value
*
* @param number value The value
*/
this.getAngle = function (value)
{
// Higher than max or lower than min
if (value > this.max || value < this.min) {
return null;
}
var angle = (((value - this.min) / (this.max - this.min)) * RG.TWOPI);
angle -= RG.HALFPI;
return angle;
};
/**
* This allows for easy specification of gradients
*/
this.parseColors = function ()
{
// Save the original colors so that they can be restored when the canvas is reset
if (this.original_colors.length === 0) {
this.original_colors['
chart.green.color
'] = RG.array_clone(prop['
chart.green.color
']);
this.original_colors['
chart.yellow.color
'] = RG.array_clone(prop['
chart.yellow.color
']);
this.original_colors['
chart.red.color
'] = RG.array_clone(prop['
chart.red.color
']);
}
// Parse the basic colors
prop['
chart.green.color
'] = this.parseSingleColorForGradient(prop['
chart.green.color
']);
prop['
chart.yellow.color
'] = this.parseSingleColorForGradient(prop['
chart.yellow.color
']);
prop['
chart.red.color
'] = this.parseSingleColorForGradient(prop['
chart.red.color
']);
};
/**
* Use this function to reset the object to the post-constructor state. Eg reset colors if
* need be etc
*/
this.reset = function ()
{
};
/**
* This parses a single color value
*/
this.parseSingleColorForGradient = function (color)
{
if (!color || typeof(color) != '
string
') {
return color;
}
if (color.match(/^gradient\((.*)\)$/i)) {
var parts = RegExp.$1.split('
:
');
// Create the gradient
var grad = co.createRadialGradient(this.centerx, this.centery, 0, this.centerx, this.centery, this.radius);
var diff = 1 / (parts.length - 1);
grad.addColorStop(0, RG.trim(parts[0]));
for (var j=1; j<parts.length; ++j) {
grad.addColorStop(j * diff, RG.trim(parts[j]));
}
}
return grad ? grad : color;
};
/**
* Using a function to add events makes it easier to facilitate method chaining
*
* @param string type The type of even to add
* @param function func
*/
this.on = function (type, func)
{
if (type.substr(0,2) !== '
on
') {
type = '
on
' + type;
}
if (typeof this[type] !== '
function
') {
this[type] = func;
} else {
RG.addCustomEventListener(this, type, func);
}
return this;
};
/**
* This function runs once only
* (put at the end of the file (before any effects))
*/
this.firstDrawFunc = function ()
{
};
/**
* Odo Grow
*
* This effect gradually increases the represented value
*
* @param An object of effect properties - eg: {frames: 30}
* @param function An optional callback function
*/
this.grow = function ()
{
var obj = this;
var opt = arguments[0] || {};
var frames = opt.frames || 30;
var frame = 0;
var current = obj.currentValue || 0;
var origValue = Number(obj.currentValue);
var newValue = obj.value;
var diff = newValue - origValue;
var step = (diff / frames);
var callback = arguments[1] || function () {};
function iterator ()
{
obj.value = origValue + (frame * step);
RG.clear(obj.canvas);
RG.redrawCanvas(obj.canvas);
if (frame++ < frames) {
RG.Effects.updateCanvas(iterator);
} else {
callback(obj);
}
}
iterator();
return this;
};
RG.att(ca);
/**
* Register the object
*/
RG.register(this);
/**
* This is the '
end' of the constructor so
if
the first argument
* contains configuration data - handle that.
*/
if
(parseConfObjectForOptions) {
RG.parseObjectStyleConfig(
this
, conf.options);
}
};