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
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license Highcharts JS
|
2
|
+
* @license Highcharts JS v6.0.0 (2017-10-04)
|
3
3
|
* Solid angular gauge module
|
4
4
|
*
|
5
5
|
* (c) 2010-2017 Torstein Honsi
|
@@ -164,13 +164,54 @@
|
|
164
164
|
}
|
165
165
|
};
|
166
166
|
/**
|
167
|
+
* A solid gauge is a circular gauge where the value is indicated by a filled
|
168
|
+
* arc, and the color of the arc may variate with the value.
|
169
|
+
*
|
170
|
+
* @sample highcharts/demo/gauge-solid/ Solid gauges
|
167
171
|
* @extends plotOptions.gauge
|
172
|
+
* @excluding dial,pivot
|
173
|
+
* @product highcharts
|
168
174
|
* @optionparent plotOptions.solidgauge
|
169
175
|
*/
|
170
176
|
var solidGaugeOptions = {
|
171
177
|
/**
|
178
|
+
* Whether to give each point an individual color.
|
172
179
|
*/
|
173
180
|
colorByPoint: true
|
181
|
+
/**
|
182
|
+
* Whether the strokes of the solid gauge should be `round` or `square`.
|
183
|
+
*
|
184
|
+
* @validvalue ["square", "round"]
|
185
|
+
* @type {String}
|
186
|
+
* @sample {highcharts} highcharts/demo/gauge-activity/ Rounded gauge
|
187
|
+
* @default round
|
188
|
+
* @since 4.2.2
|
189
|
+
* @product highcharts
|
190
|
+
* @apioption plotOptions.solidgauge.linecap
|
191
|
+
*/
|
192
|
+
|
193
|
+
/**
|
194
|
+
* Wether to draw rounded edges on the gauge.
|
195
|
+
*
|
196
|
+
* @type {Boolean}
|
197
|
+
* @sample {highcharts} highcharts/demo/gauge-activity/ Activity Gauge
|
198
|
+
* @default false
|
199
|
+
* @since 5.0.8
|
200
|
+
* @product highcharts
|
201
|
+
* @apioption plotOptions.solidgauge.rounded
|
202
|
+
*/
|
203
|
+
|
204
|
+
/**
|
205
|
+
* The threshold or base level for the gauge.
|
206
|
+
*
|
207
|
+
* @type {Number}
|
208
|
+
* @sample {highcharts} highcharts/plotoptions/solidgauge-threshold/
|
209
|
+
* Zero threshold with negative and positive values
|
210
|
+
* @default null
|
211
|
+
* @since 5.0.3
|
212
|
+
* @product highcharts
|
213
|
+
* @apioption plotOptions.solidgauge.threshold
|
214
|
+
*/
|
174
215
|
|
175
216
|
};
|
176
217
|
|
@@ -313,5 +354,85 @@
|
|
313
354
|
}
|
314
355
|
});
|
315
356
|
|
357
|
+
/**
|
358
|
+
* A `solidgauge` series. If the [type](#series.solidgauge.type) option
|
359
|
+
* is not specified, it is inherited from [chart.type](#chart.type).
|
360
|
+
*
|
361
|
+
*
|
362
|
+
* For options that apply to multiple series, it is recommended to add
|
363
|
+
* them to the [plotOptions.series](#plotOptions.series) options structure.
|
364
|
+
* To apply to all series of this specific type, apply it to [plotOptions.
|
365
|
+
* solidgauge](#plotOptions.solidgauge).
|
366
|
+
*
|
367
|
+
* @type {Object}
|
368
|
+
* @extends series,plotOptions.solidgauge
|
369
|
+
* @excluding dataParser,dataURL,stack
|
370
|
+
* @product highcharts
|
371
|
+
* @apioption series.solidgauge
|
372
|
+
*/
|
373
|
+
|
374
|
+
/**
|
375
|
+
* An array of data points for the series. For the `solidgauge` series
|
376
|
+
* type, points can be given in the following ways:
|
377
|
+
*
|
378
|
+
* 1. An array of numerical values. In this case, the numerical values
|
379
|
+
* will be interpreted as `y` options. Example:
|
380
|
+
*
|
381
|
+
* ```js
|
382
|
+
* data: [0, 5, 3, 5]
|
383
|
+
* ```
|
384
|
+
*
|
385
|
+
* 2. An array of objects with named values. The objects are point
|
386
|
+
* configuration objects as seen below. If the total number of data
|
387
|
+
* points exceeds the series' [turboThreshold](#series.solidgauge.turboThreshold),
|
388
|
+
* this option is not available.
|
389
|
+
*
|
390
|
+
* ```js
|
391
|
+
* data: [{
|
392
|
+
* y: 5,
|
393
|
+
* name: "Point2",
|
394
|
+
* color: "#00FF00"
|
395
|
+
* }, {
|
396
|
+
* y: 7,
|
397
|
+
* name: "Point1",
|
398
|
+
* color: "#FF00FF"
|
399
|
+
* }]
|
400
|
+
* ```
|
401
|
+
*
|
402
|
+
* The typical gauge only contains a single data value.
|
403
|
+
*
|
404
|
+
* @type {Array<Object|Number>}
|
405
|
+
* @extends series.gauge.data
|
406
|
+
* @sample {highcharts} highcharts/chart/reflow-true/ Numerical values
|
407
|
+
* @sample {highcharts} highcharts/series/data-array-of-arrays/ Arrays of numeric x and y
|
408
|
+
* @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/ Arrays of datetime x and y
|
409
|
+
* @sample {highcharts} highcharts/series/data-array-of-name-value/ Arrays of point.name and y
|
410
|
+
* @sample {highcharts} highcharts/series/data-array-of-objects/ Config objects
|
411
|
+
* @product highcharts
|
412
|
+
* @apioption series.solidgauge.data
|
413
|
+
*/
|
414
|
+
|
415
|
+
/**
|
416
|
+
* The inner radius of an individual point in a solid gauge. Can be
|
417
|
+
* given as a number (pixels) or percentage string.
|
418
|
+
*
|
419
|
+
* @type {Number|String}
|
420
|
+
* @sample {highcharts} highcharts/plotoptions/solidgauge-radius/ Individual radius and innerRadius
|
421
|
+
* @since 4.1.6
|
422
|
+
* @product highcharts
|
423
|
+
* @apioption series.solidgauge.data.innerRadius
|
424
|
+
*/
|
425
|
+
|
426
|
+
/**
|
427
|
+
* The outer radius of an individual point in a solid gauge. Can be
|
428
|
+
* given as a number (pixels) or percentage string.
|
429
|
+
*
|
430
|
+
* @type {Number|String}
|
431
|
+
* @sample {highcharts} highcharts/plotoptions/solidgauge-radius/ Individual radius and innerRadius
|
432
|
+
* @since 4.1.6
|
433
|
+
* @product highcharts
|
434
|
+
* @apioption series.solidgauge.data.radius
|
435
|
+
*/
|
436
|
+
|
316
437
|
}(Highcharts));
|
317
438
|
}));
|
@@ -0,0 +1,64 @@
|
|
1
|
+
/**
|
2
|
+
* @license Highcharts JS v6.0.0 (2017-10-04)
|
3
|
+
* StaticScale
|
4
|
+
*
|
5
|
+
* (c) 2016 Torstein Honsi, Lars A. V. Cabrera
|
6
|
+
*
|
7
|
+
* --- WORK IN PROGRESS ---
|
8
|
+
*
|
9
|
+
* License: www.highcharts.com/license
|
10
|
+
*/
|
11
|
+
'use strict';
|
12
|
+
(function(factory) {
|
13
|
+
if (typeof module === 'object' && module.exports) {
|
14
|
+
module.exports = factory;
|
15
|
+
} else {
|
16
|
+
factory(Highcharts);
|
17
|
+
}
|
18
|
+
}(function(Highcharts) {
|
19
|
+
(function(H) {
|
20
|
+
/**
|
21
|
+
* (c) 2017 Torstein Honsi, Lars Cabrera
|
22
|
+
*
|
23
|
+
* License: www.highcharts.com/license
|
24
|
+
*/
|
25
|
+
|
26
|
+
var Chart = H.Chart,
|
27
|
+
each = H.each,
|
28
|
+
pick = H.pick;
|
29
|
+
|
30
|
+
Chart.prototype.adjustHeight = function() {
|
31
|
+
each(this.axes, function(axis) {
|
32
|
+
var chart = axis.chart,
|
33
|
+
animate = !!chart.initiatedScale && chart.options.animation,
|
34
|
+
staticScale = axis.options.staticScale,
|
35
|
+
height,
|
36
|
+
diff;
|
37
|
+
if (
|
38
|
+
H.isNumber(staticScale) &&
|
39
|
+
!axis.horiz &&
|
40
|
+
H.defined(axis.min)
|
41
|
+
) {
|
42
|
+
height = pick(
|
43
|
+
axis.unitLength,
|
44
|
+
axis.max + axis.tickInterval - axis.min
|
45
|
+
) * staticScale;
|
46
|
+
|
47
|
+
// Minimum height is 1 x staticScale.
|
48
|
+
height = Math.max(height, staticScale);
|
49
|
+
|
50
|
+
diff = height - chart.plotHeight;
|
51
|
+
|
52
|
+
if (Math.abs(diff) >= 1) {
|
53
|
+
chart.plotHeight = height;
|
54
|
+
chart.setSize(null, chart.chartHeight + diff, animate);
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
});
|
59
|
+
this.initiatedScale = true;
|
60
|
+
};
|
61
|
+
H.addEvent(Chart.prototype, 'render', Chart.prototype.adjustHeight);
|
62
|
+
|
63
|
+
}(Highcharts));
|
64
|
+
}));
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license Highcharts JS
|
2
|
+
* @license Highcharts JS v6.0.0 (2017-10-04)
|
3
3
|
* Highstock as a plugin for Highcharts
|
4
4
|
*
|
5
5
|
* (c) 2017 Torstein Honsi
|
@@ -29,6 +29,7 @@
|
|
29
29
|
each = H.each,
|
30
30
|
extend = H.extend,
|
31
31
|
noop = H.noop,
|
32
|
+
pick = H.pick,
|
32
33
|
Series = H.Series,
|
33
34
|
timeUnits = H.timeUnits,
|
34
35
|
wrap = H.wrap;
|
@@ -238,15 +239,42 @@
|
|
238
239
|
slope,
|
239
240
|
hasBreaks = axis.isXAxis && !!axis.options.breaks,
|
240
241
|
isOrdinal = axis.options.ordinal,
|
242
|
+
overscrollPointsRange = Number.MAX_SAFE_INTEGER,
|
241
243
|
ignoreHiddenSeries = axis.chart.options.chart.ignoreHiddenSeries,
|
244
|
+
isNavigatorAxis = axis.options.className === 'highcharts-navigator-xaxis',
|
242
245
|
i;
|
243
246
|
|
244
|
-
|
247
|
+
if (
|
248
|
+
axis.options.overscroll &&
|
249
|
+
axis.max === axis.dataMax &&
|
250
|
+
(
|
251
|
+
// Panning is an execption,
|
252
|
+
// We don't want to apply overscroll when panning over the dataMax
|
253
|
+
!axis.chart.mouseIsDown ||
|
254
|
+
isNavigatorAxis
|
255
|
+
) && (
|
256
|
+
// Scrollbar buttons are the other execption:
|
257
|
+
!axis.eventArgs ||
|
258
|
+
axis.eventArgs && axis.eventArgs.trigger !== 'navigator'
|
259
|
+
)
|
260
|
+
) {
|
261
|
+
axis.max += axis.options.overscroll;
|
262
|
+
|
263
|
+
// Live data and buttons require translation for the min:
|
264
|
+
if (!isNavigatorAxis && defined(axis.userMin)) {
|
265
|
+
axis.min += axis.options.overscroll;
|
266
|
+
}
|
267
|
+
}
|
268
|
+
|
269
|
+
// Apply the ordinal logic
|
245
270
|
if (isOrdinal || hasBreaks) { // #4167 YAxis is never ordinal ?
|
246
271
|
|
247
272
|
each(axis.series, function(series, i) {
|
248
273
|
|
249
|
-
if (
|
274
|
+
if (
|
275
|
+
(!ignoreHiddenSeries || series.visible !== false) &&
|
276
|
+
(series.takeOrdinalPosition !== false || hasBreaks)
|
277
|
+
) {
|
250
278
|
|
251
279
|
// concatenate the processed X data into the existing positions, or the empty array
|
252
280
|
ordinalPositions = ordinalPositions.concat(series.processedXData);
|
@@ -257,6 +285,15 @@
|
|
257
285
|
return a - b; // without a custom function it is sorted as strings
|
258
286
|
});
|
259
287
|
|
288
|
+
overscrollPointsRange = Math.min(
|
289
|
+
overscrollPointsRange,
|
290
|
+
pick(
|
291
|
+
// Check for a single-point series:
|
292
|
+
series.closestPointRange,
|
293
|
+
overscrollPointsRange
|
294
|
+
)
|
295
|
+
);
|
296
|
+
|
260
297
|
if (len) {
|
261
298
|
i = len - 1;
|
262
299
|
while (i--) {
|
@@ -285,9 +322,27 @@
|
|
285
322
|
|
286
323
|
// When zooming in on a week, prevent axis padding for weekends even though the data within
|
287
324
|
// the week is evenly spaced.
|
288
|
-
if (!axis.options.keepOrdinalPadding &&
|
325
|
+
if (!axis.options.keepOrdinalPadding &&
|
326
|
+
(
|
327
|
+
ordinalPositions[0] - min > dist ||
|
328
|
+
max - ordinalPositions[ordinalPositions.length - 1] > dist
|
329
|
+
)
|
330
|
+
) {
|
289
331
|
useOrdinal = true;
|
290
332
|
}
|
333
|
+
} else if (axis.options.overscroll) {
|
334
|
+
if (len === 2) {
|
335
|
+
// Exactly two points, distance for overscroll is fixed:
|
336
|
+
overscrollPointsRange = ordinalPositions[1] - ordinalPositions[0];
|
337
|
+
} else if (len === 1) {
|
338
|
+
// We have just one point, closest distance is unknown.
|
339
|
+
// Assume then it is last point and overscrolled range:
|
340
|
+
overscrollPointsRange = axis.options.overscroll;
|
341
|
+
ordinalPositions = [ordinalPositions[0], ordinalPositions[0] + overscrollPointsRange];
|
342
|
+
} else {
|
343
|
+
// In case of zooming in on overscrolled range, stick to the old range:
|
344
|
+
overscrollPointsRange = axis.overscrollPointsRange;
|
345
|
+
}
|
291
346
|
}
|
292
347
|
|
293
348
|
// Record the slope and offset to compute the linear values from the array index.
|
@@ -295,6 +350,11 @@
|
|
295
350
|
// end positions within it (#719, #665b)
|
296
351
|
if (useOrdinal) {
|
297
352
|
|
353
|
+
if (axis.options.overscroll) {
|
354
|
+
axis.overscrollPointsRange = overscrollPointsRange;
|
355
|
+
ordinalPositions = ordinalPositions.concat(axis.getOverscrollPositions());
|
356
|
+
}
|
357
|
+
|
298
358
|
// Register
|
299
359
|
axis.ordinalPositions = ordinalPositions;
|
300
360
|
|
@@ -320,6 +380,7 @@
|
|
320
380
|
axis.ordinalOffset = min - (minIndex * slope);
|
321
381
|
|
322
382
|
} else {
|
383
|
+
axis.overscrollPointsRange = pick(axis.closestPointRange, axis.overscrollPointsRange);
|
323
384
|
axis.ordinalPositions = axis.ordinalSlope = axis.ordinalOffset = undefined;
|
324
385
|
}
|
325
386
|
}
|
@@ -444,6 +505,7 @@
|
|
444
505
|
grouping = axis.series[0].currentDataGrouping,
|
445
506
|
ordinalIndex = axis.ordinalIndex,
|
446
507
|
key = grouping ? grouping.count + grouping.unitName : 'raw',
|
508
|
+
overscroll = axis.options.overscroll,
|
447
509
|
extremes = axis.getExtremes(),
|
448
510
|
fakeAxis,
|
449
511
|
fakeSeries;
|
@@ -464,7 +526,7 @@
|
|
464
526
|
getExtremes: function() {
|
465
527
|
return {
|
466
528
|
min: extremes.dataMin,
|
467
|
-
max: extremes.dataMax
|
529
|
+
max: extremes.dataMax + overscroll
|
468
530
|
};
|
469
531
|
},
|
470
532
|
options: {
|
@@ -478,10 +540,13 @@
|
|
478
540
|
each(axis.series, function(series) {
|
479
541
|
fakeSeries = {
|
480
542
|
xAxis: fakeAxis,
|
481
|
-
xData: series.xData,
|
543
|
+
xData: series.xData.slice(),
|
482
544
|
chart: chart,
|
483
545
|
destroyGroupedData: noop
|
484
546
|
};
|
547
|
+
|
548
|
+
fakeSeries.xData = fakeSeries.xData.concat(axis.getOverscrollPositions());
|
549
|
+
|
485
550
|
fakeSeries.options = {
|
486
551
|
dataGrouping: grouping ? {
|
487
552
|
enabled: true,
|
@@ -496,6 +561,7 @@
|
|
496
561
|
};
|
497
562
|
series.processData.apply(fakeSeries);
|
498
563
|
|
564
|
+
|
499
565
|
fakeAxis.series.push(fakeSeries);
|
500
566
|
});
|
501
567
|
|
@@ -508,6 +574,38 @@
|
|
508
574
|
return ordinalIndex[key];
|
509
575
|
},
|
510
576
|
|
577
|
+
/**
|
578
|
+
* Get ticks for an ordinal axis within a range where points don't exist.
|
579
|
+
* It is required when overscroll is enabled. We can't base on points,
|
580
|
+
* because we may not have any, so we use approximated pointRange and
|
581
|
+
* generate these ticks between <Axis.dataMax, Axis.dataMax + Axis.overscroll>
|
582
|
+
* evenly spaced. Used in panning and navigator scrolling.
|
583
|
+
*
|
584
|
+
* @returns positions {Array} Generated ticks
|
585
|
+
* @private
|
586
|
+
*/
|
587
|
+
getOverscrollPositions: function() {
|
588
|
+
var axis = this,
|
589
|
+
extraRange = axis.options.overscroll,
|
590
|
+
distance = axis.overscrollPointsRange,
|
591
|
+
positions = [],
|
592
|
+
max = axis.dataMax;
|
593
|
+
|
594
|
+
if (H.defined(distance)) {
|
595
|
+
// Max + pointRange because we need to scroll to the last
|
596
|
+
|
597
|
+
positions.push(max);
|
598
|
+
|
599
|
+
while (max <= axis.dataMax + extraRange) {
|
600
|
+
max += distance;
|
601
|
+
positions.push(max);
|
602
|
+
}
|
603
|
+
|
604
|
+
}
|
605
|
+
|
606
|
+
return positions;
|
607
|
+
},
|
608
|
+
|
511
609
|
/**
|
512
610
|
* Find the factor to estimate how wide the plot area would have been if ordinal
|
513
611
|
* gaps were included. This value is used to compute an imagined plot width in order
|
@@ -595,6 +693,7 @@
|
|
595
693
|
wrap(Chart.prototype, 'pan', function(proceed, e) {
|
596
694
|
var chart = this,
|
597
695
|
xAxis = chart.xAxis[0],
|
696
|
+
overscroll = xAxis.options.overscroll,
|
598
697
|
chartX = e.chartX,
|
599
698
|
runBase = false;
|
600
699
|
|
@@ -607,7 +706,7 @@
|
|
607
706
|
max = extremes.max,
|
608
707
|
trimmedRange,
|
609
708
|
hoverPoints = chart.hoverPoints,
|
610
|
-
closestPointRange = xAxis.closestPointRange,
|
709
|
+
closestPointRange = xAxis.closestPointRange || xAxis.overscrollPointsRange,
|
611
710
|
pointPixelWidth = xAxis.translationSlope * (xAxis.ordinalSlope || closestPointRange),
|
612
711
|
movedUnits = (mouseDownX - chartX) / pointPixelWidth, // how many ordinal units did we move?
|
613
712
|
extendedAxis = {
|
@@ -664,7 +763,10 @@
|
|
664
763
|
);
|
665
764
|
|
666
765
|
// Apply it if it is within the available data range
|
667
|
-
if (
|
766
|
+
if (
|
767
|
+
trimmedRange.min >= Math.min(extremes.dataMin, min) &&
|
768
|
+
trimmedRange.max <= Math.max(dataMax, max) + overscroll
|
769
|
+
) {
|
668
770
|
xAxis.setExtremes(trimmedRange.min, trimmedRange.max, true, false, {
|
669
771
|
trigger: 'pan'
|
670
772
|
});
|
@@ -682,6 +784,9 @@
|
|
682
784
|
|
683
785
|
// revert to the linear chart.pan version
|
684
786
|
if (runBase) {
|
787
|
+
if (overscroll) {
|
788
|
+
xAxis.max = xAxis.dataMax + overscroll;
|
789
|
+
}
|
685
790
|
// call the original function
|
686
791
|
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
|
687
792
|
}
|
@@ -1063,7 +1168,7 @@
|
|
1063
1168
|
* @type {String}
|
1064
1169
|
* @see [gapSize](plotOptions.series.gapSize)
|
1065
1170
|
* @default relative
|
1066
|
-
* @
|
1171
|
+
* @validvalue ["relative", "value"]
|
1067
1172
|
* @since 5.0.13
|
1068
1173
|
* @product highstock
|
1069
1174
|
* @apioption plotOptions.series.gapUnit
|
@@ -1142,6 +1247,191 @@
|
|
1142
1247
|
* Start data grouping module *
|
1143
1248
|
******************************************************************************/
|
1144
1249
|
|
1250
|
+
/**
|
1251
|
+
* Data grouping is the concept of sampling the data values into larger
|
1252
|
+
* blocks in order to ease readability and increase performance of the
|
1253
|
+
* JavaScript charts. Highstock by default applies data grouping when
|
1254
|
+
* the points become closer than a certain pixel value, determined by
|
1255
|
+
* the `groupPixelWidth` option.
|
1256
|
+
*
|
1257
|
+
* If data grouping is applied, the grouping information of grouped
|
1258
|
+
* points can be read from the [Point.dataGroup](#Point.dataGroup).
|
1259
|
+
*
|
1260
|
+
* @product highstock
|
1261
|
+
* @apioption plotOptions.series.dataGrouping
|
1262
|
+
*/
|
1263
|
+
|
1264
|
+
/**
|
1265
|
+
* The method of approximation inside a group. When for example 30 days
|
1266
|
+
* are grouped into one month, this determines what value should represent
|
1267
|
+
* the group. Possible values are "average", "averages", "open", "high",
|
1268
|
+
* "low", "close" and "sum". For OHLC and candlestick series the approximation
|
1269
|
+
* is "ohlc" by default, which finds the open, high, low and close values
|
1270
|
+
* within all the grouped data. For ranges, the approximation is "range",
|
1271
|
+
* which finds the low and high values. For multi-dimensional data,
|
1272
|
+
* like ranges and OHLC, "averages" will compute the average for each
|
1273
|
+
* dimension.
|
1274
|
+
*
|
1275
|
+
* Custom aggregate methods can be added by assigning a callback function
|
1276
|
+
* as the approximation. This function takes a numeric array as the
|
1277
|
+
* argument and should return a single numeric value or `null`. Note
|
1278
|
+
* that the numeric array will never contain null values, only true
|
1279
|
+
* numbers. Instead, if null values are present in the raw data, the
|
1280
|
+
* numeric array will have an `.hasNulls` property set to `true`. For
|
1281
|
+
* single-value data sets the data is available in the first argument
|
1282
|
+
* of the callback function. For OHLC data sets, all the open values
|
1283
|
+
* are in the first argument, all high values in the second etc.
|
1284
|
+
*
|
1285
|
+
* Since v4.2.7, grouping meta data is available in the approximation
|
1286
|
+
* callback from `this.dataGroupInfo`. It can be used to extract information
|
1287
|
+
* from the raw data.
|
1288
|
+
*
|
1289
|
+
* Defaults to `average` for line-type series, `sum` for columns, `range`
|
1290
|
+
* for range series and `ohlc` for OHLC and candlestick.
|
1291
|
+
*
|
1292
|
+
* @validvalue ["average", "averages", "open", "high", "low", "close", "sum"]
|
1293
|
+
* @type {String|Function}
|
1294
|
+
* @sample {highstock} stock/plotoptions/series-datagrouping-approximation Approximation callback with custom data
|
1295
|
+
* @product highstock
|
1296
|
+
* @apioption plotOptions.series.dataGrouping.approximation
|
1297
|
+
*/
|
1298
|
+
|
1299
|
+
/**
|
1300
|
+
* Datetime formats for the header of the tooltip in a stock chart.
|
1301
|
+
* The format can vary within a chart depending on the currently selected
|
1302
|
+
* time range and the current data grouping.
|
1303
|
+
*
|
1304
|
+
* The default formats are:
|
1305
|
+
*
|
1306
|
+
* <pre>{
|
1307
|
+
* millisecond: ['%A, %b %e, %H:%M:%S.%L', '%A, %b %e, %H:%M:%S.%L', '-%H:%M:%S.%L'],
|
1308
|
+
* second: ['%A, %b %e, %H:%M:%S', '%A, %b %e, %H:%M:%S', '-%H:%M:%S'],
|
1309
|
+
* minute: ['%A, %b %e, %H:%M', '%A, %b %e, %H:%M', '-%H:%M'],
|
1310
|
+
* hour: ['%A, %b %e, %H:%M', '%A, %b %e, %H:%M', '-%H:%M'],
|
1311
|
+
* day: ['%A, %b %e, %Y', '%A, %b %e', '-%A, %b %e, %Y'],
|
1312
|
+
* week: ['Week from %A, %b %e, %Y', '%A, %b %e', '-%A, %b %e, %Y'],
|
1313
|
+
* month: ['%B %Y', '%B', '-%B %Y'],
|
1314
|
+
* year: ['%Y', '%Y', '-%Y']
|
1315
|
+
* }</pre>
|
1316
|
+
*
|
1317
|
+
* For each of these array definitions, the first item is the format
|
1318
|
+
* used when the active time span is one unit. For instance, if the
|
1319
|
+
* current data applies to one week, the first item of the week array
|
1320
|
+
* is used. The second and third items are used when the active time
|
1321
|
+
* span is more than two units. For instance, if the current data applies
|
1322
|
+
* to two weeks, the second and third item of the week array are used,
|
1323
|
+
* and applied to the start and end date of the time span.
|
1324
|
+
*
|
1325
|
+
* @type {Object}
|
1326
|
+
* @product highstock
|
1327
|
+
* @apioption plotOptions.series.dataGrouping.dateTimeLabelFormats
|
1328
|
+
*/
|
1329
|
+
|
1330
|
+
/**
|
1331
|
+
* Enable or disable data grouping.
|
1332
|
+
*
|
1333
|
+
* @type {Boolean}
|
1334
|
+
* @default true
|
1335
|
+
* @product highstock
|
1336
|
+
* @apioption plotOptions.series.dataGrouping.enabled
|
1337
|
+
*/
|
1338
|
+
|
1339
|
+
/**
|
1340
|
+
* When data grouping is forced, it runs no matter how small the intervals
|
1341
|
+
* are. This can be handy for example when the sum should be calculated
|
1342
|
+
* for values appearing at random times within each hour.
|
1343
|
+
*
|
1344
|
+
* @type {Boolean}
|
1345
|
+
* @default false
|
1346
|
+
* @product highstock
|
1347
|
+
* @apioption plotOptions.series.dataGrouping.forced
|
1348
|
+
*/
|
1349
|
+
|
1350
|
+
/**
|
1351
|
+
* The approximate pixel width of each group. If for example a series
|
1352
|
+
* with 30 points is displayed over a 600 pixel wide plot area, no grouping
|
1353
|
+
* is performed. If however the series contains so many points that
|
1354
|
+
* the spacing is less than the groupPixelWidth, Highcharts will try
|
1355
|
+
* to group it into appropriate groups so that each is more or less
|
1356
|
+
* two pixels wide. If multiple series with different group pixel widths
|
1357
|
+
* are drawn on the same x axis, all series will take the greatest width.
|
1358
|
+
* For example, line series have 2px default group width, while column
|
1359
|
+
* series have 10px. If combined, both the line and the column will
|
1360
|
+
* have 10px by default.
|
1361
|
+
*
|
1362
|
+
* @type {Number}
|
1363
|
+
* @default 2
|
1364
|
+
* @product highstock
|
1365
|
+
* @apioption plotOptions.series.dataGrouping.groupPixelWidth
|
1366
|
+
*/
|
1367
|
+
|
1368
|
+
/**
|
1369
|
+
* Normally, a group is indexed by the start of that group, so for example
|
1370
|
+
* when 30 daily values are grouped into one month, that month's x value
|
1371
|
+
* will be the 1st of the month. This apparently shifts the data to
|
1372
|
+
* the left. When the smoothed option is true, this is compensated for.
|
1373
|
+
* The data is shifted to the middle of the group, and min and max
|
1374
|
+
* values are preserved. Internally, this is used in the Navigator series.
|
1375
|
+
*
|
1376
|
+
* @type {Boolean}
|
1377
|
+
* @default false
|
1378
|
+
* @product highstock
|
1379
|
+
* @apioption plotOptions.series.dataGrouping.smoothed
|
1380
|
+
*/
|
1381
|
+
|
1382
|
+
/**
|
1383
|
+
* An array determining what time intervals the data is allowed to be
|
1384
|
+
* grouped to. Each array item is an array where the first value is
|
1385
|
+
* the time unit and the second value another array of allowed multiples.
|
1386
|
+
* Defaults to:
|
1387
|
+
*
|
1388
|
+
* <pre>units: [[
|
1389
|
+
* 'millisecond', // unit name
|
1390
|
+
* [1, 2, 5, 10, 20, 25, 50, 100, 200, 500] // allowed multiples
|
1391
|
+
* ], [
|
1392
|
+
* 'second',
|
1393
|
+
* [1, 2, 5, 10, 15, 30]
|
1394
|
+
* ], [
|
1395
|
+
* 'minute',
|
1396
|
+
* [1, 2, 5, 10, 15, 30]
|
1397
|
+
* ], [
|
1398
|
+
* 'hour',
|
1399
|
+
* [1, 2, 3, 4, 6, 8, 12]
|
1400
|
+
* ], [
|
1401
|
+
* 'day',
|
1402
|
+
* [1]
|
1403
|
+
* ], [
|
1404
|
+
* 'week',
|
1405
|
+
* [1]
|
1406
|
+
* ], [
|
1407
|
+
* 'month',
|
1408
|
+
* [1, 3, 6]
|
1409
|
+
* ], [
|
1410
|
+
* 'year',
|
1411
|
+
* null
|
1412
|
+
* ]]</pre>
|
1413
|
+
*
|
1414
|
+
* @type {Array}
|
1415
|
+
* @product highstock
|
1416
|
+
* @apioption plotOptions.series.dataGrouping.units
|
1417
|
+
*/
|
1418
|
+
|
1419
|
+
/**
|
1420
|
+
* The approximate pixel width of each group. If for example a series
|
1421
|
+
* with 30 points is displayed over a 600 pixel wide plot area, no grouping
|
1422
|
+
* is performed. If however the series contains so many points that
|
1423
|
+
* the spacing is less than the groupPixelWidth, Highcharts will try
|
1424
|
+
* to group it into appropriate groups so that each is more or less
|
1425
|
+
* two pixels wide. Defaults to `10`.
|
1426
|
+
*
|
1427
|
+
* @type {Number}
|
1428
|
+
* @sample {highstock} stock/plotoptions/series-datagrouping-grouppixelwidth/
|
1429
|
+
* Two series with the same data density but different groupPixelWidth
|
1430
|
+
* @default 10
|
1431
|
+
* @product highstock
|
1432
|
+
* @apioption plotOptions.column.dataGrouping.groupPixelWidth
|
1433
|
+
*/
|
1434
|
+
|
1145
1435
|
var seriesProto = Series.prototype,
|
1146
1436
|
baseProcessData = seriesProto.processData,
|
1147
1437
|
baseGeneratePoints = seriesProto.generatePoints,
|
@@ -1152,8 +1442,8 @@
|
|
1152
1442
|
*/
|
1153
1443
|
commonOptions = {
|
1154
1444
|
approximation: 'average', // average, open, high, low, close, sum
|
1155
|
-
//enabled: null, // (true for stock charts, false for basic),
|
1156
|
-
//forced: undefined,
|
1445
|
+
// enabled: null, // (true for stock charts, false for basic),
|
1446
|
+
// forced: undefined,
|
1157
1447
|
groupPixelWidth: 2,
|
1158
1448
|
// the first one is the point or start value, the second is the start value if we're dealing with range,
|
1159
1449
|
// the third one is the end value if dealing with a range
|
@@ -1237,7 +1527,7 @@
|
|
1237
1527
|
* only of numbers. In case null values belong to the group, the property
|
1238
1528
|
* .hasNulls will be set to true on the array.
|
1239
1529
|
*/
|
1240
|
-
approximations = {
|
1530
|
+
approximations = H.approximations = {
|
1241
1531
|
sum: function(arr) {
|
1242
1532
|
var len = arr.length,
|
1243
1533
|
ret;
|
@@ -1317,7 +1607,6 @@
|
|
1317
1607
|
}
|
1318
1608
|
};
|
1319
1609
|
|
1320
|
-
|
1321
1610
|
/**
|
1322
1611
|
* Takes parallel arrays of x and y data and groups the data into intervals
|
1323
1612
|
* defined by groupPositions, a collection of starting x values for each group.
|
@@ -1508,7 +1797,7 @@
|
|
1508
1797
|
|
1509
1798
|
// prevent the smoothed data to spill out left and right, and make
|
1510
1799
|
// sure data is not shifted to the left
|
1511
|
-
if (dataGroupingOptions.smoothed) {
|
1800
|
+
if (dataGroupingOptions.smoothed && groupedXData.length) {
|
1512
1801
|
i = groupedXData.length - 1;
|
1513
1802
|
groupedXData[i] = Math.min(groupedXData[i], xMax);
|
1514
1803
|
while (i-- && i > 0) {
|
@@ -1814,29 +2103,47 @@
|
|
1814
2103
|
* @augments seriesTypes.column
|
1815
2104
|
*/
|
1816
2105
|
/**
|
2106
|
+
* An OHLC chart is a style of financial chart used to describe price
|
2107
|
+
* movements over time. It displays open, high, low and close values per data
|
2108
|
+
* point.
|
2109
|
+
*
|
2110
|
+
* @sample stock/demo/ohlc/ OHLC chart
|
1817
2111
|
* @extends {plotOptions.column}
|
2112
|
+
* @excluding borderColor,borderRadius,borderWidth
|
2113
|
+
* @product highstock
|
1818
2114
|
* @optionparent plotOptions.ohlc
|
1819
2115
|
*/
|
1820
2116
|
seriesType('ohlc', 'column', {
|
1821
2117
|
|
2118
|
+
/**
|
2119
|
+
* The approximate pixel width of each group. If for example a series
|
2120
|
+
* with 30 points is displayed over a 600 pixel wide plot area, no grouping
|
2121
|
+
* is performed. If however the series contains so many points that
|
2122
|
+
* the spacing is less than the groupPixelWidth, Highcharts will try
|
2123
|
+
* to group it into appropriate groups so that each is more or less
|
2124
|
+
* two pixels wide. Defaults to `5`.
|
2125
|
+
*
|
2126
|
+
* @type {Number}
|
2127
|
+
* @default 5
|
2128
|
+
* @product highstock
|
2129
|
+
* @apioption plotOptions.ohlc.dataGrouping.groupPixelWidth
|
2130
|
+
*/
|
2131
|
+
|
1822
2132
|
/**
|
1823
2133
|
* The pixel width of the line/border. Defaults to `1`.
|
1824
2134
|
*
|
1825
2135
|
* @type {Number}
|
1826
|
-
* @sample {highstock} stock/plotoptions/ohlc-linewidth/
|
2136
|
+
* @sample {highstock} stock/plotoptions/ohlc-linewidth/
|
2137
|
+
* A greater line width
|
1827
2138
|
* @default 1
|
1828
2139
|
* @product highstock
|
1829
2140
|
*/
|
1830
2141
|
lineWidth: 1,
|
1831
2142
|
|
1832
|
-
/**
|
1833
|
-
*/
|
1834
2143
|
tooltip: {
|
1835
2144
|
|
1836
2145
|
|
1837
|
-
|
1838
|
-
*/
|
1839
|
-
pointFormat: '<span style="color:{point.color}">\u25CF</span> <b> {series.name}</b><br/>' +
|
2146
|
+
pointFormat: '<span style="color:{point.color}">\u25CF</span> <b> {series.name}</b><br/>' + // eslint-disable-line max-len
|
1840
2147
|
'Open: {point.open}<br/>' +
|
1841
2148
|
'High: {point.high}<br/>' +
|
1842
2149
|
'Low: {point.low}<br/>' +
|
@@ -1844,13 +2151,9 @@
|
|
1844
2151
|
|
1845
2152
|
},
|
1846
2153
|
|
1847
|
-
/**
|
1848
|
-
*/
|
1849
2154
|
threshold: null,
|
1850
2155
|
|
1851
2156
|
|
1852
|
-
/**
|
1853
|
-
*/
|
1854
2157
|
states: {
|
1855
2158
|
|
1856
2159
|
/**
|
@@ -1860,8 +2163,7 @@
|
|
1860
2163
|
hover: {
|
1861
2164
|
|
1862
2165
|
/**
|
1863
|
-
* The pixel width of the line representing the OHLC point.
|
1864
|
-
* to `3`.
|
2166
|
+
* The pixel width of the line representing the OHLC point.
|
1865
2167
|
*
|
1866
2168
|
* @type {Number}
|
1867
2169
|
* @default 3
|
@@ -1871,15 +2173,22 @@
|
|
1871
2173
|
}
|
1872
2174
|
},
|
1873
2175
|
|
2176
|
+
|
1874
2177
|
/**
|
2178
|
+
* Line color for up points.
|
2179
|
+
*
|
2180
|
+
* @type {Color}
|
2181
|
+
* @product highstock
|
2182
|
+
* @apioption plotOptions.ohlc.upColor
|
1875
2183
|
*/
|
1876
|
-
stickyTracking: true
|
1877
|
-
//upColor: undefined
|
1878
2184
|
|
1879
2185
|
|
2186
|
+
|
2187
|
+
stickyTracking: true
|
2188
|
+
|
1880
2189
|
}, /** @lends seriesTypes.ohlc */ {
|
1881
2190
|
directTouch: false,
|
1882
|
-
pointArrayMap: ['open', 'high', 'low', 'close'],
|
2191
|
+
pointArrayMap: ['open', 'high', 'low', 'close'],
|
1883
2192
|
toYData: function(point) { // return a plain array for speedy calculation
|
1884
2193
|
return [point.open, point.high, point.low, point.close];
|
1885
2194
|
},
|
@@ -1922,20 +2231,29 @@
|
|
1922
2231
|
var series = this,
|
1923
2232
|
yAxis = series.yAxis,
|
1924
2233
|
hasModifyValue = !!series.modifyValue,
|
1925
|
-
translated = [
|
2234
|
+
translated = [
|
2235
|
+
'plotOpen',
|
2236
|
+
'plotHigh',
|
2237
|
+
'plotLow',
|
2238
|
+
'plotClose',
|
2239
|
+
'yBottom'
|
2240
|
+
]; // translate OHLC for
|
1926
2241
|
|
1927
2242
|
seriesTypes.column.prototype.translate.apply(series);
|
1928
2243
|
|
1929
2244
|
// Do the translation
|
1930
2245
|
each(series.points, function(point) {
|
1931
|
-
each(
|
1932
|
-
|
1933
|
-
|
1934
|
-
|
2246
|
+
each(
|
2247
|
+
[point.open, point.high, point.low, point.close, point.low],
|
2248
|
+
function(value, i) {
|
2249
|
+
if (value !== null) {
|
2250
|
+
if (hasModifyValue) {
|
2251
|
+
value = series.modifyValue(value);
|
2252
|
+
}
|
2253
|
+
point[translated[i]] = yAxis.toPixels(value, true);
|
1935
2254
|
}
|
1936
|
-
point[translated[i]] = yAxis.toPixels(value, true);
|
1937
2255
|
}
|
1938
|
-
|
2256
|
+
);
|
1939
2257
|
|
1940
2258
|
// Align the tooltip to the high value to avoid covering the point
|
1941
2259
|
point.tooltipPos[1] =
|
@@ -1971,7 +2289,9 @@
|
|
1971
2289
|
}
|
1972
2290
|
|
1973
2291
|
|
1974
|
-
graphic.attr(
|
2292
|
+
graphic.attr(
|
2293
|
+
series.pointAttribs(point, point.selected && 'select')
|
2294
|
+
); // #3897
|
1975
2295
|
|
1976
2296
|
|
1977
2297
|
// crisp vector coordinates
|
@@ -2037,12 +2357,97 @@
|
|
2037
2357
|
*/
|
2038
2358
|
getClassName: function() {
|
2039
2359
|
return Point.prototype.getClassName.call(this) +
|
2040
|
-
(
|
2360
|
+
(
|
2361
|
+
this.open < this.close ?
|
2362
|
+
' highcharts-point-up' :
|
2363
|
+
' highcharts-point-down'
|
2364
|
+
);
|
2041
2365
|
}
|
2042
2366
|
});
|
2043
|
-
|
2044
|
-
|
2045
|
-
|
2367
|
+
|
2368
|
+
/**
|
2369
|
+
* A `ohlc` series. If the [type](#series.ohlc.type) option is not
|
2370
|
+
* specified, it is inherited from [chart.type](#chart.type).
|
2371
|
+
*
|
2372
|
+
* For options that apply to multiple series, it is recommended to add
|
2373
|
+
* them to the [plotOptions.series](#plotOptions.series) options structure.
|
2374
|
+
* To apply to all series of this specific type, apply it to [plotOptions.
|
2375
|
+
* ohlc](#plotOptions.ohlc).
|
2376
|
+
*
|
2377
|
+
* @type {Object}
|
2378
|
+
* @extends series,plotOptions.ohlc
|
2379
|
+
* @excluding dataParser,dataURL
|
2380
|
+
* @product highstock
|
2381
|
+
* @apioption series.ohlc
|
2382
|
+
*/
|
2383
|
+
|
2384
|
+
/**
|
2385
|
+
* An array of data points for the series. For the `ohlc` series type,
|
2386
|
+
* points can be given in the following ways:
|
2387
|
+
*
|
2388
|
+
* 1. An array of arrays with 5 or 4 values. In this case, the values
|
2389
|
+
* correspond to `x,open,high,low,close`. If the first value is a string,
|
2390
|
+
* it is applied as the name of the point, and the `x` value is inferred.
|
2391
|
+
* The `x` value can also be omitted, in which case the inner arrays
|
2392
|
+
* should be of length 4\. Then the `x` value is automatically calculated,
|
2393
|
+
* either starting at 0 and incremented by 1, or from `pointStart`
|
2394
|
+
* and `pointInterval` given in the series options.
|
2395
|
+
*
|
2396
|
+
* ```js
|
2397
|
+
* data: [
|
2398
|
+
* [0, 6, 5, 6, 7],
|
2399
|
+
* [1, 9, 4, 8, 2],
|
2400
|
+
* [2, 6, 3, 4, 10]
|
2401
|
+
* ]
|
2402
|
+
* ```
|
2403
|
+
*
|
2404
|
+
* 2. An array of objects with named values. The objects are point
|
2405
|
+
* configuration objects as seen below. If the total number of data
|
2406
|
+
* points exceeds the series' [turboThreshold](#series.ohlc.turboThreshold),
|
2407
|
+
* this option is not available.
|
2408
|
+
*
|
2409
|
+
* ```js
|
2410
|
+
* data: [{
|
2411
|
+
* x: 1,
|
2412
|
+
* open: 3,
|
2413
|
+
* high: 4,
|
2414
|
+
* low: 5,
|
2415
|
+
* close: 2,
|
2416
|
+
* name: "Point2",
|
2417
|
+
* color: "#00FF00"
|
2418
|
+
* }, {
|
2419
|
+
* x: 1,
|
2420
|
+
* open: 4,
|
2421
|
+
* high: 3,
|
2422
|
+
* low: 6,
|
2423
|
+
* close: 7,
|
2424
|
+
* name: "Point1",
|
2425
|
+
* color: "#FF00FF"
|
2426
|
+
* }]
|
2427
|
+
* ```
|
2428
|
+
*
|
2429
|
+
* @type {Array<Object|Array>}
|
2430
|
+
* @extends series.arearange.data
|
2431
|
+
* @excluding y,marker
|
2432
|
+
* @product highstock
|
2433
|
+
* @apioption series.ohlc.data
|
2434
|
+
*/
|
2435
|
+
|
2436
|
+
/**
|
2437
|
+
* The closing value of each data point.
|
2438
|
+
*
|
2439
|
+
* @type {Number}
|
2440
|
+
* @product highstock
|
2441
|
+
* @apioption series.ohlc.data.close
|
2442
|
+
*/
|
2443
|
+
|
2444
|
+
/**
|
2445
|
+
* The opening value of each data point.
|
2446
|
+
*
|
2447
|
+
* @type {Number}
|
2448
|
+
* @product highstock
|
2449
|
+
* @apioption series.ohlc.data.open
|
2450
|
+
*/
|
2046
2451
|
|
2047
2452
|
}(Highcharts));
|
2048
2453
|
(function(H) {
|
@@ -2058,14 +2463,18 @@
|
|
2058
2463
|
seriesTypes = H.seriesTypes;
|
2059
2464
|
|
2060
2465
|
/**
|
2466
|
+
* A candlestick chart is a style of financial chart used to describe price
|
2467
|
+
* movements over time.
|
2468
|
+
*
|
2469
|
+
* @sample stock/demo/candlestick/ Candlestick chart
|
2470
|
+
*
|
2061
2471
|
* @extends {plotOptions.ohlc}
|
2062
|
-
* @
|
2472
|
+
* @excluding borderColor,borderRadius,borderWidth
|
2473
|
+
* @product highstock
|
2063
2474
|
* @optionparent plotOptions.candlestick
|
2064
2475
|
*/
|
2065
2476
|
var candlestickOptions = {
|
2066
2477
|
|
2067
|
-
/**
|
2068
|
-
*/
|
2069
2478
|
states: {
|
2070
2479
|
|
2071
2480
|
/**
|
@@ -2075,8 +2484,7 @@
|
|
2075
2484
|
hover: {
|
2076
2485
|
|
2077
2486
|
/**
|
2078
|
-
* The pixel width of the line/border around the candlestick.
|
2079
|
-
* to `2`.
|
2487
|
+
* The pixel width of the line/border around the candlestick.
|
2080
2488
|
*
|
2081
2489
|
* @type {Number}
|
2082
2490
|
* @default 2
|
@@ -2087,24 +2495,23 @@
|
|
2087
2495
|
},
|
2088
2496
|
|
2089
2497
|
/**
|
2498
|
+
* @extends {plotOptions.ohlc.tooltip}
|
2090
2499
|
*/
|
2091
2500
|
tooltip: defaultPlotOptions.ohlc.tooltip,
|
2092
2501
|
|
2093
|
-
/**
|
2094
|
-
*/
|
2095
2502
|
threshold: null,
|
2096
2503
|
|
2097
2504
|
|
2098
2505
|
/**
|
2099
2506
|
* The color of the line/border of the candlestick.
|
2100
2507
|
*
|
2101
|
-
* In
|
2102
|
-
* style/style-by-css), the line stroke can be set with the `.highcharts-
|
2508
|
+
* In styled mode, the line stroke can be set with the `.highcharts-
|
2103
2509
|
* candlestick-series .highcahrts-point` rule.
|
2104
2510
|
*
|
2105
2511
|
* @type {Color}
|
2106
2512
|
* @see [upLineColor](#plotOptions.candlestick.upLineColor)
|
2107
|
-
* @sample {highstock} stock/plotoptions/candlestick-linecolor/
|
2513
|
+
* @sample {highstock} stock/plotoptions/candlestick-linecolor/
|
2514
|
+
* Candlestick line colors
|
2108
2515
|
* @default #000000
|
2109
2516
|
* @product highstock
|
2110
2517
|
*/
|
@@ -2114,8 +2521,7 @@
|
|
2114
2521
|
* The pixel width of the candlestick line/border. Defaults to `1`.
|
2115
2522
|
*
|
2116
2523
|
*
|
2117
|
-
* In
|
2118
|
-
* style/style-by-css), the line stroke width can be set with the `.
|
2524
|
+
* In styled mode, the line stroke width can be set with the `.
|
2119
2525
|
* highcharts-candlestick-series .highcahrts-point` rule.
|
2120
2526
|
*
|
2121
2527
|
* @type {Number}
|
@@ -2127,8 +2533,7 @@
|
|
2127
2533
|
/**
|
2128
2534
|
* The fill color of the candlestick when values are rising.
|
2129
2535
|
*
|
2130
|
-
* In
|
2131
|
-
* style/style-by-css), the up color can be set with the `.highcharts-
|
2536
|
+
* In styled mode, the up color can be set with the `.highcharts-
|
2132
2537
|
* candlestick-series .highcharts-point-up` rule.
|
2133
2538
|
*
|
2134
2539
|
* @type {Color}
|
@@ -2139,12 +2544,26 @@
|
|
2139
2544
|
*/
|
2140
2545
|
upColor: '#ffffff',
|
2141
2546
|
|
2547
|
+
stickyTracking: true
|
2548
|
+
|
2142
2549
|
/**
|
2550
|
+
* The specific line color for up candle sticks. The default is to inherit
|
2551
|
+
* the general `lineColor` setting.
|
2552
|
+
*
|
2553
|
+
* @type {Color}
|
2554
|
+
* @sample {highstock} stock/plotoptions/candlestick-linecolor/ Candlestick line colors
|
2555
|
+
* @default null
|
2556
|
+
* @since 1.3.6
|
2557
|
+
* @product highstock
|
2558
|
+
* @apioption plotOptions.candlestick.upLineColor
|
2143
2559
|
*/
|
2144
|
-
stickyTracking: true
|
2145
|
-
// upLineColor: null
|
2146
2560
|
|
2147
2561
|
|
2562
|
+
/**
|
2563
|
+
* @default ohlc
|
2564
|
+
* @apioption plotOptions.candlestick.dataGrouping.approximation
|
2565
|
+
*/
|
2566
|
+
|
2148
2567
|
};
|
2149
2568
|
|
2150
2569
|
/**
|
@@ -2190,7 +2609,7 @@
|
|
2190
2609
|
* Draw the data points
|
2191
2610
|
*/
|
2192
2611
|
drawPoints: function() {
|
2193
|
-
var series = this,
|
2612
|
+
var series = this,
|
2194
2613
|
points = series.points,
|
2195
2614
|
chart = series.chart;
|
2196
2615
|
|
@@ -2274,73 +2693,288 @@
|
|
2274
2693
|
|
2275
2694
|
});
|
2276
2695
|
|
2277
|
-
|
2278
|
-
*
|
2279
|
-
|
2696
|
+
/**
|
2697
|
+
* A `candlestick` series. If the [type](#series.candlestick.type)
|
2698
|
+
* option is not specified, it is inherited from [chart.type](#chart.
|
2699
|
+
* type).
|
2700
|
+
*
|
2701
|
+
* For options that apply to multiple series, it is recommended to add
|
2702
|
+
* them to the [plotOptions.series](#plotOptions.series) options structure.
|
2703
|
+
* To apply to all series of this specific type, apply it to [plotOptions.
|
2704
|
+
* candlestick](#plotOptions.candlestick).
|
2705
|
+
*
|
2706
|
+
* @type {Object}
|
2707
|
+
* @extends series,plotOptions.candlestick
|
2708
|
+
* @excluding dataParser,dataURL
|
2709
|
+
* @product highstock
|
2710
|
+
* @apioption series.candlestick
|
2711
|
+
*/
|
2712
|
+
|
2713
|
+
/**
|
2714
|
+
* An array of data points for the series. For the `candlestick` series
|
2715
|
+
* type, points can be given in the following ways:
|
2716
|
+
*
|
2717
|
+
* 1. An array of arrays with 5 or 4 values. In this case, the values
|
2718
|
+
* correspond to `x,open,high,low,close`. If the first value is a string,
|
2719
|
+
* it is applied as the name of the point, and the `x` value is inferred.
|
2720
|
+
* The `x` value can also be omitted, in which case the inner arrays
|
2721
|
+
* should be of length 4\. Then the `x` value is automatically calculated,
|
2722
|
+
* either starting at 0 and incremented by 1, or from `pointStart`
|
2723
|
+
* and `pointInterval` given in the series options.
|
2724
|
+
*
|
2725
|
+
* ```js
|
2726
|
+
* data: [
|
2727
|
+
* [0, 7, 2, 0, 4],
|
2728
|
+
* [1, 1, 4, 2, 8],
|
2729
|
+
* [2, 3, 3, 9, 3]
|
2730
|
+
* ]
|
2731
|
+
* ```
|
2732
|
+
*
|
2733
|
+
* 2. An array of objects with named values. The objects are point
|
2734
|
+
* configuration objects as seen below. If the total number of data
|
2735
|
+
* points exceeds the series' [turboThreshold](#series.candlestick.
|
2736
|
+
* turboThreshold), this option is not available.
|
2737
|
+
*
|
2738
|
+
* ```js
|
2739
|
+
* data: [{
|
2740
|
+
* x: 1,
|
2741
|
+
* open: 9,
|
2742
|
+
* high: 2,
|
2743
|
+
* low: 4,
|
2744
|
+
* close: 6,
|
2745
|
+
* name: "Point2",
|
2746
|
+
* color: "#00FF00"
|
2747
|
+
* }, {
|
2748
|
+
* x: 1,
|
2749
|
+
* open: 1,
|
2750
|
+
* high: 4,
|
2751
|
+
* low: 7,
|
2752
|
+
* close: 7,
|
2753
|
+
* name: "Point1",
|
2754
|
+
* color: "#FF00FF"
|
2755
|
+
* }]
|
2756
|
+
* ```
|
2757
|
+
*
|
2758
|
+
* @type {Array<Object|Array>}
|
2759
|
+
* @extends series.ohlc.data
|
2760
|
+
* @excluding y
|
2761
|
+
* @product highstock
|
2762
|
+
* @apioption series.candlestick.data
|
2763
|
+
*/
|
2280
2764
|
|
2281
2765
|
}(Highcharts));
|
2282
|
-
(function(H) {
|
2766
|
+
var onSeriesMixin = (function(H) {
|
2283
2767
|
/**
|
2284
2768
|
* (c) 2010-2017 Torstein Honsi
|
2285
2769
|
*
|
2286
2770
|
* License: www.highcharts.com/license
|
2287
2771
|
*/
|
2288
|
-
|
2289
|
-
|
2290
|
-
merge = H.merge,
|
2291
|
-
noop = H.noop,
|
2292
|
-
Renderer = H.Renderer,
|
2293
|
-
Series = H.Series,
|
2294
|
-
seriesType = H.seriesType,
|
2772
|
+
|
2773
|
+
var each = H.each,
|
2295
2774
|
seriesTypes = H.seriesTypes,
|
2296
|
-
SVGRenderer = H.SVGRenderer,
|
2297
|
-
TrackerMixin = H.TrackerMixin,
|
2298
|
-
VMLRenderer = H.VMLRenderer,
|
2299
|
-
symbols = SVGRenderer.prototype.symbols,
|
2300
2775
|
stableSort = H.stableSort;
|
2301
2776
|
|
2302
|
-
|
2303
|
-
* The flags series type.
|
2304
|
-
*
|
2305
|
-
* @constructor seriesTypes.flags
|
2306
|
-
* @augments seriesTypes.column
|
2307
|
-
*/
|
2308
|
-
/**
|
2309
|
-
* @extends {plotOptions.column}
|
2310
|
-
* @optionparent plotOptions.flags
|
2311
|
-
*/
|
2312
|
-
seriesType('flags', 'column', {
|
2313
|
-
|
2777
|
+
var onSeriesMixin = {
|
2314
2778
|
/**
|
2779
|
+
* Extend the translate method by placing the point on the related series
|
2315
2780
|
*/
|
2316
|
-
|
2317
|
-
//radius: 2,
|
2781
|
+
translate: function() {
|
2318
2782
|
|
2319
|
-
|
2320
|
-
* The shape of the marker. Can be one of "flag", "circlepin", "squarepin",
|
2321
|
-
* or an image on the format `url(/path-to-image.jpg)`. Individual
|
2322
|
-
* shapes can also be set for each point.
|
2323
|
-
*
|
2324
|
-
* @validvalue ["flag", "circlepin", "squarepin"]
|
2325
|
-
* @type {String}
|
2326
|
-
* @sample {highstock} stock/plotoptions/flags/ Different shapes
|
2327
|
-
* @default flag
|
2328
|
-
* @product highstock
|
2329
|
-
*/
|
2330
|
-
shape: 'flag',
|
2783
|
+
seriesTypes.column.prototype.translate.apply(this);
|
2331
2784
|
|
2332
|
-
|
2333
|
-
|
2334
|
-
|
2335
|
-
|
2336
|
-
|
2337
|
-
|
2338
|
-
|
2339
|
-
|
2340
|
-
|
2341
|
-
|
2785
|
+
var series = this,
|
2786
|
+
options = series.options,
|
2787
|
+
chart = series.chart,
|
2788
|
+
points = series.points,
|
2789
|
+
cursor = points.length - 1,
|
2790
|
+
point,
|
2791
|
+
lastPoint,
|
2792
|
+
optionsOnSeries = options.onSeries,
|
2793
|
+
onSeries = optionsOnSeries && chart.get(optionsOnSeries),
|
2794
|
+
onKey = options.onKey || 'y',
|
2795
|
+
step = onSeries && onSeries.options.step,
|
2796
|
+
onData = onSeries && onSeries.points,
|
2797
|
+
i = onData && onData.length,
|
2798
|
+
xAxis = series.xAxis,
|
2799
|
+
yAxis = series.yAxis,
|
2800
|
+
xAxisExt = xAxis.getExtremes(),
|
2801
|
+
xOffset = 0,
|
2802
|
+
leftPoint,
|
2803
|
+
lastX,
|
2804
|
+
rightPoint,
|
2805
|
+
currentDataGrouping;
|
2342
2806
|
|
2343
|
-
|
2807
|
+
// relate to a master series
|
2808
|
+
if (onSeries && onSeries.visible && i) {
|
2809
|
+
xOffset = (onSeries.pointXOffset || 0) + (onSeries.barW || 0) / 2;
|
2810
|
+
currentDataGrouping = onSeries.currentDataGrouping;
|
2811
|
+
lastX = (
|
2812
|
+
onData[i - 1].x +
|
2813
|
+
(currentDataGrouping ? currentDataGrouping.totalRange : 0)
|
2814
|
+
); // #2374
|
2815
|
+
|
2816
|
+
// sort the data points
|
2817
|
+
stableSort(points, function(a, b) {
|
2818
|
+
return (a.x - b.x);
|
2819
|
+
});
|
2820
|
+
|
2821
|
+
onKey = 'plot' + onKey[0].toUpperCase() + onKey.substr(1);
|
2822
|
+
while (i-- && points[cursor]) {
|
2823
|
+
point = points[cursor];
|
2824
|
+
leftPoint = onData[i];
|
2825
|
+
if (leftPoint.x <= point.x && leftPoint[onKey] !== undefined) {
|
2826
|
+
if (point.x <= lastX) { // #803
|
2827
|
+
|
2828
|
+
point.plotY = leftPoint[onKey];
|
2829
|
+
|
2830
|
+
// interpolate between points, #666
|
2831
|
+
if (leftPoint.x < point.x && !step) {
|
2832
|
+
rightPoint = onData[i + 1];
|
2833
|
+
if (rightPoint && rightPoint[onKey] !== undefined) {
|
2834
|
+
point.plotY +=
|
2835
|
+
// the distance ratio, between 0 and 1
|
2836
|
+
(
|
2837
|
+
(point.x - leftPoint.x) /
|
2838
|
+
(rightPoint.x - leftPoint.x)
|
2839
|
+
) *
|
2840
|
+
// the y distance
|
2841
|
+
(rightPoint[onKey] - leftPoint[onKey]);
|
2842
|
+
}
|
2843
|
+
}
|
2844
|
+
}
|
2845
|
+
cursor--;
|
2846
|
+
i++; // check again for points in the same x position
|
2847
|
+
if (cursor < 0) {
|
2848
|
+
break;
|
2849
|
+
}
|
2850
|
+
}
|
2851
|
+
}
|
2852
|
+
}
|
2853
|
+
|
2854
|
+
// Add plotY position and handle stacking
|
2855
|
+
each(points, function(point, i) {
|
2856
|
+
|
2857
|
+
var stackIndex;
|
2858
|
+
|
2859
|
+
// Undefined plotY means the point is either on axis, outside series
|
2860
|
+
// range or hidden series. If the series is outside the range of the
|
2861
|
+
// x axis it should fall through with an undefined plotY, but then
|
2862
|
+
// we must remove the shapeArgs (#847).
|
2863
|
+
if (point.plotY === undefined) {
|
2864
|
+
if (point.x >= xAxisExt.min && point.x <= xAxisExt.max) {
|
2865
|
+
// we're inside xAxis range
|
2866
|
+
point.plotY = chart.chartHeight - xAxis.bottom -
|
2867
|
+
(xAxis.opposite ? xAxis.height : 0) +
|
2868
|
+
xAxis.offset - yAxis.top; // #3517
|
2869
|
+
} else {
|
2870
|
+
point.shapeArgs = {}; // 847
|
2871
|
+
}
|
2872
|
+
}
|
2873
|
+
point.plotX += xOffset; // #2049
|
2874
|
+
// if multiple flags appear at the same x, order them into a stack
|
2875
|
+
lastPoint = points[i - 1];
|
2876
|
+
if (lastPoint && lastPoint.plotX === point.plotX) {
|
2877
|
+
if (lastPoint.stackIndex === undefined) {
|
2878
|
+
lastPoint.stackIndex = 0;
|
2879
|
+
}
|
2880
|
+
stackIndex = lastPoint.stackIndex + 1;
|
2881
|
+
}
|
2882
|
+
point.stackIndex = stackIndex; // #3639
|
2883
|
+
});
|
2884
|
+
|
2885
|
+
|
2886
|
+
}
|
2887
|
+
};
|
2888
|
+
return onSeriesMixin;
|
2889
|
+
}(Highcharts));
|
2890
|
+
(function(H, onSeriesMixin) {
|
2891
|
+
/**
|
2892
|
+
* (c) 2010-2017 Torstein Honsi
|
2893
|
+
*
|
2894
|
+
* License: www.highcharts.com/license
|
2895
|
+
*/
|
2896
|
+
var addEvent = H.addEvent,
|
2897
|
+
each = H.each,
|
2898
|
+
merge = H.merge,
|
2899
|
+
noop = H.noop,
|
2900
|
+
Renderer = H.Renderer,
|
2901
|
+
Series = H.Series,
|
2902
|
+
seriesType = H.seriesType,
|
2903
|
+
SVGRenderer = H.SVGRenderer,
|
2904
|
+
TrackerMixin = H.TrackerMixin,
|
2905
|
+
VMLRenderer = H.VMLRenderer,
|
2906
|
+
symbols = SVGRenderer.prototype.symbols;
|
2907
|
+
|
2908
|
+
/**
|
2909
|
+
* The Flags series.
|
2910
|
+
* @constructor seriesTypes.flags
|
2911
|
+
* @augments seriesTypes.column
|
2912
|
+
*/
|
2913
|
+
/**
|
2914
|
+
* Flags are used to mark events in stock charts. They can be added on the
|
2915
|
+
* timeline, or attached to a specific series.
|
2916
|
+
*
|
2917
|
+
* @sample stock/demo/flags-general/ Flags on a line series
|
2918
|
+
* @extends {plotOptions.column}
|
2919
|
+
* @excluding animation,borderColor,borderRadius,borderWidth,colorByPoint,dataGrouping,pointPadding,pointWidth,turboThreshold
|
2920
|
+
* @product highstock
|
2921
|
+
* @optionparent plotOptions.flags
|
2922
|
+
*/
|
2923
|
+
seriesType('flags', 'column', {
|
2924
|
+
|
2925
|
+
/**
|
2926
|
+
* In case the flag is placed on a series, on what point key to place
|
2927
|
+
* it. Line and columns have one key, `y`. In range or OHLC-type series,
|
2928
|
+
* however, the flag can optionally be placed on the `open`, `high`,
|
2929
|
+
* `low` or `close` key.
|
2930
|
+
*
|
2931
|
+
* @validvalue ["y", "open", "high", "low", "close"]
|
2932
|
+
* @type {String}
|
2933
|
+
* @sample {highstock} stock/plotoptions/flags-onkey/ Range series, flag on high
|
2934
|
+
* @default y
|
2935
|
+
* @since 4.2.2
|
2936
|
+
* @product highstock
|
2937
|
+
* @apioption plotOptions.flags.onKey
|
2938
|
+
*/
|
2939
|
+
|
2940
|
+
/**
|
2941
|
+
* The id of the series that the flags should be drawn on. If no id
|
2942
|
+
* is given, the flags are drawn on the x axis.
|
2943
|
+
*
|
2944
|
+
* @type {String}
|
2945
|
+
* @sample {highstock} stock/plotoptions/flags/ Flags on series and on x axis
|
2946
|
+
* @default undefined
|
2947
|
+
* @product highstock
|
2948
|
+
* @apioption plotOptions.flags.onSeries
|
2949
|
+
*/
|
2950
|
+
|
2951
|
+
pointRange: 0, // #673
|
2952
|
+
|
2953
|
+
/**
|
2954
|
+
* The shape of the marker. Can be one of "flag", "circlepin", "squarepin",
|
2955
|
+
* or an image on the format `url(/path-to-image.jpg)`. Individual
|
2956
|
+
* shapes can also be set for each point.
|
2957
|
+
*
|
2958
|
+
* @validvalue ["flag", "circlepin", "squarepin"]
|
2959
|
+
* @type {String}
|
2960
|
+
* @sample {highstock} stock/plotoptions/flags/ Different shapes
|
2961
|
+
* @default flag
|
2962
|
+
* @product highstock
|
2963
|
+
*/
|
2964
|
+
shape: 'flag',
|
2965
|
+
|
2966
|
+
/**
|
2967
|
+
* When multiple flags in the same series fall on the same value, this
|
2968
|
+
* number determines the vertical offset between them.
|
2969
|
+
*
|
2970
|
+
* @type {Number}
|
2971
|
+
* @sample {highstock} stock/plotoptions/flags-stackdistance/ A greater stack distance
|
2972
|
+
* @default 12
|
2973
|
+
* @product highstock
|
2974
|
+
*/
|
2975
|
+
stackDistance: 12,
|
2976
|
+
|
2977
|
+
/**
|
2344
2978
|
* Text alignment for the text inside the flag.
|
2345
2979
|
*
|
2346
2980
|
* @validvalue ["left", "center", "right"]
|
@@ -2363,15 +2997,20 @@
|
|
2363
2997
|
* @product highstock
|
2364
2998
|
*/
|
2365
2999
|
tooltip: {
|
2366
|
-
|
2367
|
-
/**
|
2368
|
-
*/
|
2369
3000
|
pointFormat: '{point.text}<br/>'
|
2370
3001
|
},
|
2371
3002
|
|
3003
|
+
threshold: null,
|
3004
|
+
|
2372
3005
|
/**
|
3006
|
+
* The text to display on each flag. This can be defined on series level,
|
3007
|
+
* or individually for each point. Defaults to `"A"`.
|
3008
|
+
*
|
3009
|
+
* @type {String}
|
3010
|
+
* @default "A"
|
3011
|
+
* @product highstock
|
3012
|
+
* @apioption plotOptions.flags.title
|
2373
3013
|
*/
|
2374
|
-
threshold: null,
|
2375
3014
|
|
2376
3015
|
/**
|
2377
3016
|
* The y position of the top left corner of the flag relative to either
|
@@ -2384,14 +3023,40 @@
|
|
2384
3023
|
*/
|
2385
3024
|
y: -30,
|
2386
3025
|
|
3026
|
+
/**
|
3027
|
+
* Whether to use HTML to render the flag texts. Using HTML allows for
|
3028
|
+
* advanced formatting, images and reliable bi-directional text rendering.
|
3029
|
+
* Note that exported images won't respect the HTML, and that HTML
|
3030
|
+
* won't respect Z-index settings.
|
3031
|
+
*
|
3032
|
+
* @type {Boolean}
|
3033
|
+
* @default false
|
3034
|
+
* @since 1.3
|
3035
|
+
* @product highstock
|
3036
|
+
* @apioption plotOptions.flags.useHTML
|
3037
|
+
*/
|
3038
|
+
|
3039
|
+
|
2387
3040
|
|
2388
3041
|
/**
|
3042
|
+
* The fill color for the flags.
|
2389
3043
|
*/
|
2390
3044
|
fillColor: '#ffffff',
|
2391
|
-
// lineColor: color,
|
2392
3045
|
|
2393
3046
|
/**
|
2394
|
-
* The
|
3047
|
+
* The color of the line/border of the flag.
|
3048
|
+
*
|
3049
|
+
* In styled mode, the stroke is set in the `.highcharts-flag-series
|
3050
|
+
* .highcharts-point` rule.
|
3051
|
+
*
|
3052
|
+
* @type {Color}
|
3053
|
+
* @default #000000
|
3054
|
+
* @product highstock
|
3055
|
+
* @apioption plotOptions.flags.lineColor
|
3056
|
+
*/
|
3057
|
+
|
3058
|
+
/**
|
3059
|
+
* The pixel width of the flag's line/border.
|
2395
3060
|
*
|
2396
3061
|
* @type {Number}
|
2397
3062
|
* @default 1
|
@@ -2399,8 +3064,6 @@
|
|
2399
3064
|
*/
|
2400
3065
|
lineWidth: 1,
|
2401
3066
|
|
2402
|
-
/**
|
2403
|
-
*/
|
2404
3067
|
states: {
|
2405
3068
|
|
2406
3069
|
/**
|
@@ -2410,7 +3073,7 @@
|
|
2410
3073
|
hover: {
|
2411
3074
|
|
2412
3075
|
/**
|
2413
|
-
* The color of the line/border of the flag
|
3076
|
+
* The color of the line/border of the flag.
|
2414
3077
|
*
|
2415
3078
|
* @type {String}
|
2416
3079
|
* @default "black"
|
@@ -2419,7 +3082,7 @@
|
|
2419
3082
|
lineColor: '#000000',
|
2420
3083
|
|
2421
3084
|
/**
|
2422
|
-
* The fill or background color of the flag
|
3085
|
+
* The fill or background color of the flag.
|
2423
3086
|
*
|
2424
3087
|
* @type {String}
|
2425
3088
|
* @default "#FCFFC5"
|
@@ -2432,8 +3095,7 @@
|
|
2432
3095
|
/**
|
2433
3096
|
* The text styles of the flag.
|
2434
3097
|
*
|
2435
|
-
* In
|
2436
|
-
* style/style-by-css), the styles are set in the `.highcharts-flag-
|
3098
|
+
* In styled mode, the styles are set in the `.highcharts-flag-
|
2437
3099
|
* series .highcharts-point` rule.
|
2438
3100
|
*
|
2439
3101
|
* @type {CSSObject}
|
@@ -2441,13 +3103,7 @@
|
|
2441
3103
|
* @product highstock
|
2442
3104
|
*/
|
2443
3105
|
style: {
|
2444
|
-
|
2445
|
-
/**
|
2446
|
-
*/
|
2447
3106
|
fontSize: '11px',
|
2448
|
-
|
2449
|
-
/**
|
2450
|
-
*/
|
2451
3107
|
fontWeight: 'bold'
|
2452
3108
|
}
|
2453
3109
|
|
@@ -2489,107 +3145,7 @@
|
|
2489
3145
|
},
|
2490
3146
|
|
2491
3147
|
|
2492
|
-
|
2493
|
-
* Extend the translate method by placing the point on the related series
|
2494
|
-
*/
|
2495
|
-
translate: function() {
|
2496
|
-
|
2497
|
-
seriesTypes.column.prototype.translate.apply(this);
|
2498
|
-
|
2499
|
-
var series = this,
|
2500
|
-
options = series.options,
|
2501
|
-
chart = series.chart,
|
2502
|
-
points = series.points,
|
2503
|
-
cursor = points.length - 1,
|
2504
|
-
point,
|
2505
|
-
lastPoint,
|
2506
|
-
optionsOnSeries = options.onSeries,
|
2507
|
-
onSeries = optionsOnSeries && chart.get(optionsOnSeries),
|
2508
|
-
onKey = options.onKey || 'y',
|
2509
|
-
step = onSeries && onSeries.options.step,
|
2510
|
-
onData = onSeries && onSeries.points,
|
2511
|
-
i = onData && onData.length,
|
2512
|
-
xAxis = series.xAxis,
|
2513
|
-
yAxis = series.yAxis,
|
2514
|
-
xAxisExt = xAxis.getExtremes(),
|
2515
|
-
xOffset = 0,
|
2516
|
-
leftPoint,
|
2517
|
-
lastX,
|
2518
|
-
rightPoint,
|
2519
|
-
currentDataGrouping;
|
2520
|
-
|
2521
|
-
// relate to a master series
|
2522
|
-
if (onSeries && onSeries.visible && i) {
|
2523
|
-
xOffset = (onSeries.pointXOffset || 0) + (onSeries.barW || 0) / 2;
|
2524
|
-
currentDataGrouping = onSeries.currentDataGrouping;
|
2525
|
-
lastX = onData[i - 1].x + (currentDataGrouping ? currentDataGrouping.totalRange : 0); // #2374
|
2526
|
-
|
2527
|
-
// sort the data points
|
2528
|
-
stableSort(points, function(a, b) {
|
2529
|
-
return (a.x - b.x);
|
2530
|
-
});
|
2531
|
-
|
2532
|
-
onKey = 'plot' + onKey[0].toUpperCase() + onKey.substr(1);
|
2533
|
-
while (i-- && points[cursor]) {
|
2534
|
-
point = points[cursor];
|
2535
|
-
leftPoint = onData[i];
|
2536
|
-
if (leftPoint.x <= point.x && leftPoint[onKey] !== undefined) {
|
2537
|
-
if (point.x <= lastX) { // #803
|
2538
|
-
|
2539
|
-
point.plotY = leftPoint[onKey];
|
2540
|
-
|
2541
|
-
// interpolate between points, #666
|
2542
|
-
if (leftPoint.x < point.x && !step) {
|
2543
|
-
rightPoint = onData[i + 1];
|
2544
|
-
if (rightPoint && rightPoint[onKey] !== undefined) {
|
2545
|
-
point.plotY +=
|
2546
|
-
((point.x - leftPoint.x) / (rightPoint.x - leftPoint.x)) * // the distance ratio, between 0 and 1
|
2547
|
-
(rightPoint[onKey] - leftPoint[onKey]); // the y distance
|
2548
|
-
}
|
2549
|
-
}
|
2550
|
-
}
|
2551
|
-
cursor--;
|
2552
|
-
i++; // check again for points in the same x position
|
2553
|
-
if (cursor < 0) {
|
2554
|
-
break;
|
2555
|
-
}
|
2556
|
-
}
|
2557
|
-
}
|
2558
|
-
}
|
2559
|
-
|
2560
|
-
// Add plotY position and handle stacking
|
2561
|
-
each(points, function(point, i) {
|
2562
|
-
|
2563
|
-
var stackIndex;
|
2564
|
-
|
2565
|
-
// Undefined plotY means the point is either on axis, outside series
|
2566
|
-
// range or hidden series. If the series is outside the range of the
|
2567
|
-
// x axis it should fall through with an undefined plotY, but then
|
2568
|
-
// we must remove the shapeArgs (#847).
|
2569
|
-
if (point.plotY === undefined) {
|
2570
|
-
if (point.x >= xAxisExt.min && point.x <= xAxisExt.max) {
|
2571
|
-
// we're inside xAxis range
|
2572
|
-
point.plotY = chart.chartHeight - xAxis.bottom -
|
2573
|
-
(xAxis.opposite ? xAxis.height : 0) +
|
2574
|
-
xAxis.offset - yAxis.top; // #3517
|
2575
|
-
} else {
|
2576
|
-
point.shapeArgs = {}; // 847
|
2577
|
-
}
|
2578
|
-
}
|
2579
|
-
point.plotX += xOffset; // #2049
|
2580
|
-
// if multiple flags appear at the same x, order them into a stack
|
2581
|
-
lastPoint = points[i - 1];
|
2582
|
-
if (lastPoint && lastPoint.plotX === point.plotX) {
|
2583
|
-
if (lastPoint.stackIndex === undefined) {
|
2584
|
-
lastPoint.stackIndex = 0;
|
2585
|
-
}
|
2586
|
-
stackIndex = lastPoint.stackIndex + 1;
|
2587
|
-
}
|
2588
|
-
point.stackIndex = stackIndex; // #3639
|
2589
|
-
});
|
2590
|
-
|
2591
|
-
|
2592
|
-
},
|
3148
|
+
translate: onSeriesMixin.translate,
|
2593
3149
|
|
2594
3150
|
/**
|
2595
3151
|
* Draw the markers
|
@@ -2799,11 +3355,77 @@
|
|
2799
3355
|
});
|
2800
3356
|
}
|
2801
3357
|
|
2802
|
-
/* ****************************************************************************
|
2803
|
-
* End Flags series code *
|
2804
|
-
*****************************************************************************/
|
2805
3358
|
|
2806
|
-
|
3359
|
+
/**
|
3360
|
+
* A `flags` series. If the [type](#series.flags.type) option is not
|
3361
|
+
* specified, it is inherited from [chart.type](#chart.type).
|
3362
|
+
*
|
3363
|
+
* For options that apply to multiple series, it is recommended to add
|
3364
|
+
* them to the [plotOptions.series](#plotOptions.series) options structure.
|
3365
|
+
* To apply to all series of this specific type, apply it to [plotOptions.
|
3366
|
+
* flags](#plotOptions.flags).
|
3367
|
+
*
|
3368
|
+
* @type {Object}
|
3369
|
+
* @extends series,plotOptions.flags
|
3370
|
+
* @excluding dataParser,dataURL
|
3371
|
+
* @product highstock
|
3372
|
+
* @apioption series.flags
|
3373
|
+
*/
|
3374
|
+
|
3375
|
+
/**
|
3376
|
+
* An array of data points for the series. For the `flags` series type,
|
3377
|
+
* points can be given in the following ways:
|
3378
|
+
*
|
3379
|
+
* 1. An array of objects with named values. The objects are point
|
3380
|
+
* configuration objects as seen below. If the total number of data
|
3381
|
+
* points exceeds the series' [turboThreshold](#series.flags.turboThreshold),
|
3382
|
+
* this option is not available.
|
3383
|
+
*
|
3384
|
+
* ```js
|
3385
|
+
* data: [{
|
3386
|
+
* x: 1,
|
3387
|
+
* title: "A",
|
3388
|
+
* text: "First event"
|
3389
|
+
* }, {
|
3390
|
+
* x: 1,
|
3391
|
+
* title: "B",
|
3392
|
+
* text: "Second event"
|
3393
|
+
* }]</pre>
|
3394
|
+
*
|
3395
|
+
* @type {Array<Object>}
|
3396
|
+
* @extends series.line.data
|
3397
|
+
* @excluding y,dataLabels,marker,name
|
3398
|
+
* @product highstock
|
3399
|
+
* @apioption series.flags.data
|
3400
|
+
*/
|
3401
|
+
|
3402
|
+
/**
|
3403
|
+
* The fill color of an individual flag. By default it inherits from
|
3404
|
+
* the series color.
|
3405
|
+
*
|
3406
|
+
* @type {Color}
|
3407
|
+
* @product highstock
|
3408
|
+
* @apioption series.flags.data.fillColor
|
3409
|
+
*/
|
3410
|
+
|
3411
|
+
/**
|
3412
|
+
* The longer text to be shown in the flag's tooltip.
|
3413
|
+
*
|
3414
|
+
* @type {String}
|
3415
|
+
* @product highstock
|
3416
|
+
* @apioption series.flags.data.text
|
3417
|
+
*/
|
3418
|
+
|
3419
|
+
/**
|
3420
|
+
* The short text to be shown on the flag.
|
3421
|
+
*
|
3422
|
+
* @type {String}
|
3423
|
+
* @product highstock
|
3424
|
+
* @apioption series.flags.data.title
|
3425
|
+
*/
|
3426
|
+
|
3427
|
+
|
3428
|
+
}(Highcharts, onSeriesMixin));
|
2807
3429
|
(function(H) {
|
2808
3430
|
/**
|
2809
3431
|
* (c) 2010-2017 Torstein Honsi
|
@@ -2829,20 +3451,17 @@
|
|
2829
3451
|
|
2830
3452
|
/**
|
2831
3453
|
*
|
2832
|
-
* The scrollbar is a means of panning over the X axis of a chart.
|
3454
|
+
* The scrollbar is a means of panning over the X axis of a stock chart.
|
2833
3455
|
*
|
2834
|
-
* In
|
2835
|
-
*
|
2836
|
-
* scrollbar
|
2837
|
-
*
|
2838
|
-
* button`, `.highcharts-scrollbar-rifles` and `.highcharts-scrollbar-
|
2839
|
-
* track`.
|
3456
|
+
* In styled mode, all the presentational options for the
|
3457
|
+
* scrollbar are replaced by the classes `.highcharts-scrollbar-thumb`,
|
3458
|
+
* `.highcharts-scrollbar-arrow`, `.highcharts-scrollbar-button`,
|
3459
|
+
* `.highcharts-scrollbar-rifles` and `.highcharts-scrollbar-track`.
|
2840
3460
|
*
|
2841
3461
|
* @product highstock
|
2842
3462
|
* @optionparent scrollbar
|
2843
3463
|
*/
|
2844
3464
|
var defaultScrollbarOptions = {
|
2845
|
-
//enabled: true
|
2846
3465
|
|
2847
3466
|
/**
|
2848
3467
|
* The height of the scrollbar. The height also applies to the width
|
@@ -2854,7 +3473,6 @@
|
|
2854
3473
|
* @product highstock
|
2855
3474
|
*/
|
2856
3475
|
height: isTouchDevice ? 20 : 14,
|
2857
|
-
// trackBorderRadius: 0
|
2858
3476
|
|
2859
3477
|
/**
|
2860
3478
|
* The border rounding radius of the bar.
|
@@ -2888,6 +3506,8 @@
|
|
2888
3506
|
liveRedraw: svg && !isTouchDevice,
|
2889
3507
|
|
2890
3508
|
/**
|
3509
|
+
* The margin between the scrollbar and its axis when the scrollbar is
|
3510
|
+
* applied directly to an axis.
|
2891
3511
|
*/
|
2892
3512
|
margin: 10,
|
2893
3513
|
|
@@ -2900,14 +3520,11 @@
|
|
2900
3520
|
* @product highstock
|
2901
3521
|
*/
|
2902
3522
|
minWidth: 6,
|
2903
|
-
//showFull: true,
|
2904
|
-
//size: null,
|
2905
3523
|
|
2906
|
-
/**
|
2907
|
-
*/
|
2908
3524
|
step: 0.2,
|
2909
3525
|
|
2910
3526
|
/**
|
3527
|
+
* The z index of the scrollbar group.
|
2911
3528
|
*/
|
2912
3529
|
zIndex: 3,
|
2913
3530
|
|
@@ -3735,9 +4352,38 @@
|
|
3735
4352
|
*
|
3736
4353
|
* License: www.highcharts.com/license
|
3737
4354
|
*/
|
3738
|
-
/*
|
3739
|
-
|
3740
|
-
|
4355
|
+
/* eslint max-len: ["warn", 80, 4] */
|
4356
|
+
|
4357
|
+
/**
|
4358
|
+
* Options for the corresponding navigator series if `showInNavigator`
|
4359
|
+
* is `true` for this series. Available options are the same as any
|
4360
|
+
* series, documented at [plotOptions](#plotOptions.series) and
|
4361
|
+
* [series](#series).
|
4362
|
+
*
|
4363
|
+
*
|
4364
|
+
* These options are merged with options in [navigator.series](#navigator.
|
4365
|
+
* series), and will take precedence if the same option is defined both
|
4366
|
+
* places.
|
4367
|
+
*
|
4368
|
+
* @type {Object}
|
4369
|
+
* @see [navigator.series](#navigator.series)
|
4370
|
+
* @default undefined
|
4371
|
+
* @since 5.0.0
|
4372
|
+
* @product highstock
|
4373
|
+
* @apioption plotOptions.series.navigatorOptions
|
4374
|
+
*/
|
4375
|
+
|
4376
|
+
/**
|
4377
|
+
* Whether or not to show the series in the navigator. Takes precedence
|
4378
|
+
* over [navigator.baseSeries](#navigator.baseSeries) if defined.
|
4379
|
+
*
|
4380
|
+
* @type {Boolean}
|
4381
|
+
* @default undefined
|
4382
|
+
* @since 5.0.0
|
4383
|
+
* @product highstock
|
4384
|
+
* @apioption plotOptions.series.showInNavigator
|
4385
|
+
*/
|
4386
|
+
|
3741
4387
|
var addEvent = H.addEvent,
|
3742
4388
|
Axis = H.Axis,
|
3743
4389
|
Chart = H.Chart,
|
@@ -3762,14 +4408,13 @@
|
|
3762
4408
|
Series = H.Series,
|
3763
4409
|
seriesTypes = H.seriesTypes,
|
3764
4410
|
wrap = H.wrap,
|
3765
|
-
swapXY = H.swapXY,
|
3766
4411
|
|
3767
4412
|
units = [].concat(defaultDataGroupingUnits), // copy
|
3768
4413
|
defaultSeriesType,
|
3769
4414
|
|
3770
|
-
// Finding the min or max of a set of variables where we don't know if they
|
3771
|
-
// is a pattern that is repeated several places in Highcharts.
|
3772
|
-
// a global utility method.
|
4415
|
+
// Finding the min or max of a set of variables where we don't know if they
|
4416
|
+
// are defined, is a pattern that is repeated several places in Highcharts.
|
4417
|
+
// Consider making this a global utility method.
|
3773
4418
|
numExt = function(extreme) {
|
3774
4419
|
var numbers = grep(arguments, isNumber);
|
3775
4420
|
if (numbers.length) {
|
@@ -3781,7 +4426,9 @@
|
|
3781
4426
|
units[4] = ['day', [1, 2, 3, 4]]; // allow more days
|
3782
4427
|
units[5] = ['week', [1, 2, 3]]; // allow more weeks
|
3783
4428
|
|
3784
|
-
defaultSeriesType = seriesTypes.areaspline === undefined ?
|
4429
|
+
defaultSeriesType = seriesTypes.areaspline === undefined ?
|
4430
|
+
'line' :
|
4431
|
+
'areaspline';
|
3785
4432
|
|
3786
4433
|
extend(defaultOptions, {
|
3787
4434
|
|
@@ -3790,15 +4437,13 @@
|
|
3790
4437
|
* a view of the entire data set. It provides tools to zoom in and
|
3791
4438
|
* out on parts of the data as well as panning across the dataset.
|
3792
4439
|
*
|
3793
|
-
* @optionparent navigator
|
3794
4440
|
* @product highstock
|
4441
|
+
* @optionparent navigator
|
3795
4442
|
*/
|
3796
4443
|
navigator: {
|
3797
|
-
//enabled: true,
|
3798
|
-
|
3799
4444
|
/**
|
3800
4445
|
* The height of the navigator.
|
3801
|
-
*
|
4446
|
+
*
|
3802
4447
|
* @type {Number}
|
3803
4448
|
* @sample {highstock} stock/navigator/height/ A higher navigator
|
3804
4449
|
* @default 40
|
@@ -3808,9 +4453,10 @@
|
|
3808
4453
|
|
3809
4454
|
/**
|
3810
4455
|
* The distance from the nearest element, the X axis or X axis labels.
|
3811
|
-
*
|
4456
|
+
*
|
3812
4457
|
* @type {Number}
|
3813
|
-
* @sample {highstock} stock/navigator/margin/
|
4458
|
+
* @sample {highstock} stock/navigator/margin/
|
4459
|
+
* A margin of 2 draws the navigator closer to the X axis labels
|
3814
4460
|
* @default 25
|
3815
4461
|
* @product highstock
|
3816
4462
|
*/
|
@@ -3819,57 +4465,125 @@
|
|
3819
4465
|
/**
|
3820
4466
|
* Whether the mask should be inside the range marking the zoomed
|
3821
4467
|
* range, or outside. In Highstock 1.x it was always `false`.
|
3822
|
-
*
|
4468
|
+
*
|
3823
4469
|
* @type {Boolean}
|
3824
|
-
* @sample {highstock} stock/navigator/maskinside-false/
|
4470
|
+
* @sample {highstock} stock/navigator/maskinside-false/
|
4471
|
+
* False, mask outside
|
3825
4472
|
* @default true
|
3826
4473
|
* @since 2.0
|
3827
4474
|
* @product highstock
|
3828
4475
|
*/
|
3829
4476
|
maskInside: true,
|
3830
4477
|
|
3831
|
-
|
3832
4478
|
/**
|
3833
|
-
* Options for the handles for dragging the zoomed area.
|
3834
|
-
*
|
3835
|
-
* (defaults to `#b2b1b6`).
|
3836
|
-
*
|
4479
|
+
* Options for the handles for dragging the zoomed area.
|
4480
|
+
*
|
3837
4481
|
* @type {Object}
|
3838
4482
|
* @sample {highstock} stock/navigator/handles/ Colored handles
|
3839
|
-
* @sample {highstock} stock/navigator/handles/ Colored handles
|
3840
4483
|
* @product highstock
|
3841
4484
|
*/
|
3842
4485
|
handles: {
|
4486
|
+
/**
|
4487
|
+
* Width for handles.
|
4488
|
+
*
|
4489
|
+
* @type {umber}
|
4490
|
+
* @default 7
|
4491
|
+
* @product highstock
|
4492
|
+
* @sample {highstock} stock/navigator/styled-handles/
|
4493
|
+
* Styled handles
|
4494
|
+
* @since 6.0.0
|
4495
|
+
*/
|
4496
|
+
width: 7,
|
4497
|
+
|
4498
|
+
/**
|
4499
|
+
* Height for handles.
|
4500
|
+
*
|
4501
|
+
* @type {Number}
|
4502
|
+
* @default 15
|
4503
|
+
* @product highstock
|
4504
|
+
* @sample {highstock} stock/navigator/styled-handles/
|
4505
|
+
* Styled handles
|
4506
|
+
* @since 6.0.0
|
4507
|
+
*/
|
4508
|
+
height: 15,
|
4509
|
+
|
4510
|
+
/**
|
4511
|
+
* Array to define shapes of handles. 0-index for left, 1-index for
|
4512
|
+
* right.
|
4513
|
+
*
|
4514
|
+
* Additionally, the URL to a graphic can be given on this form:
|
4515
|
+
* `url(graphic.png)`. Note that for the image to be applied to
|
4516
|
+
* exported charts, its URL needs to be accessible by the export
|
4517
|
+
* server.
|
4518
|
+
*
|
4519
|
+
* Custom callbacks for symbol path generation can also be added to
|
4520
|
+
* `Highcharts.SVGRenderer.prototype.symbols`. The callback is then
|
4521
|
+
* used by its method name, as shown in the demo.
|
4522
|
+
*
|
4523
|
+
* @type {Array}
|
4524
|
+
* @default ['navigator-handle', 'navigator-handle']
|
4525
|
+
* @product highstock
|
4526
|
+
* @sample {highstock} stock/navigator/styled-handles/
|
4527
|
+
* Styled handles
|
4528
|
+
* @since 6.0.0
|
4529
|
+
*/
|
4530
|
+
symbols: ['navigator-handle', 'navigator-handle'],
|
4531
|
+
|
4532
|
+
/**
|
4533
|
+
* Allows to enable/disable handles.
|
4534
|
+
*
|
4535
|
+
* @type {Boolean}
|
4536
|
+
* @default true
|
4537
|
+
* @product highstock
|
4538
|
+
* @since 6.0.0
|
4539
|
+
*/
|
4540
|
+
enabled: true,
|
4541
|
+
|
4542
|
+
|
4543
|
+
/**
|
4544
|
+
* The width for the handle border and the stripes inside.
|
4545
|
+
*
|
4546
|
+
* @type {Number}
|
4547
|
+
* @default 7
|
4548
|
+
* @product highstock
|
4549
|
+
* @sample {highstock} stock/navigator/styled-handles/
|
4550
|
+
* Styled handles
|
4551
|
+
* @since 6.0.0
|
4552
|
+
*/
|
4553
|
+
lineWidth: 1,
|
3843
4554
|
|
3844
4555
|
/**
|
3845
4556
|
* The fill for the handle.
|
3846
|
-
*
|
4557
|
+
*
|
3847
4558
|
* @type {Color}
|
3848
|
-
* @default #f2f2f2
|
3849
4559
|
* @product highstock
|
3850
4560
|
*/
|
3851
4561
|
backgroundColor: '#f2f2f2',
|
3852
4562
|
|
3853
4563
|
/**
|
3854
4564
|
* The stroke for the handle border and the stripes inside.
|
3855
|
-
*
|
4565
|
+
*
|
3856
4566
|
* @type {Color}
|
3857
|
-
* @default #999999
|
3858
4567
|
* @product highstock
|
3859
4568
|
*/
|
3860
4569
|
borderColor: '#999999'
|
4570
|
+
|
4571
|
+
|
3861
4572
|
},
|
3862
4573
|
|
4574
|
+
|
4575
|
+
|
3863
4576
|
/**
|
3864
4577
|
* The color of the mask covering the areas of the navigator series
|
3865
4578
|
* that are currently not visible in the main series. The default
|
3866
4579
|
* color is bluish with an opacity of 0.3 to see the series below.
|
3867
|
-
*
|
4580
|
+
*
|
3868
4581
|
* @type {Color}
|
3869
|
-
* @see
|
3870
|
-
*
|
3871
|
-
*
|
3872
|
-
* @sample
|
4582
|
+
* @see In styled mode, the mask is styled with the
|
4583
|
+
* `.highcharts-navigator-mask` and
|
4584
|
+
* `.highcharts-navigator-mask-inside` classes.
|
4585
|
+
* @sample {highstock} stock/navigator/maskfill/
|
4586
|
+
* Blue, semi transparent mask
|
3873
4587
|
* @default rgba(102,133,194,0.3)
|
3874
4588
|
* @product highstock
|
3875
4589
|
*/
|
@@ -3878,7 +4592,7 @@
|
|
3878
4592
|
/**
|
3879
4593
|
* The color of the line marking the currently zoomed area in the
|
3880
4594
|
* navigator.
|
3881
|
-
*
|
4595
|
+
*
|
3882
4596
|
* @type {Color}
|
3883
4597
|
* @sample {highstock} stock/navigator/outline/ 2px blue outline
|
3884
4598
|
* @default #cccccc
|
@@ -3889,10 +4603,9 @@
|
|
3889
4603
|
/**
|
3890
4604
|
* The width of the line marking the currently zoomed area in the
|
3891
4605
|
* navigator.
|
3892
|
-
*
|
4606
|
+
*
|
3893
4607
|
* @type {Number}
|
3894
|
-
* @see In
|
3895
|
-
* style/style-by-css), the outline stroke width is set with the `.
|
4608
|
+
* @see In styled mode, the outline stroke width is set with the `.
|
3896
4609
|
* highcharts-navigator-outline` class.
|
3897
4610
|
* @sample {highstock} stock/navigator/outline/ 2px blue outline
|
3898
4611
|
* @default 2
|
@@ -3905,299 +4618,258 @@
|
|
3905
4618
|
* Options for the navigator series. Available options are the same
|
3906
4619
|
* as any series, documented at [plotOptions](#plotOptions.series)
|
3907
4620
|
* and [series](#series).
|
3908
|
-
*
|
4621
|
+
*
|
3909
4622
|
* Unless data is explicitly defined on navigator.series, the data
|
3910
4623
|
* is borrowed from the first series in the chart.
|
3911
|
-
*
|
4624
|
+
*
|
3912
4625
|
* Default series options for the navigator series are:
|
3913
|
-
*
|
4626
|
+
*
|
3914
4627
|
* <pre>series: {
|
3915
|
-
*
|
3916
|
-
*
|
3917
|
-
*
|
3918
|
-
*
|
3919
|
-
*
|
3920
|
-
*
|
3921
|
-
*
|
3922
|
-
*
|
3923
|
-
*
|
3924
|
-
* }
|
4628
|
+
* type: 'areaspline',
|
4629
|
+
* fillOpacity: 0.05,
|
4630
|
+
* dataGrouping: {
|
4631
|
+
* smoothed: true
|
4632
|
+
* },
|
4633
|
+
* lineWidth: 1,
|
4634
|
+
* marker: {
|
4635
|
+
* enabled: false
|
4636
|
+
* }
|
3925
4637
|
* }</pre>
|
3926
|
-
*
|
4638
|
+
*
|
3927
4639
|
* @type {Object}
|
3928
|
-
* @see In
|
3929
|
-
* style/style-by-css), the navigator series is styled with the `.
|
4640
|
+
* @see In styled mode, the navigator series is styled with the `.
|
3930
4641
|
* highcharts-navigator-series` class.
|
3931
|
-
* @sample {highstock} stock/navigator/series-data/
|
3932
|
-
*
|
4642
|
+
* @sample {highstock} stock/navigator/series-data/
|
4643
|
+
* Using a separate data set for the navigator
|
4644
|
+
* @sample {highstock} stock/navigator/series/
|
4645
|
+
* A green navigator series
|
3933
4646
|
* @product highstock
|
3934
4647
|
*/
|
3935
4648
|
series: {
|
3936
4649
|
|
3937
4650
|
/**
|
4651
|
+
* The type of the navigator series. Defaults to `areaspline` if
|
4652
|
+
* defined, otherwise `line`.
|
4653
|
+
*
|
4654
|
+
* @type {String}
|
3938
4655
|
*/
|
3939
4656
|
type: defaultSeriesType,
|
3940
4657
|
|
3941
4658
|
|
3942
|
-
/**
|
3943
|
-
*/
|
3944
|
-
color: '#335cad',
|
3945
4659
|
|
3946
4660
|
/**
|
4661
|
+
* The fill opacity of the navigator series.
|
3947
4662
|
*/
|
3948
4663
|
fillOpacity: 0.05,
|
3949
4664
|
|
3950
4665
|
/**
|
4666
|
+
* The pixel line width of the navigator series.
|
3951
4667
|
*/
|
3952
4668
|
lineWidth: 1,
|
3953
4669
|
|
3954
4670
|
|
3955
4671
|
/**
|
4672
|
+
* @ignore
|
3956
4673
|
*/
|
3957
4674
|
compare: null,
|
3958
4675
|
|
3959
4676
|
/**
|
4677
|
+
* Data grouping options for the navigator series.
|
4678
|
+
*
|
4679
|
+
* @extends {plotOptions.series.dataGrouping}
|
3960
4680
|
*/
|
3961
4681
|
dataGrouping: {
|
3962
|
-
|
3963
|
-
/**
|
3964
|
-
*/
|
3965
4682
|
approximation: 'average',
|
3966
|
-
|
3967
|
-
/**
|
3968
|
-
*/
|
3969
4683
|
enabled: true,
|
3970
|
-
|
3971
|
-
/**
|
3972
|
-
*/
|
3973
4684
|
groupPixelWidth: 2,
|
3974
|
-
|
3975
|
-
/**
|
3976
|
-
*/
|
3977
4685
|
smoothed: true,
|
3978
|
-
|
3979
|
-
/**
|
3980
|
-
*/
|
3981
4686
|
units: units
|
3982
4687
|
},
|
3983
4688
|
|
3984
4689
|
/**
|
4690
|
+
* Data label options for the navigator series. Data labels are
|
4691
|
+
* disabled by default on the navigator series.
|
4692
|
+
*
|
4693
|
+
* @extends {plotOptions.series.dataLabels}
|
3985
4694
|
*/
|
3986
4695
|
dataLabels: {
|
3987
|
-
|
3988
|
-
/**
|
3989
|
-
*/
|
3990
4696
|
enabled: false,
|
3991
|
-
|
3992
|
-
/**
|
3993
|
-
*/
|
3994
4697
|
zIndex: 2 // #1839
|
3995
4698
|
},
|
3996
4699
|
|
3997
|
-
/**
|
3998
|
-
*/
|
3999
4700
|
id: 'highcharts-navigator-series',
|
4000
|
-
|
4001
|
-
/**
|
4002
|
-
*/
|
4003
4701
|
className: 'highcharts-navigator-series',
|
4004
4702
|
|
4005
4703
|
/**
|
4704
|
+
* Line color for the navigator series. Allows setting the color
|
4705
|
+
* while disallowing the default candlestick setting.
|
4706
|
+
*
|
4707
|
+
* @type {Color}
|
4006
4708
|
*/
|
4007
|
-
lineColor: null, //
|
4709
|
+
lineColor: null, // #4602
|
4008
4710
|
|
4009
|
-
/**
|
4010
|
-
*/
|
4011
4711
|
marker: {
|
4012
|
-
|
4013
|
-
/**
|
4014
|
-
*/
|
4015
4712
|
enabled: false
|
4016
4713
|
},
|
4017
4714
|
|
4018
|
-
/**
|
4019
|
-
*/
|
4020
4715
|
pointRange: 0,
|
4021
|
-
|
4022
|
-
/**
|
4023
|
-
*/
|
4024
|
-
shadow: false,
|
4025
|
-
|
4026
4716
|
/**
|
4717
|
+
* The threshold option. Setting it to 0 will make the default
|
4718
|
+
* navigator area series draw its area from the 0 value and up.
|
4719
|
+
* @type {Number}
|
4027
4720
|
*/
|
4028
4721
|
threshold: null
|
4029
4722
|
},
|
4030
|
-
//top: undefined,
|
4031
|
-
//opposite: undefined,
|
4032
4723
|
|
4033
4724
|
/**
|
4034
|
-
* Options for the navigator X axis.
|
4035
|
-
* as any X axis, documented at [xAxis](#xAxis). Default series options
|
4725
|
+
* Options for the navigator X axis. Default series options
|
4036
4726
|
* for the navigator xAxis are:
|
4037
|
-
*
|
4727
|
+
*
|
4038
4728
|
* <pre>xAxis: {
|
4039
|
-
*
|
4040
|
-
*
|
4041
|
-
*
|
4042
|
-
*
|
4043
|
-
*
|
4044
|
-
*
|
4045
|
-
*
|
4046
|
-
*
|
4047
|
-
*
|
4048
|
-
*
|
4049
|
-
*
|
4050
|
-
*
|
4729
|
+
* tickWidth: 0,
|
4730
|
+
* lineWidth: 0,
|
4731
|
+
* gridLineWidth: 1,
|
4732
|
+
* tickPixelInterval: 200,
|
4733
|
+
* labels: {
|
4734
|
+
* align: 'left',
|
4735
|
+
* style: {
|
4736
|
+
* color: '#888'
|
4737
|
+
* },
|
4738
|
+
* x: 3,
|
4739
|
+
* y: -4
|
4740
|
+
* }
|
4051
4741
|
* }</pre>
|
4052
|
-
*
|
4742
|
+
*
|
4053
4743
|
* @type {Object}
|
4744
|
+
* @extends {xAxis}
|
4745
|
+
* @excluding linkedTo,maxZoom,minRange,opposite,range,scrollbar,
|
4746
|
+
* showEmpty,maxRange
|
4054
4747
|
* @product highstock
|
4055
4748
|
*/
|
4056
4749
|
xAxis: {
|
4057
|
-
|
4058
4750
|
/**
|
4751
|
+
* Additional range on the right side of the xAxis. Works similar to
|
4752
|
+
* xAxis.maxPadding, but value is set in milliseconds.
|
4753
|
+
* Can be set for both, main xAxis and navigator's xAxis.
|
4754
|
+
*
|
4755
|
+
* @type {Number}
|
4756
|
+
* @default 0
|
4757
|
+
* @since 6.0.0
|
4758
|
+
* @product highstock
|
4759
|
+
* @apioption xAxis.overscroll
|
4059
4760
|
*/
|
4060
|
-
|
4761
|
+
overscroll: 0,
|
4061
4762
|
|
4062
|
-
|
4063
|
-
*/
|
4763
|
+
className: 'highcharts-navigator-xaxis',
|
4064
4764
|
tickLength: 0,
|
4065
4765
|
|
4066
4766
|
|
4067
|
-
/**
|
4068
|
-
*/
|
4069
4767
|
lineWidth: 0,
|
4070
|
-
|
4071
|
-
/**
|
4072
|
-
*/
|
4073
4768
|
gridLineColor: '#e6e6e6',
|
4074
|
-
|
4075
|
-
/**
|
4076
|
-
*/
|
4077
4769
|
gridLineWidth: 1,
|
4078
4770
|
|
4079
4771
|
|
4080
|
-
/**
|
4081
|
-
*/
|
4082
4772
|
tickPixelInterval: 200,
|
4083
4773
|
|
4084
|
-
/**
|
4085
|
-
*/
|
4086
4774
|
labels: {
|
4087
|
-
|
4088
|
-
/**
|
4089
|
-
*/
|
4090
4775
|
align: 'left',
|
4091
4776
|
|
4092
4777
|
|
4093
|
-
/**
|
4094
|
-
*/
|
4095
4778
|
style: {
|
4096
|
-
|
4097
|
-
/**
|
4098
|
-
*/
|
4099
4779
|
color: '#999999'
|
4100
4780
|
},
|
4101
4781
|
|
4102
4782
|
|
4103
|
-
/**
|
4104
|
-
*/
|
4105
4783
|
x: 3,
|
4106
|
-
|
4107
|
-
/**
|
4108
|
-
*/
|
4109
4784
|
y: -4
|
4110
4785
|
},
|
4111
4786
|
|
4112
|
-
/**
|
4113
|
-
*/
|
4114
4787
|
crosshair: false
|
4115
4788
|
},
|
4116
4789
|
|
4117
4790
|
/**
|
4118
|
-
* Options for the navigator Y axis.
|
4119
|
-
* as any y axis, documented at [yAxis](#yAxis). Default series options
|
4791
|
+
* Options for the navigator Y axis. Default series options
|
4120
4792
|
* for the navigator yAxis are:
|
4121
|
-
*
|
4793
|
+
*
|
4122
4794
|
* <pre>yAxis: {
|
4123
|
-
*
|
4124
|
-
*
|
4125
|
-
*
|
4126
|
-
*
|
4127
|
-
*
|
4128
|
-
*
|
4129
|
-
*
|
4130
|
-
*
|
4131
|
-
*
|
4132
|
-
*
|
4133
|
-
*
|
4134
|
-
*
|
4795
|
+
* gridLineWidth: 0,
|
4796
|
+
* startOnTick: false,
|
4797
|
+
* endOnTick: false,
|
4798
|
+
* minPadding: 0.1,
|
4799
|
+
* maxPadding: 0.1,
|
4800
|
+
* labels: {
|
4801
|
+
* enabled: false
|
4802
|
+
* },
|
4803
|
+
* title: {
|
4804
|
+
* text: null
|
4805
|
+
* },
|
4806
|
+
* tickWidth: 0
|
4135
4807
|
* }</pre>
|
4136
|
-
*
|
4808
|
+
*
|
4137
4809
|
* @type {Object}
|
4810
|
+
* @extends {yAxis}
|
4811
|
+
* @excluding height,linkedTo,maxZoom,minRange,ordinal,range,showEmpty,
|
4812
|
+
* scrollbar,top,units,maxRange
|
4138
4813
|
* @product highstock
|
4139
4814
|
*/
|
4140
4815
|
yAxis: {
|
4141
4816
|
|
4142
|
-
/**
|
4143
|
-
*/
|
4144
4817
|
className: 'highcharts-navigator-yaxis',
|
4145
4818
|
|
4146
4819
|
|
4147
|
-
/**
|
4148
|
-
*/
|
4149
4820
|
gridLineWidth: 0,
|
4150
4821
|
|
4151
4822
|
|
4152
|
-
/**
|
4153
|
-
*/
|
4154
4823
|
startOnTick: false,
|
4155
|
-
|
4156
|
-
/**
|
4157
|
-
*/
|
4158
4824
|
endOnTick: false,
|
4159
|
-
|
4160
|
-
/**
|
4161
|
-
*/
|
4162
4825
|
minPadding: 0.1,
|
4163
|
-
|
4164
|
-
/**
|
4165
|
-
*/
|
4166
4826
|
maxPadding: 0.1,
|
4167
|
-
|
4168
|
-
/**
|
4169
|
-
*/
|
4170
4827
|
labels: {
|
4171
|
-
|
4172
|
-
/**
|
4173
|
-
*/
|
4174
4828
|
enabled: false
|
4175
4829
|
},
|
4176
|
-
|
4177
|
-
/**
|
4178
|
-
*/
|
4179
4830
|
crosshair: false,
|
4180
|
-
|
4181
|
-
/**
|
4182
|
-
*/
|
4183
4831
|
title: {
|
4184
|
-
|
4185
|
-
/**
|
4186
|
-
*/
|
4187
4832
|
text: null
|
4188
4833
|
},
|
4189
|
-
|
4190
|
-
/**
|
4191
|
-
*/
|
4192
4834
|
tickLength: 0,
|
4193
|
-
|
4194
|
-
/**
|
4195
|
-
*/
|
4196
4835
|
tickWidth: 0
|
4197
4836
|
}
|
4198
4837
|
}
|
4199
4838
|
});
|
4200
4839
|
|
4840
|
+
/**
|
4841
|
+
* Draw one of the handles on the side of the zoomed range in the navigator
|
4842
|
+
* @param {Boolean} inverted flag for chart.inverted
|
4843
|
+
* @returns {Array} Path to be used in a handle
|
4844
|
+
*/
|
4845
|
+
H.Renderer.prototype.symbols['navigator-handle'] = function(
|
4846
|
+
x,
|
4847
|
+
y,
|
4848
|
+
w,
|
4849
|
+
h,
|
4850
|
+
options
|
4851
|
+
) {
|
4852
|
+
var halfWidth = options.width / 2,
|
4853
|
+
markerPosition = Math.round(halfWidth / 3) + 0.5,
|
4854
|
+
height = options.height;
|
4855
|
+
|
4856
|
+
return [
|
4857
|
+
'M', -halfWidth - 1, 0.5,
|
4858
|
+
'L',
|
4859
|
+
halfWidth, 0.5,
|
4860
|
+
'L',
|
4861
|
+
halfWidth, height + 0.5,
|
4862
|
+
'L', -halfWidth - 1, height + 0.5,
|
4863
|
+
'L', -halfWidth - 1, 0.5,
|
4864
|
+
'M', -markerPosition, 4,
|
4865
|
+
'L', -markerPosition, height - 3,
|
4866
|
+
'M',
|
4867
|
+
markerPosition - 1, 4,
|
4868
|
+
'L',
|
4869
|
+
markerPosition - 1, height - 3
|
4870
|
+
];
|
4871
|
+
};
|
4872
|
+
|
4201
4873
|
/**
|
4202
4874
|
* The Navigator class
|
4203
4875
|
* @param {Object} chart - Chart object
|
@@ -4216,40 +4888,23 @@
|
|
4216
4888
|
* @param {String} verb use 'animate' or 'attr'
|
4217
4889
|
*/
|
4218
4890
|
drawHandle: function(x, index, inverted, verb) {
|
4219
|
-
var navigator = this
|
4891
|
+
var navigator = this,
|
4892
|
+
height = navigator.navigatorOptions.handles.height;
|
4220
4893
|
|
4221
4894
|
// Place it
|
4222
4895
|
navigator.handles[index][verb](inverted ? {
|
4223
|
-
translateX: Math.round(navigator.left + navigator.height / 2
|
4224
|
-
translateY: Math.round(
|
4896
|
+
translateX: Math.round(navigator.left + navigator.height / 2),
|
4897
|
+
translateY: Math.round(
|
4898
|
+
navigator.top + parseInt(x, 10) + 0.5 - height
|
4899
|
+
)
|
4225
4900
|
} : {
|
4226
4901
|
translateX: Math.round(navigator.left + parseInt(x, 10)),
|
4227
|
-
translateY: Math.round(
|
4902
|
+
translateY: Math.round(
|
4903
|
+
navigator.top + navigator.height / 2 - height / 2 - 1
|
4904
|
+
)
|
4228
4905
|
});
|
4229
4906
|
},
|
4230
4907
|
|
4231
|
-
/**
|
4232
|
-
* Draw one of the handles on the side of the zoomed range in the navigator
|
4233
|
-
* @param {Boolean} inverted flag for chart.inverted
|
4234
|
-
* @returns {Array} Path to be used in a handle
|
4235
|
-
*/
|
4236
|
-
getHandlePath: function(inverted) {
|
4237
|
-
return swapXY([
|
4238
|
-
'M', -4.5, 0.5,
|
4239
|
-
'L',
|
4240
|
-
3.5, 0.5,
|
4241
|
-
'L',
|
4242
|
-
3.5, 15.5,
|
4243
|
-
'L', -4.5, 15.5,
|
4244
|
-
'L', -4.5, 0.5,
|
4245
|
-
'M', -1.5, 4,
|
4246
|
-
'L', -1.5, 12,
|
4247
|
-
'M',
|
4248
|
-
0.5, 4,
|
4249
|
-
'L',
|
4250
|
-
0.5, 12
|
4251
|
-
], inverted);
|
4252
|
-
},
|
4253
4908
|
/**
|
4254
4909
|
* Render outline around the zoomed range
|
4255
4910
|
* @param {Number} zoomedMin in pixels position where zoomed range starts
|
@@ -4358,7 +5013,7 @@
|
|
4358
5013
|
x,
|
4359
5014
|
y;
|
4360
5015
|
|
4361
|
-
// Determine rectangle position & size
|
5016
|
+
// Determine rectangle position & size
|
4362
5017
|
// According to (non)inverted position:
|
4363
5018
|
if (inverted) {
|
4364
5019
|
x = [left, left, left];
|
@@ -4446,29 +5101,38 @@
|
|
4446
5101
|
.add(navigatorGroup);
|
4447
5102
|
|
4448
5103
|
// Create the handlers:
|
4449
|
-
|
4450
|
-
|
4451
|
-
.
|
5104
|
+
if (navigatorOptions.handles.enabled) {
|
5105
|
+
each([0, 1], function(index) {
|
5106
|
+
navigatorOptions.handles.inverted = chart.inverted;
|
5107
|
+
navigator.handles[index] = renderer.symbol(
|
5108
|
+
navigatorOptions.handles.symbols[index], -navigatorOptions.handles.width / 2 - 1,
|
5109
|
+
0,
|
5110
|
+
navigatorOptions.handles.width,
|
5111
|
+
navigatorOptions.handles.height,
|
5112
|
+
navigatorOptions.handles
|
5113
|
+
);
|
4452
5114
|
// zIndex = 6 for right handle, 7 for left.
|
4453
5115
|
// Can't be 10, because of the tooltip in inverted chart #2908
|
4454
|
-
.attr({
|
4455
|
-
|
4456
|
-
|
4457
|
-
|
4458
|
-
|
4459
|
-
|
5116
|
+
navigator.handles[index].attr({
|
5117
|
+
zIndex: 7 - index
|
5118
|
+
})
|
5119
|
+
.addClass(
|
5120
|
+
'highcharts-navigator-handle ' +
|
5121
|
+
'highcharts-navigator-handle-' + ['left', 'right'][index]
|
5122
|
+
).add(navigatorGroup);
|
4460
5123
|
|
4461
5124
|
|
4462
|
-
|
4463
|
-
|
4464
|
-
|
4465
|
-
|
4466
|
-
|
4467
|
-
|
4468
|
-
|
4469
|
-
|
5125
|
+
var handlesOptions = navigatorOptions.handles;
|
5126
|
+
navigator.handles[index]
|
5127
|
+
.attr({
|
5128
|
+
fill: handlesOptions.backgroundColor,
|
5129
|
+
stroke: handlesOptions.borderColor,
|
5130
|
+
'stroke-width': handlesOptions.lineWidth
|
5131
|
+
})
|
5132
|
+
.css(mouseCursor);
|
4470
5133
|
|
4471
|
-
|
5134
|
+
});
|
5135
|
+
}
|
4472
5136
|
},
|
4473
5137
|
|
4474
5138
|
/**
|
@@ -4514,7 +5178,9 @@
|
|
4514
5178
|
verb,
|
4515
5179
|
newMin,
|
4516
5180
|
newMax,
|
4517
|
-
|
5181
|
+
currentRange,
|
5182
|
+
minRange = chart.xAxis[0].minRange,
|
5183
|
+
maxRange = chart.xAxis[0].options.maxRange;
|
4518
5184
|
|
4519
5185
|
// Don't redraw while moving the handles (#4703).
|
4520
5186
|
if (this.hasDragged && !defined(pxMin)) {
|
@@ -4541,7 +5207,8 @@
|
|
4541
5207
|
|
4542
5208
|
navigator.size = zoomedMax = navigatorSize = pick(
|
4543
5209
|
xAxis.len,
|
4544
|
-
(inverted ? chart.plotHeight : chart.plotWidth) -
|
5210
|
+
(inverted ? chart.plotHeight : chart.plotWidth) -
|
5211
|
+
2 * scrollbarHeight
|
4545
5212
|
);
|
4546
5213
|
|
4547
5214
|
if (inverted) {
|
@@ -4554,7 +5221,8 @@
|
|
4554
5221
|
pxMin = pick(pxMin, xAxis.toPixels(min, true));
|
4555
5222
|
pxMax = pick(pxMax, xAxis.toPixels(max, true));
|
4556
5223
|
|
4557
|
-
|
5224
|
+
// Verify (#1851, #2238)
|
5225
|
+
if (!isNumber(pxMin) || Math.abs(pxMin) === Infinity) {
|
4558
5226
|
pxMin = 0;
|
4559
5227
|
pxMax = navigatorWidth;
|
4560
5228
|
}
|
@@ -4562,13 +5230,30 @@
|
|
4562
5230
|
// Are we below the minRange? (#2618, #6191)
|
4563
5231
|
newMin = xAxis.toValue(pxMin, true);
|
4564
5232
|
newMax = xAxis.toValue(pxMax, true);
|
4565
|
-
|
5233
|
+
currentRange = Math.abs(H.correctFloat(newMax - newMin));
|
5234
|
+
if (currentRange < minRange) {
|
4566
5235
|
if (this.grabbedLeft) {
|
4567
5236
|
pxMin = xAxis.toPixels(newMax - minRange, true);
|
4568
5237
|
} else if (this.grabbedRight) {
|
4569
5238
|
pxMax = xAxis.toPixels(newMin + minRange, true);
|
4570
|
-
}
|
4571
|
-
|
5239
|
+
}
|
5240
|
+
} else if (defined(maxRange) && currentRange > maxRange) {
|
5241
|
+
/**
|
5242
|
+
* Maximum range which can be set using the navigator's handles.
|
5243
|
+
* Opposite of [xAxis.minRange](#xAxis.minRange).
|
5244
|
+
*
|
5245
|
+
* @type {Number}
|
5246
|
+
* @default undefined
|
5247
|
+
* @product highstock
|
5248
|
+
* @sample {highstock} stock/navigator/maxrange/
|
5249
|
+
* Defined max and min range
|
5250
|
+
* @since 6.0.0
|
5251
|
+
* @apioption xAxis.maxRange
|
5252
|
+
*/
|
5253
|
+
if (this.grabbedLeft) {
|
5254
|
+
pxMin = xAxis.toPixels(newMax - maxRange, true);
|
5255
|
+
} else if (this.grabbedRight) {
|
5256
|
+
pxMax = xAxis.toPixels(newMin + maxRange, true);
|
4572
5257
|
}
|
4573
5258
|
}
|
4574
5259
|
|
@@ -4598,8 +5283,11 @@
|
|
4598
5283
|
|
4599
5284
|
navigator.drawMasks(zoomedMin, zoomedMax, inverted, verb);
|
4600
5285
|
navigator.drawOutline(zoomedMin, zoomedMax, inverted, verb);
|
4601
|
-
|
4602
|
-
navigator.
|
5286
|
+
|
5287
|
+
if (navigator.navigatorOptions.handles.enabled) {
|
5288
|
+
navigator.drawHandle(zoomedMin, 0, inverted, verb);
|
5289
|
+
navigator.drawHandle(zoomedMax, 1, inverted, verb);
|
5290
|
+
}
|
4603
5291
|
}
|
4604
5292
|
|
4605
5293
|
if (navigator.scrollbar) {
|
@@ -4627,7 +5315,8 @@
|
|
4627
5315
|
);
|
4628
5316
|
// Keep scale 0-1
|
4629
5317
|
navigator.scrollbar.setRange(
|
4630
|
-
// Use real value, not rounded because range can be very small
|
5318
|
+
// Use real value, not rounded because range can be very small
|
5319
|
+
// (#1716)
|
4631
5320
|
navigator.zoomedMin / navigatorSize,
|
4632
5321
|
navigator.zoomedMax / navigatorSize
|
4633
5322
|
);
|
@@ -4660,7 +5349,8 @@
|
|
4660
5349
|
// Add shades and handles mousedown events
|
4661
5350
|
eventsToUnbind = navigator.getPartsEvents('mousedown');
|
4662
5351
|
// Add mouse move and mouseup events. These are bind to doc/container,
|
4663
|
-
// because Navigator.grabbedSomething flags are stored in mousedown
|
5352
|
+
// because Navigator.grabbedSomething flags are stored in mousedown
|
5353
|
+
// events
|
4664
5354
|
eventsToUnbind.push(
|
4665
5355
|
addEvent(container, 'mousemove', mouseMoveHandler),
|
4666
5356
|
addEvent(container.ownerDocument, 'mouseup', mouseUpHandler)
|
@@ -4680,9 +5370,13 @@
|
|
4680
5370
|
// Data events
|
4681
5371
|
if (navigator.series && navigator.series[0]) {
|
4682
5372
|
eventsToUnbind.push(
|
4683
|
-
addEvent(
|
4684
|
-
|
4685
|
-
|
5373
|
+
addEvent(
|
5374
|
+
navigator.series[0].xAxis,
|
5375
|
+
'foundExtremes',
|
5376
|
+
function() {
|
5377
|
+
chart.navigator.modifyNavigatorAxisExtremes();
|
5378
|
+
}
|
5379
|
+
)
|
4686
5380
|
);
|
4687
5381
|
}
|
4688
5382
|
},
|
@@ -4713,7 +5407,7 @@
|
|
4713
5407
|
|
4714
5408
|
/**
|
4715
5409
|
* Mousedown on a shaded mask, either:
|
4716
|
-
* - will be stored for future drag&drop
|
5410
|
+
* - will be stored for future drag&drop
|
4717
5411
|
* - will directly shift to a new range
|
4718
5412
|
*
|
4719
5413
|
* @param {Object} e Mouse event
|
@@ -4818,9 +5512,10 @@
|
|
4818
5512
|
chartX;
|
4819
5513
|
|
4820
5514
|
|
4821
|
-
// In iOS, a mousemove event with e.pageX === 0 is fired when holding
|
4822
|
-
// down in the center of the scrollbar. This should be
|
4823
|
-
|
5515
|
+
// In iOS, a mousemove event with e.pageX === 0 is fired when holding
|
5516
|
+
// the finger down in the center of the scrollbar. This should be
|
5517
|
+
// ignored.
|
5518
|
+
if (!e.touches || e.touches[0].pageX !== 0) { // #4696
|
4824
5519
|
|
4825
5520
|
e = chart.pointer.normalize(e);
|
4826
5521
|
chartX = e.chartX;
|
@@ -4854,7 +5549,8 @@
|
|
4854
5549
|
navigator.hasDragged = true;
|
4855
5550
|
if (chartX < dragOffset) { // outside left
|
4856
5551
|
chartX = dragOffset;
|
4857
|
-
|
5552
|
+
// outside right
|
5553
|
+
} else if (chartX > navigatorSize + dragOffset - range) {
|
4858
5554
|
chartX = navigatorSize + dragOffset - range;
|
4859
5555
|
}
|
4860
5556
|
|
@@ -4865,8 +5561,12 @@
|
|
4865
5561
|
chartX - dragOffset + range
|
4866
5562
|
);
|
4867
5563
|
}
|
4868
|
-
if (
|
4869
|
-
|
5564
|
+
if (
|
5565
|
+
navigator.hasDragged &&
|
5566
|
+
navigator.scrollbar &&
|
5567
|
+
navigator.scrollbar.options.liveRedraw
|
5568
|
+
) {
|
5569
|
+
e.DOMType = e.type; // DOMType is for IE8
|
4870
5570
|
setTimeout(function() {
|
4871
5571
|
navigator.onMouseUp(e);
|
4872
5572
|
}, 0);
|
@@ -4917,8 +5617,9 @@
|
|
4917
5617
|
Math.min(ext.min, ext.max),
|
4918
5618
|
Math.max(ext.min, ext.max),
|
4919
5619
|
true,
|
4920
|
-
|
4921
|
-
|
5620
|
+
// Run animation when clicking buttons, scrollbar track etc,
|
5621
|
+
// but not when dragging handles or scrollbar
|
5622
|
+
navigator.hasDragged ? false : null, {
|
4922
5623
|
trigger: 'navigator',
|
4923
5624
|
triggerOp: 'navigator-drag',
|
4924
5625
|
DOMEvent: DOMEvent // #1838
|
@@ -4962,7 +5663,11 @@
|
|
4962
5663
|
|
4963
5664
|
// We only listen for extremes-events on the first baseSeries
|
4964
5665
|
if (baseSeries[0].xAxis) {
|
4965
|
-
removeEvent(
|
5666
|
+
removeEvent(
|
5667
|
+
baseSeries[0].xAxis,
|
5668
|
+
'foundExtremes',
|
5669
|
+
this.modifyBaseAxisExtremes
|
5670
|
+
);
|
4966
5671
|
}
|
4967
5672
|
}
|
4968
5673
|
},
|
@@ -4993,21 +5698,30 @@
|
|
4993
5698
|
this.scrollbarOptions = scrollbarOptions;
|
4994
5699
|
this.outlineHeight = height + scrollbarHeight;
|
4995
5700
|
|
4996
|
-
this.opposite = pick(
|
5701
|
+
this.opposite = pick(
|
5702
|
+
navigatorOptions.opposite, !navigatorEnabled && chart.inverted
|
5703
|
+
); // #6262
|
4997
5704
|
|
4998
5705
|
var navigator = this,
|
4999
5706
|
baseSeries = navigator.baseSeries,
|
5000
5707
|
xAxisIndex = chart.xAxis.length,
|
5001
5708
|
yAxisIndex = chart.yAxis.length,
|
5002
|
-
baseXaxis = baseSeries && baseSeries[0] && baseSeries[0].xAxis ||
|
5709
|
+
baseXaxis = baseSeries && baseSeries[0] && baseSeries[0].xAxis ||
|
5710
|
+
chart.xAxis[0];
|
5003
5711
|
|
5004
5712
|
// Make room for the navigator, can be placed around the chart:
|
5005
5713
|
chart.extraMargin = {
|
5006
5714
|
type: navigator.opposite ? 'plotTop' : 'marginBottom',
|
5007
|
-
value: (
|
5715
|
+
value: (
|
5716
|
+
navigatorEnabled || !chart.inverted ?
|
5717
|
+
navigator.outlineHeight :
|
5718
|
+
0
|
5719
|
+
) + navigatorOptions.margin
|
5008
5720
|
};
|
5009
5721
|
if (chart.inverted) {
|
5010
|
-
chart.extraMargin.type = navigator.opposite ?
|
5722
|
+
chart.extraMargin.type = navigator.opposite ?
|
5723
|
+
'marginRight' :
|
5724
|
+
'plotLeft';
|
5011
5725
|
}
|
5012
5726
|
chart.isDirtyBox = true;
|
5013
5727
|
|
@@ -5080,7 +5794,11 @@
|
|
5080
5794
|
ext = axis.getExtremes(),
|
5081
5795
|
scrollTrackWidth = axis.len - 2 * scrollbarHeight,
|
5082
5796
|
min = numExt('min', axis.options.min, ext.dataMin),
|
5083
|
-
valueRange = numExt(
|
5797
|
+
valueRange = numExt(
|
5798
|
+
'max',
|
5799
|
+
axis.options.max,
|
5800
|
+
ext.dataMax
|
5801
|
+
) - min;
|
5084
5802
|
|
5085
5803
|
return reverse ?
|
5086
5804
|
// from pixel to value
|
@@ -5118,7 +5836,10 @@
|
|
5118
5836
|
navigator.hasDragged = navigator.scrollbar.hasDragged;
|
5119
5837
|
navigator.render(0, 0, from, to);
|
5120
5838
|
|
5121
|
-
if (
|
5839
|
+
if (
|
5840
|
+
chart.options.scrollbar.liveRedraw ||
|
5841
|
+
e.DOMType !== 'mousemove'
|
5842
|
+
) {
|
5122
5843
|
setTimeout(function() {
|
5123
5844
|
navigator.onMouseUp(e);
|
5124
5845
|
});
|
@@ -5133,8 +5854,8 @@
|
|
5133
5854
|
},
|
5134
5855
|
|
5135
5856
|
/**
|
5136
|
-
* Get the union data extremes of the chart - the outer data extremes of the
|
5137
|
-
* X axis and the navigator axis.
|
5857
|
+
* Get the union data extremes of the chart - the outer data extremes of the
|
5858
|
+
* base X axis and the navigator axis.
|
5138
5859
|
* @param {boolean} returnFalseOnNoBaseSeries - as the param says.
|
5139
5860
|
*/
|
5140
5861
|
getUnionExtremes: function(returnFalseOnNoBaseSeries) {
|
@@ -5172,20 +5893,30 @@
|
|
5172
5893
|
},
|
5173
5894
|
|
5174
5895
|
/**
|
5175
|
-
* Set the base series and update the navigator series from this. With a bit
|
5176
|
-
* of modification we should be able to make this an API method to be called
|
5896
|
+
* Set the base series and update the navigator series from this. With a bit
|
5897
|
+
* of modification we should be able to make this an API method to be called
|
5177
5898
|
* from the outside
|
5178
|
-
* @param
|
5899
|
+
* @param {Object} baseSeriesOptions
|
5900
|
+
* Additional series options for a navigator
|
5901
|
+
* @param {Boolean} [redraw]
|
5902
|
+
* Whether to redraw after update.
|
5179
5903
|
*/
|
5180
|
-
setBaseSeries: function(baseSeriesOptions) {
|
5904
|
+
setBaseSeries: function(baseSeriesOptions, redraw) {
|
5181
5905
|
var chart = this.chart,
|
5182
5906
|
baseSeries = this.baseSeries = [];
|
5183
5907
|
|
5184
|
-
baseSeriesOptions =
|
5908
|
+
baseSeriesOptions = (
|
5909
|
+
baseSeriesOptions ||
|
5910
|
+
chart.options && chart.options.navigator.baseSeries ||
|
5911
|
+
0
|
5912
|
+
);
|
5185
5913
|
|
5186
|
-
// Iterate through series and add the ones that should be shown in
|
5914
|
+
// Iterate through series and add the ones that should be shown in
|
5915
|
+
// navigator.
|
5187
5916
|
each(chart.series || [], function(series, i) {
|
5188
|
-
if (
|
5917
|
+
if (
|
5918
|
+
// Don't include existing nav series
|
5919
|
+
!series.options.isInternal &&
|
5189
5920
|
(
|
5190
5921
|
series.options.showInNavigator ||
|
5191
5922
|
(
|
@@ -5201,7 +5932,7 @@
|
|
5201
5932
|
|
5202
5933
|
// When run after render, this.xAxis already exists
|
5203
5934
|
if (this.xAxis && !this.xAxis.fake) {
|
5204
|
-
this.updateNavigatorSeries();
|
5935
|
+
this.updateNavigatorSeries(redraw);
|
5205
5936
|
}
|
5206
5937
|
},
|
5207
5938
|
|
@@ -5209,7 +5940,7 @@
|
|
5209
5940
|
* Update series in the navigator from baseSeries, adding new if does not
|
5210
5941
|
* exist.
|
5211
5942
|
*/
|
5212
|
-
updateNavigatorSeries: function() {
|
5943
|
+
updateNavigatorSeries: function(redraw) {
|
5213
5944
|
var navigator = this,
|
5214
5945
|
chart = navigator.chart,
|
5215
5946
|
baseSeries = navigator.baseSeries,
|
@@ -5236,8 +5967,8 @@
|
|
5236
5967
|
function(navSeries) {
|
5237
5968
|
var base = navSeries.baseSeries;
|
5238
5969
|
if (H.inArray(base, baseSeries) < 0) { // Not in array
|
5239
|
-
// If there is still a base series connected to this
|
5240
|
-
// remove event handler and reference.
|
5970
|
+
// If there is still a base series connected to this
|
5971
|
+
// series, remove event handler and reference.
|
5241
5972
|
if (base) {
|
5242
5973
|
removeEvent(
|
5243
5974
|
base,
|
@@ -5254,12 +5985,19 @@
|
|
5254
5985
|
}
|
5255
5986
|
);
|
5256
5987
|
|
5257
|
-
// Go through each base series and merge the options to create new
|
5988
|
+
// Go through each base series and merge the options to create new
|
5989
|
+
// series
|
5258
5990
|
if (baseSeries && baseSeries.length) {
|
5259
|
-
each(baseSeries, function(base
|
5991
|
+
each(baseSeries, function eachBaseSeries(base) {
|
5260
5992
|
var linkedNavSeries = base.navigatorSeries,
|
5261
|
-
userNavOptions =
|
5262
|
-
|
5993
|
+
userNavOptions = extend(
|
5994
|
+
// Grab color from base as default
|
5995
|
+
{
|
5996
|
+
color: base.color
|
5997
|
+
}, !isArray(chartNavigatorSeriesOptions) ?
|
5998
|
+
chartNavigatorSeriesOptions :
|
5999
|
+
defaultOptions.navigator.series
|
6000
|
+
);
|
5263
6001
|
|
5264
6002
|
// Don't update if the series exists in nav and we have disabled
|
5265
6003
|
// adaptToUpdatedData.
|
@@ -5270,7 +6008,7 @@
|
|
5270
6008
|
return;
|
5271
6009
|
}
|
5272
6010
|
|
5273
|
-
navSeriesMixin.name = 'Navigator ' +
|
6011
|
+
navSeriesMixin.name = 'Navigator ' + baseSeries.length;
|
5274
6012
|
|
5275
6013
|
baseOptions = base.options || {};
|
5276
6014
|
baseNavigatorOptions = baseOptions.navigatorOptions || {};
|
@@ -5281,24 +6019,31 @@
|
|
5281
6019
|
baseNavigatorOptions
|
5282
6020
|
);
|
5283
6021
|
|
5284
|
-
// Merge data separately. Do a slice to avoid mutating the
|
5285
|
-
|
5286
|
-
|
5287
|
-
|
6022
|
+
// Merge data separately. Do a slice to avoid mutating the
|
6023
|
+
// navigator options from base series (#4923).
|
6024
|
+
var navigatorSeriesData =
|
6025
|
+
baseNavigatorOptions.data || userNavOptions.data;
|
6026
|
+
navigator.hasNavigatorData =
|
6027
|
+
navigator.hasNavigatorData || !!navigatorSeriesData;
|
6028
|
+
mergedNavSeriesOptions.data =
|
6029
|
+
navigatorSeriesData ||
|
6030
|
+
baseOptions.data && baseOptions.data.slice(0);
|
5288
6031
|
|
5289
6032
|
// Update or add the series
|
5290
|
-
if (linkedNavSeries) {
|
5291
|
-
linkedNavSeries.update(mergedNavSeriesOptions);
|
6033
|
+
if (linkedNavSeries && linkedNavSeries.options) {
|
6034
|
+
linkedNavSeries.update(mergedNavSeriesOptions, redraw);
|
5292
6035
|
} else {
|
5293
|
-
base.navigatorSeries = chart.initSeries(
|
6036
|
+
base.navigatorSeries = chart.initSeries(
|
6037
|
+
mergedNavSeriesOptions
|
6038
|
+
);
|
5294
6039
|
base.navigatorSeries.baseSeries = base; // Store ref
|
5295
6040
|
navigatorSeries.push(base.navigatorSeries);
|
5296
6041
|
}
|
5297
6042
|
});
|
5298
6043
|
}
|
5299
6044
|
|
5300
|
-
// If user has defined data (and no base series) or explicitly defined
|
5301
|
-
// navigator.series as an array, we create these series on top of any
|
6045
|
+
// If user has defined data (and no base series) or explicitly defined
|
6046
|
+
// navigator.series as an array, we create these series on top of any
|
5302
6047
|
// base series.
|
5303
6048
|
if (
|
5304
6049
|
chartNavigatorSeriesOptions.data &&
|
@@ -5309,10 +6054,13 @@
|
|
5309
6054
|
// Allow navigator.series to be an array
|
5310
6055
|
chartNavigatorSeriesOptions = H.splat(chartNavigatorSeriesOptions);
|
5311
6056
|
each(chartNavigatorSeriesOptions, function(userSeriesOptions, i) {
|
5312
|
-
|
6057
|
+
navSeriesMixin.name =
|
6058
|
+
'Navigator ' + (navigatorSeries.length + 1);
|
6059
|
+
mergedNavSeriesOptions = merge(
|
6060
|
+
defaultOptions.navigator.series, {
|
5313
6061
|
// Since we don't have a base series to pull color from,
|
5314
6062
|
// try to fake it by using color from series with same
|
5315
|
-
// index. Otherwise pull from the colors array. We need
|
6063
|
+
// index. Otherwise pull from the colors array. We need
|
5316
6064
|
// an explicit color as otherwise updates will increment
|
5317
6065
|
// color counter and we'll get a new color for each
|
5318
6066
|
// update of the nav series.
|
@@ -5322,13 +6070,15 @@
|
|
5322
6070
|
chart.options.colors[i] ||
|
5323
6071
|
chart.options.colors[0]
|
5324
6072
|
},
|
5325
|
-
|
5326
|
-
|
6073
|
+
navSeriesMixin,
|
6074
|
+
userSeriesOptions
|
5327
6075
|
);
|
5328
6076
|
mergedNavSeriesOptions.data = userSeriesOptions.data;
|
5329
6077
|
if (mergedNavSeriesOptions.data) {
|
5330
6078
|
navigator.hasNavigatorData = true;
|
5331
|
-
navigatorSeries.push(
|
6079
|
+
navigatorSeries.push(
|
6080
|
+
chart.initSeries(mergedNavSeriesOptions)
|
6081
|
+
);
|
5332
6082
|
}
|
5333
6083
|
});
|
5334
6084
|
}
|
@@ -5346,10 +6096,14 @@
|
|
5346
6096
|
|
5347
6097
|
// Bind modified extremes event to first base's xAxis only.
|
5348
6098
|
// In event of > 1 base-xAxes, the navigator will ignore those.
|
5349
|
-
// Adding this multiple times to the same axis is no problem, as
|
6099
|
+
// Adding this multiple times to the same axis is no problem, as
|
5350
6100
|
// duplicates should be discarded by the browser.
|
5351
6101
|
if (baseSeries[0] && baseSeries[0].xAxis) {
|
5352
|
-
addEvent(
|
6102
|
+
addEvent(
|
6103
|
+
baseSeries[0].xAxis,
|
6104
|
+
'foundExtremes',
|
6105
|
+
this.modifyBaseAxisExtremes
|
6106
|
+
);
|
5353
6107
|
}
|
5354
6108
|
|
5355
6109
|
each(baseSeries, function(base) {
|
@@ -5365,7 +6119,7 @@
|
|
5365
6119
|
}
|
5366
6120
|
});
|
5367
6121
|
|
5368
|
-
// Respond to updated data in the base series, unless explicitily
|
6122
|
+
// Respond to updated data in the base series, unless explicitily
|
5369
6123
|
// not adapting to data changes.
|
5370
6124
|
if (this.navigatorOptions.adaptToUpdatedData !== false) {
|
5371
6125
|
if (base.xAxis) {
|
@@ -5385,9 +6139,9 @@
|
|
5385
6139
|
},
|
5386
6140
|
|
5387
6141
|
/**
|
5388
|
-
* Set the navigator x axis extremes to reflect the total. The navigator
|
5389
|
-
* should always be the extremes of the union of all series in the
|
5390
|
-
* well as the navigator series.
|
6142
|
+
* Set the navigator x axis extremes to reflect the total. The navigator
|
6143
|
+
* extremes should always be the extremes of the union of all series in the
|
6144
|
+
* chart as well as the navigator series.
|
5391
6145
|
*/
|
5392
6146
|
modifyNavigatorAxisExtremes: function() {
|
5393
6147
|
var xAxis = this.xAxis,
|
@@ -5395,7 +6149,13 @@
|
|
5395
6149
|
|
5396
6150
|
if (xAxis.getExtremes) {
|
5397
6151
|
unionExtremes = this.getUnionExtremes(true);
|
5398
|
-
if (
|
6152
|
+
if (
|
6153
|
+
unionExtremes &&
|
6154
|
+
(
|
6155
|
+
unionExtremes.dataMin !== xAxis.min ||
|
6156
|
+
unionExtremes.dataMax !== xAxis.max
|
6157
|
+
)
|
6158
|
+
) {
|
5399
6159
|
xAxis.min = unionExtremes.dataMin;
|
5400
6160
|
xAxis.max = unionExtremes.dataMax;
|
5401
6161
|
}
|
@@ -5416,29 +6176,34 @@
|
|
5416
6176
|
range = baseMax - baseMin,
|
5417
6177
|
stickToMin = navigator.stickToMin,
|
5418
6178
|
stickToMax = navigator.stickToMax,
|
6179
|
+
overscroll = baseXAxis.options.overscroll,
|
5419
6180
|
newMax,
|
5420
6181
|
newMin,
|
5421
6182
|
navigatorSeries = navigator.series && navigator.series[0],
|
5422
6183
|
hasSetExtremes = !!baseXAxis.setExtremes,
|
5423
6184
|
|
5424
|
-
// When the extremes have been set by range selector button, don't
|
5425
|
-
// The range selector buttons will handle the
|
5426
|
-
|
6185
|
+
// When the extremes have been set by range selector button, don't
|
6186
|
+
// stick to min or max. The range selector buttons will handle the
|
6187
|
+
// extremes. (#5489)
|
6188
|
+
unmutable = baseXAxis.eventArgs &&
|
6189
|
+
baseXAxis.eventArgs.trigger === 'rangeSelectorButton';
|
5427
6190
|
|
5428
6191
|
if (!unmutable) {
|
5429
6192
|
|
5430
|
-
// If the zoomed range is already at the min, move it to the right
|
5431
|
-
// comes in
|
6193
|
+
// If the zoomed range is already at the min, move it to the right
|
6194
|
+
// as new data comes in
|
5432
6195
|
if (stickToMin) {
|
5433
6196
|
newMin = baseDataMin;
|
5434
6197
|
newMax = newMin + range;
|
5435
6198
|
}
|
5436
6199
|
|
5437
|
-
// If the zoomed range is already at the max, move it to the right
|
5438
|
-
// comes in
|
6200
|
+
// If the zoomed range is already at the max, move it to the right
|
6201
|
+
// as new data comes in
|
5439
6202
|
if (stickToMax) {
|
5440
|
-
newMax = baseDataMax;
|
5441
|
-
|
6203
|
+
newMax = baseDataMax + overscroll;
|
6204
|
+
|
6205
|
+
// if stickToMin is true, the new min value is set above
|
6206
|
+
if (!stickToMin) {
|
5442
6207
|
newMin = Math.max(
|
5443
6208
|
newMax - range,
|
5444
6209
|
navigatorSeries && navigatorSeries.xData ?
|
@@ -5461,21 +6226,23 @@
|
|
5461
6226
|
},
|
5462
6227
|
|
5463
6228
|
/**
|
5464
|
-
* Handler for updated data on the base series. When data is modified, the
|
5465
|
-
* must reflect it. This is called from the Chart.redraw
|
5466
|
-
* extremes are computed.
|
6229
|
+
* Handler for updated data on the base series. When data is modified, the
|
6230
|
+
* navigator series must reflect it. This is called from the Chart.redraw
|
6231
|
+
* function before axis and series extremes are computed.
|
5467
6232
|
*/
|
5468
6233
|
updatedDataHandler: function() {
|
5469
6234
|
var navigator = this.chart.navigator,
|
5470
6235
|
baseSeries = this,
|
5471
6236
|
navigatorSeries = this.navigatorSeries;
|
5472
6237
|
|
5473
|
-
// If the scrollbar is scrolled all the way to the right, keep right as
|
5474
|
-
// comes in.
|
5475
|
-
navigator.stickToMax =
|
6238
|
+
// If the scrollbar is scrolled all the way to the right, keep right as
|
6239
|
+
// new data comes in.
|
6240
|
+
navigator.stickToMax =
|
6241
|
+
Math.round(navigator.zoomedMax) >= Math.round(navigator.size);
|
5476
6242
|
|
5477
|
-
// Detect whether the zoomed area should stick to the minimum or
|
5478
|
-
// axis minimum falls outside the new updated
|
6243
|
+
// Detect whether the zoomed area should stick to the minimum or
|
6244
|
+
// maximum. If the current axis minimum falls outside the new updated
|
6245
|
+
// dataset, we must adjust.
|
5479
6246
|
navigator.stickToMin = isNumber(baseSeries.xAxis.min) &&
|
5480
6247
|
(baseSeries.xAxis.min <= baseSeries.xData[0]) &&
|
5481
6248
|
(!this.chart.fixedRange || !navigator.stickToMax);
|
@@ -5483,7 +6250,12 @@
|
|
5483
6250
|
// Set the navigator series data to the new data of the base series
|
5484
6251
|
if (navigatorSeries && !navigator.hasNavigatorData) {
|
5485
6252
|
navigatorSeries.options.pointStart = baseSeries.xData[0];
|
5486
|
-
navigatorSeries.setData(
|
6253
|
+
navigatorSeries.setData(
|
6254
|
+
baseSeries.options.data,
|
6255
|
+
false,
|
6256
|
+
null,
|
6257
|
+
false
|
6258
|
+
); // #5414
|
5487
6259
|
}
|
5488
6260
|
},
|
5489
6261
|
|
@@ -5492,7 +6264,8 @@
|
|
5492
6264
|
*/
|
5493
6265
|
addChartEvents: function() {
|
5494
6266
|
addEvent(this.chart, 'redraw', function() {
|
5495
|
-
// Move the scrollbar after redraw, like after data updata even if
|
6267
|
+
// Move the scrollbar after redraw, like after data updata even if
|
6268
|
+
// axes don't redraw
|
5496
6269
|
var navigator = this.navigator,
|
5497
6270
|
xAxis = navigator && (
|
5498
6271
|
navigator.baseSeries &&
|
@@ -5552,8 +6325,9 @@
|
|
5552
6325
|
H.Navigator = Navigator;
|
5553
6326
|
|
5554
6327
|
/**
|
5555
|
-
* For Stock charts, override selection zooming with some special features
|
5556
|
-
* X axis zooming is already allowed by the Navigator and Range
|
6328
|
+
* For Stock charts, override selection zooming with some special features
|
6329
|
+
* because X axis zooming is already allowed by the Navigator and Range
|
6330
|
+
* selector.
|
5557
6331
|
*/
|
5558
6332
|
wrap(Axis.prototype, 'zoom', function(proceed, newMin, newMax) {
|
5559
6333
|
var chart = this.chart,
|
@@ -5567,8 +6341,8 @@
|
|
5567
6341
|
if (this.isXAxis && ((navigator && navigator.enabled) ||
|
5568
6342
|
(rangeSelector && rangeSelector.enabled))) {
|
5569
6343
|
|
5570
|
-
// For x only zooming, fool the chart.zoom method not to create the zoom
|
5571
|
-
// because the property already exists
|
6344
|
+
// For x only zooming, fool the chart.zoom method not to create the zoom
|
6345
|
+
// button because the property already exists
|
5572
6346
|
if (zoomType === 'x') {
|
5573
6347
|
chart.resetZoomButton = 'blocked';
|
5574
6348
|
|
@@ -5576,8 +6350,8 @@
|
|
5576
6350
|
} else if (zoomType === 'y') {
|
5577
6351
|
ret = false;
|
5578
6352
|
|
5579
|
-
// For xy zooming, record the state of the zoom before zoom selection,
|
5580
|
-
// the reset button is pressed, revert to this state
|
6353
|
+
// For xy zooming, record the state of the zoom before zoom selection,
|
6354
|
+
// then when the reset button is pressed, revert to this state
|
5581
6355
|
} else if (zoomType === 'xy') {
|
5582
6356
|
previousZoom = this.previousZoom;
|
5583
6357
|
if (defined(newMin)) {
|
@@ -5608,9 +6382,10 @@
|
|
5608
6382
|
});
|
5609
6383
|
|
5610
6384
|
/**
|
5611
|
-
* For stock charts, extend the Chart.setChartSize method so that we can set the
|
5612
|
-
* of the navigator once the height of the chart, including
|
5613
|
-
* We can't use Chart.getMargins, because
|
6385
|
+
* For stock charts, extend the Chart.setChartSize method so that we can set the
|
6386
|
+
* final top position of the navigator once the height of the chart, including
|
6387
|
+
* the legend, is determined. #367. We can't use Chart.getMargins, because
|
6388
|
+
* labels offsets are not calculated yet.
|
5614
6389
|
*/
|
5615
6390
|
wrap(Chart.prototype, 'setChartSize', function(proceed) {
|
5616
6391
|
|
@@ -5624,7 +6399,7 @@
|
|
5624
6399
|
proceed.apply(this, [].slice.call(arguments, 1));
|
5625
6400
|
|
5626
6401
|
if (navigator) {
|
5627
|
-
legendOptions = legend.options;
|
6402
|
+
legendOptions = legend && legend.options;
|
5628
6403
|
xAxis = navigator.xAxis;
|
5629
6404
|
yAxis = navigator.yAxis;
|
5630
6405
|
scrollbarHeight = navigator.scrollbarHeight;
|
@@ -5638,9 +6413,25 @@
|
|
5638
6413
|
} else {
|
5639
6414
|
navigator.left = this.plotLeft + scrollbarHeight;
|
5640
6415
|
navigator.top = navigator.navigatorOptions.top ||
|
5641
|
-
this.chartHeight -
|
5642
|
-
|
5643
|
-
|
6416
|
+
this.chartHeight -
|
6417
|
+
navigator.height -
|
6418
|
+
scrollbarHeight -
|
6419
|
+
this.spacing[2] -
|
6420
|
+
(
|
6421
|
+
this.rangeSelector && this.extraBottomMargin ?
|
6422
|
+
this.rangeSelector.getHeight() :
|
6423
|
+
0
|
6424
|
+
) -
|
6425
|
+
(
|
6426
|
+
(
|
6427
|
+
legendOptions &&
|
6428
|
+
legendOptions.verticalAlign === 'bottom' &&
|
6429
|
+
legendOptions.enabled &&
|
6430
|
+
!legendOptions.floating
|
6431
|
+
) ?
|
6432
|
+
legend.legendHeight + pick(legendOptions.margin, 10) :
|
6433
|
+
0
|
6434
|
+
);
|
5644
6435
|
}
|
5645
6436
|
|
5646
6437
|
if (xAxis && yAxis) { // false if navigator is disabled (#904)
|
@@ -5658,19 +6449,36 @@
|
|
5658
6449
|
});
|
5659
6450
|
|
5660
6451
|
// Pick up badly formatted point options to addPoint
|
5661
|
-
wrap(Series.prototype, 'addPoint', function(
|
6452
|
+
wrap(Series.prototype, 'addPoint', function(
|
6453
|
+
proceed,
|
6454
|
+
options,
|
6455
|
+
redraw,
|
6456
|
+
shift,
|
6457
|
+
animation
|
6458
|
+
) {
|
5662
6459
|
var turboThreshold = this.options.turboThreshold;
|
5663
|
-
if (
|
6460
|
+
if (
|
6461
|
+
turboThreshold &&
|
6462
|
+
this.xData.length > turboThreshold &&
|
6463
|
+
isObject(options, true) &&
|
6464
|
+
this.chart.navigator
|
6465
|
+
) {
|
5664
6466
|
error(20, true);
|
5665
6467
|
}
|
5666
6468
|
proceed.call(this, options, redraw, shift, animation);
|
5667
6469
|
});
|
5668
6470
|
|
5669
6471
|
// Handle adding new series
|
5670
|
-
wrap(Chart.prototype, 'addSeries', function(
|
6472
|
+
wrap(Chart.prototype, 'addSeries', function(
|
6473
|
+
proceed,
|
6474
|
+
options,
|
6475
|
+
redraw,
|
6476
|
+
animation
|
6477
|
+
) {
|
5671
6478
|
var series = proceed.call(this, options, false, animation);
|
5672
6479
|
if (this.navigator) {
|
5673
|
-
|
6480
|
+
// Recompute which series should be shown in navigator, and add them
|
6481
|
+
this.navigator.setBaseSeries(null, false);
|
5674
6482
|
}
|
5675
6483
|
if (pick(redraw, true)) {
|
5676
6484
|
this.redraw();
|
@@ -5682,7 +6490,7 @@
|
|
5682
6490
|
wrap(Series.prototype, 'update', function(proceed, newOptions, redraw) {
|
5683
6491
|
proceed.call(this, newOptions, false);
|
5684
6492
|
if (this.chart.navigator && !this.options.isInternal) {
|
5685
|
-
this.chart.navigator.setBaseSeries();
|
6493
|
+
this.chart.navigator.setBaseSeries(null, false);
|
5686
6494
|
}
|
5687
6495
|
if (pick(redraw, true)) {
|
5688
6496
|
this.chart.redraw();
|
@@ -5700,9 +6508,6 @@
|
|
5700
6508
|
}
|
5701
6509
|
});
|
5702
6510
|
|
5703
|
-
/* ****************************************************************************
|
5704
|
-
* End Navigator code *
|
5705
|
-
*****************************************************************************/
|
5706
6511
|
|
5707
6512
|
}(Highcharts));
|
5708
6513
|
(function(H) {
|
@@ -5744,8 +6549,8 @@
|
|
5744
6549
|
* the chart, like 1 day, 1 week, 1 month etc. It also provides input
|
5745
6550
|
* boxes where min and max dates can be manually input.
|
5746
6551
|
*
|
5747
|
-
* @optionparent rangeSelector
|
5748
6552
|
* @product highstock
|
6553
|
+
* @optionparent rangeSelector
|
5749
6554
|
*/
|
5750
6555
|
rangeSelector: {
|
5751
6556
|
// allButtonsEnabled: false,
|
@@ -5753,6 +6558,18 @@
|
|
5753
6558
|
// buttons: {Object}
|
5754
6559
|
// buttonSpacing: 0,
|
5755
6560
|
|
6561
|
+
/**
|
6562
|
+
* The vertical alignment of the rangeselector box. Allowed properties are `top`,
|
6563
|
+
* `middle`, `bottom`.
|
6564
|
+
*
|
6565
|
+
* @since 6.0.0
|
6566
|
+
*
|
6567
|
+
* @sample {highstock} stock/rangeselector/vertical-align-middle/ Middle
|
6568
|
+
*
|
6569
|
+
* @sample {highstock} stock/rangeselector/vertical-align-bottom/ Bottom
|
6570
|
+
*/
|
6571
|
+
verticalAlign: 'top',
|
6572
|
+
|
5756
6573
|
/**
|
5757
6574
|
* A collection of attributes for the buttons. The object takes SVG
|
5758
6575
|
* attributes like `fill`, `stroke`, `stroke-width`, as well as `style`,
|
@@ -5763,8 +6580,7 @@
|
|
5763
6580
|
*
|
5764
6581
|
* CSS styles for the text label.
|
5765
6582
|
*
|
5766
|
-
* In
|
5767
|
-
* style/style-by-css), the buttons are styled by the `.highcharts-
|
6583
|
+
* In styled mode, the buttons are styled by the `.highcharts-
|
5768
6584
|
* range-selector-buttons .highcharts-button` rule with its different
|
5769
6585
|
* states.
|
5770
6586
|
*
|
@@ -5773,53 +6589,103 @@
|
|
5773
6589
|
* @product highstock
|
5774
6590
|
*/
|
5775
6591
|
buttonTheme: {
|
5776
|
-
|
5777
|
-
/**
|
5778
|
-
*/
|
5779
6592
|
'stroke-width': 0,
|
5780
|
-
|
5781
|
-
/**
|
5782
|
-
*/
|
5783
6593
|
width: 28,
|
5784
|
-
|
5785
|
-
/**
|
5786
|
-
*/
|
5787
6594
|
height: 18,
|
5788
|
-
|
5789
|
-
/**
|
5790
|
-
*/
|
5791
6595
|
padding: 2,
|
5792
|
-
|
5793
|
-
/**
|
5794
|
-
*/
|
5795
6596
|
zIndex: 7 // #484, #852
|
5796
6597
|
},
|
5797
6598
|
|
5798
6599
|
/**
|
5799
|
-
*
|
5800
|
-
*
|
6600
|
+
* When the rangeselector is floating, the plot area does not reserve
|
6601
|
+
* space for it. This opens for positioning anywhere on the chart.
|
6602
|
+
*
|
6603
|
+
* @sample {highstock} stock/rangeselector/floating/
|
6604
|
+
* Placing the range selector between the plot area and the
|
6605
|
+
* navigator
|
6606
|
+
* @since 6.0.0
|
6607
|
+
* @product highstock
|
6608
|
+
*/
|
6609
|
+
floating: false,
|
6610
|
+
|
6611
|
+
/**
|
6612
|
+
* The x offset of the range selector relative to its horizontal
|
6613
|
+
* alignment within `chart.spacingLeft` and `chart.spacingRight`.
|
6614
|
+
*
|
6615
|
+
* @since 6.0.0
|
6616
|
+
* @product highstock
|
6617
|
+
*/
|
6618
|
+
x: 0,
|
6619
|
+
|
6620
|
+
/**
|
6621
|
+
* The y offset of the range selector relative to its horizontal
|
6622
|
+
* alignment within `chart.spacingLeft` and `chart.spacingRight`.
|
6623
|
+
*
|
6624
|
+
* @since 6.0.0
|
6625
|
+
* @product highstock
|
6626
|
+
*/
|
6627
|
+
y: 0,
|
6628
|
+
|
6629
|
+
/**
|
6630
|
+
* Deprecated. The height of the range selector. Currently it is
|
6631
|
+
* calculated dynamically.
|
5801
6632
|
*
|
5802
6633
|
* @type {Number}
|
5803
|
-
* @default
|
6634
|
+
* @default undefined
|
5804
6635
|
* @since 2.1.9
|
5805
6636
|
* @product highstock
|
6637
|
+
* @deprecated true
|
5806
6638
|
*/
|
5807
|
-
height:
|
6639
|
+
height: undefined, // reserved space for buttons and input
|
5808
6640
|
|
5809
6641
|
/**
|
5810
6642
|
* Positioning for the input boxes. Allowed properties are `align`,
|
5811
|
-
* `
|
6643
|
+
* `x` and `y`.
|
5812
6644
|
*
|
5813
6645
|
* @type {Object}
|
5814
6646
|
* @default { align: "right" }
|
5815
|
-
* @since 1.2.
|
6647
|
+
* @since 1.2.4
|
5816
6648
|
* @product highstock
|
5817
6649
|
*/
|
5818
6650
|
inputPosition: {
|
6651
|
+
/**
|
6652
|
+
* The alignment of the input box. Allowed properties are `left`,
|
6653
|
+
* `center`, `right`.
|
6654
|
+
* @validvalue ["left", "center", "right"]
|
6655
|
+
* @sample {highstock} stock/rangeselector/input-button-position/
|
6656
|
+
* Alignment
|
6657
|
+
* @since 6.0.0
|
6658
|
+
*/
|
6659
|
+
align: 'right',
|
6660
|
+
x: 0,
|
6661
|
+
y: 0
|
6662
|
+
},
|
5819
6663
|
|
6664
|
+
/**
|
6665
|
+
* Positioning for the button row.
|
6666
|
+
*
|
6667
|
+
* @since 1.2.4
|
6668
|
+
* @product highstock
|
6669
|
+
*/
|
6670
|
+
buttonPosition: {
|
6671
|
+
/**
|
6672
|
+
* The alignment of the input box. Allowed properties are `left`,
|
6673
|
+
* `center`, `right`.
|
6674
|
+
*
|
6675
|
+
* @validvalue ["left", "center", "right"]
|
6676
|
+
* @sample {highstock} stock/rangeselector/input-button-position/
|
6677
|
+
* Alignment
|
6678
|
+
* @since 6.0.0
|
6679
|
+
*/
|
6680
|
+
align: 'left',
|
5820
6681
|
/**
|
6682
|
+
* X offset of the button row.
|
5821
6683
|
*/
|
5822
|
-
|
6684
|
+
x: 0,
|
6685
|
+
/**
|
6686
|
+
* Y offset of the button row.
|
6687
|
+
*/
|
6688
|
+
y: 0
|
5823
6689
|
},
|
5824
6690
|
// inputDateFormat: '%b %e, %Y',
|
5825
6691
|
// inputEditDateFormat: '%Y-%m-%d',
|
@@ -5831,18 +6697,13 @@
|
|
5831
6697
|
/**
|
5832
6698
|
* CSS styles for the labels - the Zoom, From and To texts.
|
5833
6699
|
*
|
5834
|
-
* In
|
5835
|
-
* style/style-by-css), the labels are styled by the `.highcharts-
|
5836
|
-
* range-label` class.
|
6700
|
+
* In styled mode, the labels are styled by the `.highcharts-range-label` class.
|
5837
6701
|
*
|
5838
6702
|
* @type {CSSObject}
|
5839
6703
|
* @sample {highstock} stock/rangeselector/styling/ Styling the buttons and inputs
|
5840
6704
|
* @product highstock
|
5841
6705
|
*/
|
5842
6706
|
labelStyle: {
|
5843
|
-
|
5844
|
-
/**
|
5845
|
-
*/
|
5846
6707
|
color: '#666666'
|
5847
6708
|
}
|
5848
6709
|
|
@@ -5857,13 +6718,17 @@
|
|
5857
6718
|
* set it before any chart is initialized.
|
5858
6719
|
*
|
5859
6720
|
* <pre>Highcharts.setOptions({
|
5860
|
-
*
|
5861
|
-
*
|
5862
|
-
*
|
5863
|
-
*
|
5864
|
-
*
|
5865
|
-
*
|
5866
|
-
*
|
6721
|
+
* lang: {
|
6722
|
+
* months: [
|
6723
|
+
* 'Janvier', 'Février', 'Mars', 'Avril',
|
6724
|
+
* 'Mai', 'Juin', 'Juillet', 'Août',
|
6725
|
+
* 'Septembre', 'Octobre', 'Novembre', 'Décembre'
|
6726
|
+
* ],
|
6727
|
+
* weekdays: [
|
6728
|
+
* 'Dimanche', 'Lundi', 'Mardi', 'Mercredi',
|
6729
|
+
* 'Jeudi', 'Vendredi', 'Samedi'
|
6730
|
+
* ]
|
6731
|
+
* }
|
5867
6732
|
* });</pre>
|
5868
6733
|
*
|
5869
6734
|
* @optionparent lang
|
@@ -6013,6 +6878,10 @@
|
|
6013
6878
|
newMin = dataMin;
|
6014
6879
|
newMax = dataMax;
|
6015
6880
|
}
|
6881
|
+
|
6882
|
+
newMin += rangeOptions._offsetMin;
|
6883
|
+
newMax += rangeOptions._offsetMax;
|
6884
|
+
|
6016
6885
|
rangeSelector.setSelected(i);
|
6017
6886
|
|
6018
6887
|
// Update the chart
|
@@ -6089,11 +6958,11 @@
|
|
6089
6958
|
blurInputs = function() {
|
6090
6959
|
var minInput = rangeSelector.minInput,
|
6091
6960
|
maxInput = rangeSelector.maxInput;
|
6092
|
-
if (minInput && minInput.blur) {
|
6093
|
-
fireEvent(minInput, 'blur');
|
6961
|
+
if (minInput && minInput.blur) { // #3274 in some case blur is not defined
|
6962
|
+
fireEvent(minInput, 'blur'); // #3274
|
6094
6963
|
}
|
6095
|
-
if (maxInput && maxInput.blur) {
|
6096
|
-
fireEvent(maxInput, 'blur');
|
6964
|
+
if (maxInput && maxInput.blur) { // #3274 in some case blur is not defined
|
6965
|
+
fireEvent(maxInput, 'blur'); // #3274
|
6097
6966
|
}
|
6098
6967
|
};
|
6099
6968
|
|
@@ -6156,6 +7025,7 @@
|
|
6156
7025
|
state = 0,
|
6157
7026
|
disable,
|
6158
7027
|
select,
|
7028
|
+
offsetRange = rangeOptions._offsetMax - rangeOptions._offsetMin,
|
6159
7029
|
isSelected = i === selected,
|
6160
7030
|
// Disable buttons where the range exceeds what is allowed in the current view
|
6161
7031
|
isTooGreatRange = range > dataMax - dataMin,
|
@@ -6172,15 +7042,15 @@
|
|
6172
7042
|
(actualRange >= {
|
6173
7043
|
month: 28,
|
6174
7044
|
year: 365
|
6175
|
-
}[type] * day * count) &&
|
7045
|
+
}[type] * day * count + offsetRange) &&
|
6176
7046
|
(actualRange <= {
|
6177
7047
|
month: 31,
|
6178
7048
|
year: 366
|
6179
|
-
}[type] * day * count)
|
7049
|
+
}[type] * day * count + offsetRange)
|
6180
7050
|
) {
|
6181
7051
|
isSameRange = true;
|
6182
7052
|
} else if (type === 'ytd') {
|
6183
|
-
isSameRange = (ytdMax - ytdMin) === actualRange;
|
7053
|
+
isSameRange = (ytdMax - ytdMin + offsetRange) === actualRange;
|
6184
7054
|
isYTDButNotSelected = !isSelected;
|
6185
7055
|
} else if (type === 'all') {
|
6186
7056
|
isSameRange = baseAxis.max - baseAxis.min >= dataMax - dataMin;
|
@@ -6243,6 +7113,10 @@
|
|
6243
7113
|
year: 365
|
6244
7114
|
}[type] * 24 * 36e5 * count;
|
6245
7115
|
}
|
7116
|
+
|
7117
|
+
rangeOptions._offsetMin = pick(rangeOptions.offsetMin, 0);
|
7118
|
+
rangeOptions._offsetMax = pick(rangeOptions.offsetMax, 0);
|
7119
|
+
rangeOptions._range += rangeOptions._offsetMax - rangeOptions._offsetMin;
|
6246
7120
|
},
|
6247
7121
|
|
6248
7122
|
/**
|
@@ -6448,11 +7322,11 @@
|
|
6448
7322
|
getPosition: function() {
|
6449
7323
|
var chart = this.chart,
|
6450
7324
|
options = chart.options.rangeSelector,
|
6451
|
-
|
7325
|
+
top = (options.verticalAlign) === 'top' ? chart.plotTop - chart.axisOffset[0] : 0; // set offset only for varticalAlign top
|
6452
7326
|
|
6453
7327
|
return {
|
6454
|
-
buttonTop:
|
6455
|
-
inputTop:
|
7328
|
+
buttonTop: top + options.buttonPosition.y,
|
7329
|
+
inputTop: top + options.inputPosition.y - 10
|
6456
7330
|
};
|
6457
7331
|
},
|
6458
7332
|
/**
|
@@ -6493,21 +7367,36 @@
|
|
6493
7367
|
chartOptions = chart.options,
|
6494
7368
|
navButtonOptions = chartOptions.exporting && chartOptions.exporting.enabled !== false &&
|
6495
7369
|
chartOptions.navigation && chartOptions.navigation.buttonOptions,
|
6496
|
-
options = chartOptions.rangeSelector,
|
6497
|
-
buttons = rangeSelector.buttons,
|
6498
7370
|
lang = defaultOptions.lang,
|
6499
7371
|
div = rangeSelector.div,
|
7372
|
+
options = chartOptions.rangeSelector,
|
7373
|
+
floating = options.floating,
|
7374
|
+
buttons = rangeSelector.buttons,
|
6500
7375
|
inputGroup = rangeSelector.inputGroup,
|
6501
7376
|
buttonTheme = options.buttonTheme,
|
6502
|
-
buttonPosition = options.buttonPosition
|
7377
|
+
buttonPosition = options.buttonPosition,
|
7378
|
+
inputPosition = options.inputPosition,
|
6503
7379
|
inputEnabled = options.inputEnabled,
|
6504
7380
|
states = buttonTheme && buttonTheme.states,
|
6505
7381
|
plotLeft = chart.plotLeft,
|
6506
7382
|
buttonLeft,
|
6507
7383
|
pos = this.getPosition(),
|
6508
|
-
buttonGroup = rangeSelector.
|
6509
|
-
|
6510
|
-
|
7384
|
+
buttonGroup = rangeSelector.buttonGroup,
|
7385
|
+
group,
|
7386
|
+
groupHeight,
|
7387
|
+
rendered = rangeSelector.rendered,
|
7388
|
+
verticalAlign = rangeSelector.options.verticalAlign,
|
7389
|
+
legend = chart.legend,
|
7390
|
+
legendOptions = legend && legend.options,
|
7391
|
+
buttonPositionY = buttonPosition.y,
|
7392
|
+
inputPositionY = inputPosition.y,
|
7393
|
+
exportingX = 0,
|
7394
|
+
alignTranslateY,
|
7395
|
+
legendHeight,
|
7396
|
+
minPosition,
|
7397
|
+
translateY,
|
7398
|
+
translateX,
|
7399
|
+
groupOffsetY;
|
6511
7400
|
|
6512
7401
|
if (options.enabled === false) {
|
6513
7402
|
return;
|
@@ -6516,22 +7405,41 @@
|
|
6516
7405
|
// create the elements
|
6517
7406
|
if (!rendered) {
|
6518
7407
|
|
6519
|
-
rangeSelector.group =
|
7408
|
+
rangeSelector.group = group = renderer.g('range-selector-group')
|
7409
|
+
.attr({
|
7410
|
+
zIndex: 7
|
7411
|
+
})
|
7412
|
+
.add();
|
7413
|
+
|
7414
|
+
rangeSelector.buttonGroup = buttonGroup = renderer.g('range-selector-buttons').add(group);
|
6520
7415
|
|
6521
|
-
rangeSelector.zoomText = renderer.text(lang.rangeSelectorZoom, pick(buttonPosition.x, plotLeft), 15)
|
7416
|
+
rangeSelector.zoomText = renderer.text(lang.rangeSelectorZoom, pick(plotLeft + buttonPosition.x, plotLeft), 15)
|
6522
7417
|
.css(options.labelStyle)
|
6523
7418
|
.add(buttonGroup);
|
6524
7419
|
|
6525
|
-
// button
|
6526
|
-
buttonLeft = pick(buttonPosition.x, plotLeft) + rangeSelector.zoomText.getBBox().width + 5;
|
7420
|
+
// button start position
|
7421
|
+
buttonLeft = pick(plotLeft + buttonPosition.x, plotLeft) + rangeSelector.zoomText.getBBox().width + 5;
|
6527
7422
|
|
6528
7423
|
each(rangeSelector.buttonOptions, function(rangeOptions, i) {
|
7424
|
+
|
6529
7425
|
buttons[i] = renderer.button(
|
6530
7426
|
rangeOptions.text,
|
6531
7427
|
buttonLeft,
|
6532
7428
|
0,
|
6533
7429
|
function() {
|
6534
|
-
|
7430
|
+
|
7431
|
+
// extract events from button object and call
|
7432
|
+
var buttonEvents = rangeOptions.events && rangeOptions.events.click,
|
7433
|
+
callDefaultEvent;
|
7434
|
+
|
7435
|
+
if (buttonEvents) {
|
7436
|
+
callDefaultEvent = buttonEvents.call(rangeOptions);
|
7437
|
+
}
|
7438
|
+
|
7439
|
+
if (callDefaultEvent !== false) {
|
7440
|
+
rangeSelector.clickButton(i);
|
7441
|
+
}
|
7442
|
+
|
6535
7443
|
rangeSelector.isActive = true;
|
6536
7444
|
},
|
6537
7445
|
buttonTheme,
|
@@ -6561,53 +7469,263 @@
|
|
6561
7469
|
|
6562
7470
|
// Create the group to keep the inputs
|
6563
7471
|
rangeSelector.inputGroup = inputGroup = renderer.g('input-group')
|
6564
|
-
.add();
|
7472
|
+
.add(group);
|
6565
7473
|
inputGroup.offset = 0;
|
6566
7474
|
|
6567
7475
|
rangeSelector.drawInput('min');
|
6568
7476
|
rangeSelector.drawInput('max');
|
6569
7477
|
}
|
6570
7478
|
}
|
7479
|
+
|
7480
|
+
plotLeft = chart.plotLeft - chart.spacing[3];
|
7481
|
+
|
6571
7482
|
rangeSelector.updateButtonStates();
|
6572
7483
|
|
6573
|
-
//
|
6574
|
-
|
6575
|
-
|
7484
|
+
// detect collisiton with exporting
|
7485
|
+
if (
|
7486
|
+
navButtonOptions &&
|
7487
|
+
this.titleCollision(chart) &&
|
7488
|
+
verticalAlign === 'top' &&
|
7489
|
+
buttonPosition.align === 'right' &&
|
7490
|
+
(
|
7491
|
+
(buttonPosition.y + buttonGroup.getBBox().height - 12) <
|
7492
|
+
((navButtonOptions.y || 0) + navButtonOptions.height - chart.spacing[0])
|
7493
|
+
)
|
7494
|
+
) {
|
7495
|
+
exportingX = -40;
|
7496
|
+
}
|
7497
|
+
|
7498
|
+
// align button group
|
7499
|
+
buttonGroup.align(extend({
|
7500
|
+
y: pos.buttonTop,
|
7501
|
+
width: buttonGroup.getBBox().width,
|
7502
|
+
x: exportingX
|
7503
|
+
}, buttonPosition), true, chart.spacingBox);
|
7504
|
+
|
7505
|
+
translateX = buttonGroup.alignAttr.translateX + exportingX;
|
7506
|
+
|
7507
|
+
// detect left offset (axis title) or margin
|
7508
|
+
if (buttonPosition.align === 'left') {
|
7509
|
+
translateX += ((plotLeft < 0) || (H.isNumber(chart.margin[3])) ? 0 : plotLeft) - chart.spacing[3];
|
7510
|
+
} else if (buttonPosition.align === 'right') {
|
7511
|
+
translateX -= chart.spacing[1] + (H.isNumber(chart.margin[3]) ? plotLeft : 0);
|
7512
|
+
}
|
7513
|
+
|
7514
|
+
// Set / update the group position
|
7515
|
+
buttonGroup.attr({
|
7516
|
+
translateY: pos.buttonTop,
|
7517
|
+
translateX: translateX
|
6576
7518
|
});
|
6577
7519
|
|
7520
|
+
// skip animation
|
7521
|
+
rangeSelector.group.placed = false;
|
7522
|
+
rangeSelector.buttonGroup.placed = false;
|
7523
|
+
|
6578
7524
|
if (inputEnabled !== false) {
|
6579
7525
|
|
7526
|
+
var inputGroupX,
|
7527
|
+
inputGroupWidth,
|
7528
|
+
buttonGroupX,
|
7529
|
+
buttonGroupWidth;
|
7530
|
+
|
7531
|
+
// detect collision with exporting
|
7532
|
+
if (
|
7533
|
+
navButtonOptions &&
|
7534
|
+
this.titleCollision(chart) &&
|
7535
|
+
verticalAlign === 'top' &&
|
7536
|
+
inputPosition.align === 'right' &&
|
7537
|
+
(
|
7538
|
+
(pos.inputTop - inputGroup.getBBox().height - 12) <
|
7539
|
+
((navButtonOptions.y || 0) + navButtonOptions.height + chart.spacing[0])
|
7540
|
+
)
|
7541
|
+
) {
|
7542
|
+
exportingX = -40;
|
7543
|
+
} else {
|
7544
|
+
exportingX = 0;
|
7545
|
+
}
|
7546
|
+
|
6580
7547
|
// Update the alignment to the updated spacing box
|
6581
7548
|
inputGroup.align(extend({
|
6582
7549
|
y: pos.inputTop,
|
6583
|
-
width: inputGroup.
|
6584
|
-
|
6585
|
-
|
6586
|
-
|
6587
|
-
|
6588
|
-
|
6589
|
-
|
6590
|
-
if (
|
6591
|
-
|
6592
|
-
|
7550
|
+
width: inputGroup.getBBox().width
|
7551
|
+
}, inputPosition), true, chart.spacingBox);
|
7552
|
+
|
7553
|
+
translateX = inputGroup.alignAttr.translateX + exportingX;
|
7554
|
+
|
7555
|
+
if (inputPosition.align === 'left') {
|
7556
|
+
translateX += plotLeft;
|
7557
|
+
} else if (
|
7558
|
+
inputPosition.align === 'right'
|
7559
|
+
) {
|
7560
|
+
translateX = translateX - chart.axisOffset[1]; // yAxis offset
|
7561
|
+
}
|
7562
|
+
|
7563
|
+
// add y from user options
|
7564
|
+
inputGroup.attr({
|
7565
|
+
translateY: pos.inputTop + 10,
|
7566
|
+
translateX: translateX - (inputPosition.align === 'right' ? 2 : 0) // fix wrong getBBox() value on right align
|
7567
|
+
});
|
7568
|
+
|
7569
|
+
// detect collision
|
7570
|
+
inputGroupX = inputGroup.translateX + inputGroup.alignOptions.x -
|
7571
|
+
exportingX + inputGroup.getBBox().x + 2; // getBBox for detecing left margin, 2px padding to not overlap input and label
|
7572
|
+
|
7573
|
+
inputGroupWidth = inputGroup.alignOptions.width;
|
7574
|
+
|
7575
|
+
buttonGroupX = buttonGroup.translateX + buttonGroup.getBBox().x;
|
7576
|
+
buttonGroupWidth = buttonGroup.getBBox().width + 20; // 20 is minimal spacing between elements
|
7577
|
+
|
7578
|
+
if (
|
7579
|
+
(inputPosition.align === buttonPosition.align) ||
|
7580
|
+
(
|
7581
|
+
(buttonGroupX + buttonGroupWidth > inputGroupX) &&
|
7582
|
+
(inputGroupX + inputGroupWidth > buttonGroupX) &&
|
7583
|
+
(buttonPositionY < (inputPositionY + inputGroup.getBBox().height))
|
7584
|
+
)
|
7585
|
+
) {
|
7586
|
+
|
7587
|
+
// move the element to the second line
|
7588
|
+
inputGroup.attr({
|
7589
|
+
translateX: inputGroup.translateX,
|
7590
|
+
translateY: inputGroup.translateY + buttonGroup.getBBox().height + 10
|
7591
|
+
});
|
6593
7592
|
}
|
6594
7593
|
|
6595
7594
|
// Set or reset the input values
|
6596
7595
|
rangeSelector.setInputValue('min', min);
|
6597
7596
|
rangeSelector.setInputValue('max', max);
|
7597
|
+
|
7598
|
+
// skip animation
|
7599
|
+
rangeSelector.inputGroup.placed = false;
|
7600
|
+
}
|
7601
|
+
|
7602
|
+
// vertical align
|
7603
|
+
rangeSelector.group.align({
|
7604
|
+
verticalAlign: verticalAlign
|
7605
|
+
}, true, chart.spacingBox);
|
7606
|
+
|
7607
|
+
// set position
|
7608
|
+
groupHeight = rangeSelector.group.getBBox().height + 20; // # 20 padding
|
7609
|
+
|
7610
|
+
// calculate bottom position
|
7611
|
+
if (verticalAlign === 'bottom') {
|
7612
|
+
legendHeight = legendOptions && legendOptions.verticalAlign === 'bottom' && legendOptions.enabled &&
|
7613
|
+
!legendOptions.floating ? legend.legendHeight + pick(legendOptions.margin, 10) : 0;
|
7614
|
+
|
7615
|
+
groupHeight = groupHeight + legendHeight - 20;
|
7616
|
+
}
|
7617
|
+
|
7618
|
+
groupOffsetY = Math[verticalAlign === 'middle' ? 'max' : 'min'](inputPositionY, buttonPositionY);
|
7619
|
+
|
7620
|
+
if (inputGroup && (inputPositionY < buttonPositionY) && verticalAlign === 'bottom') {
|
7621
|
+
groupOffsetY += inputGroup.getBBox().height;
|
7622
|
+
}
|
7623
|
+
|
7624
|
+
// fix the position
|
7625
|
+
alignTranslateY = rangeSelector.group.alignAttr.translateY;
|
7626
|
+
minPosition = (inputPositionY < 0 && buttonPositionY < 0) ? 0 : groupOffsetY;
|
7627
|
+
translateY = Math.floor(alignTranslateY - groupHeight - minPosition);
|
7628
|
+
|
7629
|
+
if (verticalAlign === 'top') {
|
7630
|
+
if (floating) {
|
7631
|
+
translateY = 0;
|
7632
|
+
} else if (chart.spacing[0] !== chart.options.chart.spacing[0]) { // detect if spacing is customised
|
7633
|
+
translateY -= (chart.spacing[0] - chart.options.chart.spacing[0]);
|
7634
|
+
}
|
7635
|
+
} else if (verticalAlign === 'middle') {
|
7636
|
+
if (inputPositionY === buttonPositionY) {
|
7637
|
+
if (inputPositionY < 0) {
|
7638
|
+
translateY = alignTranslateY + minPosition;
|
7639
|
+
} else {
|
7640
|
+
translateY = alignTranslateY;
|
7641
|
+
}
|
7642
|
+
} else if (inputPositionY || buttonPositionY) {
|
7643
|
+
if (inputPositionY < 0 || buttonPositionY < 0) {
|
7644
|
+
translateY -= Math.min(inputPositionY, buttonPositionY);
|
7645
|
+
} else {
|
7646
|
+
translateY = alignTranslateY - groupHeight + minPosition;
|
7647
|
+
}
|
7648
|
+
}
|
7649
|
+
}
|
7650
|
+
|
7651
|
+
translateY = Math.floor(translateY);
|
7652
|
+
|
7653
|
+
if (floating) {
|
7654
|
+
translateY += options.y;
|
7655
|
+
}
|
7656
|
+
|
7657
|
+
rangeSelector.group.translate(0 + options.x, translateY - 3); // floor to avoid crisp edges, 3px to keep back compatibility
|
7658
|
+
|
7659
|
+
// translate HTML inputs
|
7660
|
+
if (inputEnabled !== false) {
|
7661
|
+
rangeSelector.minInput.style.marginTop = rangeSelector.group.translateY + 'px';
|
7662
|
+
rangeSelector.maxInput.style.marginTop = rangeSelector.group.translateY + 'px';
|
6598
7663
|
}
|
6599
7664
|
|
6600
7665
|
rangeSelector.rendered = true;
|
6601
7666
|
},
|
6602
7667
|
|
7668
|
+
/**
|
7669
|
+
* Extracts height of range selector
|
7670
|
+
* @return {Number} Returns rangeSelector height
|
7671
|
+
*/
|
7672
|
+
getHeight: function() {
|
7673
|
+
var rangeSelector = this,
|
7674
|
+
options = rangeSelector.options,
|
7675
|
+
inputPosition = options.inputPosition,
|
7676
|
+
buttonPosition = options.buttonPosition,
|
7677
|
+
yPosition = options.y,
|
7678
|
+
rangeSelectorGroup = rangeSelector.group,
|
7679
|
+
buttonPositionY = buttonPosition.y,
|
7680
|
+
inputPositionY = inputPosition.y,
|
7681
|
+
rangeSelectorHeight = 0,
|
7682
|
+
minPosition;
|
7683
|
+
|
7684
|
+
rangeSelectorHeight = rangeSelectorGroup ? (rangeSelectorGroup.getBBox(true).height) + 13 + yPosition : 0; // 13px to keep back compatibility
|
7685
|
+
minPosition = Math.min(inputPositionY, buttonPositionY);
|
7686
|
+
|
7687
|
+
if (
|
7688
|
+
(inputPositionY < 0 && buttonPositionY < 0) ||
|
7689
|
+
(inputPositionY > 0 && buttonPositionY > 0)
|
7690
|
+
) {
|
7691
|
+
rangeSelectorHeight += Math.abs(minPosition);
|
7692
|
+
}
|
7693
|
+
|
7694
|
+
return rangeSelectorHeight;
|
7695
|
+
},
|
7696
|
+
|
7697
|
+
/**
|
7698
|
+
* Detect collision with title or subtitle
|
7699
|
+
* @param {object} chart
|
7700
|
+
* @return {Boolean} Returns collision status
|
7701
|
+
*/
|
7702
|
+
titleCollision: function(chart) {
|
7703
|
+
var status = false;
|
7704
|
+
|
7705
|
+
if (
|
7706
|
+
(!H.isObject(chart.title) ||
|
7707
|
+
(chart.title && chart.title.getBBox().y > chart.plotTop)
|
7708
|
+
) && (!H.isObject(chart.subtitle) ||
|
7709
|
+
(chart.subtitle && chart.subtitle.getBBox().y > chart.plotTop)
|
7710
|
+
)
|
7711
|
+
) {
|
7712
|
+
status = true;
|
7713
|
+
}
|
7714
|
+
|
7715
|
+
return status;
|
7716
|
+
},
|
7717
|
+
|
6603
7718
|
/**
|
6604
7719
|
* Update the range selector with new options
|
7720
|
+
* @param {object} options
|
6605
7721
|
*/
|
6606
7722
|
update: function(options) {
|
6607
7723
|
var chart = this.chart;
|
7724
|
+
|
6608
7725
|
merge(true, chart.options.rangeSelector, options);
|
6609
7726
|
this.destroy();
|
6610
7727
|
this.init(chart);
|
7728
|
+
chart.rangeSelector.render();
|
6611
7729
|
},
|
6612
7730
|
|
6613
7731
|
/**
|
@@ -6740,7 +7858,7 @@
|
|
6740
7858
|
|
6741
7859
|
};
|
6742
7860
|
|
6743
|
-
// Initialize
|
7861
|
+
// Initialize rangeselector for stock charts
|
6744
7862
|
wrap(Chart.prototype, 'init', function(proceed, options, callback) {
|
6745
7863
|
|
6746
7864
|
addEvent(this, 'init', function() {
|
@@ -6753,6 +7871,103 @@
|
|
6753
7871
|
|
6754
7872
|
});
|
6755
7873
|
|
7874
|
+
wrap(Chart.prototype, 'render', function(proceed, options, callback) {
|
7875
|
+
|
7876
|
+
var chart = this,
|
7877
|
+
rangeSelector = chart.rangeSelector,
|
7878
|
+
verticalAlign;
|
7879
|
+
|
7880
|
+
if (rangeSelector) {
|
7881
|
+
|
7882
|
+
rangeSelector.render();
|
7883
|
+
verticalAlign = rangeSelector.options.verticalAlign;
|
7884
|
+
|
7885
|
+
if (!rangeSelector.options.floating) {
|
7886
|
+
if (verticalAlign === 'bottom') {
|
7887
|
+
this.extraBottomMargin = true;
|
7888
|
+
} else if (verticalAlign !== 'middle') {
|
7889
|
+
this.extraTopMargin = true;
|
7890
|
+
}
|
7891
|
+
}
|
7892
|
+
}
|
7893
|
+
|
7894
|
+
proceed.call(this, options, callback);
|
7895
|
+
|
7896
|
+
});
|
7897
|
+
|
7898
|
+
wrap(Chart.prototype, 'update', function(proceed, options, redraw, oneToOne) {
|
7899
|
+
|
7900
|
+
var chart = this,
|
7901
|
+
rangeSelector = chart.rangeSelector,
|
7902
|
+
verticalAlign;
|
7903
|
+
|
7904
|
+
this.extraBottomMargin = false;
|
7905
|
+
this.extraTopMargin = false;
|
7906
|
+
|
7907
|
+
if (rangeSelector) {
|
7908
|
+
|
7909
|
+
rangeSelector.render();
|
7910
|
+
|
7911
|
+
verticalAlign = (options.rangeSelector && options.rangeSelector.verticalAlign) ||
|
7912
|
+
(rangeSelector.options && rangeSelector.options.verticalAlign);
|
7913
|
+
|
7914
|
+
if (!rangeSelector.options.floating) {
|
7915
|
+
if (verticalAlign === 'bottom') {
|
7916
|
+
this.extraBottomMargin = true;
|
7917
|
+
} else if (verticalAlign !== 'middle') {
|
7918
|
+
this.extraTopMargin = true;
|
7919
|
+
}
|
7920
|
+
}
|
7921
|
+
}
|
7922
|
+
|
7923
|
+
proceed.call(this, H.merge(true, options, {
|
7924
|
+
chart: {
|
7925
|
+
marginBottom: pick(options.chart && options.chart.marginBottom, chart.margin.bottom),
|
7926
|
+
spacingBottom: pick(options.chart && options.chart.spacingBottom, chart.spacing.bottom)
|
7927
|
+
}
|
7928
|
+
}), redraw, oneToOne);
|
7929
|
+
|
7930
|
+
});
|
7931
|
+
|
7932
|
+
wrap(Chart.prototype, 'redraw', function(proceed, options, callback) {
|
7933
|
+
var chart = this,
|
7934
|
+
rangeSelector = chart.rangeSelector,
|
7935
|
+
verticalAlign;
|
7936
|
+
|
7937
|
+
if (rangeSelector && !rangeSelector.options.floating) {
|
7938
|
+
|
7939
|
+
rangeSelector.render();
|
7940
|
+
verticalAlign = rangeSelector.options.verticalAlign;
|
7941
|
+
|
7942
|
+
if (verticalAlign === 'bottom') {
|
7943
|
+
this.extraBottomMargin = true;
|
7944
|
+
} else if (verticalAlign !== 'middle') {
|
7945
|
+
this.extraTopMargin = true;
|
7946
|
+
}
|
7947
|
+
}
|
7948
|
+
|
7949
|
+
proceed.call(this, options, callback);
|
7950
|
+
});
|
7951
|
+
|
7952
|
+
Chart.prototype.adjustPlotArea = function() {
|
7953
|
+
var chart = this,
|
7954
|
+
rangeSelector = chart.rangeSelector,
|
7955
|
+
rangeSelectorHeight;
|
7956
|
+
|
7957
|
+
if (this.rangeSelector) {
|
7958
|
+
|
7959
|
+
rangeSelectorHeight = rangeSelector.getHeight();
|
7960
|
+
|
7961
|
+
if (this.extraTopMargin) {
|
7962
|
+
this.plotTop += rangeSelectorHeight;
|
7963
|
+
}
|
7964
|
+
|
7965
|
+
if (this.extraBottomMargin) {
|
7966
|
+
this.marginBottom += rangeSelectorHeight;
|
7967
|
+
}
|
7968
|
+
}
|
7969
|
+
};
|
7970
|
+
|
6756
7971
|
Chart.prototype.callbacks.push(function(chart) {
|
6757
7972
|
var extremes,
|
6758
7973
|
rangeSelector = chart.rangeSelector,
|
@@ -6796,7 +8011,7 @@
|
|
6796
8011
|
H.RangeSelector = RangeSelector;
|
6797
8012
|
|
6798
8013
|
/* ****************************************************************************
|
6799
|
-
* End Range Selector code
|
8014
|
+
* End Range Selector code *
|
6800
8015
|
*****************************************************************************/
|
6801
8016
|
|
6802
8017
|
}(Highcharts));
|
@@ -6835,6 +8050,53 @@
|
|
6835
8050
|
seriesProcessData = seriesProto.processData,
|
6836
8051
|
pointTooltipFormatter = Point.prototype.tooltipFormatter;
|
6837
8052
|
|
8053
|
+
|
8054
|
+
/**
|
8055
|
+
* Compare the values of the series against the first non-null, non-
|
8056
|
+
* zero value in the visible range. The y axis will show percentage
|
8057
|
+
* or absolute change depending on whether `compare` is set to `"percent"`
|
8058
|
+
* or `"value"`. When this is applied to multiple series, it allows
|
8059
|
+
* comparing the development of the series against each other.
|
8060
|
+
*
|
8061
|
+
* @type {String}
|
8062
|
+
* @see [compareBase](#plotOptions.series.compareBase), [Axis.setCompare()](#Axis.
|
8063
|
+
* setCompare())
|
8064
|
+
* @sample {highstock} stock/plotoptions/series-compare-percent/ Percent
|
8065
|
+
* @sample {highstock} stock/plotoptions/series-compare-value/ Value
|
8066
|
+
* @default undefined
|
8067
|
+
* @since 1.0.1
|
8068
|
+
* @product highstock
|
8069
|
+
* @apioption plotOptions.series.compare
|
8070
|
+
*/
|
8071
|
+
|
8072
|
+
/**
|
8073
|
+
* Defines if comparisson should start from the first point within the visible
|
8074
|
+
* range or should start from the first point <b>before</b> the range.
|
8075
|
+
* In other words, this flag determines if first point within the visible range
|
8076
|
+
* will have 0% (base) or should have been already calculated according to the
|
8077
|
+
* previous point.
|
8078
|
+
*
|
8079
|
+
* @type {Boolean}
|
8080
|
+
* @sample {highstock} stock/plotoptions/series-comparestart/ Calculate compare within visible range
|
8081
|
+
* @default undefined
|
8082
|
+
* @since 6.0.0
|
8083
|
+
* @product highstock
|
8084
|
+
* @apioption plotOptions.series.compareStart
|
8085
|
+
*/
|
8086
|
+
|
8087
|
+
/**
|
8088
|
+
* When [compare](#plotOptions.series.compare) is `percent`, this option
|
8089
|
+
* dictates whether to use 0 or 100 as the base of comparison.
|
8090
|
+
*
|
8091
|
+
* @validvalue [0, 100]
|
8092
|
+
* @type {Number}
|
8093
|
+
* @sample {highstock} / Compare base is 100
|
8094
|
+
* @default 0
|
8095
|
+
* @since 5.0.6
|
8096
|
+
* @product highstock
|
8097
|
+
* @apioption plotOptions.series.compareBase
|
8098
|
+
*/
|
8099
|
+
|
6838
8100
|
/**
|
6839
8101
|
* Factory function for creating new stock charts. Creates a new {@link Chart|
|
6840
8102
|
* Chart} object with different default options than the basic Chart.
|
@@ -6905,6 +8167,7 @@
|
|
6905
8167
|
return merge({ // defaults
|
6906
8168
|
minPadding: 0,
|
6907
8169
|
maxPadding: 0,
|
8170
|
+
overscroll: 0,
|
6908
8171
|
ordinal: true,
|
6909
8172
|
title: {
|
6910
8173
|
text: null
|
@@ -6964,7 +8227,7 @@
|
|
6964
8227
|
text: null
|
6965
8228
|
},
|
6966
8229
|
tooltip: {
|
6967
|
-
|
8230
|
+
split: true,
|
6968
8231
|
crosshairs: true
|
6969
8232
|
},
|
6970
8233
|
legend: {
|
@@ -7049,7 +8312,7 @@
|
|
7049
8312
|
x2,
|
7050
8313
|
y2,
|
7051
8314
|
result = [],
|
7052
|
-
axes = [],
|
8315
|
+
axes = [], // #3416 need a default array
|
7053
8316
|
axes2,
|
7054
8317
|
uniqueAxes,
|
7055
8318
|
transVal;
|
@@ -7102,7 +8365,7 @@
|
|
7102
8365
|
// Remove duplicates in the axes array. If there are no axes in the axes array,
|
7103
8366
|
// we are adding an axis without data, so we need to populate this with grid
|
7104
8367
|
// lines (#2796).
|
7105
|
-
uniqueAxes = axes.length ? [] : [axis.isXAxis ? chart.yAxis[0] : chart.xAxis[0]];
|
8368
|
+
uniqueAxes = axes.length ? [] : [axis.isXAxis ? chart.yAxis[0] : chart.xAxis[0]]; // #3742
|
7106
8369
|
each(axes, function(axis2) {
|
7107
8370
|
if (
|
7108
8371
|
inArray(axis2, uniqueAxes) === -1 &&
|
@@ -7159,7 +8422,7 @@
|
|
7159
8422
|
}
|
7160
8423
|
return result.length > 0 ?
|
7161
8424
|
renderer.crispPolyLine(result, lineWidth || 1) :
|
7162
|
-
null;
|
8425
|
+
null; // #3557 getPlotLinePath in regular Highcharts also returns null
|
7163
8426
|
});
|
7164
8427
|
|
7165
8428
|
// Override getPlotBandPath to allow for multipane charts
|
@@ -7442,6 +8705,7 @@
|
|
7442
8705
|
keyIndex = -1,
|
7443
8706
|
processedXData,
|
7444
8707
|
processedYData,
|
8708
|
+
compareStart = series.options.compareStart === true ? 0 : 1,
|
7445
8709
|
length,
|
7446
8710
|
compareValue;
|
7447
8711
|
|
@@ -7466,11 +8730,15 @@
|
|
7466
8730
|
}
|
7467
8731
|
|
7468
8732
|
// find the first value for comparison
|
7469
|
-
for (i = 0; i < length -
|
8733
|
+
for (i = 0; i < length - compareStart; i++) {
|
7470
8734
|
compareValue = processedYData[i] && keyIndex > -1 ?
|
7471
8735
|
processedYData[i][keyIndex] :
|
7472
8736
|
processedYData[i];
|
7473
|
-
if (
|
8737
|
+
if (
|
8738
|
+
isNumber(compareValue) &&
|
8739
|
+
processedXData[i + compareStart] >= series.xAxis.min &&
|
8740
|
+
compareValue !== 0
|
8741
|
+
) {
|
7474
8742
|
series.compareValue = compareValue;
|
7475
8743
|
break;
|
7476
8744
|
}
|