@progress/kendo-charts 1.31.0 → 1.32.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.
Files changed (60) hide show
  1. package/README.md +1 -1
  2. package/dist/cdn/js/kendo-charts.js +1 -1
  3. package/dist/cdn/main.js +1 -1
  4. package/dist/es/chart/base-theme.js +22 -2
  5. package/dist/es/chart/categorical-chart.js +6 -26
  6. package/dist/es/chart/constants.js +11 -1
  7. package/dist/es/chart/heatmap-chart/heatmap-chart.js +2 -6
  8. package/dist/es/chart/plotarea/categorical-plotarea.js +83 -16
  9. package/dist/es/chart/plotarea/plotarea-base.js +71 -2
  10. package/dist/es/chart/plotarea/plotarea-factory.js +4 -2
  11. package/dist/es/chart/plotarea/polar-plotarea.js +21 -2
  12. package/dist/es/chart/plotarea/radar-plotarea.js +13 -2
  13. package/dist/es/chart/plotarea/xy-plotarea.js +38 -5
  14. package/dist/es/chart/register-charts.js +12 -7
  15. package/dist/es/chart/scatter-charts/scatter-chart.js +3 -7
  16. package/dist/es/chart/trendlines/calculate-moving-average.js +44 -0
  17. package/dist/es/chart/trendlines/calculate-slope.js +37 -0
  18. package/dist/es/chart/trendlines/linear-trendline.js +61 -0
  19. package/dist/es/chart/trendlines/moving-average.js +65 -0
  20. package/dist/es/chart/trendlines/scatter-linear-trendline.js +63 -0
  21. package/dist/es/chart/trendlines/scatter-moving-average.js +34 -0
  22. package/dist/es/chart/trendlines/scatter-trendline-registry.js +9 -0
  23. package/dist/es/chart/trendlines/scatter-value-getter.js +7 -0
  24. package/dist/es/chart/trendlines/trendline-factory.js +10 -0
  25. package/dist/es/chart/trendlines/trendline-registry.js +9 -0
  26. package/dist/es/chart/utils.js +0 -2
  27. package/dist/es/common/constants.js +1 -0
  28. package/dist/es/common/hash-map.js +7 -11
  29. package/dist/es/core/category-axis.js +37 -30
  30. package/dist/es/core/date-category-axis.js +27 -3
  31. package/dist/es2015/chart/base-theme.js +22 -2
  32. package/dist/es2015/chart/categorical-chart.js +6 -26
  33. package/dist/es2015/chart/constants.js +11 -1
  34. package/dist/es2015/chart/heatmap-chart/heatmap-chart.js +2 -6
  35. package/dist/es2015/chart/plotarea/categorical-plotarea.js +81 -16
  36. package/dist/es2015/chart/plotarea/plotarea-base.js +69 -2
  37. package/dist/es2015/chart/plotarea/plotarea-factory.js +4 -2
  38. package/dist/es2015/chart/plotarea/polar-plotarea.js +21 -2
  39. package/dist/es2015/chart/plotarea/radar-plotarea.js +13 -2
  40. package/dist/es2015/chart/plotarea/xy-plotarea.js +36 -5
  41. package/dist/es2015/chart/register-charts.js +14 -5
  42. package/dist/es2015/chart/scatter-charts/scatter-chart.js +3 -7
  43. package/dist/es2015/chart/trendlines/calculate-moving-average.js +42 -0
  44. package/dist/es2015/chart/trendlines/calculate-slope.js +35 -0
  45. package/dist/es2015/chart/trendlines/linear-trendline.js +51 -0
  46. package/dist/es2015/chart/trendlines/moving-average.js +53 -0
  47. package/dist/es2015/chart/trendlines/scatter-linear-trendline.js +57 -0
  48. package/dist/es2015/chart/trendlines/scatter-moving-average.js +31 -0
  49. package/dist/es2015/chart/trendlines/scatter-trendline-registry.js +9 -0
  50. package/dist/es2015/chart/trendlines/scatter-value-getter.js +4 -0
  51. package/dist/es2015/chart/trendlines/trendline-factory.js +10 -0
  52. package/dist/es2015/chart/trendlines/trendline-registry.js +9 -0
  53. package/dist/es2015/chart/utils.js +0 -2
  54. package/dist/es2015/common/constants.js +1 -0
  55. package/dist/es2015/common/hash-map.js +7 -11
  56. package/dist/es2015/core/category-axis.js +37 -30
  57. package/dist/es2015/core/date-category-axis.js +27 -3
  58. package/dist/npm/main.js +889 -353
  59. package/dist/systemjs/kendo-charts.js +1 -1
  60. package/package.json +1 -1
