@progress/kendo-charts 1.32.1 → 1.33.0-dev.202311081130

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 (89) hide show
  1. package/dist/cdn/js/kendo-charts.js +1 -1
  2. package/dist/cdn/main.js +1 -1
  3. package/dist/es/chart/bar-chart/bar.js +40 -16
  4. package/dist/es/chart/bubble-chart/bubble.js +10 -0
  5. package/dist/es/chart/bullet-chart/bullet.js +32 -11
  6. package/dist/es/chart/candlestick-chart/candlestick.js +37 -1
  7. package/dist/es/chart/categorical-chart.js +1 -1
  8. package/dist/es/chart/chart.js +307 -26
  9. package/dist/es/chart/constants.js +12 -1
  10. package/dist/es/chart/funnel-chart/funnel-chart.js +5 -3
  11. package/dist/es/chart/funnel-chart/funnel-segment.js +62 -3
  12. package/dist/es/chart/heatmap-chart/heatmap-chart.js +2 -1
  13. package/dist/es/chart/heatmap-chart/heatmap-point.js +68 -29
  14. package/dist/es/chart/legend/legend-item.js +32 -2
  15. package/dist/es/chart/legend/legend.js +6 -1
  16. package/dist/es/chart/line-chart/line-point.js +109 -26
  17. package/dist/es/chart/mixins/accessibility-attributes-mixin.js +36 -0
  18. package/dist/es/chart/pie-chart/pie-chart.js +1 -1
  19. package/dist/es/chart/pie-chart/pie-segment.js +50 -14
  20. package/dist/es/chart/plotarea/categorical-plotarea.js +53 -2
  21. package/dist/es/chart/plotarea/funnel-plotarea.js +8 -0
  22. package/dist/es/chart/plotarea/heatmap-plotarea.js +66 -1
  23. package/dist/es/chart/plotarea/plotarea-base.js +71 -1
  24. package/dist/es/chart/plotarea/radar-plotarea.js +8 -0
  25. package/dist/es/chart/radar-bar-chart/radar-segment.js +4 -0
  26. package/dist/es/chart/range-area-chart/range-area-point.js +26 -1
  27. package/dist/es/chart/range-bar-chart/range-bar.js +3 -24
  28. package/dist/es/chart/scatter-charts/scatter-chart.js +1 -1
  29. package/dist/es/common/constants.js +6 -0
  30. package/dist/es/common/cycleDown.js +5 -0
  31. package/dist/es/common/cycleIndex.js +13 -0
  32. package/dist/es/common/cycleUp.js +3 -0
  33. package/dist/es/common.js +3 -0
  34. package/dist/es/core/chart-element.js +31 -3
  35. package/dist/es/core/shape-builder.js +1 -1
  36. package/dist/es/core/shape-element.js +3 -0
  37. package/dist/es/core/utils/add-accessibility-attributes-to-visual.js +8 -0
  38. package/dist/es/core/utils/guid.js +17 -0
  39. package/dist/es/map/layers/shape.js +0 -2
  40. package/dist/es/map/navigator.js +0 -1
  41. package/dist/es/map/scroller/user-events.js +0 -2
  42. package/dist/es/map/utils.js +0 -18
  43. package/dist/es/map/zoom.js +0 -1
  44. package/dist/es2015/chart/bar-chart/bar.js +40 -16
  45. package/dist/es2015/chart/bubble-chart/bubble.js +10 -0
  46. package/dist/es2015/chart/bullet-chart/bullet.js +32 -11
  47. package/dist/es2015/chart/candlestick-chart/candlestick.js +37 -1
  48. package/dist/es2015/chart/categorical-chart.js +1 -1
  49. package/dist/es2015/chart/chart.js +295 -26
  50. package/dist/es2015/chart/constants.js +12 -1
  51. package/dist/es2015/chart/funnel-chart/funnel-chart.js +5 -3
  52. package/dist/es2015/chart/funnel-chart/funnel-segment.js +62 -3
  53. package/dist/es2015/chart/heatmap-chart/heatmap-chart.js +2 -1
  54. package/dist/es2015/chart/heatmap-chart/heatmap-point.js +68 -29
  55. package/dist/es2015/chart/legend/legend-item.js +32 -2
  56. package/dist/es2015/chart/legend/legend.js +6 -1
  57. package/dist/es2015/chart/line-chart/line-point.js +110 -26
  58. package/dist/es2015/chart/mixins/accessibility-attributes-mixin.js +36 -0
  59. package/dist/es2015/chart/pie-chart/pie-chart.js +1 -1
  60. package/dist/es2015/chart/pie-chart/pie-segment.js +50 -14
  61. package/dist/es2015/chart/plotarea/categorical-plotarea.js +49 -2
  62. package/dist/es2015/chart/plotarea/funnel-plotarea.js +8 -0
  63. package/dist/es2015/chart/plotarea/heatmap-plotarea.js +60 -1
  64. package/dist/es2015/chart/plotarea/plotarea-base.js +67 -1
  65. package/dist/es2015/chart/plotarea/radar-plotarea.js +8 -0
  66. package/dist/es2015/chart/radar-bar-chart/radar-segment.js +4 -0
  67. package/dist/es2015/chart/range-area-chart/range-area-point.js +26 -1
  68. package/dist/es2015/chart/range-bar-chart/range-bar.js +3 -24
  69. package/dist/es2015/chart/scatter-charts/scatter-chart.js +1 -1
  70. package/dist/es2015/common/constants.js +6 -0
  71. package/dist/es2015/common/cycleDown.js +5 -0
  72. package/dist/es2015/common/cycleIndex.js +13 -0
  73. package/dist/es2015/common/cycleUp.js +3 -0
  74. package/dist/es2015/common.js +3 -0
  75. package/dist/es2015/core/chart-element.js +31 -3
  76. package/dist/es2015/core/shape-builder.js +1 -1
  77. package/dist/es2015/core/shape-element.js +3 -0
  78. package/dist/es2015/core/utils/add-accessibility-attributes-to-visual.js +8 -0
  79. package/dist/es2015/core/utils/guid.js +17 -0
  80. package/dist/es2015/map/layers/shape.js +0 -2
  81. package/dist/es2015/map/navigator.js +0 -2
  82. package/dist/es2015/map/scroller/user-events.js +0 -2
  83. package/dist/es2015/map/utils.js +0 -18
  84. package/dist/es2015/map/zoom.js +0 -2
  85. package/dist/npm/main.js +1098 -156
  86. package/dist/systemjs/kendo-charts.js +1 -1
  87. package/package.json +1 -1
  88. package/dist/es/chart/area-chart/area-segment-mixin.js +0 -91
  89. package/dist/es2015/chart/area-chart/area-segment-mixin.js +0 -91
