highcharts-rails 5.0.14 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.markdown +60 -0
- data/Rakefile +54 -5
- data/app/assets/images/highcharts/earth.svg +432 -0
- data/app/assets/javascripts/highcharts.js +5103 -3147
- data/app/assets/javascripts/highcharts/highcharts-3d.js +930 -277
- data/app/assets/javascripts/highcharts/highcharts-more.js +1374 -249
- data/app/assets/javascripts/highcharts/lib/canvg.js +3073 -0
- data/app/assets/javascripts/highcharts/lib/jspdf.js +16624 -0
- data/app/assets/javascripts/highcharts/lib/rgbcolor.js +299 -0
- data/app/assets/javascripts/highcharts/lib/svg2pdf.js +3488 -0
- data/app/assets/javascripts/highcharts/modules/accessibility.js +654 -212
- data/app/assets/javascripts/highcharts/modules/annotations.js +1552 -274
- data/app/assets/javascripts/highcharts/modules/boost-canvas.js +773 -0
- data/app/assets/javascripts/highcharts/modules/boost.js +636 -210
- data/app/assets/javascripts/highcharts/modules/broken-axis.js +2 -2
- data/app/assets/javascripts/highcharts/modules/bullet.js +364 -0
- data/app/assets/javascripts/highcharts/modules/data.js +766 -38
- data/app/assets/javascripts/highcharts/modules/drag-panes.js +588 -0
- data/app/assets/javascripts/highcharts/modules/drilldown.js +106 -36
- data/app/assets/javascripts/highcharts/modules/export-data.js +597 -0
- data/app/assets/javascripts/highcharts/modules/exporting.js +424 -162
- data/app/assets/javascripts/highcharts/modules/funnel.js +144 -22
- data/app/assets/javascripts/highcharts/modules/gantt.js +1154 -0
- data/app/assets/javascripts/highcharts/modules/grid-axis.js +1 -1
- data/app/assets/javascripts/highcharts/modules/heatmap.js +406 -80
- data/app/assets/javascripts/highcharts/modules/histogram-bellcurve.js +513 -0
- data/app/assets/javascripts/highcharts/modules/item-series.js +126 -0
- data/app/assets/javascripts/highcharts/modules/no-data-to-display.js +31 -13
- data/app/assets/javascripts/highcharts/modules/offline-exporting.js +179 -57
- data/app/assets/javascripts/highcharts/modules/oldie.js +1378 -0
- data/app/assets/javascripts/highcharts/modules/overlapping-datalabels.js +8 -6
- data/app/assets/javascripts/highcharts/modules/parallel-coordinates.js +494 -0
- data/app/assets/javascripts/highcharts/modules/pareto.js +275 -0
- data/app/assets/javascripts/highcharts/modules/sankey.js +641 -0
- data/app/assets/javascripts/highcharts/modules/series-label.js +355 -145
- data/app/assets/javascripts/highcharts/modules/solid-gauge.js +122 -1
- data/app/assets/javascripts/highcharts/modules/static-scale.js +64 -0
- data/app/assets/javascripts/highcharts/modules/stock.js +1944 -676
- data/app/assets/javascripts/highcharts/modules/streamgraph.js +139 -0
- data/app/assets/javascripts/highcharts/modules/sunburst.js +2403 -0
- data/app/assets/javascripts/highcharts/modules/tilemap.js +1199 -0
- data/app/assets/javascripts/highcharts/modules/treemap.js +538 -134
- data/app/assets/javascripts/highcharts/modules/variable-pie.js +490 -0
- data/app/assets/javascripts/highcharts/modules/variwide.js +283 -0
- data/app/assets/javascripts/highcharts/modules/vector.js +294 -0
- data/app/assets/javascripts/highcharts/modules/windbarb.js +490 -0
- data/app/assets/javascripts/highcharts/modules/wordcloud.js +681 -0
- data/app/assets/javascripts/highcharts/modules/xrange.js +615 -0
- data/app/assets/javascripts/highcharts/themes/avocado.js +54 -0
- data/app/assets/javascripts/highcharts/themes/dark-blue.js +6 -6
- data/app/assets/javascripts/highcharts/themes/dark-green.js +6 -6
- data/app/assets/javascripts/highcharts/themes/dark-unica.js +6 -6
- data/app/assets/javascripts/highcharts/themes/gray.js +14 -10
- data/app/assets/javascripts/highcharts/themes/grid-light.js +6 -6
- data/app/assets/javascripts/highcharts/themes/grid.js +7 -5
- data/app/assets/javascripts/highcharts/themes/sand-signika.js +8 -7
- data/app/assets/javascripts/highcharts/themes/skies.js +15 -9
- data/app/assets/javascripts/highcharts/themes/sunset.js +53 -0
- data/app/assets/stylesheets/highcharts/highcharts.css +802 -0
- data/app/assets/stylesheets/highcharts/highcharts.scss +665 -0
- data/lib/highcharts/version.rb +1 -1
- metadata +31 -1
@@ -0,0 +1,681 @@
|
|
1
|
+
/**
|
2
|
+
* @license Highcharts JS v6.0.0 (2017-10-04)
|
3
|
+
*
|
4
|
+
* (c) 2016 Highsoft AS
|
5
|
+
* Authors: Jon Arild Nygard
|
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
|
+
var draw = (function() {
|
18
|
+
var isFn = function(x) {
|
19
|
+
return typeof x === 'function';
|
20
|
+
};
|
21
|
+
|
22
|
+
/**
|
23
|
+
* draw - Handles the drawing of a point.
|
24
|
+
* TODO: add type checking.
|
25
|
+
*
|
26
|
+
* @param {object} params Parameters.
|
27
|
+
* @return {undefined} Returns undefined.
|
28
|
+
*/
|
29
|
+
var draw = function draw(params) {
|
30
|
+
var point = this,
|
31
|
+
graphic = point.graphic,
|
32
|
+
animate = params.animate,
|
33
|
+
attr = params.attr,
|
34
|
+
onComplete = params.onComplete,
|
35
|
+
css = params.css,
|
36
|
+
group = params.group,
|
37
|
+
renderer = params.renderer,
|
38
|
+
shape = params.shapeArgs,
|
39
|
+
type = params.shapeType;
|
40
|
+
|
41
|
+
if (point.shouldDraw()) {
|
42
|
+
if (!graphic) {
|
43
|
+
point.graphic = graphic = renderer[type](shape).add(group);
|
44
|
+
}
|
45
|
+
graphic.css(css).attr(attr).animate(animate, undefined, onComplete);
|
46
|
+
} else if (graphic) {
|
47
|
+
graphic.animate(animate, undefined, function() {
|
48
|
+
point.graphic = graphic = graphic.destroy();
|
49
|
+
if (isFn(onComplete)) {
|
50
|
+
onComplete();
|
51
|
+
}
|
52
|
+
});
|
53
|
+
}
|
54
|
+
};
|
55
|
+
return draw;
|
56
|
+
}());
|
57
|
+
(function(H, drawPoint) {
|
58
|
+
/**
|
59
|
+
* (c) 2016 Highsoft AS
|
60
|
+
* Authors: Jon Arild Nygard
|
61
|
+
*
|
62
|
+
* License: www.highcharts.com/license
|
63
|
+
*
|
64
|
+
* This is an experimental Highcharts module which enables visualization
|
65
|
+
* of a word cloud.
|
66
|
+
*/
|
67
|
+
var each = H.each,
|
68
|
+
extend = H.extend,
|
69
|
+
isNumber = H.isNumber,
|
70
|
+
isObject = H.isObject,
|
71
|
+
Series = H.Series;
|
72
|
+
|
73
|
+
/**
|
74
|
+
* isRectanglesIntersecting - Detects if there is a collision between two
|
75
|
+
* rectangles.
|
76
|
+
*
|
77
|
+
* @param {object} r1 First rectangle.
|
78
|
+
* @param {object} r2 Second rectangle.
|
79
|
+
* @return {boolean} Returns true if the rectangles overlap.
|
80
|
+
*/
|
81
|
+
var isRectanglesIntersecting = function isRectanglesIntersecting(r1, r2) {
|
82
|
+
return !(
|
83
|
+
r2.left > r1.right ||
|
84
|
+
r2.right < r1.left ||
|
85
|
+
r2.top > r1.bottom ||
|
86
|
+
r2.bottom < r1.top
|
87
|
+
);
|
88
|
+
};
|
89
|
+
|
90
|
+
/**
|
91
|
+
* intersectsAnyWord - Detects if a word collides with any previously placed
|
92
|
+
* words.
|
93
|
+
*
|
94
|
+
* @param {Point} point Point which the word is connected to.
|
95
|
+
* @param {Array} points Previously placed points to check against.
|
96
|
+
* @return {boolean} Returns true if there is collision.
|
97
|
+
*/
|
98
|
+
var intersectsAnyWord = function intersectsAnyWord(point, points) {
|
99
|
+
var intersects = false,
|
100
|
+
rect1 = point.rect,
|
101
|
+
rect2;
|
102
|
+
if (point.lastCollidedWith) {
|
103
|
+
rect2 = point.lastCollidedWith.rect;
|
104
|
+
intersects = isRectanglesIntersecting(rect1, rect2);
|
105
|
+
// If they no longer intersects, remove the cache from the point.
|
106
|
+
if (!intersects) {
|
107
|
+
delete point.lastCollidedWith;
|
108
|
+
}
|
109
|
+
}
|
110
|
+
if (!intersects) {
|
111
|
+
intersects = !!H.find(points, function(p) {
|
112
|
+
var result;
|
113
|
+
rect2 = p.rect;
|
114
|
+
result = isRectanglesIntersecting(rect1, rect2);
|
115
|
+
if (result) {
|
116
|
+
point.lastCollidedWith = p;
|
117
|
+
}
|
118
|
+
return result;
|
119
|
+
});
|
120
|
+
}
|
121
|
+
return intersects;
|
122
|
+
};
|
123
|
+
|
124
|
+
/**
|
125
|
+
* archimedeanSpiral - Gives a set of cordinates for an Archimedian Spiral.
|
126
|
+
*
|
127
|
+
* @param {type} t How far along the spiral we have traversed.
|
128
|
+
* @return {object} Resulting coordinates, x and y.
|
129
|
+
*/
|
130
|
+
var archimedeanSpiral = function archimedeanSpiral(t) {
|
131
|
+
t *= 0.1;
|
132
|
+
return {
|
133
|
+
x: t * Math.cos(t),
|
134
|
+
y: t * Math.sin(t)
|
135
|
+
};
|
136
|
+
};
|
137
|
+
|
138
|
+
/**
|
139
|
+
* getRandomPosition
|
140
|
+
*
|
141
|
+
* @param {number} size
|
142
|
+
* @return {number}
|
143
|
+
*/
|
144
|
+
var getRandomPosition = function getRandomPosition(size) {
|
145
|
+
return Math.round((size * (Math.random() + 0.5)) / 2);
|
146
|
+
};
|
147
|
+
|
148
|
+
/**
|
149
|
+
* getScale - Calculates the proper scale to fit the cloud inside the plotting
|
150
|
+
* area.
|
151
|
+
*
|
152
|
+
* @param {number} targetWidth Width of target area.
|
153
|
+
* @param {number} targetHeight Height of target area.
|
154
|
+
* @param {object} field The playing field.
|
155
|
+
* @param {Series} series Series object.
|
156
|
+
* @return {number} Returns the value to scale the playing field up to the size
|
157
|
+
* of the target area.
|
158
|
+
*/
|
159
|
+
var getScale = function getScale(targetWidth, targetHeight, field) {
|
160
|
+
var height = Math.max(Math.abs(field.top), Math.abs(field.bottom)) * 2,
|
161
|
+
width = Math.max(Math.abs(field.left), Math.abs(field.right)) * 2,
|
162
|
+
scaleX = 1 / width * targetWidth,
|
163
|
+
scaleY = 1 / height * targetHeight;
|
164
|
+
return Math.min(scaleX, scaleY);
|
165
|
+
};
|
166
|
+
|
167
|
+
/**
|
168
|
+
* getPlayingField - Calculates what is called the playing field.
|
169
|
+
* The field is the area which all the words are allowed to be positioned
|
170
|
+
* within. The area is proportioned to match the target aspect ratio.
|
171
|
+
*
|
172
|
+
* @param {number} targetWidth Width of the target area.
|
173
|
+
* @param {number} targetHeight Height of the target area.
|
174
|
+
* @return {object} The width and height of the playing field.
|
175
|
+
*/
|
176
|
+
var getPlayingField = function getPlayingField(targetWidth, targetHeight) {
|
177
|
+
var ratio = targetWidth / targetHeight;
|
178
|
+
return {
|
179
|
+
width: 256 * ratio,
|
180
|
+
height: 256
|
181
|
+
};
|
182
|
+
};
|
183
|
+
|
184
|
+
|
185
|
+
/**
|
186
|
+
* getRotation - Calculates a number of degrees to rotate, based upon a number
|
187
|
+
* of orientations within a range from-to.
|
188
|
+
*
|
189
|
+
* @param {type} orientations Number of orientations.
|
190
|
+
* @param {type} from The smallest degree of rotation.
|
191
|
+
* @param {type} to The largest degree of rotation.
|
192
|
+
* @return {type} Returns the resulting rotation for the word.
|
193
|
+
*/
|
194
|
+
var getRotation = function getRotation(orientations, from, to) {
|
195
|
+
var range = to - from,
|
196
|
+
intervals = range / (orientations - 1),
|
197
|
+
orientation = Math.floor(Math.random() * orientations);
|
198
|
+
return from + (orientation * intervals);
|
199
|
+
};
|
200
|
+
|
201
|
+
/**
|
202
|
+
* outsidePlayingField - Detects if a word is placed outside the playing field.
|
203
|
+
*
|
204
|
+
* @param {Point} point Point which the word is connected to.
|
205
|
+
* @param {object} field The width and height of the playing field.
|
206
|
+
* @return {boolean} Returns true if the word is placed outside the field.
|
207
|
+
*/
|
208
|
+
var outsidePlayingField = function outsidePlayingField(wrapper, field) {
|
209
|
+
var rect = wrapper.getBBox(),
|
210
|
+
playingField = {
|
211
|
+
left: -(field.width / 2),
|
212
|
+
right: field.width / 2,
|
213
|
+
top: -(field.height / 2),
|
214
|
+
bottom: field.height / 2
|
215
|
+
};
|
216
|
+
return !(
|
217
|
+
playingField.left < rect.x &&
|
218
|
+
playingField.right > (rect.x + rect.width) &&
|
219
|
+
playingField.top < rect.y &&
|
220
|
+
playingField.bottom > (rect.y + rect.height)
|
221
|
+
);
|
222
|
+
};
|
223
|
+
|
224
|
+
/**
|
225
|
+
* intersectionTesting - Check if a point intersects with previously placed
|
226
|
+
* words, or if it goes outside the field boundaries. If a collision, then try
|
227
|
+
* to adjusts the position.
|
228
|
+
*
|
229
|
+
* @param {object} point Point to test for intersections.
|
230
|
+
* @param {object} options Options object.
|
231
|
+
* @return {boolean|object} Returns an object with how much to correct the
|
232
|
+
* positions. Returns false if the word should not be placed at all.
|
233
|
+
*/
|
234
|
+
var intersectionTesting = function intersectionTesting(point, options) {
|
235
|
+
var placed = options.placed,
|
236
|
+
element = options.element,
|
237
|
+
field = options.field,
|
238
|
+
clientRect = options.clientRect,
|
239
|
+
spiral = options.spiral,
|
240
|
+
maxDelta = options.maxDelta,
|
241
|
+
spiralIsSmallish = true,
|
242
|
+
attempt = 0,
|
243
|
+
delta = {
|
244
|
+
x: 0,
|
245
|
+
y: 0
|
246
|
+
},
|
247
|
+
rect = point.rect = extend({}, clientRect);
|
248
|
+
/**
|
249
|
+
* while w intersects any previously placed words:
|
250
|
+
* do {
|
251
|
+
* move w a little bit along a spiral path
|
252
|
+
* } while any part of w is outside the playing field and
|
253
|
+
* the spiral radius is still smallish
|
254
|
+
*/
|
255
|
+
while (
|
256
|
+
(
|
257
|
+
intersectsAnyWord(point, placed) ||
|
258
|
+
outsidePlayingField(element, field)
|
259
|
+
) && spiralIsSmallish
|
260
|
+
) {
|
261
|
+
delta = spiral(attempt);
|
262
|
+
// Update the DOMRect with new positions.
|
263
|
+
rect.left = clientRect.left + delta.x;
|
264
|
+
rect.right = rect.left + rect.width;
|
265
|
+
rect.top = clientRect.top + delta.y;
|
266
|
+
rect.bottom = rect.top + rect.height;
|
267
|
+
spiralIsSmallish = (
|
268
|
+
Math.min(Math.abs(delta.x), Math.abs(delta.y)) < maxDelta
|
269
|
+
);
|
270
|
+
attempt++;
|
271
|
+
// Emergency brake. TODO make spiralling logic more foolproof.
|
272
|
+
if (attempt > 1000) {
|
273
|
+
spiralIsSmallish = false;
|
274
|
+
}
|
275
|
+
}
|
276
|
+
if (!spiralIsSmallish) {
|
277
|
+
delta = false;
|
278
|
+
}
|
279
|
+
return delta;
|
280
|
+
};
|
281
|
+
|
282
|
+
/**
|
283
|
+
* updateFieldBoundaries - If a rectangle is outside a give field, then the
|
284
|
+
* boundaries of the field is adjusted accordingly. Modifies the field object
|
285
|
+
* which is passed as the first parameter.
|
286
|
+
*
|
287
|
+
* @param {object} field The bounding box of a playing field.
|
288
|
+
* @param {object} placement The bounding box for a placed point.
|
289
|
+
* @return {object} Returns a modified field object.
|
290
|
+
*/
|
291
|
+
var updateFieldBoundaries = function updateFieldBoundaries(field, rectangle) {
|
292
|
+
// TODO improve type checking.
|
293
|
+
if (!isNumber(field.left) || field.left > rectangle.left) {
|
294
|
+
field.left = rectangle.left;
|
295
|
+
}
|
296
|
+
if (!isNumber(field.right) || field.right < rectangle.right) {
|
297
|
+
field.right = rectangle.right;
|
298
|
+
}
|
299
|
+
if (!isNumber(field.top) || field.top > rectangle.top) {
|
300
|
+
field.top = rectangle.top;
|
301
|
+
}
|
302
|
+
if (!isNumber(field.bottom) || field.bottom < rectangle.bottom) {
|
303
|
+
field.bottom = rectangle.bottom;
|
304
|
+
}
|
305
|
+
return field;
|
306
|
+
};
|
307
|
+
|
308
|
+
/**
|
309
|
+
* A word cloud is a visualization of a set of words, where the size and
|
310
|
+
* placement of a word is determined by how it is weighted.
|
311
|
+
*
|
312
|
+
* @extends {plotOptions.column}
|
313
|
+
* @sample highcharts/demo/wordcloud Word Cloud chart
|
314
|
+
* @excluding allAreas, boostThreshold, clip, colorAxis, compare, compareBase,
|
315
|
+
* crisp, cropTreshold, dataGrouping, dataLabels, depth, edgeColor,
|
316
|
+
* findNearestPointBy, getExtremesFromAll, grouping, groupPadding,
|
317
|
+
* groupZPadding, joinBy, maxPointWidth, minPointLength,
|
318
|
+
* navigatorOptions, negativeColor, pointInterval, pointIntervalUnit,
|
319
|
+
* pointPadding, pointPlacement, pointRange, pointStart, pointWidth,
|
320
|
+
* pointStart, pointWidth, shadow, showCheckbox, showInNavigator,
|
321
|
+
* softThreshold, stacking, threshold, zoneAxis, zones
|
322
|
+
* @product highcharts
|
323
|
+
* @since 6.0.0
|
324
|
+
* @optionparent plotOptions.wordcloud
|
325
|
+
*/
|
326
|
+
var wordCloudOptions = {
|
327
|
+
animation: {
|
328
|
+
duration: 500
|
329
|
+
},
|
330
|
+
borderWidth: 0,
|
331
|
+
clip: false, // Something goes wrong with clip. // TODO fix this
|
332
|
+
/**
|
333
|
+
* When using automatic point colors pulled from the `options.colors`
|
334
|
+
* collection, this option determines whether the chart should receive
|
335
|
+
* one color per series or one color per point.
|
336
|
+
*
|
337
|
+
* @see [series colors](#plotOptions.column.colors)
|
338
|
+
*/
|
339
|
+
colorByPoint: true,
|
340
|
+
/**
|
341
|
+
* This option decides which algorithm is used for placement, and rotation
|
342
|
+
* of a word. The choice of algorith is therefore a crucial part of the
|
343
|
+
* resulting layout of the wordcloud.
|
344
|
+
* It is possible for users to add their own custom placement strategies
|
345
|
+
* for use in word cloud. Read more about it in our
|
346
|
+
* [documentation](https://www.highcharts.com/docs/chart-and-series-types/word-cloud-series#custom-placement-strategies)
|
347
|
+
*
|
348
|
+
* @validvalue: ["random"]
|
349
|
+
*/
|
350
|
+
placementStrategy: 'random',
|
351
|
+
/**
|
352
|
+
* Rotation options for the words in the wordcloud.
|
353
|
+
* @sample highcharts/plotoptions/wordcloud-rotation
|
354
|
+
* Word cloud with rotation
|
355
|
+
*/
|
356
|
+
rotation: {
|
357
|
+
/**
|
358
|
+
* The smallest degree of rotation for a word.
|
359
|
+
*/
|
360
|
+
from: 0,
|
361
|
+
/**
|
362
|
+
* The number of possible orientations for a word, within the range of
|
363
|
+
* `rotation.from` and `rotation.to`.
|
364
|
+
*/
|
365
|
+
orientations: 2,
|
366
|
+
/**
|
367
|
+
* The largest degree of rotation for a word.
|
368
|
+
*/
|
369
|
+
to: 90
|
370
|
+
},
|
371
|
+
showInLegend: false,
|
372
|
+
/**
|
373
|
+
* Spiral used for placing a word after the inital position experienced a
|
374
|
+
* collision with either another word or the borders.
|
375
|
+
* It is possible for users to add their own custom spiralling algorithms
|
376
|
+
* for use in word cloud. Read more about it in our
|
377
|
+
* [documentation](https://www.highcharts.com/docs/chart-and-series-types/word-cloud-series#custom-spiralling-algorithm)
|
378
|
+
*
|
379
|
+
* @validvalue: ["archimedean"]
|
380
|
+
*/
|
381
|
+
spiral: 'archimedean',
|
382
|
+
/**
|
383
|
+
* CSS styles for the words.
|
384
|
+
*
|
385
|
+
* @type {CSSObject}
|
386
|
+
* @default {"fontFamily":"Impact, sans-serif"}
|
387
|
+
*/
|
388
|
+
style: {
|
389
|
+
/**
|
390
|
+
* The font family to use for the word cloud.
|
391
|
+
*/
|
392
|
+
fontFamily: 'Impact, sans-serif'
|
393
|
+
},
|
394
|
+
tooltip: {
|
395
|
+
followPointer: true
|
396
|
+
}
|
397
|
+
};
|
398
|
+
|
399
|
+
/**
|
400
|
+
* Properties of the WordCloud series.
|
401
|
+
*/
|
402
|
+
var wordCloudSeries = {
|
403
|
+
animate: Series.prototype.animate,
|
404
|
+
bindAxes: function() {
|
405
|
+
var wordcloudAxis = {
|
406
|
+
endOnTick: false,
|
407
|
+
gridLineWidth: 0,
|
408
|
+
lineWidth: 0,
|
409
|
+
maxPadding: 0,
|
410
|
+
startOnTick: false,
|
411
|
+
title: null,
|
412
|
+
tickPositions: []
|
413
|
+
};
|
414
|
+
Series.prototype.bindAxes.call(this);
|
415
|
+
extend(this.yAxis.options, wordcloudAxis);
|
416
|
+
extend(this.xAxis.options, wordcloudAxis);
|
417
|
+
},
|
418
|
+
/**
|
419
|
+
* deriveFontSize - Calculates the fontSize of a word based on its weight.
|
420
|
+
*
|
421
|
+
* @param {number} relativeWeight The weight of the word, on a scale 0-1.
|
422
|
+
* @return {number} Returns the resulting fontSize of a word.
|
423
|
+
*/
|
424
|
+
deriveFontSize: function deriveFontSize(relativeWeight) {
|
425
|
+
var maxFontSize = 25;
|
426
|
+
return Math.floor(maxFontSize * relativeWeight);
|
427
|
+
},
|
428
|
+
drawPoints: function() {
|
429
|
+
var series = this,
|
430
|
+
hasRendered = series.hasRendered,
|
431
|
+
xAxis = series.xAxis,
|
432
|
+
yAxis = series.yAxis,
|
433
|
+
chart = series.chart,
|
434
|
+
group = series.group,
|
435
|
+
options = series.options,
|
436
|
+
animation = options.animation,
|
437
|
+
renderer = chart.renderer,
|
438
|
+
testElement = renderer.text().add(group),
|
439
|
+
placed = [],
|
440
|
+
placementStrategy = series.placementStrategy[options.placementStrategy],
|
441
|
+
spiral = series.spirals[options.spiral],
|
442
|
+
rotation = options.rotation,
|
443
|
+
scale,
|
444
|
+
weights = series.points
|
445
|
+
.map(function(p) {
|
446
|
+
return p.weight;
|
447
|
+
}),
|
448
|
+
maxWeight = Math.max.apply(null, weights),
|
449
|
+
field = getPlayingField(xAxis.len, yAxis.len),
|
450
|
+
maxDelta = (field.width * field.width) + (field.height * field.height),
|
451
|
+
data = series.points
|
452
|
+
.sort(function(a, b) {
|
453
|
+
return b.weight - a.weight; // Sort descending
|
454
|
+
});
|
455
|
+
each(data, function(point) {
|
456
|
+
var relativeWeight = 1 / maxWeight * point.weight,
|
457
|
+
css = extend({
|
458
|
+
fontSize: series.deriveFontSize(relativeWeight),
|
459
|
+
fill: point.color
|
460
|
+
}, options.style),
|
461
|
+
placement = placementStrategy(point, {
|
462
|
+
data: data,
|
463
|
+
field: field,
|
464
|
+
placed: placed,
|
465
|
+
rotation: rotation
|
466
|
+
}),
|
467
|
+
attr = {
|
468
|
+
align: 'center',
|
469
|
+
x: placement.x,
|
470
|
+
y: placement.y,
|
471
|
+
text: point.name,
|
472
|
+
rotation: placement.rotation
|
473
|
+
},
|
474
|
+
animate,
|
475
|
+
delta,
|
476
|
+
clientRect;
|
477
|
+
testElement.css(css).attr(attr);
|
478
|
+
// Cache the original DOMRect values for later calculations.
|
479
|
+
point.clientRect = clientRect = extend({},
|
480
|
+
testElement.element.getBoundingClientRect()
|
481
|
+
);
|
482
|
+
delta = intersectionTesting(point, {
|
483
|
+
clientRect: clientRect,
|
484
|
+
element: testElement,
|
485
|
+
field: field,
|
486
|
+
maxDelta: maxDelta,
|
487
|
+
placed: placed,
|
488
|
+
spiral: spiral
|
489
|
+
});
|
490
|
+
/**
|
491
|
+
* Check if point was placed, if so delete it,
|
492
|
+
* otherwise place it on the correct positions.
|
493
|
+
*/
|
494
|
+
if (isObject(delta)) {
|
495
|
+
attr.x += delta.x;
|
496
|
+
attr.y += delta.y;
|
497
|
+
extend(placement, {
|
498
|
+
left: attr.x - (clientRect.width / 2),
|
499
|
+
right: attr.x + (clientRect.width / 2),
|
500
|
+
top: attr.y - (clientRect.height / 2),
|
501
|
+
bottom: attr.y + (clientRect.height / 2)
|
502
|
+
});
|
503
|
+
field = updateFieldBoundaries(field, placement);
|
504
|
+
placed.push(point);
|
505
|
+
point.isNull = false;
|
506
|
+
} else {
|
507
|
+
point.isNull = true;
|
508
|
+
}
|
509
|
+
|
510
|
+
if (animation) {
|
511
|
+
// Animate to new positions
|
512
|
+
animate = {
|
513
|
+
x: attr.x,
|
514
|
+
y: attr.y
|
515
|
+
};
|
516
|
+
// Animate from center of chart
|
517
|
+
if (!hasRendered) {
|
518
|
+
attr.x = 0;
|
519
|
+
attr.y = 0;
|
520
|
+
// or animate from previous position
|
521
|
+
} else {
|
522
|
+
delete attr.x;
|
523
|
+
delete attr.y;
|
524
|
+
}
|
525
|
+
}
|
526
|
+
|
527
|
+
point.draw({
|
528
|
+
animate: animate,
|
529
|
+
attr: attr,
|
530
|
+
css: css,
|
531
|
+
group: group,
|
532
|
+
renderer: renderer,
|
533
|
+
shapeArgs: undefined,
|
534
|
+
shapeType: 'text'
|
535
|
+
});
|
536
|
+
});
|
537
|
+
|
538
|
+
// Destroy the element after use.
|
539
|
+
testElement = testElement.destroy();
|
540
|
+
|
541
|
+
/**
|
542
|
+
* Scale the series group to fit within the plotArea.
|
543
|
+
*/
|
544
|
+
scale = getScale(xAxis.len, yAxis.len, field);
|
545
|
+
series.group.attr({
|
546
|
+
scaleX: scale,
|
547
|
+
scaleY: scale
|
548
|
+
});
|
549
|
+
},
|
550
|
+
/**
|
551
|
+
* Strategies used for deciding rotation and initial position of a word.
|
552
|
+
* To implement a custom strategy, have a look at the function
|
553
|
+
* randomPlacement for example.
|
554
|
+
*/
|
555
|
+
placementStrategy: {
|
556
|
+
random: function randomPlacement(point, options) {
|
557
|
+
var field = options.field,
|
558
|
+
r = options.rotation;
|
559
|
+
return {
|
560
|
+
x: getRandomPosition(field.width) - (field.width / 2),
|
561
|
+
y: getRandomPosition(field.height) - (field.height / 2),
|
562
|
+
rotation: getRotation(r.orientations, r.from, r.to)
|
563
|
+
};
|
564
|
+
}
|
565
|
+
},
|
566
|
+
pointArrayMap: ['weight'],
|
567
|
+
/**
|
568
|
+
* Spirals used for placing a word after the inital position experienced a
|
569
|
+
* collision with either another word or the borders.
|
570
|
+
* To implement a custom spiral, look at the function archimedeanSpiral for
|
571
|
+
* example.
|
572
|
+
*/
|
573
|
+
spirals: {
|
574
|
+
'archimedean': archimedeanSpiral
|
575
|
+
},
|
576
|
+
getPlotBox: function() {
|
577
|
+
var series = this,
|
578
|
+
chart = series.chart,
|
579
|
+
inverted = chart.inverted,
|
580
|
+
// Swap axes for inverted (#2339)
|
581
|
+
xAxis = series[(inverted ? 'yAxis' : 'xAxis')],
|
582
|
+
yAxis = series[(inverted ? 'xAxis' : 'yAxis')],
|
583
|
+
width = xAxis ? xAxis.len : chart.plotWidth,
|
584
|
+
height = yAxis ? yAxis.len : chart.plotHeight,
|
585
|
+
x = xAxis ? xAxis.left : chart.plotLeft,
|
586
|
+
y = yAxis ? yAxis.top : chart.plotTop;
|
587
|
+
return {
|
588
|
+
translateX: x + (width / 2),
|
589
|
+
translateY: y + (height / 2),
|
590
|
+
scaleX: 1, // #1623
|
591
|
+
scaleY: 1
|
592
|
+
};
|
593
|
+
}
|
594
|
+
};
|
595
|
+
|
596
|
+
/**
|
597
|
+
* Properties of the Sunburst series.
|
598
|
+
*/
|
599
|
+
var wordCloudPoint = {
|
600
|
+
draw: drawPoint,
|
601
|
+
shouldDraw: function shouldDraw() {
|
602
|
+
var point = this;
|
603
|
+
return !point.isNull;
|
604
|
+
}
|
605
|
+
};
|
606
|
+
|
607
|
+
/**
|
608
|
+
* A `wordcloud` series. If the [type](#series.wordcloud.type) option is
|
609
|
+
* not specified, it is inherited from [chart.type](#chart.type).
|
610
|
+
*
|
611
|
+
* For options that apply to multiple series, it is recommended to add
|
612
|
+
* them to the [plotOptions.series](#plotOptions.series) options structure.
|
613
|
+
* To apply to all series of this specific type, apply it to [plotOptions.
|
614
|
+
* wordcloud](#plotOptions.wordcloud).
|
615
|
+
*
|
616
|
+
* @type {Object}
|
617
|
+
* @extends plotOptions.wordcloud
|
618
|
+
* @product highcharts
|
619
|
+
* @apioption series.wordcloud
|
620
|
+
*/
|
621
|
+
|
622
|
+
/**
|
623
|
+
* An array of data points for the series. For the `wordcloud` series
|
624
|
+
* type, points can be given in the following ways:
|
625
|
+
*
|
626
|
+
* 1. An array of arrays with 2 values. In this case, the values
|
627
|
+
* correspond to `name,weight`.
|
628
|
+
*
|
629
|
+
* ```js
|
630
|
+
* data: [
|
631
|
+
* ['Lorem', 4],
|
632
|
+
* ['Ipsum', 1]
|
633
|
+
* ]
|
634
|
+
* ```
|
635
|
+
*
|
636
|
+
* 2. An array of objects with named values. The objects are point
|
637
|
+
* configuration objects as seen below. If the total number of data
|
638
|
+
* points exceeds the series' [turboThreshold](#series.arearange.turboThreshold),
|
639
|
+
* this option is not available.
|
640
|
+
*
|
641
|
+
* ```js
|
642
|
+
* data: [{
|
643
|
+
* name: "Lorem",
|
644
|
+
* weight: 4
|
645
|
+
* }, {
|
646
|
+
* name: "Ipsum",
|
647
|
+
* weight: 1
|
648
|
+
* }]
|
649
|
+
* ```
|
650
|
+
*
|
651
|
+
* @type {Array<Object|Array>}
|
652
|
+
* @extends series.line.data
|
653
|
+
* @excluding drilldown,marker,x,y
|
654
|
+
* @product highcharts
|
655
|
+
* @apioption series.wordcloud.data
|
656
|
+
*/
|
657
|
+
|
658
|
+
/**
|
659
|
+
* The name decides the text for a word.
|
660
|
+
*
|
661
|
+
* @type {String}
|
662
|
+
* @default undefined
|
663
|
+
* @since 6.0.0
|
664
|
+
* @product highcharts
|
665
|
+
* @apioption series.sunburst.data.name
|
666
|
+
*/
|
667
|
+
|
668
|
+
/**
|
669
|
+
* The weighting of a word. The weight decides the relative size of a word
|
670
|
+
* compared to the rest of the collection.
|
671
|
+
*
|
672
|
+
* @type {Number}
|
673
|
+
* @default undefined
|
674
|
+
* @since 6.0.0
|
675
|
+
* @product highcharts
|
676
|
+
* @apioption series.sunburst.data.weight
|
677
|
+
*/
|
678
|
+
H.seriesType('wordcloud', 'column', wordCloudOptions, wordCloudSeries, wordCloudPoint);
|
679
|
+
|
680
|
+
}(Highcharts, draw));
|
681
|
+
}));
|