highcharts-rails 3.0.2 → 3.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- checksums.yaml.gz.asc +18 -0
- data/CHANGELOG.markdown +4 -0
- data/Rakefile +29 -1
- data/app/assets/javascripts/highcharts/adapters/mootools.js +1 -1
- data/app/assets/javascripts/highcharts/adapters/prototype.js +1 -1
- data/app/assets/javascripts/highcharts/highcharts-more.js +118 -217
- data/app/assets/javascripts/highcharts/modules/annotations.js +74 -27
- data/app/assets/javascripts/highcharts/modules/canvas-tools.js +1 -1
- data/app/assets/javascripts/highcharts/modules/data.js +74 -29
- data/app/assets/javascripts/highcharts/modules/exporting.js +5 -8
- data/app/assets/javascripts/highcharts/modules/funnel.js +2 -2
- data/app/assets/javascripts/highcharts/modules/heatmap.js +57 -0
- data/app/assets/javascripts/highcharts/modules/map.js +576 -0
- data/app/assets/javascripts/highcharts.js +853 -497
- data/highcharts-rails.gemspec +1 -0
- data/lib/highcharts/version.rb +1 -1
- data.tar.gz.asc +14 -14
- metadata +18 -23
- metadata.gz.asc +14 -14
@@ -0,0 +1,576 @@
|
|
1
|
+
/**
|
2
|
+
* @license Map plugin v0.1 for Highcharts
|
3
|
+
*
|
4
|
+
* (c) 2011-2013 Torstein Hønsi
|
5
|
+
*
|
6
|
+
* License: www.highcharts.com/license
|
7
|
+
*/
|
8
|
+
|
9
|
+
/*
|
10
|
+
* See www.highcharts.com/studies/world-map.htm for use case.
|
11
|
+
*
|
12
|
+
* To do:
|
13
|
+
* - Optimize long variable names and alias adapter methods and Highcharts namespace variables
|
14
|
+
* - Zoom and pan GUI
|
15
|
+
*/
|
16
|
+
(function (Highcharts) {
|
17
|
+
var UNDEFINED,
|
18
|
+
Axis = Highcharts.Axis,
|
19
|
+
each = Highcharts.each,
|
20
|
+
extend = Highcharts.extend,
|
21
|
+
merge = Highcharts.merge,
|
22
|
+
pick = Highcharts.pick,
|
23
|
+
numberFormat = Highcharts.numberFormat,
|
24
|
+
plotOptions = Highcharts.getOptions().plotOptions,
|
25
|
+
Color = Highcharts.Color,
|
26
|
+
noop = function () {};
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Utility for reading SVG paths directly.
|
30
|
+
*
|
31
|
+
* @todo This is moved to the Data plugin. Make sure it is deleted here.
|
32
|
+
*/
|
33
|
+
Highcharts.pathToArray = function (path) {
|
34
|
+
var i;
|
35
|
+
|
36
|
+
// Move letters apart
|
37
|
+
path = path.replace(/([A-Za-z])/g, ' $1 ');
|
38
|
+
// Trim
|
39
|
+
path = path.replace(/^\s*/, "").replace(/\s*$/, "");
|
40
|
+
|
41
|
+
// Split on spaces and commas
|
42
|
+
path = path.split(/[ ,]+/);
|
43
|
+
|
44
|
+
for (i = 0; i < path.length; i++) {
|
45
|
+
if (!/[a-zA-Z]/.test(path[i])) {
|
46
|
+
path[i] = parseFloat(path[i]);
|
47
|
+
}
|
48
|
+
}
|
49
|
+
return path;
|
50
|
+
};
|
51
|
+
|
52
|
+
/**
|
53
|
+
* Extend the Axis object with methods specific to maps
|
54
|
+
*/
|
55
|
+
Highcharts.wrap(Axis.prototype, 'init', function (proceed, chart, userOptions) {
|
56
|
+
|
57
|
+
if (chart.options.chart.type === 'map') {
|
58
|
+
extend(this, {
|
59
|
+
|
60
|
+
/**
|
61
|
+
* Override to use the extreme coordinates from the SVG shape, not the
|
62
|
+
* data values
|
63
|
+
*/
|
64
|
+
getSeriesExtremes: function () {
|
65
|
+
var isXAxis = this.isXAxis,
|
66
|
+
dataMin = Number.MAX_VALUE,
|
67
|
+
dataMax = Number.MIN_VALUE;
|
68
|
+
each(this.series, function (series) {
|
69
|
+
dataMin = Math.min(dataMin, series[isXAxis ? 'minX' : 'minY']);
|
70
|
+
dataMax = Math.max(dataMax, series[isXAxis ? 'maxX' : 'maxY']);
|
71
|
+
});
|
72
|
+
this.dataMin = dataMin;
|
73
|
+
this.dataMax = dataMax;
|
74
|
+
},
|
75
|
+
|
76
|
+
/**
|
77
|
+
* Override axis translation to make sure the aspect ratio is always kept
|
78
|
+
*/
|
79
|
+
setAxisTranslation: function () {
|
80
|
+
var chart = this.chart,
|
81
|
+
mapRatio,
|
82
|
+
plotRatio = chart.plotWidth / chart.plotHeight,
|
83
|
+
isXAxis = this.isXAxis,
|
84
|
+
adjustedAxisLength,
|
85
|
+
xAxis = chart.xAxis[0],
|
86
|
+
padAxis;
|
87
|
+
|
88
|
+
// Run the parent method
|
89
|
+
Axis.prototype.setAxisTranslation.call(this);
|
90
|
+
|
91
|
+
// On Y axis, handle both
|
92
|
+
if (!isXAxis && xAxis.transA !== UNDEFINED) {
|
93
|
+
|
94
|
+
// Use the same translation for both axes
|
95
|
+
this.transA = xAxis.transA = Math.min(this.transA, xAxis.transA);
|
96
|
+
|
97
|
+
mapRatio = (xAxis.max - xAxis.min) / (this.max - this.min);
|
98
|
+
|
99
|
+
// What axis to pad to put the map in the middle
|
100
|
+
padAxis = mapRatio > plotRatio ? this : xAxis;
|
101
|
+
|
102
|
+
// Pad it
|
103
|
+
adjustedAxisLength = (padAxis.max - padAxis.min) * padAxis.transA;
|
104
|
+
padAxis.minPixelPadding = (padAxis.len - adjustedAxisLength) / 2;
|
105
|
+
}
|
106
|
+
|
107
|
+
}
|
108
|
+
});
|
109
|
+
}
|
110
|
+
|
111
|
+
return proceed.call(this, chart, userOptions);
|
112
|
+
});
|
113
|
+
|
114
|
+
/**
|
115
|
+
* Extend the default options with map options
|
116
|
+
*/
|
117
|
+
plotOptions.map = merge(
|
118
|
+
plotOptions.scatter,
|
119
|
+
{
|
120
|
+
animation: false, // makes the complex shapes slow
|
121
|
+
minOpacity: 0.2,
|
122
|
+
nullColor: '#F8F8F8',
|
123
|
+
borderColor: 'silver',
|
124
|
+
borderWidth: 1,
|
125
|
+
marker: null,
|
126
|
+
stickyTracking: false,
|
127
|
+
tooltip: {
|
128
|
+
followPointer: true,
|
129
|
+
headerFormat: '<span style="font-size:10px">{point.key}</span><br/>',
|
130
|
+
pointFormat: '{series.name}: {point.y}<br/>'
|
131
|
+
}
|
132
|
+
}
|
133
|
+
);
|
134
|
+
|
135
|
+
/**
|
136
|
+
* Add the series type
|
137
|
+
*/
|
138
|
+
Highcharts.seriesTypes.map = Highcharts.extendClass(Highcharts.seriesTypes.scatter, {
|
139
|
+
type: 'map',
|
140
|
+
pointAttrToOptions: { // mapping between SVG attributes and the corresponding options
|
141
|
+
stroke: 'borderColor',
|
142
|
+
'stroke-width': 'borderWidth',
|
143
|
+
fill: 'color'
|
144
|
+
},
|
145
|
+
colorKey: 'y',
|
146
|
+
trackerGroups: ['group', 'markerGroup'],
|
147
|
+
getSymbol: noop,
|
148
|
+
getExtremesFromAll: true,
|
149
|
+
init: function (chart) {
|
150
|
+
var series = this,
|
151
|
+
valueDecimals = chart.options.legend.valueDecimals,
|
152
|
+
legendItems = [],
|
153
|
+
name,
|
154
|
+
from,
|
155
|
+
to,
|
156
|
+
fromLabel,
|
157
|
+
toLabel,
|
158
|
+
colorRange,
|
159
|
+
gradientColor,
|
160
|
+
grad,
|
161
|
+
tmpLabel,
|
162
|
+
horizontal = chart.options.legend.layout === 'horizontal';
|
163
|
+
|
164
|
+
|
165
|
+
Highcharts.Series.prototype.init.apply(this, arguments);
|
166
|
+
colorRange = series.options.colorRange;
|
167
|
+
|
168
|
+
if (series.options.valueRanges) {
|
169
|
+
each(series.options.valueRanges, function (range) {
|
170
|
+
from = range.from;
|
171
|
+
to = range.to;
|
172
|
+
|
173
|
+
// Assemble the default name. This can be overridden by legend.options.labelFormatter
|
174
|
+
name = '';
|
175
|
+
if (from === UNDEFINED) {
|
176
|
+
name = '< ';
|
177
|
+
} else if (to === UNDEFINED) {
|
178
|
+
name = '> ';
|
179
|
+
}
|
180
|
+
if (from !== UNDEFINED) {
|
181
|
+
name += numberFormat(from, valueDecimals);
|
182
|
+
}
|
183
|
+
if (from !== UNDEFINED && to !== UNDEFINED) {
|
184
|
+
name += ' - ';
|
185
|
+
}
|
186
|
+
if (to !== UNDEFINED) {
|
187
|
+
name += numberFormat(to, valueDecimals);
|
188
|
+
}
|
189
|
+
|
190
|
+
// Add a mock object to the legend items
|
191
|
+
legendItems.push(Highcharts.extend({
|
192
|
+
chart: series.chart,
|
193
|
+
name: name,
|
194
|
+
options: {},
|
195
|
+
drawLegendSymbol: Highcharts.seriesTypes.area.prototype.drawLegendSymbol,
|
196
|
+
visible: true,
|
197
|
+
setState: function () {},
|
198
|
+
setVisible: function () {}
|
199
|
+
}, range));
|
200
|
+
});
|
201
|
+
series.legendItems = legendItems;
|
202
|
+
|
203
|
+
} else if (colorRange) {
|
204
|
+
|
205
|
+
from = colorRange.from;
|
206
|
+
to = colorRange.to;
|
207
|
+
fromLabel = colorRange.fromLabel;
|
208
|
+
toLabel = colorRange.toLabel;
|
209
|
+
|
210
|
+
// Flips linearGradient variables and label text.
|
211
|
+
grad = horizontal ? [0, 0, 1, 0] : [0, 1, 0, 0];
|
212
|
+
if (!horizontal) {
|
213
|
+
tmpLabel = fromLabel;
|
214
|
+
fromLabel = toLabel;
|
215
|
+
toLabel = tmpLabel;
|
216
|
+
}
|
217
|
+
|
218
|
+
// Creates color gradient.
|
219
|
+
gradientColor = {
|
220
|
+
linearGradient: { x1: grad[0], y1: grad[1], x2: grad[2], y2: grad[3] },
|
221
|
+
stops:
|
222
|
+
[
|
223
|
+
[0, from],
|
224
|
+
[1, to]
|
225
|
+
]
|
226
|
+
};
|
227
|
+
|
228
|
+
// Add a mock object to the legend items.
|
229
|
+
legendItems = [{
|
230
|
+
chart: series.chart,
|
231
|
+
options: {},
|
232
|
+
fromLabel: fromLabel,
|
233
|
+
toLabel: toLabel,
|
234
|
+
color: gradientColor,
|
235
|
+
drawLegendSymbol: this.drawLegendSymbol,
|
236
|
+
visible: true,
|
237
|
+
setState: function () {},
|
238
|
+
setVisible: function () {}
|
239
|
+
}];
|
240
|
+
|
241
|
+
series.legendItems = legendItems;
|
242
|
+
}
|
243
|
+
},
|
244
|
+
|
245
|
+
/**
|
246
|
+
* Gets the series' symbol in the legend and extended legend with more information.
|
247
|
+
*
|
248
|
+
* @param {Object} legend The legend object
|
249
|
+
* @param {Object} item The series (this) or point
|
250
|
+
*/
|
251
|
+
drawLegendSymbol: function (legend, item) {
|
252
|
+
|
253
|
+
var spacing = legend.options.symbolPadding,
|
254
|
+
padding = pick(legend.options.padding, 8),
|
255
|
+
positionY,
|
256
|
+
positionX,
|
257
|
+
gradientSize = this.chart.renderer.fontMetrics(legend.options.itemStyle.fontSize).h,
|
258
|
+
horizontal = legend.options.layout === 'horizontal',
|
259
|
+
box1,
|
260
|
+
box2,
|
261
|
+
box3,
|
262
|
+
rectangleLength = pick(legend.options.rectangleLength, 200);
|
263
|
+
|
264
|
+
// Set local variables based on option.
|
265
|
+
if (horizontal) {
|
266
|
+
positionY = -(spacing / 2);
|
267
|
+
positionX = 0;
|
268
|
+
} else {
|
269
|
+
positionY = -rectangleLength + legend.baseline - (spacing / 2);
|
270
|
+
positionX = padding + gradientSize;
|
271
|
+
}
|
272
|
+
|
273
|
+
// Creates the from text.
|
274
|
+
item.fromText = this.chart.renderer.text(
|
275
|
+
item.fromLabel, // Text.
|
276
|
+
positionX, // Lower left x.
|
277
|
+
positionY // Lower left y.
|
278
|
+
).attr({
|
279
|
+
zIndex: 2
|
280
|
+
}).add(item.legendGroup);
|
281
|
+
box1 = item.fromText.getBBox();
|
282
|
+
|
283
|
+
// Creates legend symbol.
|
284
|
+
// Ternary changes variables based on option.
|
285
|
+
item.legendSymbol = this.chart.renderer.rect(
|
286
|
+
horizontal ? box1.x + box1.width + spacing : box1.x - gradientSize - spacing, // Upper left x.
|
287
|
+
box1.y, // Upper left y.
|
288
|
+
horizontal ? rectangleLength : gradientSize, // Width.
|
289
|
+
horizontal ? gradientSize : rectangleLength, // Height.
|
290
|
+
2 // Corner radius.
|
291
|
+
).attr({
|
292
|
+
zIndex: 1
|
293
|
+
}).add(item.legendGroup);
|
294
|
+
box2 = item.legendSymbol.getBBox();
|
295
|
+
|
296
|
+
// Creates the to text.
|
297
|
+
// Vertical coordinate changed based on option.
|
298
|
+
item.toText = this.chart.renderer.text(
|
299
|
+
item.toLabel,
|
300
|
+
box2.x + box2.width + spacing,
|
301
|
+
horizontal ? positionY : box2.y + box2.height - spacing
|
302
|
+
).attr({
|
303
|
+
zIndex: 2
|
304
|
+
}).add(item.legendGroup);
|
305
|
+
box3 = item.toText.getBBox();
|
306
|
+
|
307
|
+
// Changes legend box settings based on option.
|
308
|
+
if (horizontal) {
|
309
|
+
legend.offsetWidth = box1.width + box2.width + box3.width + (spacing * 2) + padding;
|
310
|
+
legend.itemY = gradientSize + padding;
|
311
|
+
} else {
|
312
|
+
legend.offsetWidth = Math.max(box1.width, box3.width) + (spacing) + box2.width + padding;
|
313
|
+
legend.itemY = box2.height + padding;
|
314
|
+
legend.itemX = spacing;
|
315
|
+
}
|
316
|
+
},
|
317
|
+
|
318
|
+
/**
|
319
|
+
* Get the bounding box of all paths in the map combined.
|
320
|
+
*/
|
321
|
+
getBox: function () {
|
322
|
+
var chart = this.chart,
|
323
|
+
maxX = -Math.pow(2, 31),
|
324
|
+
minX = Math.pow(2, 31) - 1,
|
325
|
+
maxY = -Math.pow(2, 31),
|
326
|
+
minY = Math.pow(2, 31) - 1,
|
327
|
+
xyRatio,
|
328
|
+
ratioCorrection,
|
329
|
+
plotWidth = chart.plotWidth,
|
330
|
+
plotHeight = chart.plotHeight,
|
331
|
+
pad;
|
332
|
+
|
333
|
+
|
334
|
+
// Find the bounding box
|
335
|
+
each(this.options.data, function (point) {
|
336
|
+
var path = point.path,
|
337
|
+
i = path.length,
|
338
|
+
even = false; // while loop reads from the end
|
339
|
+
|
340
|
+
while (i--) {
|
341
|
+
if (typeof path[i] === 'number') {
|
342
|
+
if (even) { // even = x
|
343
|
+
maxX = Math.max(maxX, path[i]);
|
344
|
+
minX = Math.min(minX, path[i]);
|
345
|
+
} else { // odd = Y
|
346
|
+
maxY = Math.max(maxY, path[i]);
|
347
|
+
minY = Math.min(minY, path[i]);
|
348
|
+
}
|
349
|
+
even = !even;
|
350
|
+
}
|
351
|
+
}
|
352
|
+
});
|
353
|
+
this.minY = minY;
|
354
|
+
this.maxY = maxY;
|
355
|
+
this.minX = minX;
|
356
|
+
this.maxX = maxX;
|
357
|
+
|
358
|
+
},
|
359
|
+
|
360
|
+
|
361
|
+
|
362
|
+
/**
|
363
|
+
* Translate the path so that it automatically fits into the plot area box
|
364
|
+
* @param {Object} path
|
365
|
+
*/
|
366
|
+
translatePath: function (path) {
|
367
|
+
|
368
|
+
var series = this,
|
369
|
+
chart = series.chart,
|
370
|
+
even = false, // while loop reads from the end
|
371
|
+
xAxis = series.xAxis,
|
372
|
+
yAxis = series.yAxis;
|
373
|
+
|
374
|
+
// Preserve the original
|
375
|
+
path = [].concat(path);
|
376
|
+
|
377
|
+
// Do the translation
|
378
|
+
i = path.length;
|
379
|
+
while (i--) {
|
380
|
+
if (typeof path[i] === 'number') {
|
381
|
+
if (even) { // even = x
|
382
|
+
path[i] = Math.round(xAxis.translate(path[i]));
|
383
|
+
} else { // odd = Y
|
384
|
+
path[i] = Math.round(yAxis.len - yAxis.translate(path[i]));
|
385
|
+
}
|
386
|
+
even = !even;
|
387
|
+
}
|
388
|
+
}
|
389
|
+
return path;
|
390
|
+
},
|
391
|
+
|
392
|
+
setData: function () {
|
393
|
+
Highcharts.Series.prototype.setData.apply(this, arguments);
|
394
|
+
this.getBox();
|
395
|
+
},
|
396
|
+
|
397
|
+
/**
|
398
|
+
* Add the path option for data points. Find the max value for color calculation.
|
399
|
+
*/
|
400
|
+
translate: function () {
|
401
|
+
var series = this,
|
402
|
+
options = series.options,
|
403
|
+
dataMin = Number.MAX_VALUE,
|
404
|
+
dataMax = Number.MIN_VALUE,
|
405
|
+
opacity,
|
406
|
+
minOpacity = options.minOpacity,
|
407
|
+
path,
|
408
|
+
color;
|
409
|
+
|
410
|
+
series.generatePoints();
|
411
|
+
|
412
|
+
each(series.data, function (point) {
|
413
|
+
|
414
|
+
point.shapeType = 'path';
|
415
|
+
point.shapeArgs = {
|
416
|
+
d: series.translatePath(point.path)
|
417
|
+
};
|
418
|
+
|
419
|
+
// TODO: do point colors in drawPoints instead of point.init
|
420
|
+
if (typeof point.y === 'number') {
|
421
|
+
if (point.y > dataMax) {
|
422
|
+
dataMax = point.y;
|
423
|
+
} else if (point.y < dataMin) {
|
424
|
+
dataMin = point.y;
|
425
|
+
}
|
426
|
+
}
|
427
|
+
});
|
428
|
+
|
429
|
+
series.translateColors(dataMin, dataMax);
|
430
|
+
},
|
431
|
+
|
432
|
+
/**
|
433
|
+
* In choropleth maps, the color is a result of the value, so this needs translation tood
|
434
|
+
*/
|
435
|
+
translateColors: function (dataMin, dataMax) {
|
436
|
+
|
437
|
+
var seriesOptions = this.options,
|
438
|
+
valueRanges = seriesOptions.valueRanges,
|
439
|
+
colorRange = seriesOptions.colorRange,
|
440
|
+
colorKey = this.colorKey;
|
441
|
+
|
442
|
+
each(this.data, function (point) {
|
443
|
+
var value = point[colorKey],
|
444
|
+
rgba = [],
|
445
|
+
range,
|
446
|
+
from,
|
447
|
+
to,
|
448
|
+
i,
|
449
|
+
pos;
|
450
|
+
|
451
|
+
if (valueRanges) {
|
452
|
+
i = valueRanges.length;
|
453
|
+
while (i--) {
|
454
|
+
range = valueRanges[i];
|
455
|
+
from = range.from;
|
456
|
+
to = range.to;
|
457
|
+
if ((from === UNDEFINED || value >= from) && (to === UNDEFINED || value <= to)) {
|
458
|
+
point.options.color = range.color;
|
459
|
+
break;
|
460
|
+
}
|
461
|
+
|
462
|
+
}
|
463
|
+
} else if (colorRange && value !== undefined) {
|
464
|
+
from = Color(colorRange.from);
|
465
|
+
to = Color(colorRange.to);
|
466
|
+
pos = (dataMax - value) / (dataMax - dataMin);
|
467
|
+
i = 4;
|
468
|
+
while (i--) {
|
469
|
+
rgba[i] = Math.round(
|
470
|
+
to.rgba[i] + (from.rgba[i] - to.rgba[i]) * pos
|
471
|
+
);
|
472
|
+
}
|
473
|
+
point.options.color = 'rgba(' + rgba.join(',') + ')';
|
474
|
+
}
|
475
|
+
});
|
476
|
+
},
|
477
|
+
|
478
|
+
drawGraph: noop,
|
479
|
+
|
480
|
+
/**
|
481
|
+
* We need the points' bounding boxes in order to draw the data labels, so
|
482
|
+
* we skip it now and call if from drawPoints instead.
|
483
|
+
*/
|
484
|
+
drawDataLabels: noop,
|
485
|
+
|
486
|
+
/**
|
487
|
+
* Use the drawPoints method of column, that is able to handle simple shapeArgs.
|
488
|
+
* Extend it by assigning the tooltip position.
|
489
|
+
*/
|
490
|
+
drawPoints: function () {
|
491
|
+
var series = this,
|
492
|
+
chart = series.chart,
|
493
|
+
saturation,
|
494
|
+
bBox,
|
495
|
+
colorKey = series.colorKey;
|
496
|
+
|
497
|
+
// Make points pass test in drawing
|
498
|
+
each(series.data, function (point) {
|
499
|
+
point.plotY = 1; // pass null test in column.drawPoints
|
500
|
+
if (point[colorKey] === null) {
|
501
|
+
point[colorKey] = 0;
|
502
|
+
point.isNull = true;
|
503
|
+
}
|
504
|
+
});
|
505
|
+
|
506
|
+
// Draw them
|
507
|
+
Highcharts.seriesTypes.column.prototype.drawPoints.apply(series);
|
508
|
+
|
509
|
+
each(series.data, function (point) {
|
510
|
+
|
511
|
+
bBox = point.graphic.getBBox();
|
512
|
+
// for tooltip
|
513
|
+
point.tooltipPos = [
|
514
|
+
bBox.x + bBox.width / 2,
|
515
|
+
bBox.y + bBox.height / 2
|
516
|
+
];
|
517
|
+
// for data labels
|
518
|
+
point.plotX = point.tooltipPos[0];
|
519
|
+
point.plotY = point.tooltipPos[1];
|
520
|
+
|
521
|
+
// Reset escaped null points
|
522
|
+
if (point.isNull) {
|
523
|
+
point[colorKey] = null;
|
524
|
+
}
|
525
|
+
});
|
526
|
+
|
527
|
+
// Now draw the data labels
|
528
|
+
Highcharts.Series.prototype.drawDataLabels.call(series);
|
529
|
+
|
530
|
+
}
|
531
|
+
});
|
532
|
+
|
533
|
+
/**
|
534
|
+
* A wrapper for Chart with all the default values for a Map
|
535
|
+
*/
|
536
|
+
Highcharts.Map = function (options, callback) {
|
537
|
+
|
538
|
+
var hiddenAxis = {
|
539
|
+
endOnTick: false,
|
540
|
+
gridLineWidth: 0,
|
541
|
+
labels: {
|
542
|
+
enabled: false
|
543
|
+
},
|
544
|
+
lineWidth: 0,
|
545
|
+
minPadding: 0,
|
546
|
+
maxPadding: 0,
|
547
|
+
startOnTick: false,
|
548
|
+
tickWidth: 0,
|
549
|
+
title: null
|
550
|
+
};
|
551
|
+
|
552
|
+
// Don't merge the data
|
553
|
+
seriesOptions = options.series;
|
554
|
+
options.series = null;
|
555
|
+
|
556
|
+
options = merge({
|
557
|
+
chart: {
|
558
|
+
type: 'map'
|
559
|
+
},
|
560
|
+
xAxis: hiddenAxis,
|
561
|
+
yAxis: merge(hiddenAxis, { reversed: true })
|
562
|
+
},
|
563
|
+
options, // user's options
|
564
|
+
|
565
|
+
{ // forced options
|
566
|
+
chart: {
|
567
|
+
inverted: false
|
568
|
+
}
|
569
|
+
});
|
570
|
+
|
571
|
+
options.series = seriesOptions;
|
572
|
+
|
573
|
+
|
574
|
+
return new Highcharts.Chart(options, callback);
|
575
|
+
};
|
576
|
+
}(Highcharts));
|