@@ -4,11 +4,12 @@ import { ChartElement, ShapeBuilder, TextBox, Box } from '../../core';
4
4
 
5
5
  import PointEventsMixin from '../mixins/point-events-mixin';
6
6
 
7
- import { OUTSIDE_END, INSIDE_END, PIE, FADEIN, TOOLTIP_OFFSET } from '../constants';
7
+ import { OUTSIDE_END, INSIDE_END, PIE, FADEIN, TOOLTIP_OFFSET, CHART_POINT_ROLE, CHART_POINT_CLASSNAME, CHART_POINT_ROLE_DESCRIPTION } from '../constants';
8
8
  import hasGradientOverlay from '../utils/has-gradient-overlay';
9
9
 
10
10
  import { TOP, BOTTOM, LEFT, RIGHT, DEFAULT_FONT, CIRCLE, WHITE, CENTER, DEFAULT_PRECISION } from '../../common/constants';
11
11
  import { autoTextColor, setDefaultOptions, getSpacing, getTemplate, deepExtend, round, rad } from '../../common';
12
+ import AccessibilityAttributesMixin from '../mixins/accessibility-attributes-mixin';
12
13
 
13
14
  class PieSegment extends ChartElement {
14
15
  constructor(value, sector, options) {
@@ -19,23 +20,18 @@ class PieSegment extends ChartElement {
19
20
  }
20
21
 
21
22
  render() {
22
- const labels = this.options.labels;
23
- const chartService = this.owner.chartService;
24
- let labelText = this.value;
25
-
26
23
  if (this._rendered || this.visible === false) {
27
24
  return;
28
25
  }
29
26
  this._rendered = true;
30
27
 
31
- const labelTemplate = getTemplate(labels);
32
- const pointData = this.pointData();
28
+ this.createLabel();
29
+ }
33
30
 
34
- if (labelTemplate) {
35
- labelText = labelTemplate(pointData);
36
- } else if (labels.format) {
37
- labelText = chartService.format.auto(labels.format, labelText);
38
- }
31
+ createLabel() {
32
+ const labels = this.options.labels;
33
+ const chartService = this.owner.chartService;
34
+ let labelText = this.getLabelText(labels);
39
35
 
40
36
  if (labels.visible && (labelText || labelText === 0)) {
41
37
  if (labels.position === CENTER || labels.position === INSIDE_END) {
@@ -59,12 +55,22 @@ class PieSegment extends ChartElement {
59
55
  type: FADEIN,
60
56
  delay: this.animationDelay
61
57
  }
62
- }), pointData);
58
+ }), this.pointData());
63
59
 
