1 | define(["dojo/_base/declare", "./ScaleIndicatorBase", "./_circularUtils", "dojo/_base/event"], |
---|
2 | function(declare, ScaleIndicatorBase, _circularUtils, eventUtil){ |
---|
3 | return declare("dojox.dgauges.CircularRangeIndicator", ScaleIndicatorBase, { |
---|
4 | // summary: |
---|
5 | // A CircularRangeIndicator is used to represent a range of values on a scale. |
---|
6 | // Use the addIndicator method of CircularScale to use it. |
---|
7 | // It is represented as a donut slice. |
---|
8 | |
---|
9 | // start: Number |
---|
10 | // The start value of the range indicator. |
---|
11 | start: 0, |
---|
12 | // radius: Number |
---|
13 | // The outer radius in pixels of the range indicator. |
---|
14 | radius: NaN, |
---|
15 | // startThickness: Number |
---|
16 | // The start thickness of the donut slice in pixels. |
---|
17 | startThickness: 6, |
---|
18 | // endThickness: Number |
---|
19 | // The end thickness of the donut slice in pixels. |
---|
20 | endThickness: 6, |
---|
21 | // fill: Object |
---|
22 | // A fill object that will be passed to the setFill method of GFX. |
---|
23 | fill: null, |
---|
24 | // stroke: Object |
---|
25 | // A stroke object that will be passed to the setStroke method of GFX. |
---|
26 | stroke: null, |
---|
27 | constructor: function(){ |
---|
28 | this.indicatorShapeFunc = null; |
---|
29 | this.fill = [255, 120, 0]; |
---|
30 | this.stroke = { |
---|
31 | color: "black", |
---|
32 | width: .2 |
---|
33 | }; |
---|
34 | this.interactionMode = "none"; |
---|
35 | |
---|
36 | this.addInvalidatingProperties(["start", "radius", "startThickness", "endThickness", "fill", "stroke"]); |
---|
37 | }, |
---|
38 | |
---|
39 | _interpolateColor: function(from, dest, n){ |
---|
40 | // summary: |
---|
41 | // Internal method. |
---|
42 | // tags: |
---|
43 | // private |
---|
44 | var fr = (from >> 16) & 0xff; |
---|
45 | var fg = (from >> 8) & 0xff; |
---|
46 | var fb = from & 0xff; |
---|
47 | |
---|
48 | var tr = (dest >> 16) & 0xff; |
---|
49 | var tg = (dest >> 8) & 0xff; |
---|
50 | var tb = dest & 0xff; |
---|
51 | |
---|
52 | var r = ((1 - n) * fr + n * tr) & 0xff; |
---|
53 | var g = ((1 - n) * fg + n * tg) & 0xff; |
---|
54 | var b = ((1 - n) * fb + n * tb) & 0xff; |
---|
55 | |
---|
56 | return r << 16 | g << 8 | b; |
---|
57 | }, |
---|
58 | |
---|
59 | _colorsInterpolation: function(colors, ratios, len){ |
---|
60 | // summary: |
---|
61 | // Internal method. |
---|
62 | // tags: |
---|
63 | // private |
---|
64 | var ret = []; |
---|
65 | var ilen = 0; |
---|
66 | |
---|
67 | for(var i = 0; i < colors.length - 1; i++){ |
---|
68 | ilen = (ratios[i + 1] - ratios[i]) * len; |
---|
69 | ilen = Math.round(ilen); |
---|
70 | ret = ret.concat(_colorInterpolation(colors[i], colors[i + 1], ilen)); |
---|
71 | } |
---|
72 | return ret; |
---|
73 | }, |
---|
74 | |
---|
75 | _alphasInterpolation: function(alphas, positions, len){ |
---|
76 | // summary: |
---|
77 | // Internal method. |
---|
78 | // tags: |
---|
79 | // private |
---|
80 | var ret = []; |
---|
81 | var ilen = 0; |
---|
82 | for(var i = 0; i < alphas.length - 1; i++){ |
---|
83 | ilen = (positions[i + 1] - positions[i]) * len; |
---|
84 | ilen = Math.round(ilen); |
---|
85 | ret = ret.concat(_alphaInterpolation(alphas[i], alphas[i + 1], ilen)); |
---|
86 | } |
---|
87 | return ret; |
---|
88 | }, |
---|
89 | |
---|
90 | _alphaInterpolation: function(c1, c2, len){ |
---|
91 | // summary: |
---|
92 | // Internal method. |
---|
93 | // tags: |
---|
94 | // private |
---|
95 | var step = (c2 - c1) / (len - 1); |
---|
96 | var ret = []; |
---|
97 | for(var i = 0; i < len; i++){ |
---|
98 | ret.push(c1 + i * step); |
---|
99 | } |
---|
100 | return ret; |
---|
101 | }, |
---|
102 | |
---|
103 | _colorInterpolation: function(c1, c2, len){ |
---|
104 | // summary: |
---|
105 | // Internal method. |
---|
106 | // tags: |
---|
107 | // private |
---|
108 | var ret = []; |
---|
109 | for (var i = 0; i < len; i++){ |
---|
110 | ret.push(_interpolateColor(c1, c2, i / (len - 1))); |
---|
111 | } |
---|
112 | return ret; |
---|
113 | }, |
---|
114 | |
---|
115 | _getEntriesFor: function(entries, attr){ |
---|
116 | // summary: |
---|
117 | // Internal method. |
---|
118 | // tags: |
---|
119 | // private |
---|
120 | var ret = []; |
---|
121 | var e; |
---|
122 | var val; |
---|
123 | for(var i = 0; i < entries.length; i++){ |
---|
124 | e = entries[i]; |
---|
125 | if(e[attr] == null || isNaN(e[attr])) { |
---|
126 | val = i / (entries.length - 1); |
---|
127 | } |
---|
128 | else{ |
---|
129 | val = e[attr]; |
---|
130 | } |
---|
131 | ret.push(val); |
---|
132 | } |
---|
133 | return ret; |
---|
134 | }, |
---|
135 | |
---|
136 | _drawColorTrack: function(g, ox, oy, radius, orientation, startAngleRadians, endAngleRadians, sWeight, eWeight, fill, stroke, clippingAngleRadians){ |
---|
137 | // summary: |
---|
138 | // Internal method. |
---|
139 | // tags: |
---|
140 | // private |
---|
141 | var angleStep = 0.05; |
---|
142 | var totalAngle; |
---|
143 | |
---|
144 | totalAngle = 6.28318530718 - _circularUtils.computeAngle(startAngleRadians, endAngleRadians, orientation); |
---|
145 | if(!isNaN(clippingAngleRadians)){ |
---|
146 | var deltaAngle = _circularUtils.computeAngle(startAngleRadians, clippingAngleRadians, orientation); |
---|
147 | eWeight *= deltaAngle / totalAngle; |
---|
148 | totalAngle = deltaAngle; |
---|
149 | } |
---|
150 | var iterCount = Math.max(2, Math.floor(totalAngle / angleStep)); |
---|
151 | |
---|
152 | angleStep = totalAngle / iterCount; |
---|
153 | var innerRadius; |
---|
154 | var outerRadius; |
---|
155 | var outerStep = 0; |
---|
156 | var innerStep = 0; |
---|
157 | var px; |
---|
158 | var py; |
---|
159 | innerRadius = -sWeight; |
---|
160 | outerRadius = 0; |
---|
161 | innerStep = (sWeight - eWeight) / iterCount; |
---|
162 | |
---|
163 | var angle; |
---|
164 | var i; |
---|
165 | if(orientation == "clockwise"){ |
---|
166 | angleStep = -angleStep; |
---|
167 | } |
---|
168 | |
---|
169 | var gp = []; |
---|
170 | |
---|
171 | px = ox + Math.cos(startAngleRadians) * (radius + innerRadius); |
---|
172 | py = oy - Math.sin(startAngleRadians) * (radius + innerRadius); |
---|
173 | gp.push(px, py); |
---|
174 | for(i = 0; i < iterCount; i++){ |
---|
175 | angle = startAngleRadians + i * angleStep; |
---|
176 | px = ox + Math.cos(angle + angleStep) * (radius + innerRadius + i * innerStep); |
---|
177 | py = oy - Math.sin(angle + angleStep) * (radius + innerRadius + i * innerStep); |
---|
178 | gp.push(px, py); |
---|
179 | } |
---|
180 | if(isNaN(angle)){ |
---|
181 | angle = startAngleRadians; |
---|
182 | } |
---|
183 | px = ox + Math.cos(angle + angleStep) * (radius + outerRadius + (iterCount - 1) * outerStep); |
---|
184 | py = oy - Math.sin(angle + angleStep) * (radius + outerRadius + (iterCount - 1) * outerStep); |
---|
185 | gp.push(px, py); |
---|
186 | for(i = iterCount - 1; i >= 0; i--){ |
---|
187 | angle = startAngleRadians + i * angleStep; |
---|
188 | px = ox + Math.cos(angle + angleStep) * (radius + outerRadius + i * outerStep); |
---|
189 | py = oy - Math.sin(angle + angleStep) * (radius + outerRadius + i * outerStep); |
---|
190 | gp.push(px, py); |
---|
191 | } |
---|
192 | px = ox + Math.cos(startAngleRadians) * (radius + outerRadius); |
---|
193 | py = oy - Math.sin(startAngleRadians) * (radius + outerRadius); |
---|
194 | gp.push(px, py); |
---|
195 | |
---|
196 | px = ox + Math.cos(startAngleRadians) * (radius + innerRadius); |
---|
197 | py = oy - Math.sin(startAngleRadians) * (radius + innerRadius); |
---|
198 | gp.push(px, py); |
---|
199 | g.createPolyline(gp).setFill(fill).setStroke(stroke); |
---|
200 | }, |
---|
201 | |
---|
202 | refreshRendering: function(){ |
---|
203 | this.inherited(arguments); |
---|
204 | |
---|
205 | var g = this._gfxGroup; |
---|
206 | g.clear(); |
---|
207 | var ox = this.scale.originX; |
---|
208 | var oy = this.scale.originY; |
---|
209 | var radius = isNaN(this.radius) ? this.scale.radius : this.radius; |
---|
210 | var orientation = this.scale.orientation; |
---|
211 | var startAngleRadians = _circularUtils.toRadians(360 - this.scale.positionForValue(this.start)); |
---|
212 | var v = isNaN(this._transitionValue) ? this.value : this._transitionValue; |
---|
213 | var endAngleRadians = _circularUtils.toRadians(360 - this.scale.positionForValue(v)); |
---|
214 | var sWeight = this.startThickness; |
---|
215 | var eWeight = this.endThickness; |
---|
216 | var clippingAngleRadians = NaN; |
---|
217 | |
---|
218 | this._drawColorTrack(g, ox, oy, radius, orientation, startAngleRadians, endAngleRadians, sWeight, eWeight, this.fill, this.stroke, clippingAngleRadians); |
---|
219 | }, |
---|
220 | |
---|
221 | _onMouseDown: function(event){ |
---|
222 | // summary: |
---|
223 | // Internal method. |
---|
224 | // tags: |
---|
225 | // private |
---|
226 | this.inherited(arguments); |
---|
227 | var origin = this.scale._gauge._gaugeToPage(this.scale.originX, this.scale.originY); |
---|
228 | var angle = ((Math.atan2(event.pageY - origin.y, event.pageX - origin.x)) * 180) / (Math.PI); |
---|
229 | this.set("value", this.scale.valueForPosition(angle)); |
---|
230 | |
---|
231 | // prevent the browser from selecting text |
---|
232 | eventUtil.stop(event); |
---|
233 | }, |
---|
234 | |
---|
235 | _onMouseMove: function(event){ |
---|
236 | // summary: |
---|
237 | // Internal method. |
---|
238 | // tags: |
---|
239 | // private |
---|
240 | this.inherited(arguments); |
---|
241 | |
---|
242 | var origin = this.scale._gauge._gaugeToPage(this.scale.originX, this.scale.originY); |
---|
243 | var angle = ((Math.atan2(event.pageY - origin.y, event.pageX - origin.x)) * 180) / (Math.PI); |
---|
244 | this.set("value", this.scale.valueForPosition(angle)); |
---|
245 | } |
---|
246 | }); |
---|
247 | }); |
---|