@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.
@@ -1,16 +1,13 @@
1
- import { drawing } from '@progress/kendo-drawing';
2
-
3
1
  export default function mousewheelDelta(e) {
4
2
  let delta = 0;
5
3
 
6
4
  if (e.wheelDelta) {
7
5
  delta = -e.wheelDelta / 120;
8
- delta = delta > 0 ? Math.ceil(delta) : Math.floor(delta);
6
+ } else if (e.detail) {
7
+ delta = e.detail / 3;
9
8
  }
10
9
 
11
- if (e.detail) {
12
- delta = drawing.util.round(e.detail / 3);
13
- }
10
+ delta = delta > 0 ? Math.ceil(delta) : Math.floor(delta);
14
11
 
15
12
  return delta;
16
- }
13
+ }
@@ -818,6 +818,65 @@ class Axis extends ChartElement {
818
818
  };
819
819
  }
820
820
 
821
+ lineDir() {
822
+ /*
823
+ * Axis line direction:
824
+ * * Vertical: up.
825
+ * * Horizontal: right.
826
+ */
827
+
828
+ const { vertical, reverse } = this.options;
829
+ return (vertical ? -1 : 1) * (reverse ? -1 : 1);
830
+ }
831
+
832
+ lineInfo() {
833
+ const { vertical } = this.options;
834
+ const lineBox = this.lineBox();
835
+ const lineSize = vertical ? lineBox.height() : lineBox.width();
836
+ const axis = vertical ? Y : X;
837
+ const axisDir = this.lineDir();
838
+ const startEdge = axisDir === 1 ? 1 : 2;
839
+ const axisOrigin = axis + startEdge.toString();
840
+ const lineStart = lineBox[axisOrigin];
841
+
842
+ return {
843
+ axis,
844
+ axisOrigin,
845
+ axisDir,
846
+ lineBox,
847
+ lineSize,
848
+ lineStart
849
+ };
850
+ }
851
+
852
+ pointOffset(point) {
853
+ const { axis, axisDir, axisOrigin, lineBox, lineSize } = this.lineInfo();
854
+ const relative = axisDir > 0 ? point[axis] - lineBox[axisOrigin] : lineBox[axisOrigin] - point[axis];
855
+ const offset = relative / lineSize;
856
+
857
+ return offset;
858
+ }
859
+
860
+ // Computes the axis range change (delta) for a given scale factor.
861
+ // The delta is subtracted from the axis range:
862
+ // * delta > 0 reduces the axis range (zoom-in)
863
+ // * delta < 0 expands the axis range (zoom-out)
864
+ scaleToDelta(rawScale, range) {
865
+ // Scale >= 1 would result in axis range of 0.
866
+ // Scale <= -1 would reverse the scale direction.
867
+ const MAX_SCALE = 0.999;
868
+ const scale = limitValue(rawScale, -MAX_SCALE, MAX_SCALE);
869
+
870
+ let delta;
871
+ if (scale > 0) {
872
+ delta = range * Math.min(1, scale);
873
+ } else {
874
+ delta = range - (range / (1 + scale));
875
+ }
876
+
877
+ return delta;
878
+ }
879
+
821
880
  labelsBetweenTicks() {
822
881
  return !this.options.justified;
823
882
  }
