corrade-nucleus-nucleons – Blame information for rev 31

Subversion Repositories:
Rev:
Rev Author Line No. Line
31 office 1 /**
2 * @license Highcharts JS v5.0.14 (2017-07-28)
3 * Highcharts funnel module
4 *
5 * (c) 2010-2017 Torstein Honsi
6 *
7 * License: www.highcharts.com/license
8 */
9 'use strict';
10 (function(factory) {
11 if (typeof module === 'object' && module.exports) {
12 module.exports = factory;
13 } else {
14 factory(Highcharts);
15 }
16 }(function(Highcharts) {
17 (function(Highcharts) {
18 /**
19 * Highcharts funnel module
20 *
21 * (c) 2010-2017 Torstein Honsi
22 *
23 * License: www.highcharts.com/license
24 */
25 /* eslint indent:0 */
26  
27 // create shortcuts
28 var seriesType = Highcharts.seriesType,
29 seriesTypes = Highcharts.seriesTypes,
30 noop = Highcharts.noop,
31 pick = Highcharts.pick,
32 each = Highcharts.each;
33  
34  
35 seriesType('funnel', 'pie',
36 /**
37 * Funnel charts are a type of chart often used to visualize stages in a sales
38 * project, where the top are the initial stages with the most clients.
39 * It requires that the modules/funnel.js file is loaded.
40 *
41 * @sample highcharts/demo/funnel/ Funnel demo
42 * @extends {plotOptions.pie}
43 * @optionparent plotOptions.funnel
44 */
45 {
46  
47 /**
48 */
49 animation: false,
50  
51 /**
52 * The center of the series. By default, it is centered in the middle
53 * of the plot area, so it fills the plot area height.
54 *
55 * @type {Array<String|Number>}
56 * @default ["50%", "50%"]
57 * @since 3.0
58 * @product highcharts
59 */
60 center: ['50%', '50%'],
61  
62 /**
63 * The width of the funnel compared to the width of the plot area,
64 * or the pixel width if it is a number.
65 *
66 * @type {Number|String}
67 * @default 90%
68 * @since 3.0
69 * @product highcharts
70 */
71 width: '90%',
72  
73 /**
74 * The width of the neck, the lower part of the funnel. A number defines
75 * pixel width, a percentage string defines a percentage of the plot
76 * area width.
77 *
78 * @type {Number|String}
79 * @sample {highcharts} highcharts/demo/funnel/ Funnel demo
80 * @default 30%
81 * @since 3.0
82 * @product highcharts
83 */
84 neckWidth: '30%',
85  
86 /**
87 * The height of the funnel or pyramid. If it is a number it defines
88 * the pixel height, if it is a percentage string it is the percentage
89 * of the plot area height.
90 *
91 * @type {Number|String}
92 * @sample {highcharts} highcharts/demo/funnel/ Funnel demo
93 * @since 3.0
94 * @product highcharts
95 */
96 height: '100%',
97  
98 /**
99 * The height of the neck, the lower part of the funnel. A number defines
100 * pixel width, a percentage string defines a percentage of the plot
101 * area height.
102 *
103 * @type {Number|String}
104 * @default 25%
105 * @product highcharts
106 */
107 neckHeight: '25%',
108  
109 /**
110 * A reversed funnel has the widest area down. A reversed funnel with
111 * no neck width and neck height is a pyramid.
112 *
113 * @type {Boolean}
114 * @default false
115 * @since 3.0.10
116 * @product highcharts
117 */
118 reversed: false,
119  
120 /**
121 */
122 size: true, // to avoid adapting to data label size in Pie.drawDataLabels
123  
124  
125 // Presentational
126  
127 /**
128 */
129 dataLabels: {
130 //position: 'right',
131  
132 /**
133 */
134 connectorWidth: 1
135 //connectorColor: null
136 },
137  
138 /**
139 */
140 states: {
141  
142 /**
143 */
144 select: {
145  
146 /**
147 */
148 color: '#cccccc',
149  
150 /**
151 */
152 borderColor: '#000000',
153  
154 /**
155 */
156 shadow: false
157 }
158 }
159  
160 },
161  
162 // Properties
163 {
164 animate: noop,
165  
166 /**
167 * Overrides the pie translate method
168 */
169 translate: function() {
170  
171 var
172 // Get positions - either an integer or a percentage string must be given
173 getLength = function(length, relativeTo) {
174 return (/%$/).test(length) ?
175 relativeTo * parseInt(length, 10) / 100 :
176 parseInt(length, 10);
177 },
178  
179 sum = 0,
180 series = this,
181 chart = series.chart,
182 options = series.options,
183 reversed = options.reversed,
184 ignoreHiddenPoint = options.ignoreHiddenPoint,
185 plotWidth = chart.plotWidth,
186 plotHeight = chart.plotHeight,
187 cumulative = 0, // start at top
188 center = options.center,
189 centerX = getLength(center[0], plotWidth),
190 centerY = getLength(center[1], plotHeight),
191 width = getLength(options.width, plotWidth),
192 tempWidth,
193 getWidthAt,
194 height = getLength(options.height, plotHeight),
195 neckWidth = getLength(options.neckWidth, plotWidth),
196 neckHeight = getLength(options.neckHeight, plotHeight),
197 neckY = (centerY - height / 2) + height - neckHeight,
198 data = series.data,
199 path,
200 fraction,
201 half = options.dataLabels.position === 'left' ? 1 : 0,
202  
203 x1,
204 y1,
205 x2,
206 x3,
207 y3,
208 x4,
209 y5;
210  
211 // Return the width at a specific y coordinate
212 series.getWidthAt = getWidthAt = function(y) {
213 var top = (centerY - height / 2);
214  
215 return y > neckY || height === neckHeight ?
216 neckWidth :
217 neckWidth + (width - neckWidth) * (1 - (y - top) / (height - neckHeight));
218 };
219 series.getX = function(y, half, point) {
220 return centerX + (half ? -1 : 1) * ((getWidthAt(reversed ? 2 * centerY - y : y) / 2) + point.labelDistance);
221 };
222  
223 // Expose
224 series.center = [centerX, centerY, height];
225 series.centerX = centerX;
226  
227 /*
228 * Individual point coordinate naming:
229 *
230 * x1,y1 _________________ x2,y1
231 * \ /
232 * \ /
233 * \ /
234 * \ /
235 * \ /
236 * x3,y3 _________ x4,y3
237 *
238 * Additional for the base of the neck:
239 *
240 * | |
241 * | |
242 * | |
243 * x3,y5 _________ x4,y5
244 */
245  
246  
247  
248  
249 // get the total sum
250 each(data, function(point) {
251 if (!ignoreHiddenPoint || point.visible !== false) {
252 sum += point.y;
253 }
254 });
255  
256 each(data, function(point) {
257 // set start and end positions
258 y5 = null;
259 fraction = sum ? point.y / sum : 0;
260 y1 = centerY - height / 2 + cumulative * height;
261 y3 = y1 + fraction * height;
262 //tempWidth = neckWidth + (width - neckWidth) * ((height - neckHeight - y1) / (height - neckHeight));
263 tempWidth = getWidthAt(y1);
264 x1 = centerX - tempWidth / 2;
265 x2 = x1 + tempWidth;
266 tempWidth = getWidthAt(y3);
267 x3 = centerX - tempWidth / 2;
268 x4 = x3 + tempWidth;
269  
270 // the entire point is within the neck
271 if (y1 > neckY) {
272 x1 = x3 = centerX - neckWidth / 2;
273 x2 = x4 = centerX + neckWidth / 2;
274  
275 // the base of the neck
276 } else if (y3 > neckY) {
277 y5 = y3;
278  
279 tempWidth = getWidthAt(neckY);
280 x3 = centerX - tempWidth / 2;
281 x4 = x3 + tempWidth;
282  
283 y3 = neckY;
284 }
285  
286 if (reversed) {
287 y1 = 2 * centerY - y1;
288 y3 = 2 * centerY - y3;
289 y5 = (y5 ? 2 * centerY - y5 : null);
290 }
291 // save the path
292 path = [
293 'M',
294 x1, y1,
295 'L',
296 x2, y1,
297 x4, y3
298 ];
299 if (y5) {
300 path.push(x4, y5, x3, y5);
301 }
302 path.push(x3, y3, 'Z');
303  
304 // prepare for using shared dr
305 point.shapeType = 'path';
306 point.shapeArgs = {
307 d: path
308 };
309  
310  
311 // for tooltips and data labels
312 point.percentage = fraction * 100;
313 point.plotX = centerX;
314 point.plotY = (y1 + (y5 || y3)) / 2;
315  
316 // Placement of tooltips and data labels
317 point.tooltipPos = [
318 centerX,
319 point.plotY
320 ];
321  
322 // Slice is a noop on funnel points
323 point.slice = noop;
324  
325 // Mimicking pie data label placement logic
326 point.half = half;
327  
328 if (!ignoreHiddenPoint || point.visible !== false) {
329 cumulative += fraction;
330 }
331 });
332 },
333  
334 /**
335 * Funnel items don't have angles (#2289)
336 */
337 sortByAngle: function(points) {
338 points.sort(function(a, b) {
339 return a.plotY - b.plotY;
340 });
341 },
342  
343 /**
344 * Extend the pie data label method
345 */
346 drawDataLabels: function() {
347 var series = this,
348 data = series.data,
349 labelDistance = series.options.dataLabels.distance,
350 leftSide,
351 sign,
352 point,
353 i = data.length,
354 x,
355 y;
356  
357 // In the original pie label anticollision logic, the slots are distributed
358 // from one labelDistance above to one labelDistance below the pie. In funnels
359 // we don't want this.
360 series.center[2] -= 2 * labelDistance;
361  
362 // Set the label position array for each point.
363 while (i--) {
364 point = data[i];
365 leftSide = point.half;
366 sign = leftSide ? 1 : -1;
367 y = point.plotY;
368 point.labelDistance = pick(
369 point.options.dataLabels && point.options.dataLabels.distance,
370 labelDistance
371 );
372  
373 series.maxLabelDistance = Math.max(point.labelDistance, series.maxLabelDistance || 0);
374 x = series.getX(y, leftSide, point);
375  
376 // set the anchor point for data labels
377 point.labelPos = [
378 0, // first break of connector
379 y, // a/a
380 x + (point.labelDistance - 5) * sign, // second break, right outside point shape
381 y, // a/a
382 x + point.labelDistance * sign, // landing point for connector
383 y, // a/a
384 leftSide ? 'right' : 'left', // alignment
385  
386 ];
387 }
388  
389 seriesTypes.pie.prototype.drawDataLabels.call(this);
390 }
391  
392 });
393  
394 /**
395 * Pyramid series type.
396 */
397 seriesType('pyramid', 'funnel',
398 /**
399 * A pyramid series is a special type of funnel, without neck and reversed by default.
400 * @extends funnel
401 * @optionparent plotOptions.pyramid
402 */
403 {
404  
405 /**
406 */
407 neckWidth: '0%',
408  
409 /**
410 */
411 neckHeight: '0%',
412  
413 /**
414 * The pyramid is reversed by default, as opposed to the funnel, which
415 * shares the layout engine, and is not reversed.
416 *
417 * @type {Boolean}
418 * @default true
419 * @since 3.0.10
420 * @product highcharts
421 */
422 reversed: true
423 });
424  
425 }(Highcharts));
426 }));