@progress/kendo-charts 1.20.0-dev.202110131408 → 1.20.0-dev.202111190958

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.
@@ -7,10 +7,11 @@ import createAxisTick from './utils/create-axis-tick';
7
7
  import createAxisGridLine from './utils/create-axis-grid-line';
8
8
  import limitCoordinate from './utils/limit-coordinate';
9
9
 
10
- import { DEFAULT_PRECISION, BLACK, X, Y } from '../common/constants';
11
- import { deepExtend, defined, inArray, limitValue, round, setDefaultOptions } from '../common';
10
+ import { DEFAULT_PRECISION, BLACK } from '../common/constants';
11
+ import { deepExtend, defined, inArray, limitValue, round, setDefaultOptions, valueOrDefault } from '../common';
12
12
 
13
13
  var DEFAULT_MAJOR_UNIT = 10;
14
+ var MIN_VALUE_RANGE = 1e-6;
14
15
 
15
16
  var LogarithmicAxis = (function (Axis) {
16
17
  function LogarithmicAxis(seriesMin, seriesMax, options, chartService) {
@@ -59,51 +60,37 @@ var LogarithmicAxis = (function (Axis) {
59
60
  var options = ref.options;
60
61
  var logMin = ref.logMin;
61
62
  var logMax = ref.logMax;
62
- var reverse = options.reverse;
63
- var vertical = options.vertical;
64
63
  var base = options.majorUnit;
65
- var valueAxis = vertical ? Y : X;
66
- var lineBox = this.lineBox();
67
- var lineStart = lineBox[valueAxis + (reverse ? 2 : 1)];
68
- var lineSize = vertical ? lineBox.height() : lineBox.width();
69
- var dir = reverse ? -1 : 1;
70
- var step = dir * (lineSize / (logMax - logMin));
71
- var slotBox = new Box(lineBox.x1, lineBox.y1, lineBox.x1, lineBox.y1);
72
- var start = a;
73
- var end = b;
74
-
75
- if (!defined(start)) {
76
- start = end || 1;
77
- }
78
-
79
- if (!defined(end)) {
80
- end = start || 1;
81
- }
64
+ var min = options.min;
65
+ var max = options.max;
66
+ var ref$1 = this.lineInfo();
67
+ var axis = ref$1.axis;
68
+ var axisDir = ref$1.axisDir;
69
+ var lineBox = ref$1.lineBox;
70
+ var lineSize = ref$1.lineSize;
71
+ var lineStart = ref$1.lineStart;
72
+ var step = axisDir * (lineSize / (logMax - logMin));
73
+ var start = valueOrDefault(a, b || 1);
74
+ var end = valueOrDefault(b, a || 1);
82
75
 
83
76
  if (start <= 0 || end <= 0) {
84
77
  return null;
85
78
  }
86
79
 
87
80
  if (limit) {
88
- start = Math.max(Math.min(start, options.max), options.min);
89
- end = Math.max(Math.min(end, options.max), options.min);
81
+ start = limitValue(start, min, max);
82
+ end = limitValue(end, min, max);
90
83
  }
91
84
 
92
85
  start = log(start, base);
93
86
  end = log(end, base);
94
87
 
95
- var p1, p2;
96
-
97
- if (vertical) {
98
- p1 = logMax - Math.max(start, end);
99
- p2 = logMax - Math.min(start, end);
100
- } else {
101
- p1 = Math.min(start, end) - logMin;
102
- p2 = Math.max(start, end) - logMin;
103
- }
88
+ var p1 = Math.min(start, end) - logMin;
89
+ var p2 = Math.max(start, end) - logMin;
104
90
 
105
- slotBox[valueAxis + 1] = limitCoordinate(lineStart + step * (reverse ? p2 : p1));
106
- slotBox[valueAxis + 2] = limitCoordinate(lineStart + step * (reverse ? p1 : p2));
91
+ var slotBox = new Box(lineBox.x1, lineBox.y1, lineBox.x1, lineBox.y1);
92
+ slotBox[axis + 1] = limitCoordinate(lineStart + step * (axisDir > 0 ? p1 : p2));
93
+ slotBox[axis + 2] = limitCoordinate(lineStart + step * (axisDir > 0 ? p2 : p1));
107
94
 
108
95
  return slotBox;
109
96
  };
@@ -113,17 +100,14 @@ var LogarithmicAxis = (function (Axis) {
113
100
  var options = ref.options;
114
101
  var logMin = ref.logMin;
115
102
  var logMax = ref.logMax;
116
- var reverse = options.reverse;
117
- var vertical = options.vertical;
118
103
  var base = options.majorUnit;
119
- var lineBox = this.lineBox();
120
- var dir = vertical === reverse ? 1 : -1;
121
- var startEdge = dir === 1 ? 1 : 2;
122
- var lineSize = vertical ? lineBox.height() : lineBox.width();
104
+ var ref$1 = this.lineInfo();
105
+ var axis = ref$1.axis;
106
+ var axisDir = ref$1.axisDir;
107
+ var lineStart = ref$1.lineStart;
108
+ var lineSize = ref$1.lineSize;
123
109
  var step = ((logMax - logMin) / lineSize);
124
- var valueAxis = vertical ? Y : X;
125
- var lineStart = lineBox[valueAxis + startEdge];
126
- var offset = dir * (point[valueAxis] - lineStart);
110
+ var offset = axisDir * (point[axis] - lineStart);
127
111
  var valueOffset = offset * step;
128
112
 
129
113
  if (offset < 0 || offset > lineSize) {
@@ -140,16 +124,6 @@ var LogarithmicAxis = (function (Axis) {
140
124
  return { min: options.min, max: options.max };
141
125
  };
142
126
 
143
- LogarithmicAxis.prototype.scaleRange = function scaleRange (delta) {
144
- var base = this.options.majorUnit;
145
- var offset = -delta;
146
-
147
- return {
148
- min: Math.pow(base, this.logMin - offset),
149
- max: Math.pow(base, this.logMax + offset)
150
- };
151
- };
152
-
153
127
  LogarithmicAxis.prototype.translateRange = function translateRange (delta) {
154
128
  var ref = this;
155
129
  var options = ref.options;
@@ -259,7 +233,7 @@ var LogarithmicAxis = (function (Axis) {
259
233
  };
260
234
 
261
235
  LogarithmicAxis.prototype.traverseMajorTicksPositions = function traverseMajorTicksPositions (callback, tickOptions) {
262
- var ref = this._lineOptions();
236
+ var ref = this.lineInfo();
263
237
  var lineStart = ref.lineStart;
264
238
  var step = ref.step;
265
239
  var ref$1 = this;
@@ -280,7 +254,7 @@ var LogarithmicAxis = (function (Axis) {
280
254
  var max = ref.max;
281
255
  var minorUnit = ref.minorUnit;
282
256
  var base = ref.majorUnit;
283
- var ref$1 = this._lineOptions();
257
+ var ref$1 = this.lineInfo();
284
258
  var lineStart = ref$1.lineStart;
285
259
  var step = ref$1.step;
286
260
  var ref$2 = this;
@@ -333,24 +307,37 @@ var LogarithmicAxis = (function (Axis) {
333
307
  };
334
308
  };
335
309
 
336
- LogarithmicAxis.prototype.zoomRange = function zoomRange (delta) {
310
+ LogarithmicAxis.prototype.scaleRange = function scaleRange (scale, cursor) {
311
+ var ref = this.options;
312
+ var base = ref.majorUnit;
313
+ var logMin = log(this.options.min, base);
314
+ var logMax = log(this.options.max, base);
315
+ var position = Math.abs(this.pointOffset(cursor));
316
+ var range = logMax - logMin;
317
+ var delta = this.scaleToDelta(scale, range);
318
+ var min = Math.pow(base, logMin + position * delta);
319
+ var max = Math.pow(base, logMax - (1 - position) * delta);
320
+
321
+ if (max - min < MIN_VALUE_RANGE) {
322
+ max = min + MIN_VALUE_RANGE;
323
+ }
324
+
325
+ return {
326
+ min: min,
327
+ max: max
328
+ };
329
+ };
330
+
331
+ LogarithmicAxis.prototype.zoomRange = function zoomRange (scale, cursor) {
332
+ var range = this.scaleRange(scale, cursor);
337
333
  var ref = this;
338
- var options = ref.options;
339
334
  var totalMin = ref.totalMin;
340
335
  var totalMax = ref.totalMax;
341
- var newRange = this.scaleRange(delta);
342
- var min = limitValue(newRange.min, totalMin, totalMax);
343
- var max = limitValue(newRange.max, totalMin, totalMax);
344
- var base = options.majorUnit;
345
- var acceptOptionsRange = max > min && options.min && options.max && (round(log(options.max, base) - log(options.min, base), DEFAULT_PRECISION) < 1);
346
- var acceptNewRange = !(options.min === totalMin && options.max === totalMax) && round(log(max, base) - log(min, base), DEFAULT_PRECISION) >= 1;
347
-
348
- if (acceptOptionsRange || acceptNewRange) {
349
- return {
350
- min: min,
351
- max: max
352
- };
353
- }
336
+
337
+ return {
338
+ min: limitValue(range.min, totalMin, totalMax),
339
+ max: limitValue(range.max, totalMin, totalMax)
340
+ };
354
341
  };
355
342
 
356
343
  LogarithmicAxis.prototype._minorIntervalOptions = function _minorIntervalOptions (power) {
@@ -368,23 +355,11 @@ var LogarithmicAxis = (function (Axis) {
368
355
  };
369
356
  };
370
357
 
371
- LogarithmicAxis.prototype._lineOptions = function _lineOptions () {
372
- var ref = this.options;
373
- var reverse = ref.reverse;
374
- var vertical = ref.vertical;
375
- var valueAxis = vertical ? Y : X;
376
- var lineBox = this.lineBox();
377
- var dir = vertical === reverse ? 1 : -1;
378
- var startEdge = dir === 1 ? 1 : 2;
379
- var lineSize = vertical ? lineBox.height() : lineBox.width();
380
- var step = dir * (lineSize / (this.logMax - this.logMin));
381
- var lineStart = lineBox[valueAxis + startEdge];
358
+ LogarithmicAxis.prototype.lineInfo = function lineInfo () {
359
+ var info = Axis.prototype.lineInfo.call(this);
360
+ info.step = info.axisDir * (info.lineSize / (this.logMax - this.logMin));
382
361
 
383
- return {
384
- step: step,
385
- lineStart: lineStart,
386
- lineBox: lineBox
387
- };
362
+ return info;
388
363
  };
389
364
 
390
365
  return LogarithmicAxis;
@@ -445,8 +420,8 @@ function throwNegativeValuesError() {
445
420
  throw new Error("Non positive values cannot be used for a logarithmic axis");
446
421
  }
447
422
 
448
- function log(y, x) {
449
- return Math.log(y) / Math.log(x);
423
+ function log(x, base) {
424
+ return Math.log(x) / Math.log(base);
450
425
  }
451
426
 
452
427
  setDefaultOptions(LogarithmicAxis, {
@@ -3,8 +3,8 @@ import Axis from './axis';
3
3
  import AxisLabel from './axis-label';
4
4
  import Box from './box';
5
5
 
6
- import { BLACK, DEFAULT_PRECISION, COORD_PRECISION, X, Y } from '../common/constants';
7
- import { deepExtend, defined, limitValue, round, setDefaultOptions } from '../common';
6
+ import { BLACK, DEFAULT_PRECISION, COORD_PRECISION } from '../common/constants';
7
+ import { deepExtend, defined, limitValue, round, setDefaultOptions, valueOrDefault } from '../common';
8
8
 
9
9
  import autoMajorUnit from './utils/auto-major-unit';
10
10
  import autoAxisMin from './utils/auto-axis-min';
@@ -73,18 +73,17 @@ var NumericAxis = (function (Axis) {
73
73
 
74
74
  NumericAxis.prototype.getTickPositions = function getTickPositions (unit, skipUnit) {
75
75
  var options = this.options;
76
- var vertical = options.vertical;
77
- var reverse = options.reverse;
78
- var lineBox = this.lineBox();
79
- var lineSize = vertical ? lineBox.height() : lineBox.width();
76
+ var ref = this.lineInfo();
77
+ var axisDir = ref.axisDir;
78
+ var axisOrigin = ref.axisOrigin;
79
+ var lineBox = ref.lineBox;
80
+ var lineSize = ref.lineSize;
80
81
  var range = options.max - options.min;
81
82
  var scale = lineSize / range;
82
83
  var step = unit * scale;
83
84
  var divisions = this.getDivisions(unit);
84
- var dir = (vertical ? -1 : 1) * (reverse ? -1 : 1);
85
- var startEdge = dir === 1 ? 1 : 2;
86
85
  var positions = [];
87
- var pos = lineBox[(vertical ? Y : X) + startEdge];
86
+ var pos = lineBox[axisOrigin];
88
87
  var skipStep = 0;
89
88
 
90
89
  if (skipUnit) {
@@ -96,7 +95,7 @@ var NumericAxis = (function (Axis) {
96
95
  positions.push(round(pos, COORD_PRECISION));
97
96
  }
98
97
 
99
- pos = pos + step * dir;
98
+ pos = pos + step * axisDir;
100
99
  }
101
100
 
102
101
  return positions;
@@ -114,71 +113,44 @@ var NumericAxis = (function (Axis) {
114
113
  if ( limit === void 0 ) limit = false;
115
114
 
116
115
  var options = this.options;
117
- var vertical = options.vertical;
118
- var reverse = options.reverse;
119
- var valueAxis = vertical ? Y : X;
120
- var lineBox = this.lineBox();
121
- var lineStart = lineBox[valueAxis + (reverse ? 2 : 1)];
122
- var lineSize = vertical ? lineBox.height() : lineBox.width();
123
- var dir = reverse ? -1 : 1;
124
- var step = dir * (lineSize / (options.max - options.min));
125
- var slotBox = new Box(lineBox.x1, lineBox.y1, lineBox.x1, lineBox.y1);
116
+ var ref = this.lineInfo();
117
+ var axis = ref.axis;
118
+ var axisDir = ref.axisDir;
119
+ var lineBox = ref.lineBox;
120
+ var lineSize = ref.lineSize;
121
+ var lineStart = ref.lineStart;
122
+ var step = axisDir * (lineSize / (options.max - options.min));
126
123
 
127
- var start = a;
128
- var end = b;
129
-
130
- if (!defined(start)) {
131
- start = end || 0;
132
- }
133
-
134
- if (!defined(end)) {
135
- end = start || 0;
136
- }
124
+ var start = valueOrDefault(a, b || 0);
125
+ var end = valueOrDefault(b, a || 0);
137
126
 
138
127
  if (limit) {
139
- start = Math.max(Math.min(start, options.max), options.min);
140
- end = Math.max(Math.min(end, options.max), options.min);
128
+ start = limitValue(start, options.min, options.max);
129
+ end = limitValue(end, options.min, options.max);
141
130
  }
142
131
 
143
- var p1, p2;
132
+ var p1 = Math.min(start, end) - options.min;
133
+ var p2 = Math.max(start, end) - options.min;
144
134
 
145
- if (vertical) {
146
- p1 = options.max - Math.max(start, end);
147
- p2 = options.max - Math.min(start, end);
148
- } else {
149
- p1 = Math.min(start, end) - options.min;
150
- p2 = Math.max(start, end) - options.min;
151
- }
152
-
153
- slotBox[valueAxis + 1] = limitCoordinate(lineStart + step * (reverse ? p2 : p1));
154
- slotBox[valueAxis + 2] = limitCoordinate(lineStart + step * (reverse ? p1 : p2));
135
+ var slotBox = new Box(lineBox.x1, lineBox.y1, lineBox.x1, lineBox.y1);
136
+ slotBox[axis + 1] = limitCoordinate(lineStart + step * (axisDir > 0 ? p1 : p2));
137
+ slotBox[axis + 2] = limitCoordinate(lineStart + step * (axisDir > 0 ? p2 : p1));
155
138
 
156
139
  return slotBox;
157
140
  };
158
141
 
159
142
  NumericAxis.prototype.getValue = function getValue (point) {
160
143
  var options = this.options;
161
- var vertical = options.vertical;
162
- var reverse = options.reverse;
163
144
  var max = Number(options.max);
164
145
  var min = Number(options.min);
165
- var valueAxis = vertical ? Y : X;
166
- var lineBox = this.lineBox();
167
- var lineStart = lineBox[valueAxis + (reverse ? 2 : 1)];
168
- var lineSize = vertical ? lineBox.height() : lineBox.width();
169
- var dir = reverse ? -1 : 1;
170
- var offset = dir * (point[valueAxis] - lineStart);
171
- var step = (max - min) / lineSize;
172
- var valueOffset = offset * step;
173
-
174
- if (offset < 0 || offset > lineSize) {
146
+ var offset = this.pointOffset(point);
147
+ var valueOffset = offset * (max - min);
148
+
149
+ if (offset < 0 || offset > 1) {
175
150
  return null;
176
151
  }
177
152
 
178
- var value = vertical ?
179
- max - valueOffset :
180
- min + valueOffset;
181
-
153
+ var value = min + valueOffset;
182
154
  return round(value, DEFAULT_PRECISION);
183
155
  };
184
156
 
@@ -188,10 +160,10 @@ var NumericAxis = (function (Axis) {
188
160
  var reverse = options.reverse;
189
161
  var max = options.max;
190
162
  var min = options.min;
191
- var lineBox = this.lineBox();
192
- var size = vertical ? lineBox.height() : lineBox.width();
163
+ var ref = this.lineInfo();
164
+ var lineSize = ref.lineSize;
193
165
  var range = max - min;
194
- var scale = size / range;
166
+ var scale = lineSize / range;
195
167
  var offset = round(delta / scale, DEFAULT_PRECISION);
196
168
 
197
169
  if ((vertical || reverse) && !(vertical && reverse )) {
@@ -205,16 +177,6 @@ var NumericAxis = (function (Axis) {
205
177
  };
206
178
  };
207
179
 
208
- NumericAxis.prototype.scaleRange = function scaleRange (delta) {
209
- var options = this.options;
210
- var offset = -delta * options.majorUnit;
211
-
212
- return {
213
- min: options.min - offset,
214
- max: options.max + offset
215
- };
216
- };
217
-
218
180
  NumericAxis.prototype.labelsCount = function labelsCount () {
219
181
  return this.getDivisions(this.options.majorUnit);
220
182
  };
@@ -251,20 +213,35 @@ var NumericAxis = (function (Axis) {
251
213
  }
252
214
  };
253
215
 
254
- NumericAxis.prototype.zoomRange = function zoomRange (delta) {
216
+ NumericAxis.prototype.scaleRange = function scaleRange (scale, cursor) {
217
+ var position = Math.abs(this.pointOffset(cursor));
218
+ var range = this.options.max - this.options.min;
219
+ var delta = this.scaleToDelta(scale, range);
220
+ var minDelta = position * delta;
221
+ var maxDelta = (1 - position) * delta;
222
+ var min = round(this.options.min + minDelta, DEFAULT_PRECISION);
223
+ var max = round(this.options.max - maxDelta, DEFAULT_PRECISION);
224
+
225
+ if (max - min < MIN_VALUE_RANGE) {
226
+ max = min + MIN_VALUE_RANGE;
227
+ }
228
+
229
+ return {
230
+ min: min,
231
+ max: max
232
+ };
233
+ };
234
+
235
+ NumericAxis.prototype.zoomRange = function zoomRange (scale, cursor) {
255
236
  var ref = this;
256
237
  var totalMin = ref.totalMin;
257
238
  var totalMax = ref.totalMax;
258
- var newRange = this.scaleRange(delta);
259
- var min = limitValue(newRange.min, totalMin, totalMax);
260
- var max = limitValue(newRange.max, totalMin, totalMax);
239
+ var range = this.scaleRange(scale, cursor);
261
240
 
262
- if (this.isValidRange(min, max)) {
263
- return {
264
- min: min,
265
- max: max
266
- };
267
- }
241
+ return {
242
+ min: limitValue(range.min, totalMin, totalMax),
243
+ max: limitValue(range.max, totalMin, totalMax)
244
+ };
268
245
  };
269
246
 
270
247
  NumericAxis.prototype.isValidRange = function isValidRange (min, max) {
@@ -286,6 +286,7 @@ var Navigator = (function (Class) {
286
286
 
287
287
  var fromIx = mainAxis.categoryIndex(selection.options.from);
288
288
  var toIx = mainAxis.categoryIndex(selection.options.to);
289
+ var coords = this.chart._eventCoordinates(e.originalEvent);
289
290
 
290
291
  e.originalEvent.preventDefault();
291
292
 
@@ -294,11 +295,11 @@ var Navigator = (function (Class) {
294
295
  }
295
296
 
296
297
  if (toIx - fromIx > 1) {
297
- selection.expand(delta);
298
+ selection.zoom(delta, coords);
298
299
  this.readSelection();
299
300
  } else {
300
301
  axis.options.min = select.from;
301
- select.from = axis.scaleRange(-e.delta).min;
302
+ select.from = axis.scaleRange(-e.delta * this.chart._mousewheelZoomRate(), coords).min;
302
303
  }
303
304
 
304
305
  if (liveDrag) {
@@ -22,12 +22,13 @@ import { ChartPane, ChartPlotArea, findAxisByName } from './api-elements';
22
22
 
23
23
  import { X, Y, VALUE, DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_SERIES_OPACITY } from '../common/constants';
24
24
  import { addClass, Class, setDefaultOptions, deepExtend, defined, find, isObject, isFunction, elementSize, elementOffset,
25
- elementScale, elementStyles, eventCoordinates, bindEvents, unbindEvents, mousewheelDelta, FontLoader, inArray, last, round, HashMap } from '../common';
25
+ elementScale, elementStyles, eventCoordinates, bindEvents, unbindEvents, mousewheelDelta, FontLoader, inArray, last, round,
26
+ HashMap, valueOrDefault } from '../common';
26
27
 
27
28
  import { dateComparer } from '../date-utils';
28
29
 
29
30
  import { DRAG_START, DRAG, DRAG_END, ZOOM_START, ZOOM, ZOOM_END, SELECT_START, SELECT, SELECT_END, PLOT_AREA_HOVER, PLOT_AREA_LEAVE,
30
- RENDER, CATEGORY, PIE, DONUT, FUNNEL, COLUMN, MOUSEWHEEL, MOUSEWHEEL_DELAY, SHOW_TOOLTIP, SERIES_HOVER } from './constants';
31
+ RENDER, CATEGORY, PIE, DONUT, FUNNEL, COLUMN, MOUSEWHEEL, MOUSEWHEEL_DELAY, MOUSEWHEEL_ZOOM_RATE, SHOW_TOOLTIP, SERIES_HOVER } from './constants';
31
32
 
32
33
  import './animations';
33
34
  import './register-charts';
@@ -651,12 +652,13 @@ class Chart extends Class {
651
652
  this._gestureDistance = e.distance;
652
653
  const args = { delta: scaleDelta, axisRanges: axisRanges(this._plotArea.axes), originalEvent: e };
653
654
  if (this._zooming || !this.trigger(ZOOM_START, args)) {
655
+ const coords = this._eventCoordinates(e);
654
656
 
655
657
  if (!this._zooming) {
656
658
  this._zooming = true;
657
659
  }
658
660
 
659
- const ranges = args.axisRanges = mousewheelZoom.updateRanges(scaleDelta);
661
+ const ranges = args.axisRanges = mousewheelZoom.updateRanges(scaleDelta, coords);
660
662
  if (ranges && !this.trigger(ZOOM, args)) {
661
663
  mousewheelZoom.zoom();
662
664
  }
@@ -787,6 +789,12 @@ class Chart extends Class {
787
789
  }
788
790
  }
789
791
 
792
+ _mousewheelZoomRate() {
793
+ const zoomable = this.options.zoomable;
794
+ const mousewheel = (zoomable || {}).mousewheel || {};
795
+ return valueOrDefault(mousewheel.rate, MOUSEWHEEL_ZOOM_RATE);
796
+ }
797
+
790
798
  _mousewheel(e) {
791
799
  const delta = mousewheelDelta(e);
792
800
  const mousewheelZoom = this._mousewheelZoom;
@@ -811,7 +819,7 @@ class Chart extends Class {
811
819
  clearTimeout(this._mwTimeout);
812
820
  }
813
821
 
814
- args.axisRanges = mousewheelZoom.updateRanges(delta);
822
+ args.axisRanges = mousewheelZoom.updateRanges(delta, coords);
815
823
  if (args.axisRanges && !this.trigger(ZOOM, args)) {
816
824
  mousewheelZoom.zoom();
817
825
  }
@@ -844,7 +852,7 @@ class Chart extends Class {
844
852
  const currentAxis = axes[i];
845
853
  const axisName = currentAxis.options.name;
846
854
  if (axisName) {
847
- ranges[axisName] = currentAxis.scaleRange(-totalDelta);
855
+ ranges[axisName] = currentAxis.scaleRange(-totalDelta * this._mousewheelZoomRate(), coords);
848
856
  }
849
857
  }
850
858
 
@@ -1156,8 +1164,9 @@ class Chart extends Class {
1156
1164
  for (let i = 0; i < elements.length; i++) {
1157
1165
  const element = elements[i];
1158
1166
  const currSeries = element.series || series;
1167
+ const shouldHighlight = currSeries && (currSeries.highlight || {}).visible;
1159
1168
 
1160
- if (currSeries && element.visual) {
1169
+ if (shouldHighlight && element.visual) {
1161
1170
  const opacity = series ? series.opacity : element.series.opacity;
1162
1171
  if (currSeries !== activeSeries || reset) {
1163
1172
  element.visual.opacity(reset ? 1 : opacity);
@@ -94,6 +94,7 @@ const OUTSIDE_END = "outsideEnd";
94
94
 
95
95
  const MOUSEWHEEL = "DOMMouseScroll mousewheel";
96
96
  const MOUSEWHEEL_DELAY = 150;
97
+ const MOUSEWHEEL_ZOOM_RATE = 0.3;
97
98
 
98
99
  export {
99
100
  INITIAL_ANIMATION_DURATION, FADEIN,
@@ -115,7 +116,8 @@ export {
115
116
  LOGARITHMIC, DRAG, DRAG_START, DRAG_END, ZOOM_START, ZOOM, ZOOM_END,
116
117
  SELECT_START, SELECT, SELECT_END, PANE_RENDER, GAP,
117
118
  DONUT, INSIDE_END, INSIDE_BASE, OUTSIDE_END,
118
- MOUSEWHEEL, MOUSEWHEEL_DELAY, SHOW_TOOLTIP, HIDE_TOOLTIP,
119
+ MOUSEWHEEL, MOUSEWHEEL_DELAY, MOUSEWHEEL_ZOOM_RATE,
120
+ SHOW_TOOLTIP, HIDE_TOOLTIP,
119
121
  EQUALLY_SPACED_SERIES, ABOVE, BELOW,
120
122
  HEATMAP
121
123
  };
@@ -3,16 +3,25 @@ import toChartAxisRanges from './to-chart-axis-ranges';
3
3
 
4
4
  import { X, Y } from '../../common/constants';
5
5
  import { Class, deepExtend } from '../../common';
6
+ import { limitValue } from '../../drawing-utils';
7
+
8
+ // Limit the zoom rate between 1% and 90% per mousewheel event.
9
+ // At zoom rates close to 100% the axis range quickly becomes 0.
10
+ const MIN_RATE = 0.01;
11
+ const MAX_RATE = 0.9;
12
+ const DEFAULT_RATE = 0.3;
6
13
 
7
14
  class MousewheelZoom extends Class {
8
15
  constructor(chart, options) {
9
16
  super();
10
17
 
11
18
  this.chart = chart;
12
- this.options = deepExtend({}, this.options, options);
19
+ this.options = deepExtend({
20
+ rate: DEFAULT_RATE
21
+ }, this.options, options);
13
22
  }
14
23
 
15
- updateRanges(delta) {
24
+ updateRanges(delta, coords) {
16
25
  const lock = (this.options.lock || "").toLowerCase();
17
26
  const axisRanges = [];
18
27
  const axes = this.chart._plotArea.axes;
@@ -22,7 +31,8 @@ class MousewheelZoom extends Class {
22
31
  const vertical = axis.options.vertical;
23
32
 
24
33
  if (!(lock === X && !vertical) && !(lock === Y && vertical) && axis.zoomRange) {
25
- const range = axis.zoomRange(-delta);
34
+ const rate = limitValue(this.options.rate, MIN_RATE, MAX_RATE);
35
+ const range = axis.zoomRange(-delta * rate, coords);
26
36
 
27
37
  if (range) {
28
38
  axisRanges.push({
@@ -55,4 +65,4 @@ class MousewheelZoom extends Class {
55
65
  }
56
66
  }
57
67
 
58
- export default MousewheelZoom;
68
+ export default MousewheelZoom;
@@ -4,7 +4,7 @@ import { DateCategoryAxis, Point } from '../core';
4
4
 
5
5
  import { MOUSEWHEEL_DELAY, MOUSEWHEEL, SELECT_START, SELECT, SELECT_END } from './constants';
6
6
 
7
- import { LEFT, RIGHT, MIN_VALUE, MAX_VALUE } from '../common/constants';
7
+ import { LEFT, RIGHT, MIN_VALUE, MAX_VALUE, X } from '../common/constants';
8
8
  import { addClass, Class, removeClass, deepExtend, elementStyles, eventElement, setDefaultOptions, limitValue, round, bindEvents, unbindEvents, mousewheelDelta, hasClasses } from '../common';
9
9
  import { parseDate } from '../date-utils';
10
10
 
@@ -542,6 +542,45 @@ class Selection extends Class {
542
542
  }
543
543
  }
544
544
 
545
+ zoom(delta, coords) {
546
+ const options = this.options;
547
+ const min = this._index(options.min);
548
+ const max = this._index(options.max);
549
+ const from = this._index(options.from);
550
+ const to = this._index(options.to);
551
+ let range = { from: from, to: to };
552
+ const oldRange = deepExtend({}, range);
553
+
554
+ const { reverse } = this.categoryAxis.options;
555
+ const origin = X + (reverse ? '2' : '1');
556
+ const lineBox = this.categoryAxis.lineBox();
557
+ const relative = Math.abs(lineBox[origin] - coords[X]);
558
+ const size = lineBox.width();
559
+ const position = round(relative / size, 2);
560
+ const minDelta = round(position * delta);
561
+ const maxDelta = round((1 - position) * delta);
562
+
563
+ if (this._state) {
564
+ range = this._state.range;
565
+ }
566
+
567
+ range.from = limitValue(
568
+ limitValue(from - minDelta, 0, to - 1),
569
+ min, max
570
+ );
571
+
572
+ range.to = limitValue(
573
+ limitValue(to + maxDelta, range.from + 1, max),
574
+ min,
575
+ max
576
+ );
577
+
578
+ if (range.from !== oldRange.from || range.to !== oldRange.to) {
579
+ this.set(range.from, range.to);
580
+ return true;
581
+ }
582
+ }
583
+
545
584
  trigger(name, args) {
546
585
  return (this.observer || this.chart).trigger(name, args);
547
586
  }