summaryrefslogtreecommitdiff
path: root/js/dojo-1.7.2/dojox/gauges/AnalogGauge.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/dojo-1.7.2/dojox/gauges/AnalogGauge.js')
-rw-r--r--js/dojo-1.7.2/dojox/gauges/AnalogGauge.js369
1 files changed, 369 insertions, 0 deletions
diff --git a/js/dojo-1.7.2/dojox/gauges/AnalogGauge.js b/js/dojo-1.7.2/dojox/gauges/AnalogGauge.js
new file mode 100644
index 0000000..2024615
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/gauges/AnalogGauge.js
@@ -0,0 +1,369 @@
+//>>built
+define("dojox/gauges/AnalogGauge", ["dojo/_base/kernel","dojo/_base/declare","dojo/_base/array","dojo/_base/lang","dojo/_base/html","dojo/_base/event",
+ "dojox/gfx", "./_Gauge","./AnalogLineIndicator", "dojo/dom-geometry"],
+ function(dojo, declare, arr, lang, html, event,
+ gfx, Gauge, AnalogLineIndicator, domGeometry) {
+
+/*=====
+ Gauge = dojox.gauges._Gauge;
+=====*/
+
+return declare("dojox.gauges.AnalogGauge",Gauge,{
+ // summary:
+ // a gauge built using the dojox.gfx package.
+ //
+ // description:
+ // using dojo.gfx (and thus either SVG or VML based on what is supported), this widget
+ // builds a gauge component, used to display numerical data in a familiar format
+ //
+ // example:
+ // | <script type="text/javascript">
+ // | require(["dojox/gauges/AnalogGauge"]);
+ // | </script>
+ // |
+ // | <div dojoType="dojox.gauges.AnalogGauge"
+ // | id="testGauge"
+ // | width="300"
+ // | height="200"
+ // | cx=150
+ // | cy=175
+ // | radius=125
+ // | image="gaugeOverlay.png"
+ // | imageOverlay="false"
+ // | imageWidth="280"
+ // | imageHeight="155"
+ // | imageX="12"
+ // | imageY="38">
+ // | </div>
+
+ // startAngle: Number
+ // angle (in degrees) for start of gauge (default is -90)
+ startAngle: -90,
+
+ // endAngle: Number
+ // angle (in degrees) for end of gauge (default is 90)
+ endAngle: 90,
+
+ // cx: Number
+ // center of gauge x coordinate (default is gauge width / 2)
+ cx: 0,
+
+ // cy: Number
+ // center of gauge x coordinate (default is gauge height / 2)
+ cy: 0,
+
+ // radius: Number
+ // radius of gauge (default is smaller of cx-25 or cy-25)
+ radius: 0,
+
+ // orientation: String
+ // The orientation of the gauge. The value can be 'clockwise' or 'cclockwise' (default is 'clockwise')
+ orientation: "clockwise",
+
+ // _defaultIndicator: dojox.gauges._Indicator
+ // override of dojox.gauges._Gauge._defaultIndicator
+ _defaultIndicator: AnalogLineIndicator,
+
+ startup: function(){
+ // handle settings from HTML by making sure all the options are
+ // converted correctly to numbers and that we calculate defaults
+ // for cx, cy and radius
+ // also connects mouse handling events
+
+ if(this.getChildren){
+ arr.forEach(this.getChildren(), function(child){ child.startup(); });
+ }
+
+ this.startAngle = Number(this.startAngle);
+ this.endAngle = Number(this.endAngle);
+
+ this.cx = Number(this.cx);
+ if(!this.cx){this.cx = this.width/2;}
+ this.cy = Number(this.cy);
+ if(!this.cy){this.cy = this.height/2;}
+ this.radius = Number(this.radius);
+ if(!this.radius){this.radius = Math.min(this.cx,this.cy) - 25;}
+
+
+ this.inherited(arguments);
+ },
+
+ _getAngle: function(/*Number*/value){
+ // summary:
+ // This is a helper function used to determine the angle that represents
+ // a given value on the gauge
+ // value: Number
+ // A value to be converted to an angle for this gauge.
+
+ var v = Number(value);
+ var angle;
+ if (value == null || isNaN(v) || v <= this.min)
+ angle = this._mod360(this.startAngle);
+ else
+ if (v >= this.max)
+ angle = this._mod360(this.endAngle);
+ else {
+ var startAngle = this._mod360(this.startAngle);
+ var relativeValue = (v - this.min);
+ if (this.orientation != 'clockwise')
+ relativeValue = -relativeValue;
+
+ angle = this._mod360(startAngle + this._getAngleRange() * relativeValue / Math.abs(this.min - this.max));
+ }
+
+ return angle;
+ },
+
+ _getValueForAngle: function(/*Number*/angle){
+ // summary:
+ // This is a helper function used to determine the value represented by a
+ // given angle on the gauge
+ // angle: Number
+ // A angle to be converted to a value for this gauge.
+ var startAngle = this._mod360(this.startAngle);
+ var endAngle = this._mod360(this.endAngle);
+
+ if (!this._angleInRange(angle)){
+
+ var min1 = this._mod360(startAngle - angle);
+ var min2 = 360 - min1;
+ var max1 = this._mod360(endAngle - angle);
+ var max2 = 360 - max1;
+ if (Math.min(min1, min2) < Math.min(max1, max2))
+ return this.min;
+ else
+ return this.max;
+ }
+ else {
+ var range = Math.abs(this.max - this.min);
+ var relativeAngle = this._mod360(this.orientation == 'clockwise' ?
+ (angle - startAngle): (-angle + startAngle));
+ return this.min + range * relativeAngle / this._getAngleRange();
+ }
+ },
+
+ _getAngleRange: function(){
+ // summary:
+ // This is a helper function that returns the angle range
+ // from startAngle to endAngle according to orientation.
+ var range;
+ var startAngle = this._mod360(this.startAngle);
+ var endAngle = this._mod360(this.endAngle);
+ if (startAngle == endAngle)
+ return 360;
+ if (this.orientation == 'clockwise'){
+ if (endAngle < startAngle)
+ range = 360 - (startAngle - endAngle);
+ else
+ range = endAngle - startAngle;
+ }
+ else {
+ if (endAngle < startAngle)
+ range = startAngle - endAngle;
+ else
+ range = 360 - (endAngle - startAngle);
+ }
+ return range;
+ },
+
+ _angleInRange: function(value){
+ // summary:
+ // Test if the angle value is in the startAngle/endAngle range
+ var startAngle = this._mod360(this.startAngle);
+ var endAngle = this._mod360(this.endAngle);
+ if (startAngle == endAngle)
+ return true;
+ value = this._mod360(value);
+ if (this.orientation == "clockwise"){
+ if (startAngle < endAngle)
+ return value >= startAngle && value <= endAngle;
+ else
+ return !(value > endAngle && value < startAngle);
+ }
+ else {
+ if (startAngle < endAngle)
+ return !(value > startAngle && value < endAngle);
+ else
+ return value >= endAngle && value <= startAngle;
+ }
+ },
+
+ _isScaleCircular: function(){
+ // summary:
+ // internal method to check if the scale is fully circular
+ return (this._mod360(this.startAngle) == this._mod360(this.endAngle));
+ },
+
+ _mod360:function(v){
+ // summary:
+ // returns the angle between 0 and 360;
+ while (v>360) v = v - 360;
+ while (v<0) v = v + 360;
+ return v;
+ },
+
+ _getRadians: function(/*Number*/angle){
+ // summary:
+ // This is a helper function than converts degrees to radians
+ // angle: Number
+ // An angle, in degrees, to be converted to radians.
+ return angle*Math.PI/180;
+ },
+
+ _getDegrees: function(/*Number*/radians){
+ // summary:
+ // This is a helper function that converts radians to degrees
+ // radians: Number
+ // An angle, in radians, to be converted to degrees.
+ return radians*180/Math.PI;
+ },
+
+
+ drawRange: function(/*dojox.gfx.Group*/ group, /*Object*/range){
+ // summary:
+ // This function is used to draw (or redraw) a range
+ // description:
+ // Draws a range (colored area on the background of the gauge)
+ // based on the given arguments.
+ // group:
+ // The GFX group where the range must be drawn.
+ // range:
+ // A range is a dojox.gauges.Range or an object
+ // with similar parameters (low, high, hover, etc.).
+ var path;
+ if(range.shape){
+ range.shape.parent.remove(range.shape);
+ range.shape = null;
+ }
+ var a1, a2;
+ if((range.low == this.min) && (range.high == this.max) && ((this._mod360(this.endAngle) == this._mod360(this.startAngle)))){
+ path = group.createCircle({cx: this.cx, cy: this.cy, r: this.radius});
+ }else{
+
+
+ a1 = this._getRadians(this._getAngle(range.low));
+ a2 = this._getRadians(this._getAngle(range.high));
+ if (this.orientation == 'cclockwise')
+ {
+ var a = a2;
+ a2 = a1;
+ a1 = a;
+ }
+
+ var x1=this.cx+this.radius*Math.sin(a1),
+ y1=this.cy-this.radius*Math.cos(a1),
+ x2=this.cx+this.radius*Math.sin(a2),
+ y2=this.cy-this.radius*Math.cos(a2),
+ big=0
+ ;
+
+ var arange;
+ if (a1<=a2)
+ arange = a2-a1;
+ else
+ arange = 2*Math.PI-a1+a2;
+ if(arange>Math.PI){big=1;}
+
+ path = group.createPath();
+ if(range.size){
+ path.moveTo(this.cx+(this.radius-range.size)*Math.sin(a1),
+ this.cy-(this.radius-range.size)*Math.cos(a1));
+ }else{
+ path.moveTo(this.cx,this.cy);
+ }
+ path.lineTo(x1,y1);
+ path.arcTo(this.radius,this.radius,0,big,1,x2,y2);
+ if(range.size){
+ path.lineTo(this.cx+(this.radius-range.size)*Math.sin(a2),
+ this.cy-(this.radius-range.size)*Math.cos(a2));
+ path.arcTo((this.radius-range.size),(this.radius-range.size),0,big,0,
+ this.cx+(this.radius-range.size)*Math.sin(a1),
+ this.cy-(this.radius-range.size)*Math.cos(a1));
+ }
+ path.closePath();
+ }
+
+ if(lang.isArray(range.color) || lang.isString(range.color)){
+ path.setStroke({color: range.color});
+ path.setFill(range.color);
+ }else if(range.color.type){
+ // Color is a gradient
+ a1 = this._getRadians(this._getAngle(range.low));
+ a2 = this._getRadians(this._getAngle(range.high));
+ range.color.x1 = this.cx+(this.radius*Math.sin(a1))/2;
+ range.color.x2 = this.cx+(this.radius*Math.sin(a2))/2;
+ range.color.y1 = this.cy-(this.radius*Math.cos(a1))/2;
+ range.color.y2 = this.cy-(this.radius*Math.cos(a2))/2;
+ path.setFill(range.color);
+ path.setStroke({color: range.color.colors[0].color});
+ }else if (gfx.svg){
+ // We've defined a style rather than an explicit color
+ path.setStroke({color: "green"}); // Arbitrary color, just have to indicate
+ path.setFill("green"); // that we want it filled
+ path.getEventSource().setAttribute("class", range.color.style);
+ }
+
+ path.connect("onmouseover", lang.hitch(this, this._handleMouseOverRange, range));
+ path.connect("onmouseout", lang.hitch(this, this._handleMouseOutRange, range));
+
+ range.shape = path;
+ },
+
+ getRangeUnderMouse: function(/*Object*/e){
+ // summary:
+ // Determines which range the mouse is currently over
+ // e: Object
+ // The event object as received by the mouse handling functions below.
+ var range = null,
+ pos = domGeometry.getContentBox(this.gaugeContent),
+ x = e.clientX - pos.x,
+ y = e.clientY - pos.y,
+ r = Math.sqrt((y - this.cy)*(y - this.cy) + (x - this.cx)*(x - this.cx))
+ ;
+ if(r < this.radius){
+ var angle = this._getDegrees(Math.atan2(y - this.cy, x - this.cx) + Math.PI/2),
+ //if(angle > this.endAngle){angle = angle - 360;}
+ value = this._getValueForAngle(angle)
+ ;
+ if(this._rangeData){
+ for(var i=0; (i<this._rangeData.length) && !range; i++){
+ if((Number(this._rangeData[i].low) <= value) && (Number(this._rangeData[i].high) >= value)){
+ range = this._rangeData[i];
+ }
+ }
+ }
+ }
+ return range;
+ },
+
+ _dragIndicator: function(/*Object*/ widget, /*Object*/ e){
+ // summary:
+ // Handles the dragging of an indicator to the event position, including moving/re-drawing
+ // get angle for mouse position
+ this._dragIndicatorAt(widget, e.pageX, e.pageY);
+ event.stop(e);
+ },
+
+ _dragIndicatorAt: function(/*Object*/ widget, x,y){
+ // summary:
+ // Handles the dragging of an indicator to a specific position, including moving/re-drawing
+ // get angle for mouse position
+ var pos = domGeometry.position(widget.gaugeContent, true),
+ xf = x - pos.x,
+ yf = y - pos.y,
+ angle = widget._getDegrees(Math.atan2(yf - widget.cy, xf - widget.cx) + Math.PI/2);
+
+ // get value and restrict to our min/max
+ var value = widget._getValueForAngle(angle);
+ value = Math.min(Math.max(value, widget.min), widget.max);
+ // update the indicator
+ widget._drag.value = widget._drag.currentValue = value;
+ // callback
+ widget._drag.onDragMove(widget._drag);
+ // rotate indicator
+ widget._drag.draw(this._indicatorsGroup, true);
+ widget._drag.valueChanged();
+ }
+
+});
+});