@@ -15,7 +15,7 @@ import { COLUMN, DONUT, PIE, FUNNEL, PYRAMID, BAR, LINE, VERTICAL_LINE, AREA, VE
15
15
  RANGE_BAR, WATERFALL, HORIZONTAL_WATERFALL, SCATTER, SCATTER_LINE, BUBBLE,
16
16
  POLAR_AREA, POLAR_LINE, POLAR_SCATTER, RADAR_AREA, RADAR_COLUMN, RADAR_LINE, CATEGORY,
17
17
  RANGE_AREA, VERTICAL_RANGE_AREA, X_ERROR_LOW_FIELD, X_ERROR_HIGH_FIELD, Y_ERROR_LOW_FIELD, Y_ERROR_HIGH_FIELD,
18
- ERROR_LOW_FIELD, ERROR_HIGH_FIELD, HEATMAP, DRILLDOWN_FIELD } from './constants';
18
+ ERROR_LOW_FIELD, ERROR_HIGH_FIELD, HEATMAP, DRILLDOWN_FIELD, TRENDLINE_SERIES } from './constants';
19
19
  import { X, Y, VALUE } from '../common/constants';
20
20
 
21
21
  var COLOR = "color";
@@ -30,19 +30,24 @@ var TO = "to";
30
30
  PlotAreaFactory.current.register(CategoricalPlotArea, [
31
31
  BAR, COLUMN, LINE, VERTICAL_LINE, AREA, VERTICAL_AREA,
32
32
  CANDLESTICK, OHLC, BULLET, VERTICAL_BULLET, BOX_PLOT, VERTICAL_BOX_PLOT,
33
- RANGE_COLUMN, RANGE_BAR, WATERFALL, HORIZONTAL_WATERFALL, RANGE_AREA, VERTICAL_RANGE_AREA
34
- ]);
33
+ RANGE_COLUMN, RANGE_BAR, WATERFALL, HORIZONTAL_WATERFALL, RANGE_AREA, VERTICAL_RANGE_AREA ].concat( TRENDLINE_SERIES
34
+ ));
35
35
 
36
36
  PlotAreaFactory.current.register(XYPlotArea, [
37
- SCATTER, SCATTER_LINE, BUBBLE
38
- ]);
37
+ SCATTER, SCATTER_LINE, BUBBLE ].concat( TRENDLINE_SERIES
38
+ ));
39
39
 
40
40
  PlotAreaFactory.current.register(PiePlotArea, [ PIE ]);
41
41
  PlotAreaFactory.current.register(DonutPlotArea, [ DONUT ]);
42
42
  PlotAreaFactory.current.register(FunnelPlotArea, [ FUNNEL, PYRAMID ]);
43
43
 
44
- PlotAreaFactory.current.register(PolarPlotArea, [ POLAR_AREA, POLAR_LINE, POLAR_SCATTER ]);
45
- PlotAreaFactory.current.register(RadarPlotArea, [ RADAR_AREA, RADAR_COLUMN, RADAR_LINE ]);
44
+ PlotAreaFactory.current.register(PolarPlotArea, [
45
+ POLAR_AREA, POLAR_LINE, POLAR_SCATTER ].concat( TRENDLINE_SERIES
46
+ ));
47
+
48
+ PlotAreaFactory.current.register(RadarPlotArea, [
49
+ RADAR_AREA, RADAR_COLUMN, RADAR_LINE ].concat( TRENDLINE_SERIES
50
+ ));
46
51
 
47
52
  PlotAreaFactory.current.register(HeatmapPlotArea, [ HEATMAP ]);