64
60
  this.append(this.label);
65
61
  }
66
62
  }
67
63
 
64
+ getLabelText(options) {
65
+ let labelTemplate = getTemplate(options);
66
+
67
+ if (labelTemplate) {
68
+ return labelTemplate(this.pointData());
69
+ }
70
+
71
+ return this.owner.chartService.format.auto(options.format, this.value);
72
+ }
73
+
68
74
  reflow(targetBox) {
69
75
  this.render();
70
76
  this.box = targetBox;
@@ -110,6 +116,8 @@ class PieSegment extends ChartElement {
110
116
 
111
117
  super.createVisual();
112
118
 
119
+ this.addAccessibilityAttributesToVisual();
120
+
113
121
  if (this.value) {
114
122
  if (options.visual) {
115
123
  const startAngle = (sector.startAngle + 180) % 360;
@@ -238,6 +246,24 @@ class PieSegment extends ChartElement {
238
246
  };
239
247
  }
240
248
 
249
+ createFocusHighlight(style) {
250
+ const borderWidth = this.options.accessibility.highlight.border.width;
251
+ const result = this.createSegment(this.sector, deepExtend({}, style, {
252
+ stroke: {
253
+ width: borderWidth * 2
254
+ }
255
+ }));
256
+
257
+ const clipPath = new draw.MultiPath();
258
+
259
+ clipPath.paths.push(draw.Path.fromRect(result.bbox()));
260
+ clipPath.paths.push(this.createSegment(this.sector, {}));
261
+
262
+ result.clip(clipPath);
263
+
264
+ return result;
265
+ }
266
+
241
267
  tooltipAnchor() {
242
268
  const sector = this.sector.clone().expand(TOOLTIP_OFFSET);
243
269
  const midAndle = sector.middle();
@@ -262,6 +288,10 @@ class PieSegment extends ChartElement {
262
288
  percentage: this.percentage
263
289
  };
264
290
  }
291
+
292
+ getIndex() {
293
+ return this.index;
294
+ }
265
295
  }
266
296
 
267
297
  const RAD_30 = round(rad(30), DEFAULT_PRECISION);
@@ -323,9 +353,15 @@ setDefaultOptions(PieSegment, {
323
353
  width: 1
324
354
  }
325
355
  },
326
- visible: true
356
+ visible: true,
357
+ accessibility: {
358
+ role: CHART_POINT_ROLE,
359
+ className: CHART_POINT_CLASSNAME,
360
+ ariaRoleDescription: CHART_POINT_ROLE_DESCRIPTION
361
+ }
327
362
  });
328
363
 
329
364
  deepExtend(PieSegment.prototype, PointEventsMixin);
365
+ deepExtend(PieSegment.prototype, AccessibilityAttributesMixin);
330
366
 
331
367
  export default PieSegment;
@@ -24,10 +24,10 @@ import { appendIfNotNull, categoriesCount, createOutOfRangePoints, equalsIgnoreC
24
24
 
25
25
  import { BAR, COLUMN, BULLET, VERTICAL_BULLET, LINE, VERTICAL_LINE, AREA, VERTICAL_AREA,
26
26
  RANGE_AREA, VERTICAL_RANGE_AREA, RANGE_COLUMN, RANGE_BAR, WATERFALL, HORIZONTAL_WATERFALL,
27
- BOX_PLOT, VERTICAL_BOX_PLOT, OHLC, CANDLESTICK, LOGARITHMIC, STEP, EQUALLY_SPACED_SERIES } from '../constants';
27
+ BOX_PLOT, VERTICAL_BOX_PLOT, OHLC, CANDLESTICK, LOGARITHMIC, STEP, EQUALLY_SPACED_SERIES, RADAR_LINE, RADAR_AREA } from '../constants';
28
28
 
29
29
  import { DATE, MAX_VALUE } from '../../common/constants';
30
- import { setDefaultOptions, inArray, deepExtend, defined, eventElement, grep } from '../../common';
30
+ import { setDefaultOptions, inArray, deepExtend, defined, eventElement, grep, cycleIndex } from '../../common';
31
31
 
32
32
  const AREA_SERIES = [ AREA, VERTICAL_AREA, RANGE_AREA, VERTICAL_RANGE_AREA ];
33
33
  const OUT_OF_RANGE_SERIES = [ LINE, VERTICAL_LINE ].concat(AREA_SERIES);
