highcharts-rails 5.0.14 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
}
|