UNPKG

10.7 kBJavaScriptView Raw
1/**
2 * @license Highcharts JS v5.0.2 (2016-10-26)
3 * Solid angular gauge module
4 *
5 * (c) 2010-2016 Torstein Honsi
6 *
7 * License: www.highcharts.com/license
8 */
9(function(factory) {
10 if (typeof module === 'object' && module.exports) {
11 module.exports = factory;
12 } else {
13 factory(Highcharts);
14 }
15}(function(Highcharts) {
16 (function(H) {
17 /**
18 * Solid angular gauge module
19 *
20 * (c) 2010-2016 Torstein Honsi
21 *
22 * License: www.highcharts.com/license
23 */
24
25 'use strict';
26
27 var pInt = H.pInt,
28 pick = H.pick,
29 each = H.each,
30 isNumber = H.isNumber,
31 colorAxisMethods;
32
33 // These methods are defined in the ColorAxis object, and copied here.
34 // If we implement an AMD system we should make ColorAxis a dependency.
35 colorAxisMethods = {
36
37
38 initDataClasses: function(userOptions) {
39 var axis = this,
40 chart = this.chart,
41 dataClasses,
42 colorCounter = 0,
43 options = this.options;
44 this.dataClasses = dataClasses = [];
45
46 each(userOptions.dataClasses, function(dataClass, i) {
47 var colors;
48
49 dataClass = H.merge(dataClass);
50 dataClasses.push(dataClass);
51 if (!dataClass.color) {
52 if (options.dataClassColor === 'category') {
53 colors = chart.options.colors;
54 dataClass.color = colors[colorCounter++];
55 // loop back to zero
56 if (colorCounter === colors.length) {
57 colorCounter = 0;
58 }
59 } else {
60 dataClass.color = axis.tweenColors(H.color(options.minColor), H.color(options.maxColor), i / (userOptions.dataClasses.length - 1));
61 }
62 }
63 });
64 },
65
66 initStops: function(userOptions) {
67 this.stops = userOptions.stops || [
68 [0, this.options.minColor],
69 [1, this.options.maxColor]
70 ];
71 each(this.stops, function(stop) {
72 stop.color = H.color(stop[1]);
73 });
74 },
75 /**
76 * Translate from a value to a color
77 */
78 toColor: function(value, point) {
79 var pos,
80 stops = this.stops,
81 from,
82 to,
83 color,
84 dataClasses = this.dataClasses,
85 dataClass,
86 i;
87
88 if (dataClasses) {
89 i = dataClasses.length;
90 while (i--) {
91 dataClass = dataClasses[i];
92 from = dataClass.from;
93 to = dataClass.to;
94 if ((from === undefined || value >= from) && (to === undefined || value <= to)) {
95 color = dataClass.color;
96 if (point) {
97 point.dataClass = i;
98 }
99 break;
100 }
101 }
102
103 } else {
104
105 if (this.isLog) {
106 value = this.val2lin(value);
107 }
108 pos = 1 - ((this.max - value) / (this.max - this.min));
109 i = stops.length;
110 while (i--) {
111 if (pos > stops[i][0]) {
112 break;
113 }
114 }
115 from = stops[i] || stops[i + 1];
116 to = stops[i + 1] || from;
117
118 // The position within the gradient
119 pos = 1 - (to[0] - pos) / ((to[0] - from[0]) || 1);
120
121 color = this.tweenColors(
122 from.color,
123 to.color,
124 pos
125 );
126 }
127 return color;
128 },
129 /*
130 * Return an intermediate color between two colors, according to pos where 0
131 * is the from color and 1 is the to color.
132 */
133 tweenColors: function(from, to, pos) {
134 // Check for has alpha, because rgba colors perform worse due to lack of
135 // support in WebKit.
136 var hasAlpha,
137 ret;
138
139 // Unsupported color, return to-color (#3920)
140 if (!to.rgba.length || !from.rgba.length) {
141 ret = to.input || 'none';
142
143 // Interpolate
144 } else {
145 from = from.rgba;
146 to = to.rgba;
147 hasAlpha = (to[3] !== 1 || from[3] !== 1);
148 ret = (hasAlpha ? 'rgba(' : 'rgb(') +
149 Math.round(to[0] + (from[0] - to[0]) * (1 - pos)) + ',' +
150 Math.round(to[1] + (from[1] - to[1]) * (1 - pos)) + ',' +
151 Math.round(to[2] + (from[2] - to[2]) * (1 - pos)) +
152 (hasAlpha ? (',' + (to[3] + (from[3] - to[3]) * (1 - pos))) : '') + ')';
153 }
154 return ret;
155 }
156 };
157
158 /**
159 * Handle animation of the color attributes directly
160 */
161 each(['fill', 'stroke'], function(prop) {
162 H.Fx.prototype[prop + 'Setter'] = function() {
163 this.elem.attr(prop, colorAxisMethods.tweenColors(H.color(this.start), H.color(this.end), this.pos));
164 };
165 });
166
167 // The solidgauge series type
168 H.seriesType('solidgauge', 'gauge', {
169 colorByPoint: true
170
171 }, {
172 bindAxes: function() {
173 var axis;
174 H.seriesTypes.gauge.prototype.bindAxes.call(this);
175
176 axis = this.yAxis;
177 H.extend(axis, colorAxisMethods);
178
179 // Prepare data classes
180 if (axis.options.dataClasses) {
181 axis.initDataClasses(axis.options);
182 }
183 axis.initStops(axis.options);
184 },
185
186 /**
187 * Draw the points where each point is one needle
188 */
189 drawPoints: function() {
190 var series = this,
191 yAxis = series.yAxis,
192 center = yAxis.center,
193 options = series.options,
194 renderer = series.chart.renderer,
195 overshoot = options.overshoot,
196 overshootVal = isNumber(overshoot) ? overshoot / 180 * Math.PI : 0;
197
198 each(series.points, function(point) {
199 var graphic = point.graphic,
200 rotation = yAxis.startAngleRad + yAxis.translate(point.y, null, null, null, true),
201 radius = (pInt(pick(point.options.radius, options.radius, 100)) * center[2]) / 200,
202 innerRadius = (pInt(pick(point.options.innerRadius, options.innerRadius, 60)) * center[2]) / 200,
203 shapeArgs,
204 d,
205 toColor = yAxis.toColor(point.y, point),
206 axisMinAngle = Math.min(yAxis.startAngleRad, yAxis.endAngleRad),
207 axisMaxAngle = Math.max(yAxis.startAngleRad, yAxis.endAngleRad),
208 minAngle,
209 maxAngle;
210
211 if (toColor === 'none') { // #3708
212 toColor = point.color || series.color || 'none';
213 }
214 if (toColor !== 'none') {
215 point.color = toColor;
216 }
217
218 // Handle overshoot and clipping to axis max/min
219 rotation = Math.max(axisMinAngle - overshootVal, Math.min(axisMaxAngle + overshootVal, rotation));
220
221 // Handle the wrap option
222 if (options.wrap === false) {
223 rotation = Math.max(axisMinAngle, Math.min(axisMaxAngle, rotation));
224 }
225
226 minAngle = Math.min(rotation, yAxis.startAngleRad);
227 maxAngle = Math.max(rotation, yAxis.startAngleRad);
228
229 if (maxAngle - minAngle > 2 * Math.PI) {
230 maxAngle = minAngle + 2 * Math.PI;
231 }
232
233 point.shapeArgs = shapeArgs = {
234 x: center[0],
235 y: center[1],
236 r: radius,
237 innerR: innerRadius,
238 start: minAngle,
239 end: maxAngle,
240 fill: toColor
241 };
242 point.startR = radius; // For PieSeries.animate
243
244 if (graphic) {
245 d = shapeArgs.d;
246 graphic.animate(shapeArgs);
247 if (d) {
248 shapeArgs.d = d; // animate alters it
249 }
250 } else {
251 point.graphic = renderer.arc(shapeArgs)
252 .addClass('highcharts-point')
253 .attr({
254 fill: toColor,
255 'sweep-flag': 0
256 })
257 .add(series.group);
258
259
260 if (options.linecap !== 'square') {
261 point.graphic.attr({
262 'stroke-linecap': 'round',
263 'stroke-linejoin': 'round'
264 });
265 }
266 point.graphic.attr({
267 stroke: options.borderColor || 'none',
268 'stroke-width': options.borderWidth || 0
269 });
270
271 }
272 });
273 },
274
275 /**
276 * Extend the pie slice animation by animating from start angle and up
277 */
278 animate: function(init) {
279
280 if (!init) {
281 this.startAngleRad = this.yAxis.startAngleRad;
282 H.seriesTypes.pie.prototype.animate.call(this, init);
283 }
284 }
285 });
286
287 }(Highcharts));
288}));