@@ -814,6 +814,53 @@ class CategoricalPlotArea extends PlotAreaBase {
814
814
  updateAxisOptions(this.options, axis, options);
815
815
  updateAxisOptions(this.originalOptions, axis, options);
816
816
  }
817
+
818
+ _pointsByVertical(basePoint, offset = 0) {
819
+ if (this.invertAxes) {
820
+ return this._siblingsBySeriesIndex(basePoint, offset);
821
+ }
822
+
823
+ return this._siblingsByPointIndex(basePoint, offset);
824
+ }
825
+
826
+ _pointsByHorizontal(basePoint, offset = 0) {
827
+ if (this.invertAxes) {
828
+ return this._siblingsByPointIndex(basePoint, offset);
829
+ }
830
+
831
+ return this._siblingsBySeriesIndex(basePoint, offset);
832
+ }
833
+
834
+ _siblingsByPointIndex(basePoint) {
835
+ return this
836
+ .pointsByPointIndex(basePoint.getIndex())
837
+ .sort(this._getSeriesCompareFn(basePoint));
838
+ }
839
+
840
+ _siblingsBySeriesIndex(basePoint, offset) {
841
+ const index = cycleIndex(basePoint.series.index + offset, this.series.length);
842
+
843
+ return this.pointsBySeriesIndex(index);
844
+ }
845
+
846
+ _getSeriesCompareFn(point) {
847
+ const isStacked = this._isInStackedSeries(point);
848
+
849
+ if (isStacked && this.invertAxes || !isStacked && !this.invertAxes) {
850
+ return (a, b) => a.box.center().x - b.box.center().x;
851
+ }
852
+
853
+ return (a, b) => a.box.center().y - b.box.center().y;
854
+ }
855
+
856
+ _isInStackedSeries(point) {
857
+ const sortableSeries = inArray(point.series.type,
858
+ [ AREA, VERTICAL_AREA, RANGE_AREA, VERTICAL_RANGE_AREA, LINE, VERTICAL_LINE, RADAR_LINE, RADAR_AREA]);
859
+
860
+ const stackableSeries = inArray(point.series.type, [ COLUMN, BAR]);
861
+
862
+ return sortableSeries || stackableSeries && point.options.isStacked;
863
+ }
817
864
  }
818
865
 
819
866
  function updateAxisOptions(targetOptions, axis, options) {
@@ -36,6 +36,14 @@ class FunnelPlotArea extends PlotAreaBase {
36
36
  super.appendChart(chart, pane);
37
37
  append(this.options.legend.items, chart.legendItems);
38
38
  }
39
+
40
+ _pointsByVertical(basePoint) {
41
+ return this.pointsBySeriesIndex(basePoint.series.index);
42
+ }
43
+
44
+ _pointsByHorizontal(basePoint) {
45
+ return [basePoint];
46
+ }
39
47
  }
40
48
 
41
49
  export default FunnelPlotArea;
@@ -1,6 +1,7 @@
1
- import { deepExtend, eventElement, grep, inArray, setDefaultOptions, createHashSet } from '../../common';
1
+ import { deepExtend, eventElement, grep, inArray, setDefaultOptions, createHashSet, cycleIndex } from '../../common';
2
2
  import { DATE } from '../../common/constants';
3
3
  import { CategoryAxis, DateCategoryAxis, Point } from '../../core';
4
+ import { dateEquals } from '../../date-utils';
4
5
  import { HEATMAP } from '../constants';
5
6
  import HeatmapChart from '../heatmap-chart/heatmap-chart';
6
7
  import PlotAreaEventsMixin from '../mixins/plotarea-events-mixin';
@@ -272,6 +273,64 @@ class HeatmapPlotArea extends PlotAreaBase {
272
273
  // Stack the crosshair above the series points.
273
274
  return Object.assign({}, axis.options.crosshair, { zIndex: 0 });
274
275
  }