48
53
 
@@ -4,10 +4,8 @@ import ClipAnimationMixin from '../mixins/clip-animation-mixin';
4
4
  import ErrorRangeCalculator from '../error-bars/error-range-calculator';
5
5
  import ScatterErrorBar from '../error-bars/scatter-error-bar';
6
6
  import LinePoint from '../line-chart/line-point';
7
- import CategoricalChart from '../categorical-chart';
8
7
 
9
- import hasValue from '../utils/has-value';
10
- import evalOptions from '../utils/eval-options';
8
+ import { hasValue, evalOptions } from '../utils';
11
9
 
12
10
  import { deepExtend, isNumber, isString, defined, isFunction, setDefaultOptions } from '../../common';
13
11
  import { X, Y, MIN_VALUE, MAX_VALUE } from '../../common/constants';
@@ -306,7 +304,7 @@ var ScatterChart = (function (ChartElement) {
306
304
  }
307
305
 
308
306
  for (var pointIx = 0; pointIx < currentSeries.data.length; pointIx++) {
309
- var ref$1 = this$1._bindPoint(currentSeries, seriesIx, pointIx);
307
+ var ref$1 = this$1.plotArea.bindPoint(currentSeries, pointIx);
310
308
  var value = ref$1.valueFields;
311
309
  var fields = ref$1.fields;
312
310
 
@@ -347,8 +345,6 @@ setDefaultOptions(ScatterChart, {
347
345
  },
348
346
  clip: true
349
347
  });
350
- deepExtend(ScatterChart.prototype, ClipAnimationMixin, {
351
- _bindPoint: CategoricalChart.prototype._bindPoint
352
- });
348
+ deepExtend(ScatterChart.prototype, ClipAnimationMixin);
353
349
 
354
350
  export default ScatterChart;
@@ -0,0 +1,44 @@
1
+ import { MIN_MOVING_AVERAGE_PERIOD } from '../constants';
2
+
3
+ function calculateMovingAverage(sourceValues, valueGetter, period) {
4
+ var averagePoints = [];
5
+ var values = [];
6
+ var start = Math.max(MIN_MOVING_AVERAGE_PERIOD, period) - 1;
7
+
8
+ var end = 0;
9
+ var sum = 0;
10
+
11
+ for (var i = 0; i < sourceValues.length; i++) {
12
+ var value = sourceValues[i];
13
+ var ref = valueGetter(value);
14
+ var xValue = ref.xValue;
15
+ var yValue = ref.yValue;
16
+
17
+ if (isFinite(yValue) && yValue !== null) {
18
+ values.push(yValue);
19
+ sum += yValue;
20
+ end = Math.max(i, end);
21
+ } else {
22
+ values.push(null);
23
+ }
24
+
25
+ if (i >= start) {
26
+ var count = values.filter(function (value) { return value !== null; }).length;
27
+ var lastValue = values.shift() || 0;
28
+
29
+ if (count > 0) {
30
+ var average = sum / count;
31
+ averagePoints.push([xValue, average]);
32
+
33
+ sum -= lastValue;
34
+ continue;
35
+ }
36
+ }
37
+
38
+ averagePoints.push([xValue, null]);
39
+ }
40
+
41
+ return averagePoints.slice(0, end + 1);
42
+ }
43
+
44
+ export default calculateMovingAverage;
@@ -0,0 +1,37 @@
1
+ function calculateSlope(sourceValues, valueGetter) {
2
+ var x = 0;
3
+ var y = 0;
4
+ var x2 = 0;
5
+ var xy = 0;
6
+ var count = 0;
7
+ var slope, intercept;
8
+ var xMin = Number.MAX_VALUE;
9
+ var xMax = Number.MIN_VALUE;
10
+
11
+ for (var i = 0; i < sourceValues.length; i++) {
12
+ var value = sourceValues[i];
13
+ var ref = valueGetter(value);
14
+ var xValue = ref.xValue;
15
+ var yValue = ref.yValue;
16
+
17
+ if (isFinite(xValue) && xValue !== null && isFinite(yValue) && yValue !== null) {
18
+ xMin = Math.min(xValue, xMin);
19
+ xMax = Math.max(xValue, xMax);
20
+
21
+ count++;
22
+ x += xValue;
23
+ y += yValue;
24
+ x2 += Math.pow(xValue, 2);
25
+ xy += xValue * yValue;
26
+ }
27
+ }
28
+
29
+ if (count > 0) {
30
+ slope = (count * xy - x * y) / (count * x2 - Math.pow(x, 2));
31
+ intercept = (y - slope * x) / count;
32
+ }
33
+
34
+ return { slope: slope, intercept: intercept, count: count, xMin: xMin, xMax: xMax };
35
+ }
36
+
37
+ export default calculateSlope;
@@ -0,0 +1,61 @@
1
+ import calculateSlope from './calculate-slope';
2
+
3
+ function linearTrendline(context) {
4
+ var options = context.options;
5
+ var categoryAxis = context.categoryAxis;
6
+ var seriesValues = context.seriesValues;
7
+
8
+ var ref = getData({ seriesValues: seriesValues, categoryAxis: categoryAxis, options: options });
9
+ var data = ref.data;
10
+ if (data) {
11
+ return Object.assign({}, options,
12
+
13
+ {type: 'line',
14
+ data: data,
15
+ categoryField: 'category',
16
+ field: 'value'});
17
+ }
18
+
19
+ return null;
20
+ }
21
+
22
+ var valueGetter = function (fieldName) { return function (ref) {
23
+ var categoryIx = ref.categoryIx;
24
+ var valueFields = ref.valueFields;
25
+
26
+ return ({ xValue: categoryIx + 1, yValue: valueFields[fieldName] });
27
+ ; } };
28
+
29
+ function getData(ref) {
30
+ var seriesValues = ref.seriesValues;
31
+ var categoryAxis = ref.categoryAxis;
32
+ var options = ref.options;
33
+
34
+ var ref$1 = calculateSlope(seriesValues(), valueGetter(options.field));
35
+ var slope = ref$1.slope;
36
+ var intercept = ref$1.intercept;
37
+ var count = ref$1.count;
38
+
39
+ if (count > 0) {
40
+ var data = [];
41
+ var totalRange = categoryAxis.totalRangeIndices();
42
+ var currentRange = categoryAxis.currentRangeIndices();
43
+ var range = {
44
+ min: Math.floor(Math.max(currentRange.min - 1, totalRange.min)),
45
+ max: Math.ceil(Math.min(currentRange.max + 2, totalRange.max))
46
+ };
47
+
48
+ for (var i = range.min; i < range.max; i++) {
49
+ data[i] = {
50
+ category: categoryAxis.categoryAt(i, true),
51
+ value: slope * (i + 1) + intercept
52
+ };
53
+ }
54
+
55
+ return { data: data };
56
+ }
57
+
58
+ return { data: null };
59
+ }
60
+
61
+ export default linearTrendline;
@@ -0,0 +1,65 @@
1
+ import { MIN_MOVING_AVERAGE_PERIOD } from '../constants';
2
+ import calculateMovingAverage from './calculate-moving-average';
3
+
4
+ function movingAverageTrendline(context) {
5
+ var options = context.options;
6
+
7
+ var ref = getData(context);
8
+ var data = ref.data;
9
+ if (data) {
10
+ return Object.assign({}, options,
11
+
12
+ {type: 'line',
13
+ data: data,
14
+ categoryField: 'category',
15
+ field: 'value'});
16
+ }
17
+
18
+ return null;
19
+ }
20
+
21
+ var valueGetter = function (fieldName) { return function (ref) {
22
+ var categoryIx = ref.categoryIx;
23
+ var valueFields = ref.valueFields;
24
+
25
+ return ({ xValue: categoryIx, yValue: valueFields[fieldName] });
26
+ ; } };
27
+
28
+ function calculatePoints(ref) {
29
+ var options = ref.options;
30
+ var categoryAxis = ref.categoryAxis;
31
+ var seriesValues = ref.seriesValues;
32
+
33
+ var period = (options.trendline || {}).period || MIN_MOVING_AVERAGE_PERIOD;
34
+ var totalRange = categoryAxis.totalRangeIndices();
35
+ var currentRange = categoryAxis.currentRangeIndices();
36
+ var range = {
37
+ min: Math.floor(Math.max(currentRange.min - period, totalRange.min)),
38
+ max: Math.ceil(Math.min(currentRange.max + period + 2, totalRange.max))
39
+ };
40
+
41
+ return calculateMovingAverage(seriesValues(range), valueGetter(options.field), period);
42
+ }
43
+
44
+ function getData(context) {
45
+ var categoryAxis = context.categoryAxis;
46
+ var points = calculatePoints(context);
47
+ var data = [];
48
+ points.forEach(function (ref) {
49
+ var categoryIx = ref[0];
50
+ var value = ref[1];
51
+
52
+ data[categoryIx] = {
53
+ category: categoryAxis.categoryAt(categoryIx, true),
54
+ value: value
55
+ };
56
+ });
57
+
58
+ if (data.length > 0) {
59
+ return { data: data };
60
+ }
61
+
62
+ return { data: null };
63
+ }
64
+
65
+ export default movingAverageTrendline;
@@ -0,0 +1,63 @@
1
+ import autoMajorUnit from '../../core/utils/auto-major-unit';
2
+ import { valueOrDefault } from '../../common';
3
+ import calculateSlope from './calculate-slope';
4
+ import scatterValueGetter from './scatter-value-getter';
5
+
6
+ function scatterLinearTrendLine(context) {
7
+ var options = context.options;
8
+ var seriesValues = context.seriesValues;
9
+
10
+ var data = getData({ seriesValues: seriesValues, options: options });
11
+ if (data) {
12
+ return Object.assign({}, options,
13
+
14
+ {type: 'scatterLine',
15
+ data: data});
16
+ }
17
+
18
+ return null;
19
+ }
20
+
21
+ function getData(ref) {
22
+ var seriesValues = ref.seriesValues;
23
+ var options = ref.options;
24
+
25
+ var ref$1 = calculateSlope(seriesValues(), scatterValueGetter(options.field));
26
+ var slope = ref$1.slope;
27
+ var intercept = ref$1.intercept;
28
+ var count = ref$1.count;
29
+ var xMin = ref$1.xMin;
30
+ var xMax = ref$1.xMax;
31
+
32
+ if (count > 0) {
33
+ var data = [];
34
+ var forecast = (options.trendline || {}).forecast;
35
+ if (forecast) {
36
+ if (forecast.before > 0) {
37
+ xMin -= forecast.before;
38
+ }
39
+
40
+ if (forecast.after > 0) {
41
+ xMax += forecast.after;
42
+ }
43
+ }
44
+
45
+ var samplingInterval = (options.trendline || {}).samplingInterval;
46
+ var delta = valueOrDefault(samplingInterval, autoMajorUnit(xMin, xMax) / 10);
47
+ if (samplingInterval <= 0) {
48
+ delta = xMax - xMin;
49
+ }
50
+
51
+ for (var x = xMin; x <= xMax; x += delta) {
52
+ data.push([ x,
53
+ slope * x + intercept
54
+ ]);
55
+ }
56
+
57
+ return data;
58
+ }
59
+
60
+ return null;
61
+ }
62
+
63
+ export default scatterLinearTrendLine;
@@ -0,0 +1,34 @@
1
+ import calculateMovingAverage from './calculate-moving-average';
2
+ import { MIN_MOVING_AVERAGE_PERIOD } from '../constants';
3
+ import scatterValueGetter from './scatter-value-getter';
4
+
5
+ function scatterMovingAverageTrendline(context) {
6
+ var options = context.options;
7
+
8
+ var data = getData(context);
9
+ if (data) {
10
+ return Object.assign({}, options,
11
+
12
+ {type: 'scatterLine',
13
+ data: data});
14
+ }
15
+
16
+ return null;
17
+ }
18
+
19
+ function getData(ref) {
20
+ var options = ref.options;
21
+ var seriesValues = ref.seriesValues;
22
+
23
+ var period = (options.trendline || {}).period || MIN_MOVING_AVERAGE_PERIOD;
24
+ var range = { before: period, after: period };
25
+ var data = calculateMovingAverage(seriesValues(range), scatterValueGetter(options.field), period);
26
+
27
+ if (data.length > 0) {
28
+ return data;
29
+ }
30
+
31
+ return null;
32
+ }
33
+
34
+ export default scatterMovingAverageTrendline;
@@ -0,0 +1,9 @@
1
+ import scatterLinearTrendLine from './scatter-linear-trendline';
2
+ import scatterMovingAverageTrendline from './scatter-moving-average';
3
+ import { TRENDLINE_LINEAR, TRENDLINE_MOVING_AVERAGE } from '../constants';
4
+
5
+ var scatterRegistry = {};
6
+ scatterRegistry[TRENDLINE_LINEAR] = scatterLinearTrendLine;
7
+ scatterRegistry[TRENDLINE_MOVING_AVERAGE] = scatterMovingAverageTrendline;
8
+
9
+ export default scatterRegistry;
@@ -0,0 +1,7 @@
1
+ var scatterValueGetter = function (fieldName) { return function (ref) {
2
+ var valueFields = ref.valueFields;
3
+
4
+ return ({ xValue: valueFields.x, yValue: valueFields[fieldName] });
5
+ ; } };
6
+
7
+ export default scatterValueGetter;
@@ -0,0 +1,10 @@
1
+ function trendlineFactory(registry, type, context) {
2
+ var impl = registry[String(type)];
3
+ if (impl) {
4
+ return impl(context);
5
+ }
6
+
7
+ return null;
8
+ }
9
+
10
+ export default trendlineFactory;
@@ -0,0 +1,9 @@
1
+ import linearTrendline from './linear-trendline';
2
+ import movingAverageTrendline from './moving-average';
3
+ import { TRENDLINE_LINEAR, TRENDLINE_MOVING_AVERAGE } from '../constants';
4
+
5
+ var registry = {};
6
+ registry[TRENDLINE_LINEAR] = linearTrendline;
7
+ registry[TRENDLINE_MOVING_AVERAGE] = movingAverageTrendline;
8
+
9
+ export default registry;
@@ -15,5 +15,3 @@ export { default as isDateAxis } from './utils/is-date-axis';
15
15
  export { default as segmentVisible } from './utils/segment-visible';
16
16
  export { default as singleItemOrArray } from './utils/single-item-or-array';
17
17
  export { default as createOutOfRangePoints } from './utils/create-out-of-range-points';
18
-
19
-
@@ -16,6 +16,7 @@ export var FORMAT_REGEX = /\{\d+:?/;
16
16
  export var HEIGHT = "height";
17
17
  export var HIGHLIGHT_ZINDEX = 100;
18
18
  export var INSIDE = "inside";
19
+ export var INHERIT = "inherit";
19
20
  export var LEFT = "left";
20
21
  export var MAX_VALUE = Number.MAX_VALUE;
21
22
  export var MIN_VALUE = -Number.MAX_VALUE;
@@ -1,18 +1,14 @@
1
-
1
+ // TODO: Remove and replace with Map/WeakMap.
2
2
  var HashMap = function HashMap() {
3
- this._map = {};
4
- };
5
-
6
- HashMap.prototype.get = function get (name) {
7
- return this._map[this._key(name)];
3
+ this._map = new Map();
8
4
  };
9
5
 
10
- HashMap.prototype.set = function set (name, value) {
11
- this._map[this._key(name)] = value;
6
+ HashMap.prototype.get = function get (key) {
7
+ return this._map.get(key);
12
8
  };
13
9
 
14
- HashMap.prototype._key = function _key (name) {
15
- return name instanceof Date ? name.getTime() : name;
10
+ HashMap.prototype.set = function set (key, value) {
11
+ this._map.set(key, value);
16
12
  };
17
13
 
18
- export default HashMap;
14
+ export default HashMap;
@@ -89,31 +89,6 @@ var CategoryAxis = (function (Axis) {
89
89
  };
90
90
  };
91
91
 
92
- CategoryAxis.prototype.totalRangeIndices = function totalRangeIndices (limit) {
93
- var options = this.options;
94
- var min = isNumber(options.min) ? options.min : 0;
95
- var max;
96
-
97
- if (isNumber(options.max)) {
98
- max = options.max;
99
- } else if (isNumber(options.min)) {
100
- max = min + options.categories.length;
101
- } else {
102
- max = this.totalRange().max || 1;
103
- }
104
-
105
- if (limit) {
106
- var totalRange = this.totalRange();
107
- min = limitValue(min, 0, totalRange.max);
108
- max = limitValue(max, 0, totalRange.max);
109
- }
110
-
111
- return {
112
- min: min,
113
- max: max
114
- };
115
- };
116
-
117
92
  CategoryAxis.prototype.range = function range () {
118
93
  var options = this.options;
119
94
  var min = isNumber(options.min) ? options.min : 0;
@@ -444,7 +419,7 @@ var CategoryAxis = (function (Axis) {
444
419
 
445
420
  CategoryAxis.prototype.scaleRange = function scaleRange (scale, cursor) {
446
421
  var position = Math.abs(this.pointOffset(cursor));
447
- var rangeIndices = this.totalRangeIndices();
422
+ var rangeIndices = this.limitedRangeIndices();
448
423
  var range = rangeIndices.max - rangeIndices.min;
449
424
  var delta = this.scaleToDelta(scale, range);
450
425
  var minDelta = position * delta;
@@ -484,7 +459,7 @@ var CategoryAxis = (function (Axis) {
484
459
  var options = this.options;
485
460
  var justified = options.justified;
486
461
  var labelOptions = options.labels;
487
- var ref = this.totalRangeIndices(true);
462
+ var ref = this.limitedRangeIndices(true);
488
463
  var min = ref.min;
489
464
  var max = ref.max;
490
465
  var start = Math.floor(min);
@@ -523,7 +498,7 @@ var CategoryAxis = (function (Axis) {
523
498
  };
524
499
 
525
500
  CategoryAxis.prototype.shouldRenderNote = function shouldRenderNote (value) {
526
- var range = this.totalRangeIndices();
501
+ var range = this.limitedRangeIndices();
527
502
 
528
503
  return Math.floor(range.min) <= value && value <= Math.ceil(range.max);
529
504
  };
@@ -558,7 +533,7 @@ var CategoryAxis = (function (Axis) {
558
533
  };
559
534
 
560
535
  CategoryAxis.prototype.pan = function pan (delta) {
561
- var range = this.totalRangeIndices(true);
536
+ var range = this.limitedRangeIndices(true);
562
537
  var ref = this.scaleOptions();
563
538
  var scale = ref.scale;
564
539
  var offset = round(delta / scale, DEFAULT_PRECISION);
@@ -574,7 +549,7 @@ var CategoryAxis = (function (Axis) {
574
549
  var reverse = ref.reverse;
575
550
  var vertical = ref.vertical;
576
551
  var valueAxis = vertical ? Y : X;
577
- var range = this.totalRangeIndices(true);
552
+ var range = this.limitedRangeIndices(true);
578
553
  var ref$1 = this.scaleOptions();
579
554
  var scale = ref$1.scale;
580
555
  var box = ref$1.box;
@@ -629,6 +604,38 @@ var CategoryAxis = (function (Axis) {
629
604
  };
630
605
  };
631
606
 
607
+ CategoryAxis.prototype.limitedRangeIndices = function limitedRangeIndices (totalLimit) {
608
+ var options = this.options;
609
+ var min = isNumber(options.min) ? options.min : 0;
610
+ var max;
611
+
612
+ if (isNumber(options.max)) {
613
+ max = options.max;
614
+ } else if (isNumber(options.min)) {
615
+ max = min + options.categories.length;
616
+ } else {
617
+ max = this.totalRange().max || 1;
618
+ }
619
+
620
+ if (totalLimit) {
621
+ var totalRange = this.totalRange();
622
+ min = limitValue(min, 0, totalRange.max);
623
+ max = limitValue(max, 0, totalRange.max);
624
+ }
625
+
626
+ return {
627
+ min: min,
628
+ max: max
629
+ };
630
+ };
631
+
632
+ CategoryAxis.prototype.totalRangeIndices = function totalRangeIndices () {
633
+ return {
634
+ min: 0,
635
+ max: this.totalRange().max || 1
636
+ };
637
+ };
638
+
632
639
  CategoryAxis.prototype.mapCategories = function mapCategories () {
633
640
  if (!this._categoriesMap) {
634
641
  var map = this._categoriesMap = new HashMap();
@@ -20,7 +20,11 @@ var BASE_UNITS = [
20
20
  var FIT = "fit";
21
21
 
22
22
 
23
- function categoryRange(categories) {
23
+ function categoryRange(categories, clearCache) {
24
+ if (clearCache) {
25
+ categories._range = undefined;
26
+ }
27
+
24
28
  var range = categories._range;
25
29
  if (!range) {
26
30
  range = categories._range = sparseArrayLimits(categories);
@@ -368,10 +372,22 @@ var DateCategoryAxis = (function (CategoryAxis) {
368
372
  options.srcCategories = categories;
369
373
 
370
374
  if (categories.length > 0) {
371
- var range = categoryRange(categories);
375
+ var range = categoryRange(categories, true);
372
376
  var maxDivisions = options.maxDivisions;
377
+ var safeOptions = initUnit(options);
378
+
379
+ var forecast = options._forecast;
380
+ if (forecast) {
381
+ if (forecast.before > 0) {
382
+ range.min = addDuration(range.min, -forecast.before, safeOptions.baseUnit, safeOptions.weekStartDay);
383
+ }
384
+
385
+ if (forecast.after > 0) {
386
+ range.max = addDuration(range.max, forecast.after, safeOptions.baseUnit, safeOptions.weekStartDay);
387
+ }
388
+ }
373
389
 
374
- this.dataRange = new DateRange(range.min, range.max, initUnit(options));
390
+ this.dataRange = new DateRange(range.min, range.max, safeOptions);
375
391
 
376
392
  if (maxDivisions) {
377
393
  var dataRange = this.dataRange.displayRange();
@@ -906,6 +922,14 @@ var DateCategoryAxis = (function (CategoryAxis) {
906
922
  return this.dataRange.total();
907
923
  };
908
924
 
925
+ DateCategoryAxis.prototype.totalRangeIndices = function totalRangeIndices () {
926
+ var range = this.dataRange.total();
927
+ return {
928
+ min: this.dataRange.totalIndex(range.min),
929
+ max: this.dataRange.totalIndex(range.max)
930
+ };
931
+ };
932
+
909
933
  DateCategoryAxis.prototype.totalCount = function totalCount () {
910
934
  return this.dataRange.totalCount();
911
935
  };
@@ -1,3 +1,6 @@
1
+ import { TRENDLINE_SERIES } from './constants';
2
+ import { INHERIT } from '../common/constants';
3
+
1
4
  const BAR_GAP = 1.5;
2
5
  const BAR_SPACING = 0.4;
3
6
  const BLACK = '#000';
@@ -262,7 +265,22 @@ const heatmapSeries = () => ({
262
265
  }
263
266
  });
264
267
 
265
- const seriesDefaults = (options) => ({
268
+ const trendlineSeriesDefaults = () => TRENDLINE_SERIES.reduce(
269
+ (options, type) => {
270
+ options[type] = {
271
+ color: INHERIT,
272
+ trendline: {},
273
+ markers: {
274
+ visible: false
275
+ },
276
+ width: 1,
277
+ dashType: 'longDash'
278
+ };
279
+
280
+ return options;
281
+ }, {});
282
+
283
+ const seriesDefaults = (options) => (Object.assign({
266
284
  visible: true,
267
285
  labels: {
268
286
  font: SANS11
@@ -300,7 +318,9 @@ const seriesDefaults = (options) => ({
300
318
  verticalBullet: bulletSeries(),
301
319
  verticalLine: lineSeries(),
302
320
  waterfall: waterfallSeries()
303
- });
321
+ },
322
+ trendlineSeriesDefaults()
323
+ ));
304
324
 
305
325
  const title = () => ({
306
326
  font: SANS16