1 //Class c.raphael.Gauge1 : Gauge1 2 //This is the custom wrapper class for protovis bar charts 3 4 //Constructor 5 wso2vis.s.gauge.raphael.Gauge1 = function(canvas, chartTitle, chartDesc) { 6 wso2vis.s.gauge.Gauge.call(this, canvas, chartTitle, chartDesc); 7 8 /* @private */ 9 this.y = null; 10 this.x = null; 11 12 this.r = null; // raphael page 13 this.s = null; // needle set 14 this.cx = 0; 15 this.cy = 0; 16 17 this.minValue(0); 18 this.maxValue(1000); 19 this.largeTick(100); 20 this.smallTick(10); 21 this.minAngle(30); 22 this.maxAngle(330); 23 this.radius(60); 24 25 this.needleLength(55); 26 this.smallTickLength(10); 27 this.largeTickLength(15); 28 //this.legendText("Data 1"); 29 } 30 31 // this makes c.protovis.BarChart.prototype inherits 32 // from Chart.prototype 33 wso2vis.extend(wso2vis.s.gauge.raphael.Gauge1, wso2vis.s.gauge.Gauge); 34 35 wso2vis.s.gauge.raphael.Gauge1.prototype 36 .property("dataField") 37 .property("dataValue") 38 .property("dataLabel") 39 .property("ySuffix") 40 .property("xSuffix") 41 .property("titleTop") 42 .property("titleLeft") 43 .property("titleRight") 44 .property("titleBottom") 45 .property("xTitle") 46 .property("yTitle") 47 .property("legendText") 48 .property("segmentBorderColor") 49 50 .property("minAngle") 51 .property("maxAngle") 52 .property("radius") 53 54 .property("minValue") 55 .property("maxValue") 56 .property("largeTick") 57 .property("smallTick") 58 .property("largeTickLength") 59 .property("smallTickLength") 60 .property("needleLength") 61 62 .property("needleColor") 63 .property("needleBaseColor") 64 .property("labelColor") 65 .property("largeTickColor") 66 .property("smallTickColor"); 67 68 69 70 //Public function load 71 //Loads the chart inside the given HTML element 72 wso2vis.s.gauge.raphael.Gauge1.prototype.load = function (w, h) { 73 if ( w !== undefined ) { 74 this.width(w); 75 } 76 if ( h !== undefined ) { 77 this.height(h); 78 } 79 80 this.cx = this.width() / 2; 81 this.cy = this.height() / 2; 82 83 this.r = Raphael(this.divEl(), this.width(), this.height()); 84 85 this.drawDial(this.r, this.largeTick(), this.radius(), this.largeTickLength(), this.cx, this.cy, true); 86 this.drawDial(this.r, this.smallTick(), this.radius(), this.smallTickLength(), this.cx, this.cy, false); 87 88 //drawBorder(this.r, this.radius(), this.cx, this.cy); 89 90 this.drawInitialNeedle(this.r, this.radius(), this.cx, this.cy); 91 this.showTitle(); 92 }; 93 94 95 /** 96 * @private 97 */ 98 wso2vis.s.gauge.raphael.Gauge1.prototype.showTitle = function() { 99 this.r.text(this.cx, this.cy + this.radius() + 20, this.title()).attr({"stroke-width": 1, stroke: "#ccc"}); 100 } 101 102 /** 103 * @private 104 */ 105 wso2vis.s.gauge.raphael.Gauge1.prototype.drawDial = function(r, tick, radius, length, cx, cy, isLargeTick) { 106 var maxValAlt = Math.floor(this.maxValue() / tick) * tick; 107 var minValAlt = Math.ceil(this.minValue() / tick) * tick; 108 109 var n = Math.floor((maxValAlt - minValAlt) / tick); 110 111 var tickAngle = tick * (this.maxAngle() - this.minAngle()) / (this.maxValue() - this.minValue()); 112 var startAngle = 0; 113 if (this.minValue() >= 0) 114 { 115 startAngle = ((this.minValue() % tick) == 0)? 0 : (tick - this.minValue() % tick) * (this.maxAngle() - this.minAngle()) / (this.maxValue() - this.minValue()); 116 } 117 else 118 { 119 startAngle = (-this.minValue() % tick) * (this.maxAngle() - this.minAngle()) / (this.maxValue() - this.minValue()); 120 } 121 for (var i = 0; i <= n; i++) { 122 var ang = (this.minAngle() + startAngle + i * tickAngle); 123 r.path("M" + cx + " " + (cy + radius) + "L" + cx+ " " + (cy + radius - length)).attr({rotation: ang + " " + cx + " " + cy, "stroke-width": isLargeTick? 2 : 1, stroke: "#fff"}); 124 if (isLargeTick) 125 { 126 /*if (minValAlt + i * tick == 0) 127 r.text(cx, cy + radius + 10, "0").attr({rotation:ang + " " + cx + " " + cy, "stroke-width": 1, stroke: "#fff"}); 128 else 129 r.text(cx, cy + radius + 10, minValAlt + i * tick).attr({rotation:ang + " " + cx + " " + cy, "stroke-width": 1, stroke: "#fff"}); 130 */ 131 if (ang >= 90 && ang <= 270) { 132 if (minValAlt + i * tick == 0) 133 r.text(cx, cy - radius - 10, "0").attr({rotation:(ang-180) + " " + cx + " " + cy, "stroke-width": 1, stroke: "#fff"}); 134 else 135 r.text(cx, cy - radius - 10, minValAlt + i * tick).attr({rotation:(ang-180) + " " + cx + " " + cy, "stroke-width": 1, stroke: "#fff"}); 136 } 137 else { 138 if (minValAlt + i * tick == 0) 139 r.text(cx, cy + radius + 10, "0").attr({rotation:ang + " " + cx + " " + cy, "stroke-width": 1, stroke: "#fff"}); 140 else 141 r.text(cx, cy + radius + 10, minValAlt + i * tick).attr({rotation:ang + " " + cx + " " + cy, "stroke-width": 1, stroke: "#fff"}); 142 } 143 144 } 145 146 } 147 } 148 149 /** 150 * @private 151 */ 152 wso2vis.s.gauge.raphael.Gauge1.prototype.drawBorder = function(r, radius, cx, cy) { 153 var alpha = (360 - (this.maxAngle() - this.minAngle())); 154 var alphar = alpha * Math.PI / 180; 155 var tx, ty; 156 tx = cx + radius * Math.sin(alphar); 157 ty = cy + radius * Math.cos(alphar); 158 r.path("M320 " + (cy + radius) + " A " + radius + " " + radius + " 0 1 1 "+ tx + " " + ty).attr({rotation: this.minAngle(), "stroke-width": 1, stroke: "#fff"}); 159 } 160 161 /** 162 * @private 163 */ 164 wso2vis.s.gauge.raphael.Gauge1.prototype.drawInitialNeedle = function(r, radius, cx, cy) { 165 this.s = r.set(); 166 this.s.push(r.path("M" + cx + " " + (cy - 15) + " L" + cx + " " + (cy + this.needleLength())).attr({fill: "none", "stroke-width": 4, stroke: "#f00"})); 167 this.s.push(r.circle(cx, cy, 5).attr({fill: "none", "stroke-width": 10, stroke: "#aaa"})); 168 this.s.animate({rotation:this.minAngle() + " " + cx + " " + cy}, 0, "<>"); 169 } 170 171 /** 172 * @private 173 */ 174 wso2vis.s.gauge.raphael.Gauge1.prototype.updateNeedle = function(val) { 175 var angle = (val - this.minValue()) * (this.maxAngle() - this.minAngle()) / (this.maxValue() - this.minValue()) + this.minAngle(); 176 this.s.animate({rotation:angle + " " + this.cx + " " + this.cy}, 800, "<>"); 177 } 178 179 /** 180 * @private 181 */ 182 wso2vis.s.gauge.raphael.Gauge1.prototype.titleSpacing = function () { 183 if(this.title() === "") { 184 return 1; 185 } 186 else { 187 return 0.9; 188 } 189 }; 190 191 /** 192 * @private 193 */ 194 wso2vis.s.gauge.raphael.Gauge1.prototype.populateData = function (thisObject) { 195 var _dataField = thisObject.traverseToDataField(thisObject.data, thisObject.dataField()); 196 197 var dataGrpCount = 1; 198 if( _dataField instanceof Array ) { 199 dataGrpCount = _dataField.length; 200 } 201 202 var rootObj; 203 if (_dataField instanceof Array ) { 204 rootObj = _dataField[0]; 205 } 206 else { 207 rootObj = _dataField; 208 } 209 210 this.updateNeedle(parseInt(thisObject.traverseToDataField(rootObj, this.dataValue()))); 211 212 /*thisObject.formattedData = pv.range(dataGrpCount).map( genDataMap ); 213 214 215 var maxVal = thisObject.formattedData.max(); 216 if (maxVal < 5) maxVal = 5; // fixing value repeating issue. 217 218 thisObject.x.domain(0, maxVal).range(0, (thisObject.width() - thisObject.paddingLeft() - thisObject.paddingRight()) ); 219 thisObject.y.domain(pv.range(dataGrpCount)).splitBanded(0, (thisObject.height() - thisObject.paddingTop() - thisObject.paddingBottom()), 4/5); 220 221 function genDataMap(x) { 222 var rootObj; 223 if( _dataField instanceof Array ) { 224 rootObj = _dataField[x]; 225 } 226 else { 227 rootObj = _dataField; 228 } 229 return parseInt(thisObject.traverseToDataField(rootObj, thisObject.dataValue())); 230 }*/ 231 }; 232 233 //wso2vis.s.gauge.raphael.Gauge1.prototype.getData = function (thisObject) { 234 //return thisObject.formattedData; 235 //}; 236 237 wso2vis.s.gauge.raphael.Gauge1.prototype.update = function () { 238 this.populateData(this); 239 //this.vis.render(); 240 if(this.tooltip() === true) { 241 tooltip.init(); 242 } 243 }; 244 245 wso2vis.s.gauge.raphael.Gauge1.prototype.getDataLabel = function (i) { 246 if (this.data !== null){ 247 248 var rootObj = this.traverseToDataField(this.data, this.dataField()); 249 if( rootObj instanceof Array ) { 250 return this.traverseToDataField(rootObj[i], this.dataLabel()); 251 } 252 else { 253 return this.traverseToDataField(rootObj, this.dataLabel()); 254 } 255 } 256 257 return i; 258 }; 259