276
+
277
+ _pointsByVertical(basePoint, offset = 0) {
278
+ const normalizedOffset = this.axisX.options.reverse ? offset * -1 : offset;
279
+ const axisXItems = this.axisX.children;
280
+ let xIndex = this._getPointAxisXIndex(basePoint) + normalizedOffset;
281
+
282
+ xIndex = cycleIndex(xIndex, axisXItems.length);
283
+ const targetXValue = axisXItems[xIndex].value;
284
+
285
+ const points = this
286
+ .filterPoints(point => compareValues(point.pointData().x, targetXValue))
287
+ .sort((a, b) => this._getPointAxisYIndex(a) - this._getPointAxisYIndex(b));
288
+
289
+ if (this.axisY.options.reverse) {
290
+ return points.reverse();
291
+ }
292
+
293
+ return points;
294
+ }
295
+
296
+ _pointsByHorizontal(basePoint, offset = 0) {
297
+ const normalizedOffset = this.axisY.options.reverse ? offset * -1 : offset;
298
+ const axisYItems = this.axisY.children;
299
+ let yIndex = this._getPointAxisYIndex(basePoint) + normalizedOffset;
300
+
301
+ yIndex = cycleIndex(yIndex, axisYItems.length);
302
+ const targetYValue = axisYItems[yIndex].value;
303
+
304
+ const points = this
305
+ .filterPoints(point => compareValues(point.pointData().y, targetYValue))
306
+ .sort((a, b) => this._getPointAxisXIndex(a) - this._getPointAxisXIndex(b));
307
+
308
+ if (this.axisX.options.reverse) {
309
+ return points.reverse();
310
+ }
311
+
312
+ return points;
313
+ }
314
+
315
+ _getPointAxisXIndex(point) {
316
+ return this._getPointAxisIndex(this.axisX, point.pointData().x);
317
+ }
318
+
319
+ _getPointAxisYIndex(point) {
320
+ return this._getPointAxisIndex(this.axisY, point.pointData().y);
321
+ }
322
+
323
+ _getPointAxisIndex(axis, pointValue) {
324
+ return axis.children.findIndex(axisItem => compareValues(pointValue, axisItem.value));
325
+ }
326
+ }
327
+
328
+ function compareValues(a, b) {
329
+ if (a instanceof Date && b instanceof Date) {
330
+ return dateEquals(a, b);
331
+ }
332
+
333
+ return a === b;
275
334
  }
276
335
 