@@ -6,6 +6,7 @@ import { defined, isNumber, last, limitValue, round, setDefaultOptions, valueOrD
6
6
  import { dateEquals } from '../date-utils';
7
7
 
8
8
  const MIN_CATEGORY_POINTS_RANGE = 0.01;
9
+ const MIN_CATEGORY_RANGE = 0.1;
9
10
 
10
11
  function indexOf(value, arr) {
11
12
  if (value instanceof Date) {
@@ -244,13 +245,44 @@ class CategoryAxis extends Axis {
244
245
  return positions.slice(startIndex, endIndex + 1);
245
246
  }
246
247
 
248
+ lineInfo() {
249
+ const { vertical, reverse } = this.options;
250
+ const lineBox = this.lineBox();
251
+ const lineSize = vertical ? lineBox.height() : lineBox.width();
252
+ const axis = vertical ? Y : X;
253
+ const axisDir = reverse ? -1 : 1;
254
+ const startEdge = axisDir === 1 ? 1 : 2;
255
+ const axisOrigin = axis + startEdge.toString();
256
+ const lineStart = lineBox[axisOrigin];
257
+
258
+ return {
259
+ axis,
260
+ axisOrigin,
261
+ axisDir,
262
+ lineBox,
263
+ lineSize,
264
+ lineStart
265
+ };
266
+ }
267
+
268
+ lineDir() {
269
+ /*
270
+ * Category axis line direction:
271
+ * * Vertical: down.
272
+ * * Horizontal: right.
273
+ */
274
+
275
+ const { reverse } = this.options;
276
+ return reverse ? -1 : 1;
277
+ }
278
+
247
279
  // TODO: Rename to slotBox, valueSlot, slotByIndex?
248
280
  getSlot(from, to, limit) {
249
281
  const options = this.options;
250
- const { reverse, justified, vertical } = options;
282
+ const { reverse, justified } = options;
251
283
  const { scale, box, min } = this.scaleOptions();
252
- const valueAxis = vertical ? Y : X;
253
- const lineStart = box[valueAxis + (reverse ? 2 : 1)];
284
+ const { axis: valueAxis, lineStart } = this.lineInfo();
285
+
254
286
  const slotBox = box.clone();
255
287
  const singleSlot = !defined(to);
256
288
 
@@ -375,27 +407,33 @@ class CategoryAxis extends Axis {
375
407
  };
376
408
  }
377
409
 
378
- zoomRange(rate) {
410
+ scaleRange(scale, cursor) {
411
+ const position = Math.abs(this.pointOffset(cursor));
379
412
  const rangeIndices = this.totalRangeIndices();
380
- const { min: totalMin, max: totalMax } = this.totalRange();
381
- const min = limitValue(rangeIndices.min + rate, totalMin, totalMax);
382
- const max = limitValue(rangeIndices.max - rate, totalMin, totalMax);
383
-
384
- if (max - min > 0) {
385
- return {
386
- min: min,
387
- max: max
388
- };
413
+ const range = rangeIndices.max - rangeIndices.min;
414
+ const delta = this.scaleToDelta(scale, range);
415
+ const minDelta = position * delta;
416
+ const maxDelta = (1 - position) * delta;
417
+ const min = rangeIndices.min + minDelta;
418
+ let max = rangeIndices.max - maxDelta;
419
+
420
+ if (max - min < MIN_CATEGORY_RANGE) {
421
+ max = min + MIN_CATEGORY_RANGE;
389
422
  }
423
+
424
+ return {
425
+ min: min,
426
+ max: max
427
+ };
390
428
  }
391
429
 
392
- scaleRange(scale) {
393
- const range = this.options.categories.length;
394
- const delta = scale * range;
430
+ zoomRange(scale, cursor) {
431
+ const { min: totalMin, max: totalMax } = this.totalRange();
432
+ const range = this.scaleRange(scale, cursor);
395
433
 
396
434
  return {
397
- min: -delta,
398
- max: range + delta
435
+ min: limitValue(range.min, totalMin, totalMax),
436
+ max: limitValue(range.max, totalMin, totalMax)
399
437
  };
400
438
  }
401
439
 
@@ -459,30 +459,6 @@ class DateCategoryAxis extends CategoryAxis {
459
459
  return range;
460
460
  }
461
461
 
462
- scaleRange(delta) {
463
- let rounds = Math.abs(delta);
464
- let result = this.range();
465
- let { min: from, max: to } = result;
466
-
467
- if (from && to) {
468
- while (rounds--) {
469
- const range = dateDiff(from, to);
470
- const step = Math.round(range * 0.1);
471
- if (delta < 0) {
472
- from = addTicks(from, step);
473
- to = addTicks(to, -step);
474
- } else {
475
- from = addTicks(from, -step);
476
- to = addTicks(to, step);
477
- }
478
- }
479
-
480
- result = { min: from, max: to };
481
- }
482
-
483
- return result;
484
- }
485
-
486
462
  labelsRange() {
487
463
  return {
488
464
  min: this.options.labels.skip,
@@ -541,18 +517,25 @@ class DateCategoryAxis extends CategoryAxis {
541
517
  };
542
518
  }
543
519
 
544
- zoomRange(delta) {
520
+ scaleRange(scale, cursor) {
545
521
  if (this.isEmpty()) {
546
- return null;
522
+ return {};
547
523
  }
548
524
 
549
525
  const options = this.options;
550
526
  const fit = options.userSetBaseUnit === FIT;
551
527
  const totalLimits = this.dataRange.total();
552
528
  const { min: rangeMin, max: rangeMax } = this.dataRange.displayRange();
553
- let { weekStartDay, baseUnit, baseUnitStep } = this.dataRange.options;
554
- let min = addDuration(rangeMin, delta * baseUnitStep, baseUnit, weekStartDay);
555
- let max = addDuration(rangeMax, -delta * baseUnitStep, baseUnit, weekStartDay);
529
+
530
+ const position = Math.abs(this.pointOffset(cursor));
531
+ const range = rangeMax - rangeMin;
532
+ const delta = this.scaleToDelta(scale, range);
533
+ const minDelta = Math.round(position * delta);
534
+ const maxDelta = Math.round((1 - position) * delta);
535
+
536
+ let { baseUnit } = this.dataRange.options;
537
+ let min = new Date(rangeMin.getTime() + minDelta);
538
+ let max = new Date(rangeMax.getTime() - maxDelta);
556
539
 
557
540
  if (fit) {
558
541
  const { autoBaseUnitSteps, maxDateGroups } = options;
@@ -594,13 +577,6 @@ class DateCategoryAxis extends CategoryAxis {
594
577
  }
595
578
  }
596
579
 
597
- if (min < totalLimits.min) {
598
- min = totalLimits.min;
599
- }
600
- if (max > totalLimits.max) {
601
- max = totalLimits.max;
602
- }
603
-
604
580
  if (min && max && dateDiff(max, min) > 0) {
605
581
  return {
606
582
  min: min,
@@ -611,6 +587,22 @@ class DateCategoryAxis extends CategoryAxis {
611
587
  }
612
588
  }
613
589
 
590
+ zoomRange(scale, cursor) {
591
+ const totalLimits = this.dataRange.total();
592
+ const range = this.scaleRange(scale, cursor);
593
+
594
+ if (range) {
595
+ if (range.min < totalLimits.min) {
596
+ range.min = totalLimits.min;
597
+ }
598
+ if (range.max > totalLimits.max) {
599
+ range.max = totalLimits.max;
600
+ }
601
+ }
602
+
603
+ return range;
604
+ }
605
+
614
606
  range() {
615
607
  return this.dataRange.displayRange();
616
608
  }
@@ -3,7 +3,7 @@ import NumericAxis from './numeric-axis';
3
3
  import AxisLabel from './axis-label';
4
4
  import { DateLabelFormats } from './constants';
5
5
 
6
- import { BLACK, DATE, COORD_PRECISION, DEFAULT_PRECISION, X, Y } from '../common/constants';
6
+ import { BLACK, DATE, COORD_PRECISION, DEFAULT_PRECISION } from '../common/constants';
7
7
  import { setDefaultOptions, deepExtend, limitValue, round } from '../common';
8
8
 
9
9
  import autoMajorUnit from './utils/auto-major-unit';
@@ -12,6 +12,8 @@ import ceil from './utils/ceil';
12
12
  import { toDate, toTime, floorDate, ceilDate, duration, addDuration, addTicks, dateDiff, absoluteDateDiff, dateComparer, parseDate, parseDates, firstDay } from '../date-utils';
13
13
  import { HOURS, DAYS, WEEKS, MONTHS, YEARS, TIME_PER_DAY, TIME_PER_WEEK, TIME_PER_MONTH, TIME_PER_YEAR, TIME_PER_UNIT } from '../date-utils/constants';
14
14
 
15
+ const MIN_VALUE_RANGE = 1000;
16
+
15
17
  class DateValueAxis extends Axis {
16
18
  constructor(seriesMin, seriesMax, axisOptions, chartService) {
17
19
  const min = toDate(seriesMin);
@@ -57,14 +59,9 @@ class DateValueAxis extends Axis {
57
59
 
58
60
  getTickPositions(step) {
59
61
  const options = this.options;
60
- const vertical = options.vertical;
61
- const lineBox = this.lineBox();
62
- const dir = (vertical ? -1 : 1) * (options.reverse ? -1 : 1);
63
- const startEdge = dir === 1 ? 1 : 2;
64
- const start = lineBox[(vertical ? Y : X) + startEdge];
62
+ const { axisDir: dir, lineSize, lineStart: start } = this.lineInfo();
65
63
  const divisions = this.getDivisions(step);
66
64
  const timeRange = dateDiff(options.max, options.min);
67
- const lineSize = vertical ? lineBox.height() : lineBox.width();
68
65
  const scale = lineSize / timeRange;
69
66
  const weekStartDay = options.weekStartDay || 0;
70
67
 
@@ -120,23 +117,22 @@ class DateValueAxis extends Axis {
120
117
  return new AxisLabel(date, text, index, null, labelOptions);
121
118
  }
122
119
 
123
- translateRange(delta, exact) {
120
+ translateRange(delta) {
124
121
  const options = this.options;
125
- const baseUnit = options.baseUnit;
126
- const weekStartDay = options.weekStartDay || 0;
127
122
  const lineBox = this.lineBox();
128
- const size = options.vertical ? lineBox.height() : lineBox.width();
123
+ const { vertical, reverse } = options;
124
+ const size = vertical ? lineBox.height() : lineBox.width();
129
125
  const range = this.range();
130
126
  const scale = size / dateDiff(range.max, range.min);
131
- const offset = round(delta / scale, DEFAULT_PRECISION) * (options.reverse ? -1 : 1);
132
- let from = addTicks(options.min, offset);
133
- let to = addTicks(options.max, offset);
134
127
 
135
- if (!exact) {
136
- from = addDuration(from, 0, baseUnit, weekStartDay);
137
- to = addDuration(to, 0, baseUnit, weekStartDay);
128
+ let offset = round(delta / scale, DEFAULT_PRECISION);
129
+ if ((vertical || reverse) && !(vertical && reverse )) {
130
+ offset = -offset;
138
131
  }
139
132
 
133
+ let from = addTicks(options.min, offset);
134
+ let to = addTicks(options.max, offset);
135
+
140
136
  return {
141
137
  min: from,
142
138
  max: to,
@@ -144,25 +140,6 @@ class DateValueAxis extends Axis {
144
140
  };
145
141
  }
146
142
 
147
- scaleRange(delta) {
148
- let { min: from, max: to } = this.options;
149
- let rounds = Math.abs(delta);
150
-
151
- while (rounds--) {
152
- const range = dateDiff(from, to);
153
- const step = Math.round(range * 0.1);
154
- if (delta < 0) {
155
- from = addTicks(from, step);
156
- to = addTicks(to, -step);
157
- } else {
158
- from = addTicks(from, -step);
159
- to = addTicks(to, step);
160
- }
161
- }
162
-
163
- return { min: from, max: to };
164
- }
165
-
166
143
  shouldRenderNote(value) {
167
144
  const range = this.range();
168
145
 
@@ -193,16 +170,35 @@ class DateValueAxis extends Axis {
193
170
  };
194
171
  }
195
172
 
196
- zoomRange(delta) {
197
- const range = this.scaleRange(delta);
198
- const min = toDate(limitValue(toTime(range.min), this.totalMin, this.totalMax));
199
- const max = toDate(limitValue(toTime(range.max), this.totalMin, this.totalMax));
173
+ scaleRange(scale, cursor) {
174
+ const position = Math.abs(this.pointOffset(cursor));
175
+ const range = this.options.max - this.options.min;
176
+ const delta = this.scaleToDelta(scale, range);
177
+ const minDelta = position * delta;
178
+ const maxDelta = (1 - position) * delta;
179
+ const min = toDate(toTime(this.options.min) + minDelta);
180
+ let max = toDate(toTime(this.options.max) - maxDelta);
181
+
182
+ if (max - min < MIN_VALUE_RANGE) {
183
+ max = toDate(toTime(min) + MIN_VALUE_RANGE);
184
+ }
200
185
 
201
186
  return {
202
187
  min: min,
203
188
  max: max
204
189
  };
205
190
  }
191
+
192
+ zoomRange(scale, cursor) {
193
+ const range = this.scaleRange(scale, cursor);
194
+ const min = toDate(limitValue(toTime(range.min), this.totalMin, this.totalMax));
195
+ const max = toDate(limitValue(toTime(range.max), this.totalMin, this.totalMax));
196
+
197
+ return {
198
+ min,
199
+ max
200
+ };
201
+ }
206
202
  }
207
203
 
208
204
  function timeUnits(delta) {
@@ -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
  const DEFAULT_MAJOR_UNIT = 10;
14
+ const MIN_VALUE_RANGE = 1e-6;
14
15
 
15
16
  class LogarithmicAxis extends Axis {
16
17
  constructor(seriesMin, seriesMax, options, chartService) {
@@ -52,64 +53,40 @@ class LogarithmicAxis extends Axis {
52
53
 
53
54
  getSlot(a, b, limit) {
54
55
  const { options, logMin, logMax } = this;
55
- const { reverse, vertical, majorUnit: base } = options;
56
- const valueAxis = vertical ? Y : X;
57
- const lineBox = this.lineBox();
58
- const lineStart = lineBox[valueAxis + (reverse ? 2 : 1)];
59
- const lineSize = vertical ? lineBox.height() : lineBox.width();
60
- const dir = reverse ? -1 : 1;
61
- const step = dir * (lineSize / (logMax - logMin));
62
- const slotBox = new Box(lineBox.x1, lineBox.y1, lineBox.x1, lineBox.y1);
63
- let start = a;
64
- let end = b;
65
-
66
- if (!defined(start)) {
67
- start = end || 1;
68
- }
69
-
70
- if (!defined(end)) {
71
- end = start || 1;
72
- }
56
+ const { majorUnit: base, min, max } = options;
57
+ const { axis, axisDir, lineBox, lineSize, lineStart } = this.lineInfo();
58
+ const step = axisDir * (lineSize / (logMax - logMin));
59
+ let start = valueOrDefault(a, b || 1);
60
+ let end = valueOrDefault(b, a || 1);
73
61
 
74
62
  if (start <= 0 || end <= 0) {
75
63
  return null;
76
64
  }
77
65
 
78
66
  if (limit) {
79
- start = Math.max(Math.min(start, options.max), options.min);
80
- end = Math.max(Math.min(end, options.max), options.min);
67
+ start = limitValue(start, min, max);
68
+ end = limitValue(end, min, max);
81
69
  }
82
70
 
83
71
  start = log(start, base);
84
72
  end = log(end, base);
85
73
 
86
- let p1, p2;
74
+ const p1 = Math.min(start, end) - logMin;
75
+ const p2 = Math.max(start, end) - logMin;
87
76
 
88
- if (vertical) {
89
- p1 = logMax - Math.max(start, end);
90
- p2 = logMax - Math.min(start, end);
91
- } else {
92
- p1 = Math.min(start, end) - logMin;
93
- p2 = Math.max(start, end) - logMin;
94
- }
95
-
96
- slotBox[valueAxis + 1] = limitCoordinate(lineStart + step * (reverse ? p2 : p1));
97
- slotBox[valueAxis + 2] = limitCoordinate(lineStart + step * (reverse ? p1 : p2));
77
+ const slotBox = new Box(lineBox.x1, lineBox.y1, lineBox.x1, lineBox.y1);
78
+ slotBox[axis + 1] = limitCoordinate(lineStart + step * (axisDir > 0 ? p1 : p2));
79
+ slotBox[axis + 2] = limitCoordinate(lineStart + step * (axisDir > 0 ? p2 : p1));
98
80
 
99
81
  return slotBox;
100
82
  }
101
83
 
102
84
  getValue(point) {
103
85
  const { options, logMin, logMax } = this;
104
- const { reverse, vertical, majorUnit: base } = options;
105
- const lineBox = this.lineBox();
106
- const dir = vertical === reverse ? 1 : -1;
107
- const startEdge = dir === 1 ? 1 : 2;
108
- const lineSize = vertical ? lineBox.height() : lineBox.width();
86
+ const { majorUnit: base } = options;
87
+ const { axis, axisDir, lineStart, lineSize } = this.lineInfo();
109
88
  const step = ((logMax - logMin) / lineSize);
110
- const valueAxis = vertical ? Y : X;
111
- const lineStart = lineBox[valueAxis + startEdge];
112
- const offset = dir * (point[valueAxis] - lineStart);
89
+ const offset = axisDir * (point[axis] - lineStart);
113
90
  const valueOffset = offset * step;
114
91
 
115
92
  if (offset < 0 || offset > lineSize) {
@@ -126,16 +103,6 @@ class LogarithmicAxis extends Axis {
126
103
  return { min: options.min, max: options.max };
127
104
  }
128
105
 
129
- scaleRange(delta) {
130
- const base = this.options.majorUnit;
131
- const offset = -delta;
132
-
133
- return {
134
- min: Math.pow(base, this.logMin - offset),
135
- max: Math.pow(base, this.logMax + offset)
136
- };
137
- }
138
-
139
106
  translateRange(delta) {
140
107
  const { options, logMin, logMax } = this;
141
108
  const { reverse, vertical, majorUnit: base } = options;
@@ -236,7 +203,7 @@ class LogarithmicAxis extends Axis {
236
203
  }
237
204
 
238
205
  traverseMajorTicksPositions(callback, tickOptions) {
239
- const { lineStart, step } = this._lineOptions();
206
+ const { lineStart, step } = this.lineInfo();
240
207
  const { logMin, logMax } = this;
241
208
 
242
209
  for (let power = Math.ceil(logMin) + tickOptions.skip; power <= logMax; power += tickOptions.step) {
@@ -247,7 +214,7 @@ class LogarithmicAxis extends Axis {
247
214
 
248
215
  traverseMinorTicksPositions(callback, tickOptions) {
249
216
  const { min, max, minorUnit, majorUnit: base } = this.options;
250
- const { lineStart, step } = this._lineOptions();
217
+ const { lineStart, step } = this.lineInfo();
251
218
  const { logMin, logMax } = this;
252
219
  const start = Math.floor(logMin);
253
220
 
@@ -296,21 +263,34 @@ class LogarithmicAxis extends Axis {
296
263
  };
297
264
  }
298
265
 
299
- zoomRange(delta) {
300
- const { options, totalMin, totalMax } = this;
301
- const newRange = this.scaleRange(delta);
302
- const min = limitValue(newRange.min, totalMin, totalMax);
303
- const max = limitValue(newRange.max, totalMin, totalMax);
304
- const base = options.majorUnit;
305
- const acceptOptionsRange = max > min && options.min && options.max && (round(log(options.max, base) - log(options.min, base), DEFAULT_PRECISION) < 1);
306
- const acceptNewRange = !(options.min === totalMin && options.max === totalMax) && round(log(max, base) - log(min, base), DEFAULT_PRECISION) >= 1;
307
-
308
- if (acceptOptionsRange || acceptNewRange) {
309
- return {
310
- min: min,
311
- max: max
312
- };
266
+ scaleRange(scale, cursor) {
267
+ const { majorUnit: base } = this.options;
268
+ const logMin = log(this.options.min, base);
269
+ const logMax = log(this.options.max, base);
270
+ const position = Math.abs(this.pointOffset(cursor));
271
+ const range = logMax - logMin;
272
+ const delta = this.scaleToDelta(scale, range);
273
+ const min = Math.pow(base, logMin + position * delta);
274
+ let max = Math.pow(base, logMax - (1 - position) * delta);
275
+
276
+ if (max - min < MIN_VALUE_RANGE) {
277
+ max = min + MIN_VALUE_RANGE;
313
278
  }
279
+
280
+ return {
281
+ min: min,
282
+ max: max
283
+ };
284
+ }
285
+
286
+ zoomRange(scale, cursor) {
287
+ const range = this.scaleRange(scale, cursor);
288
+ const { totalMin, totalMax } = this;
289
+
290
+ return {
291
+ min: limitValue(range.min, totalMin, totalMax),
292
+ max: limitValue(range.max, totalMin, totalMax)
293
+ };
314
294
  }
315
295
 
316
296
  _minorIntervalOptions(power) {
@@ -326,21 +306,11 @@ class LogarithmicAxis extends Axis {
326
306
  };
327
307
  }
328
308
 
329
- _lineOptions() {
330
- const { reverse, vertical } = this.options;
331
- const valueAxis = vertical ? Y : X;
332
- const lineBox = this.lineBox();
333
- const dir = vertical === reverse ? 1 : -1;
334
- const startEdge = dir === 1 ? 1 : 2;
335
- const lineSize = vertical ? lineBox.height() : lineBox.width();
336
- const step = dir * (lineSize / (this.logMax - this.logMin));
337
- const lineStart = lineBox[valueAxis + startEdge];
309
+ lineInfo() {
310
+ const info = super.lineInfo();
311
+ info.step = info.axisDir * (info.lineSize / (this.logMax - this.logMin));
338
312
 
339
- return {
340
- step: step,
341
- lineStart: lineStart,
342
- lineBox: lineBox
343
- };
313
+ return info;
344
314
  }
345
315
  }
346
316
 
@@ -398,8 +368,8 @@ function throwNegativeValuesError() {
398
368
  throw new Error("Non positive values cannot be used for a logarithmic axis");
399
369
  }
400
370
 
401
- function log(y, x) {
402
- return Math.log(y) / Math.log(x);
371
+ function log(x, base) {
372
+ return Math.log(x) / Math.log(base);
403
373
  }
404
374
 
405
375
  setDefaultOptions(LogarithmicAxis, {