277
336
  function updateAxisOptions(targetOptions, axisIndex, vertical, options) {
@@ -7,7 +7,8 @@ import { hasValue } from '../utils';
7
7
  import SeriesBinder from '../series-binder';
8
8
 
9
9
  import { WHITE, BLACK, X, Y, COORD_PRECISION, TOP, BOTTOM, LEFT, RIGHT, START, END, INHERIT } from '../../common/constants';
10
- import { append, deepExtend, defined, getSpacing, getTemplate, inArray, isFunction, isString, limitValue, round, setDefaultOptions, last } from '../../common';
10
+ import { append, deepExtend, defined, getSpacing, getTemplate, inArray, isFunction, isString,
11
+ limitValue, round, setDefaultOptions, last, cycleIndex } from '../../common';
11
12
  import { TRENDLINE_SERIES } from '../constants';
12
13
 
13
14
  class PlotAreaBase extends ChartElement {
@@ -818,6 +819,7 @@ class PlotAreaBase extends ChartElement {
818
819
  if (categoryIndex !== null) {
819
820
  for (let i = 0; i < charts.length; i++) {
820
821
  const chart = charts[i];
822
+
821
823
  if (chart.pane.options.name === "_navigator") {
822
824
  continue;
823
825
  }
@@ -843,6 +845,12 @@ class PlotAreaBase extends ChartElement {
843
845
  });
844
846
  }
845
847
 
848
+ pointsByPointIndex(pointIndex) {
849
+ return this.filterPoints(function(point) {
850
+ return point.getIndex() === pointIndex;
851
+ });
852
+ }
853
+
846
854
  pointsBySeriesName(name) {
847
855
  return this.filterPoints(function(point) {
848
856
  return point.series.name === name;
@@ -1004,6 +1012,64 @@ class PlotAreaBase extends ChartElement {
1004
1012
  seriesByName(name) {
1005
1013
  return this.series.find(series => series.name === name);
1006
1014
  }
1015
+
1016
+ getFirstPoint() {
1017
+ return this.pointsBySeriesIndex(0)[0];
1018
+ }
1019
+
1020
+ getPointBelow(point) {
1021
+ return this._getNextPoint(point, this._pointsByVertical, 1);
1022
+ }
1023
+
1024
+ getPointAbove(point) {
1025
+ return this._getNextPoint(point, this._pointsByVertical, -1);
1026
+ }
1027
+
1028
+ getPointToTheRight(point) {
1029
+ return this._getNextPoint(point, this._pointsByHorizontal, 1);
1030
+ }
1031
+
1032
+ getPointToTheLeft(point) {
1033
+ return this._getNextPoint(point, this._pointsByHorizontal, -1);
1034
+ }
1035
+
1036
+ _getNextPoint(point, getPointsFunc, increment) {
1037
+ let points = getPointsFunc.call(this, point);
1038
+ const pointIndex = points.indexOf(point);
1039
+ let nextIndex = pointIndex + increment;
1040
+ const loopPoints = (direction) => {
1041
+ // loop over to last non-empty collection
1042
+ let result;
1043
+ let offset = 0;
1044
+ do {
1045
+ offset += direction;
1046
+ result = getPointsFunc.call(this, point, offset);
1047
+ } while (result.length === 0);
1048
+
1049
+ return result;
1050
+ };
1051
+
1052
+ if (nextIndex < 0) {
1053
+ points = loopPoints(-1);
1054
+
1055
+ return points.at(-1);
1056
+ } else if (nextIndex >= points.length) {
1057
+ points = loopPoints(1);
1058
+
1059
+ return points.at(0);
1060
+ }
1061
+
1062
+ return points[nextIndex];
1063
+ }
1064
+
1065
+ _pointsByVertical(basePoint) {
1066
+ return this.pointsByPointIndex(basePoint.getIndex());
1067
+ }
1068
+
1069
+ _pointsByHorizontal(basePoint, offset = 0) {
1070
+ let index = cycleIndex(basePoint.series.index + offset, this.series.length);
1071
+ return this.pointsBySeriesIndex(index);
1072
+ }
1007
1073
  }
1008
1074
 
1009
1075
  function isSingleAxis(axis) {
@@ -158,6 +158,14 @@ class RadarPlotArea extends PolarPlotAreaBase {
158
158
  }
159
159
 
160
160
  createCrosshairs() {}
161
+
162
+ _pointsByVertical(basePoint) {
163
+ return super._pointsByVertical(basePoint).sort(this._getSeriesCompareFn());
164
+ }
165
+
166
+ _getSeriesCompareFn() {
167
+ return (a, b) => b.value - a.value;
168
+ }
161
169
  }
162
170
 
163
171
  deepExtend(RadarPlotArea.prototype, PlotAreaEventsMixin, {
@@ -6,6 +6,10 @@ class RadarSegment extends DonutSegment {
6
6
  constructor(value, options) {
7
7
  super(value, null, options);
8
8
  }
9
+
10
+ getIndex() {
11
+ return this.categoryIx;
12
+ }
9
13
  }
10
14
 
11
15
  setDefaultOptions(RadarSegment, {
@@ -5,7 +5,7 @@ import RangeLinePoint from './range-line-point';
5
5
  import PointEventsMixin from '../mixins/point-events-mixin';
6
6
  import NoteMixin from '../mixins/note-mixin';
7
7
 
8
- import { LINE_MARKER_SIZE, FADEIN, INITIAL_ANIMATION_DURATION, TOOLTIP_OFFSET, ABOVE, BELOW } from '../constants';
8
+ import { LINE_MARKER_SIZE, FADEIN, INITIAL_ANIMATION_DURATION, TOOLTIP_OFFSET, ABOVE, BELOW, CHART_POINT_ROLE, CHART_POINT_CLASSNAME, CHART_POINT_ROLE_DESCRIPTION } from '../constants';
9
9
  import { WHITE, CIRCLE, HIGHLIGHT_ZINDEX, LEFT, RIGHT, BOTTOM, CENTER } from '../../common/constants';
10
10
  import { deepExtend, valueOrDefault, getSpacing } from '../../common';
11
11
 
@@ -84,6 +84,14 @@ class RangeAreaPoint extends ChartElement {
84
84
  };
85
85
  }
86
86
 
87
+ createFocusHighlight() {
88
+ const group = new draw.Group();
89
+ group.append(this.fromPoint.createFocusHighlight());
90
+ group.append(this.toPoint.createFocusHighlight());
91
+
92
+ return group;
93
+ }
94
+
87
95
  tooltipAnchor() {
88
96
  const clipBox = this.owner.pane.clipBox();
89
97
  const showTooltip = !clipBox || clipBox.overlaps(this.box);
@@ -184,6 +192,18 @@ class RangeAreaPoint extends ChartElement {
184
192
  point.color = this.color;
185
193
  point.owner = this.owner;
186
194
  }
195
+
196
+ focusVisual() {
197
+ this.fromPoint.focusVisual();
198
+ }
199
+
200
+ clearFocusFromVisual() {
201
+ this.toPoint.clearFocusFromVisual();
202
+ }
203
+
204
+ getIndex() {
205
+ return this.categoryIx;
206
+ }
187
207
  }
188
208
 
189
209
  deepExtend(RangeAreaPoint.prototype, PointEventsMixin);
@@ -224,6 +244,11 @@ RangeAreaPoint.prototype.defaults = {
224
244
  },
225
245
  tooltip: {
226
246
  format: '{0} - {1}'
247
+ },
248
+ accessibility: {
249
+ role: CHART_POINT_ROLE,
250
+ className: CHART_POINT_CLASSNAME,
251
+ ariaRoleDescription: CHART_POINT_ROLE_DESCRIPTION
227
252
  }
228
253
  };
229
254
 
@@ -1,7 +1,6 @@
1
1
  import Bar from '../bar-chart/bar';
2
- import BarLabel from '../bar-chart/bar-label';
3
2
 
4
- import { deepExtend, getTemplate } from '../../common';
3
+ import { deepExtend } from '../../common';
5
4
 
6
5
  class RangeBar extends Bar {
7
6
  createLabel() {
@@ -10,36 +9,16 @@ class RangeBar extends Bar {
10
9
  const toOptions = deepExtend({}, labels, labels.to);
11
10
 
12
11
  if (fromOptions.visible) {
13
- this.labelFrom = this._createLabel(fromOptions);
12
+ this.labelFrom = this.createLabelElement(fromOptions);
14
13
  this.append(this.labelFrom);
15
14
  }
16
15
 
17
16
  if (toOptions.visible) {
18
- this.labelTo = this._createLabel(toOptions);
17
+ this.labelTo = this.createLabelElement(toOptions);
19
18
  this.append(this.labelTo);
20
19
  }
21
20
  }
22
21
 
23
- _createLabel(options) {
24
- const labelTemplate = getTemplate(options);
25
- const pointData = this.pointData();
26
-
27
- let labelText;
28
-
29
- if (labelTemplate) {
30
- labelText = labelTemplate(pointData);
31
- } else {
32
- labelText = this.formatValue(options.format);
33
- }
34
-
35
- return new BarLabel(labelText,
36
- deepExtend({
37
- vertical: this.options.vertical
38
- },
39
- options
40
- ), pointData);
41
- }
42
-
43
22
  reflow(targetBox) {
44
23
  this.render();
45
24
 
@@ -161,7 +161,7 @@ class ScatterChart extends ChartElement {
161
161
  excluded: [
162
162
  "data", "tooltip", "content", "template", "visual", "toggle",
163
163
  "_outOfRangeMinPoint", "_outOfRangeMaxPoint",
164
- "drilldownSeriesFactory"
164
+ "drilldownSeriesFactory", "ariaTemplate"
165
165
  ]
166
166
  };
167
167
 
@@ -1,4 +1,10 @@
1
1
  export const ARC = "arc";
2
+ export const ARROW_UP = "ArrowUp";
3
+ export const ARROW_DOWN = "ArrowDown";
4
+ export const ARROW_LEFT = "ArrowLeft";
5
+ export const ARROW_RIGHT = "ArrowRight";
6
+ export const TAB = "Tab";
7
+ export const ARIA_ACTIVE_DESCENDANT = "aria-activedescendant";
2
8
  export const AXIS_LABEL_CLICK = "axisLabelClick";
3
9
  export const BLACK = "#000";
4
10
  export const BOTTOM = "bottom";
@@ -0,0 +1,5 @@
1
+ export default function cycleDown(index, count) {
2
+ let result = index - 1;
3
+
4
+ return result < 0 ? count - 1 : result;
5
+ }
@@ -0,0 +1,13 @@
1
+ export default function cycleIndex(index, length) {
2
+ if (length === 1 || (index % length) === 0) {
3
+ return 0;
4
+ }
5
+
6
+ if (index < 0) {
7
+ return length + (index % length);
8
+ } else if (index >= length) {
9
+ return index % length;
10
+ }
11
+
12
+ return index;
13
+ }
@@ -0,0 +1,3 @@
1
+ export default function cycleUp(index, count) {
2
+ return (index + 1) % count;
3
+ }
@@ -3,6 +3,9 @@ export { default as removeClass } from './common/remove-class';
3
3
  export { default as alignPathToPixel } from './common/align-path-to-pixel';
4
4
  export { default as clockwise } from './common/clockwise';
5
5
  export { default as convertableToNumber } from './common/convertable-to-number';
6
+ export { default as cycleUp } from './common/cycleUp';
7
+ export { default as cycleDown } from './common/cycleDown';
8
+ export { default as cycleIndex } from './common/cycleIndex';
6
9
  export { default as deepExtend } from './common/deep-extend';
7
10
  export { default as elementStyles } from './common/element-styles';
8
11
  export { default as getSpacing } from './common/get-spacing';
@@ -1,7 +1,7 @@
1
1
  import { drawing as draw } from '@progress/kendo-drawing';
2
2
 
3
3
  import { WHITE } from '../common/constants';
4
- import { Class, deepExtend, defined, valueOrDefault } from '../common';
4
+ import { Class, deepExtend, defined, valueOrDefault, autoTextColor } from '../common';
5
5
 
6
6
  class ChartElement extends Class {
7
7
  constructor(options) {
@@ -251,8 +251,8 @@ class ChartElement extends Class {
251
251
  percentage: this.percentage,
252
252
  runningTotal: this.runningTotal,
253
253
  total: this.total
254
- }
255
- ));
254
+ })
255
+ );
256
256
 
257
257
  if (!highlight) {
258
258
  return;
@@ -271,6 +271,34 @@ class ChartElement extends Class {
271
271
  highlight.visible(show);
272
272
  }
273
273
 
274
+ toggleFocusHighlight(show) {
275
+ const options = ((this.options || {}).accessibility || {}).highlight || {};
276
+ let focusHighlight = this._focusHighlight;
277
+
278
+ if (!show && !focusHighlight) {
279
+ return;
280
+ }
281
+
282
+ if (!focusHighlight) {
283
+ const rootBackground = this.getRoot().options.background;
284
+ const highlightColor = autoTextColor(rootBackground);
285
+ const focusHighlightOptions = {
286
+ fill: {
287
+ opacity: options.opacity,
288
+ color: options.color
289
+ },
290
+ stroke: Object.assign({}, {color: highlightColor}, options.border),
291
+ zIndex: options.zIndex
292
+ };
293
+
294
+ focusHighlight = this._focusHighlight = this.createFocusHighlight(focusHighlightOptions);
295
+
296
+ this.appendVisual(focusHighlight);
297
+ }
298
+
299
+ focusHighlight.visible(show);
300
+ }
301
+
274
302
  createGradientOverlay(element, options, gradientOptions) {
275
303
  const overlay = new draw.Path(Object.assign({
276
304
  stroke: {
@@ -9,7 +9,7 @@ class ShapeBuilder extends Class {
9
9
  let endAngle = sector.angle + startAngle;
10
10
 
11
11
  //required in order to avoid reversing the arc direction in cases like 0.000000000000001 + 100 === 100
12
- if (sector.angle > 0 && startAngle === endAngle) {
12
+ if (sector.angle === 0 || sector.angle > 0 && startAngle === endAngle) {
13
13
  endAngle += DIRECTION_ANGLE;
14
14
  }
15
15
 
@@ -3,6 +3,7 @@ import { round, setDefaultOptions } from '../common';
3
3
  import { CENTER, CIRCLE, COORD_PRECISION, CROSS, ROUNDED_RECT, TRIANGLE } from '../common/constants';
4
4
  import { valueOrDefault } from '../drawing-utils';
5
5
  import BoxElement from './box-element';
6
+ import addAccessibilityAttributesToVisual from './utils/add-accessibility-attributes-to-visual';
6
7
 
7
8
  class ShapeElement extends BoxElement {
8
9
 
@@ -104,6 +105,8 @@ class ShapeElement extends BoxElement {
104
105
 
105
106
  createVisual() {
106
107
  this.visual = this.createElement();
108
+
109
+ addAccessibilityAttributesToVisual(this.visual, this.options.accessibilityOptions);
107
110
  }
108
111
  }
109
112
 
@@ -0,0 +1,8 @@
1
+ export default function addAccessibilityAttributesToVisual(visual, accessibilityOptions) {
2
+ if (accessibilityOptions) {
3
+ visual.options.className = accessibilityOptions.className;
4
+ visual.options.role = accessibilityOptions.role;
5
+ visual.options.ariaLabel = accessibilityOptions.ariaLabel;
6
+ visual.options.ariaRoleDescription = accessibilityOptions.ariaRoleDescription;
7
+ }
8
+ }
@@ -0,0 +1,17 @@
1
+ export default function guid() {
2
+ let id = "";
3
+ let i;
4
+ let random;
5
+
6
+ for (i = 0; i < 32; i++) {
7
+ random = Math.random() * 16 | 0;
8
+
9
+ if (i === 8 || i === 12 || i === 16 || i === 20) {
10
+ id += "-";
11
+ }
12
+
13
+ id += (i === 12 ? 4 : (i === 16 ? (random & 3 | 8) : random)).toString(16); // eslint-disable-line no-nested-ternary
14
+ }
15
+
16
+ return id;
17
+ }