mdt-charts 1.20.0 → 1.20.1

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 (57) hide show
  1. package/lib/config/config.d.ts +14 -0
  2. package/lib/engine/block/blockSvg.d.ts +1 -1
  3. package/lib/engine/block/blockSvg.js +1 -1
  4. package/lib/engine/elementHighlighter/elementHighlighter.d.ts +0 -1
  5. package/lib/engine/elementHighlighter/elementHighlighter.js +5 -8
  6. package/lib/engine/elementHighlighter/selectHighlighter.js +11 -10
  7. package/lib/engine/features/legend/legendMarkerCreator.js +1 -1
  8. package/lib/engine/features/markDots/markDot.d.ts +11 -3
  9. package/lib/engine/features/markDots/markDot.js +21 -10
  10. package/lib/engine/features/tolltip/tooltip.js +5 -4
  11. package/lib/engine/features/valueLabels/valueLabels.d.ts +45 -0
  12. package/lib/engine/features/valueLabels/valueLabels.js +139 -0
  13. package/lib/engine/features/valueLabels/valueLabelsHelper.d.ts +6 -0
  14. package/lib/engine/features/valueLabels/valueLabelsHelper.js +21 -0
  15. package/lib/engine/features/valueLabelsCollision/valueLabelsCollision.d.ts +23 -0
  16. package/lib/engine/features/valueLabelsCollision/valueLabelsCollision.js +24 -0
  17. package/lib/engine/features/valueLabelsCollision/valueLabelsCollisionHelper.d.ts +5 -0
  18. package/lib/engine/features/valueLabelsCollision/valueLabelsCollisionHelper.js +47 -0
  19. package/lib/engine/twoDimensionalNotation/area/area.d.ts +18 -11
  20. package/lib/engine/twoDimensionalNotation/area/area.js +32 -22
  21. package/lib/engine/twoDimensionalNotation/area/areaGenerator.d.ts +14 -0
  22. package/lib/engine/twoDimensionalNotation/area/areaGenerator.js +22 -0
  23. package/lib/engine/twoDimensionalNotation/area/areaHelper.d.ts +7 -7
  24. package/lib/engine/twoDimensionalNotation/area/areaHelper.js +30 -31
  25. package/lib/engine/twoDimensionalNotation/bar/barHelper.js +1 -1
  26. package/lib/engine/twoDimensionalNotation/bar/stackedData/dataStacker.d.ts +4 -2
  27. package/lib/engine/twoDimensionalNotation/bar/stackedData/dataStacker.js +2 -5
  28. package/lib/engine/twoDimensionalNotation/line/line.d.ts +0 -6
  29. package/lib/engine/twoDimensionalNotation/line/line.js +4 -4
  30. package/lib/engine/twoDimensionalNotation/line/lineGenerator.d.ts +4 -7
  31. package/lib/engine/twoDimensionalNotation/line/lineGenerator.js +2 -16
  32. package/lib/engine/twoDimensionalNotation/line/lineHelper.d.ts +4 -13
  33. package/lib/engine/twoDimensionalNotation/line/lineHelper.js +22 -10
  34. package/lib/engine/twoDimensionalNotation/lineLike/generatorFactory/lineLikeGeneratorFactory.d.ts +12 -0
  35. package/lib/engine/twoDimensionalNotation/lineLike/generatorFactory/lineLikeGeneratorFactory.js +1 -0
  36. package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorCurveMiddleware.d.ts +14 -0
  37. package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorCurveMiddleware.js +21 -0
  38. package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorDefineMiddleware.d.ts +20 -0
  39. package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorDefineMiddleware.js +9 -0
  40. package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorMiddleware.d.ts +5 -0
  41. package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorMiddleware.js +1 -0
  42. package/lib/engine/twoDimensionalNotation/twoDimensionalManager.d.ts +1 -0
  43. package/lib/engine/twoDimensionalNotation/twoDimensionalManager.js +19 -3
  44. package/lib/model/featuresModel/axisModel.js +3 -1
  45. package/lib/model/featuresModel/valueLabelsModel/valueLabelsModel.d.ts +9 -0
  46. package/lib/model/featuresModel/valueLabelsModel/valueLabelsModel.js +33 -0
  47. package/lib/model/helpers/modelHelper.d.ts +1 -0
  48. package/lib/model/helpers/modelHelper.js +3 -2
  49. package/lib/model/helpers/twoDimensionalModelHelper.d.ts +5 -0
  50. package/lib/model/helpers/twoDimensionalModelHelper.js +16 -0
  51. package/lib/model/model.d.ts +28 -5
  52. package/lib/model/modelInstance/configReader.d.ts +2 -1
  53. package/lib/model/modelInstance/configReader.js +17 -0
  54. package/lib/model/notations/twoDimensionalModel.js +24 -24
  55. package/package.json +1 -1
  56. /package/lib/engine/block/{defs.d.ts → defs/hatchPattern.d.ts} +0 -0
  57. /package/lib/engine/block/{defs.js → defs/hatchPattern.js} +0 -0
@@ -8,6 +8,7 @@ export declare type TwoDimensionalChartType = 'line' | 'bar' | 'area';
8
8
  export declare type PolarChartType = 'donut';
9
9
  export declare type IntervalChartType = 'gantt';
10
10
  export declare type EmbeddedLabelType = 'none' | 'key' | 'value';
11
+ export declare type ValueLabelsCollisionMode = "none" | "hide";
11
12
  export declare type MdtChartsDataRow = {
12
13
  [field: string]: any;
13
14
  };
@@ -53,6 +54,7 @@ export interface MdtChartsTwoDimensionalOptions extends GraphicNotationOptions {
53
54
  additionalElements: AdditionalElements;
54
55
  charts: MdtChartsTwoDimensionalChart[];
55
56
  orientation: ChartOrientation;
57
+ valueLabels?: TwoDimensionalValueLabels;
56
58
  }
57
59
  export interface MdtChartsPolarOptions extends GraphicNotationOptions {
58
60
  type: 'polar';
@@ -172,6 +174,12 @@ export interface MdtChartsShowAxisLabelRule {
172
174
  spaceForOneLabel?: number;
173
175
  showTickFn?: ShowTickFn;
174
176
  }
177
+ export interface TwoDimensionalValueLabels {
178
+ collision: ValueLabelsCollision;
179
+ }
180
+ export interface ValueLabelsCollision {
181
+ mode: ValueLabelsCollisionMode;
182
+ }
175
183
  export interface IntervalAxis {
176
184
  key: DiscreteAxisOptions;
177
185
  value: DateAxisOptions;
@@ -210,6 +218,7 @@ export interface MdtChartsTwoDimensionalChart extends ChartSettings, MdtChartsLi
210
218
  data: TwoDimensionalChartData;
211
219
  embeddedLabels: EmbeddedLabelType;
212
220
  isSegmented: boolean;
221
+ valueLabels?: TwoDimensionalChartValueLabels;
213
222
  }
214
223
  export interface PolarChart extends ChartSettings {
215
224
  type: PolarChartType;
@@ -224,6 +233,11 @@ export interface TwoDimensionalChartData {
224
233
  valueFields: TwoDimValueField[];
225
234
  valueGroup?: TwoDimensionalValueGroup;
226
235
  }
236
+ export interface TwoDimensionalChartValueLabels {
237
+ on: boolean;
238
+ format?: ValueLabelsFormatter;
239
+ }
240
+ export declare type ValueLabelsFormatter = (value: number) => string;
227
241
  export declare type TwoDimensionalValueGroup = 'main' | 'secondary';
228
242
  interface MarkersOptions {
229
243
  show: boolean;
@@ -23,6 +23,6 @@ export declare class BlockSvg {
23
23
  renderChartClipPath(margin: BlockMargin, blockSize: Size): void;
24
24
  updateChartClipPath(margin: BlockMargin, blockSize: Size): void;
25
25
  renderBarHatchPattern(): void;
26
- private ensureDefsRendered;
26
+ ensureDefsRendered(): Selection<SVGDefsElement, unknown, HTMLElement, unknown>;
27
27
  }
28
28
  export {};
@@ -1,6 +1,6 @@
1
1
  import { NamesHelper } from "../helpers/namesHelper";
2
2
  import { BlockHelper } from "./blockHelper";
3
- import { HatchPatternDef } from "./defs";
3
+ import { HatchPatternDef } from "./defs/hatchPattern";
4
4
  export class BlockSvg {
5
5
  constructor(options) {
6
6
  this.hatchPatternDef = new HatchPatternDef();
@@ -18,7 +18,6 @@ export declare class ElementHighlighter {
18
18
  static toggleDonutHighlightState(segment: Selection<SVGGElement, PieArcDatum<MdtChartsDataRow>, BaseType, unknown>, margin: BlockMargin, blockSize: Size, donutThickness: number, transitionDuration: number, on: boolean): Promise<any>;
19
19
  static removeDonutHighlightingByKeys(arcSegments: Selection<SVGGElement, PieArcDatum<MdtChartsDataRow>, BaseType, unknown>, keyFieldName: string, keyValues: string[], margin: BlockMargin, blockSize: Size, donutThickness: number): void;
20
20
  static setInactiveFor2D(block: Block, keyFieldName: string, charts: TwoDimensionalChartModel[]): void;
21
- static toggleMarkDotVisible(markDots: Selection<BaseType, any, BaseType, any>, isHighlight: boolean): void;
22
21
  static remove2DChartsFullHighlighting(block: Block, charts: TwoDimensionalChartModel[], transitionDuration?: number): void;
23
22
  static removeUnselected2DHighlight(block: Block, keyFieldName: string, charts: TwoDimensionalChartModel[], transitionDuration: number): void;
24
23
  static toggle2DElements(elemSelection: Selection<BaseType, any, BaseType, any>, isHighlight: boolean, chart: TwoDimensionalChartModel, transitionDuration: number): void;
@@ -1,13 +1,13 @@
1
1
  import { select } from 'd3-selection';
2
2
  import { easeLinear } from 'd3-ease';
3
3
  import { interrupt } from 'd3-transition';
4
- import { DonutHelper } from '../polarNotation/donut/DonutHelper';
5
4
  import { DomHelper, SelectionCondition } from '../helpers/domHelper';
6
5
  import { Donut } from '../polarNotation/donut/donut';
7
6
  import { MarkDot } from '../features/markDots/markDot';
8
7
  import { Helper } from '../helpers/helper';
9
8
  import * as chroma from 'chroma-js';
10
9
  import { NamesHelper } from '../helpers/namesHelper';
10
+ import { DonutHelper } from '../polarNotation/donut/DonutHelper';
11
11
  export class ElementHighlighter {
12
12
  static toggleActivityStyle(elementSelection, isActive) {
13
13
  elementSelection.classed(this.inactiveElemClass, !isActive);
@@ -86,14 +86,11 @@ export class ElementHighlighter {
86
86
  }
87
87
  });
88
88
  }
89
- static toggleMarkDotVisible(markDots, isHighlight) {
90
- markDots.classed(MarkDot.hiddenDotClass, !isHighlight);
91
- }
92
89
  static remove2DChartsFullHighlighting(block, charts, transitionDuration = 0) {
93
90
  charts.forEach(chart => {
94
91
  const elems = DomHelper.get2DChartElements(block, chart);
95
- if (chart.type !== 'bar' && !chart.markersOptions.show)
96
- elems.classed(MarkDot.hiddenDotClass, true);
92
+ if (chart.type !== 'bar')
93
+ MarkDot.tryMakeMarkDotVisible(elems, chart.markersOptions, false);
97
94
  this.toggle2DElements(elems, false, chart, transitionDuration);
98
95
  this.toggleActivityStyle(elems, true);
99
96
  });
@@ -102,8 +99,8 @@ export class ElementHighlighter {
102
99
  charts.forEach(chart => {
103
100
  const elems = DomHelper.get2DChartElements(block, chart);
104
101
  const selectedElems = DomHelper.getChartElementsByKeys(elems, chart.isSegmented, keyFieldName, block.filterEventManager.getSelectedKeys(), SelectionCondition.Exclude);
105
- if (chart.type !== 'bar' && !chart.markersOptions.show)
106
- selectedElems.classed(MarkDot.hiddenDotClass, true);
102
+ if (chart.type !== 'bar')
103
+ MarkDot.tryMakeMarkDotVisible(selectedElems, chart.markersOptions, false);
107
104
  this.toggle2DElements(selectedElems, false, chart, transitionDuration);
108
105
  if (block.filterEventManager.getSelectedKeys().length > 0)
109
106
  this.toggleActivityStyle(selectedElems, false);
@@ -4,6 +4,7 @@ import { DomHelper, SelectionCondition } from "../helpers/domHelper";
4
4
  import { Donut } from "../polarNotation/donut/donut";
5
5
  import { DonutHelper } from "../polarNotation/donut/DonutHelper";
6
6
  import { ElementHighlighter } from "./elementHighlighter";
7
+ import { MarkDot } from "../../engine/features/markDots/markDot";
7
8
  export class SelectHighlighter {
8
9
  static click2DHandler(multySelection, appendKey, keyValue, selectedKeys, block, options) {
9
10
  options.charts.forEach(chart => {
@@ -11,15 +12,15 @@ export class SelectHighlighter {
11
12
  const elements = DomHelper.get2DChartElements(block, chart);
12
13
  if (!appendKey) {
13
14
  ElementHighlighter.toggle2DElements(selectedElements, false, chart, block.transitionManager.durations.markerHover);
14
- if (chart.type !== 'bar' && !chart.markersOptions.show)
15
- ElementHighlighter.toggleMarkDotVisible(selectedElements, false);
15
+ if (chart.type !== 'bar')
16
+ MarkDot.tryMakeMarkDotVisible(selectedElements, chart.markersOptions, false);
16
17
  if (selectedKeys.length > 0) {
17
18
  ElementHighlighter.toggleActivityStyle(selectedElements, false);
18
19
  }
19
20
  else {
20
21
  ElementHighlighter.toggleActivityStyle(elements, true);
21
- if (chart.type !== 'bar' && !chart.markersOptions.show)
22
- ElementHighlighter.toggleMarkDotVisible(elements, false);
22
+ if (chart.type !== 'bar')
23
+ MarkDot.tryMakeMarkDotVisible(elements, chart.markersOptions, false);
23
24
  }
24
25
  return;
25
26
  }
@@ -31,13 +32,13 @@ export class SelectHighlighter {
31
32
  else {
32
33
  ElementHighlighter.toggle2DElements(DomHelper.getChartElementsByKeys(elements, chart.isSegmented, options.data.keyField.name, selectedKeys, SelectionCondition.Exclude), false, chart, block.transitionManager.durations.markerHover);
33
34
  ElementHighlighter.toggleActivityStyle(elements, false);
34
- if (chart.type !== 'bar' && !chart.markersOptions.show)
35
- ElementHighlighter.toggleMarkDotVisible(elements, false);
35
+ if (chart.type !== 'bar')
36
+ MarkDot.tryMakeMarkDotVisible(elements, chart.markersOptions, false);
36
37
  ElementHighlighter.toggleActivityStyle(selectedElements, true);
37
38
  ElementHighlighter.toggle2DElements(selectedElements, true, chart, block.transitionManager.durations.markerHover);
38
39
  }
39
- if (chart.type !== 'bar' && !chart.markersOptions.show)
40
- ElementHighlighter.toggleMarkDotVisible(selectedElements, true);
40
+ if (chart.type !== 'bar')
41
+ MarkDot.tryMakeMarkDotVisible(selectedElements, chart.markersOptions, true);
41
42
  });
42
43
  }
43
44
  static clickPolarHandler(multySelection, appendKey, selectedSegment, selectedKeys, margin, blockSize, block, options, arcItems, donutSettings) {
@@ -78,8 +79,8 @@ export class SelectHighlighter {
78
79
  const elements = DomHelper.get2DChartElements(block, chart);
79
80
  ElementHighlighter.toggle2DElements(elements, false, chart, block.transitionManager.durations.markerHover);
80
81
  ElementHighlighter.toggleActivityStyle(elements, true);
81
- if (chart.type !== 'bar' && !chart.markersOptions.show)
82
- ElementHighlighter.toggleMarkDotVisible(elements, false);
82
+ if (chart.type !== 'bar')
83
+ MarkDot.tryMakeMarkDotVisible(elements, chart.markersOptions, false);
83
84
  });
84
85
  }
85
86
  static clearPolar(margin, blockSize, block, options, arcItems, donutSettings) {
@@ -1,5 +1,5 @@
1
1
  import { Legend } from "./legend";
2
- import { HatchPatternDef } from "../../block/defs";
2
+ import { HatchPatternDef } from "../../block/defs/hatchPattern";
3
3
  import { applyLineDash } from "../../twoDimensionalNotation/line/lineHelper";
4
4
  export class LegendMarkerCreator {
5
5
  create(selection, options) {
@@ -1,19 +1,27 @@
1
1
  import { Selection, BaseType } from 'd3-selection';
2
2
  import { MdtChartsDataRow } from '../../../config/config';
3
- import { BlockMargin, Orient, TwoDimensionalChartModel } from "../../../model/model";
3
+ import { BlockMargin, MarkersOptions, Orient, TwoDimensionalChartModel } from "../../../model/model";
4
4
  import { Block } from "../../block/block";
5
5
  import { Scales } from "../scale/scale";
6
6
  export interface DotAttrs {
7
7
  cx: (data: MdtChartsDataRow) => number;
8
8
  cy: (data: MdtChartsDataRow) => number;
9
9
  }
10
+ interface MarkDotDataItem extends MdtChartsDataRow {
11
+ $mdtChartsMetadata: {
12
+ valueFieldName: string;
13
+ };
14
+ }
10
15
  export declare class MarkDot {
11
16
  static readonly markerDotClass: string;
12
17
  static readonly hiddenDotClass: string;
13
18
  static render(block: Block, data: MdtChartsDataRow[], keyAxisOrient: Orient, scales: Scales, margin: BlockMargin, keyFieldName: string, vfIndex: number, valueFieldName: string, chart: TwoDimensionalChartModel): void;
14
- static update(block: Block, newData: MdtChartsDataRow[], keyAxisOrient: Orient, scales: Scales, margin: BlockMargin, keyField: string, vfIndex: number, valueFieldName: string, chart: TwoDimensionalChartModel): void;
19
+ static update(block: Block, newData: MdtChartsDataRow[], keyAxisOrient: Orient, scales: Scales, margin: BlockMargin, keyFieldName: string, vfIndex: number, valueFieldName: string, chart: TwoDimensionalChartModel): void;
15
20
  static updateColors(block: Block, chart: TwoDimensionalChartModel, valueFieldIndex: number): void;
16
- static getMarkDotForChart(block: Block, chartCssClasses: string[]): Selection<BaseType, MdtChartsDataRow, BaseType, unknown>;
21
+ static getMarkDotForChart(block: Block, chartCssClasses: string[]): Selection<BaseType, MarkDotDataItem, BaseType, unknown>;
22
+ static tryMakeMarkDotVisible(elems: Selection<BaseType, MdtChartsDataRow, BaseType, unknown>, markersOptions: MarkersOptions, turnOnIfCan: boolean): void;
23
+ private static toggleMarkDotVisible;
17
24
  private static setClassesAndStyle;
18
25
  private static setAttrs;
19
26
  }
27
+ export {};
@@ -9,30 +9,31 @@ export class MarkDot {
9
9
  static render(block, data, keyAxisOrient, scales, margin, keyFieldName, vfIndex, valueFieldName, chart) {
10
10
  const dotsWrapper = block.svg.getChartGroup(chart.index)
11
11
  .selectAll(`.${this.markerDotClass}${Helper.getCssClassesLine(chart.cssClasses)}.chart-index-${vfIndex}`)
12
- .data(data)
12
+ .data(data.map(row => (Object.assign(Object.assign({}, row), { $mdtChartsMetadata: { valueFieldName } }))))
13
13
  .enter();
14
14
  const attrs = MarkDotHelper.getDotAttrs(keyAxisOrient, scales, margin, keyFieldName, valueFieldName, chart.isSegmented);
15
15
  const dots = dotsWrapper.append('circle');
16
16
  this.setAttrs(block, dots, attrs, chart.markersOptions.styles);
17
17
  this.setClassesAndStyle(dots, chart.cssClasses, vfIndex, chart.style.elementColors);
18
- if (!chart.markersOptions.show)
19
- dots.classed(this.hiddenDotClass, true);
18
+ MarkDot.tryMakeMarkDotVisible(dots, chart.markersOptions, false);
20
19
  }
21
- static update(block, newData, keyAxisOrient, scales, margin, keyField, vfIndex, valueFieldName, chart) {
20
+ static update(block, newData, keyAxisOrient, scales, margin, keyFieldName, vfIndex, valueFieldName, chart) {
22
21
  const dots = block.svg.getChartGroup(chart.index)
23
22
  .selectAll(`.${this.markerDotClass}${Helper.getCssClassesLine(chart.cssClasses)}.chart-element-${vfIndex}`)
24
- .data(newData);
23
+ .data(newData.map(row => (Object.assign(Object.assign({}, row), { $mdtChartsMetadata: { valueFieldName } }))));
25
24
  dots.exit().remove();
26
- if (chart.markersOptions.show)
27
- dots.classed(this.hiddenDotClass, false);
28
- const attrs = MarkDotHelper.getDotAttrs(keyAxisOrient, scales, margin, keyField, valueFieldName, chart.isSegmented);
25
+ dots.each(function (datum) {
26
+ if (chart.markersOptions.show({ row: datum, valueFieldName })) {
27
+ MarkDot.toggleMarkDotVisible(select(this), true);
28
+ }
29
+ });
30
+ const attrs = MarkDotHelper.getDotAttrs(keyAxisOrient, scales, margin, keyFieldName, valueFieldName, chart.isSegmented);
29
31
  const newDots = dots
30
32
  .enter()
31
33
  .append('circle');
32
34
  this.setAttrs(block, newDots, attrs, chart.markersOptions.styles);
33
35
  this.setClassesAndStyle(newDots, chart.cssClasses, vfIndex, chart.style.elementColors);
34
- if (!chart.markersOptions.show)
35
- newDots.classed(this.hiddenDotClass, true);
36
+ MarkDot.tryMakeMarkDotVisible(newDots, chart.markersOptions, false);
36
37
  const animationName = 'data-updating';
37
38
  dots
38
39
  .interrupt(animationName)
@@ -50,6 +51,16 @@ export class MarkDot {
50
51
  return block.getSvg()
51
52
  .selectAll(`.${MarkDot.markerDotClass}${Helper.getCssClassesLine(chartCssClasses)}`);
52
53
  }
54
+ static tryMakeMarkDotVisible(elems, markersOptions, turnOnIfCan) {
55
+ elems.each(function (datum) {
56
+ var _a;
57
+ if (!markersOptions.show({ row: datum, valueFieldName: (_a = datum.$mdtChartsMetadata) === null || _a === void 0 ? void 0 : _a.valueFieldName }))
58
+ MarkDot.toggleMarkDotVisible(select(this), turnOnIfCan);
59
+ });
60
+ }
61
+ static toggleMarkDotVisible(markDots, isHighlight) {
62
+ markDots.classed(MarkDot.hiddenDotClass, !isHighlight);
63
+ }
53
64
  static setClassesAndStyle(dots, cssClasses, vfIndex, elementColors) {
54
65
  DomHelper.setCssClasses(dots, Helper.getCssClassesWithElementIndex(cssClasses, vfIndex));
55
66
  DomHelper.setChartElementColor(dots, elementColors, vfIndex, 'stroke');
@@ -10,6 +10,7 @@ import { Helper } from '../../helpers/helper';
10
10
  import { TooltipHelper } from './tooltipHelper';
11
11
  import { DomHelper } from '../../helpers/domHelper';
12
12
  import { NewTooltip } from './newTooltip/newTooltip';
13
+ import { MarkDot } from "../../../engine/features/markDots/markDot";
13
14
  export class Tooltip {
14
15
  static render(block, model, data, tooltipOptions, scales) {
15
16
  TooltipComponentsManager.renderTooltipWrapper(block);
@@ -79,16 +80,16 @@ export class Tooltip {
79
80
  const elements = DomHelper.get2DChartElements(block, chart);
80
81
  if (!block.filterEventManager.isSelected(currentKey)) {
81
82
  const oldElements = DomHelper.getChartElementsByKeys(elements, chart.isSegmented, args.dataOptions.keyField.name, [currentKey]);
82
- if (chart.type !== 'bar' && !chart.markersOptions.show)
83
- ElementHighlighter.toggleMarkDotVisible(oldElements, false);
83
+ if (chart.type !== 'bar')
84
+ MarkDot.tryMakeMarkDotVisible(oldElements, chart.markersOptions, false);
84
85
  ElementHighlighter.toggle2DElements(oldElements, false, chart, block.transitionManager.durations.markerHover);
85
86
  if (block.filterEventManager.getSelectedKeys().length > 0) {
86
87
  ElementHighlighter.toggleActivityStyle(oldElements, false);
87
88
  }
88
89
  }
89
90
  const selectedElements = DomHelper.getChartElementsByKeys(elements, chart.isSegmented, args.dataOptions.keyField.name, [keyValue]);
90
- if (chart.type !== 'bar' && !chart.markersOptions.show)
91
- ElementHighlighter.toggleMarkDotVisible(selectedElements, true);
91
+ if (chart.type !== 'bar')
92
+ MarkDot.tryMakeMarkDotVisible(selectedElements, chart.markersOptions, true);
92
93
  ElementHighlighter.toggleActivityStyle(selectedElements, true);
93
94
  if (block.filterEventManager.getSelectedKeys().length === 0 || block.filterEventManager.isSelected(keyValue)) {
94
95
  ElementHighlighter.toggle2DElements(selectedElements, true, chart, block.transitionManager.durations.markerHover);
@@ -0,0 +1,45 @@
1
+ import { Block } from "../../../engine/block/block";
2
+ import { OptionsModelData, Orient, TwoDimensionalChartModel, TwoDimensionalValueLabels, ValueLabelAnchor, ValueLabelDominantBaseline } from "../../../model/model";
3
+ import { MdtChartsDataRow, MdtChartsDataSource } from "../../../config/config";
4
+ import { Scales, ScalesWithSecondary } from "../../../engine/features/scale/scale";
5
+ export interface ValueLabelsOptions {
6
+ elementAccessors: {
7
+ getBlock: () => Block;
8
+ };
9
+ data: {
10
+ keyFieldName: string;
11
+ };
12
+ canvas: {
13
+ keyAxisOrient: Orient;
14
+ valueLabels: TwoDimensionalValueLabels;
15
+ };
16
+ }
17
+ export interface ValueLabelAttrs {
18
+ x: (data: MdtChartsDataRow) => number;
19
+ y: (data: MdtChartsDataRow) => number;
20
+ textAnchor: ValueLabelAnchor;
21
+ dominantBaseline: ValueLabelDominantBaseline;
22
+ }
23
+ export declare class ChartValueLabels {
24
+ private readonly globalOptions;
25
+ private readonly chart;
26
+ private static readonly valueLabelClass;
27
+ constructor(globalOptions: ValueLabelsOptions, chart: TwoDimensionalChartModel);
28
+ render(scales: Scales, data: MdtChartsDataRow[]): void;
29
+ update(scales: Scales, newData: MdtChartsDataRow[]): Promise<void[]>;
30
+ static getChartValueLabelsClassName(): string;
31
+ private getAllValueLabelsOfChart;
32
+ private setAttrs;
33
+ private setClasses;
34
+ }
35
+ export declare class CanvasValueLabels {
36
+ private readonly options;
37
+ private chartsValueLabels;
38
+ constructor(options: ValueLabelsOptions);
39
+ render(scales: ScalesWithSecondary, charts: TwoDimensionalChartModel[], data: MdtChartsDataSource, dataOptions: OptionsModelData): void;
40
+ update(scales: ScalesWithSecondary, charts: TwoDimensionalChartModel[], data: MdtChartsDataSource, dataOptions: OptionsModelData): void;
41
+ private toggleOldValueLabelsVisibility;
42
+ private hideValueLabelsCollision;
43
+ private getAllValueLabels;
44
+ private getChartScales;
45
+ }
@@ -0,0 +1,139 @@
1
+ import { NamesHelper } from "../../../engine/helpers/namesHelper";
2
+ import { ValueLabelsHelper } from "../../../engine/features/valueLabels/valueLabelsHelper";
3
+ import { Helper } from "../../../engine/helpers/helper";
4
+ import { select } from "d3-selection";
5
+ import { DomHelper } from "../../../engine/helpers/domHelper";
6
+ import { CLASSES } from "../../../model/modelBuilder";
7
+ import { ValueLabelsCollision } from "../../../engine/features/valueLabelsCollision/valueLabelsCollision";
8
+ export class ChartValueLabels {
9
+ constructor(globalOptions, chart) {
10
+ this.globalOptions = globalOptions;
11
+ this.chart = chart;
12
+ }
13
+ render(scales, data) {
14
+ this.chart.data.valueFields.forEach((valueField, vfIndex) => {
15
+ const valueLabels = this.getAllValueLabelsOfChart(vfIndex)
16
+ .data(data)
17
+ .enter()
18
+ .append('text');
19
+ const attrs = ValueLabelsHelper.getValueLabelsAttrs(this.globalOptions, this.chart.valueLabels, scales, valueField);
20
+ this.setAttrs(valueLabels, attrs, valueField.name, this.chart.valueLabels.format);
21
+ this.setClasses(valueLabels, this.chart.cssClasses, vfIndex);
22
+ });
23
+ }
24
+ update(scales, newData) {
25
+ const updatePromises = [];
26
+ this.chart.data.valueFields.forEach((valueField, vfIndex) => {
27
+ const updateProms = new Promise((resolve) => {
28
+ const valueLabels = this.getAllValueLabelsOfChart(vfIndex)
29
+ .data(newData);
30
+ valueLabels.exit().remove();
31
+ const attrs = ValueLabelsHelper.getValueLabelsAttrs(this.globalOptions, this.chart.valueLabels, scales, valueField);
32
+ const newValueLabels = valueLabels
33
+ .enter()
34
+ .append('text');
35
+ const mergedValueLabels = newValueLabels.merge(valueLabels);
36
+ this.setAttrs(newValueLabels, attrs, valueField.name, this.chart.valueLabels.format);
37
+ this.setClasses(mergedValueLabels, this.chart.cssClasses, vfIndex);
38
+ this.setAttrs(valueLabels, attrs, valueField.name, this.chart.valueLabels.format, true, resolve);
39
+ });
40
+ updatePromises.push(updateProms);
41
+ });
42
+ return Promise.all(updatePromises);
43
+ }
44
+ static getChartValueLabelsClassName() {
45
+ return ChartValueLabels.valueLabelClass;
46
+ }
47
+ getAllValueLabelsOfChart(vfIndex) {
48
+ const block = this.globalOptions.elementAccessors.getBlock().svg.getChartBlock();
49
+ return block
50
+ .selectAll(`.${ChartValueLabels.valueLabelClass}.${CLASSES.dataLabel}${Helper.getCssClassesLine(this.chart.cssClasses)}.chart-element-${vfIndex}`);
51
+ }
52
+ setAttrs(valueLabels, attrs, valueFieldName, formatter, animate = false, onEndAnimation) {
53
+ const animationName = 'labels-updating';
54
+ valueLabels
55
+ .text(d => formatter(d[valueFieldName]))
56
+ .attr('dominant-baseline', attrs.dominantBaseline)
57
+ .attr('text-anchor', attrs.textAnchor);
58
+ if (animate) {
59
+ const transition = valueLabels
60
+ .interrupt(animationName)
61
+ .transition(animationName)
62
+ .duration(this.globalOptions.elementAccessors.getBlock().transitionManager.durations.chartUpdate)
63
+ .attr('x', d => attrs.x(d))
64
+ .attr('y', d => attrs.y(d));
65
+ if (onEndAnimation)
66
+ transition.on('end', onEndAnimation);
67
+ }
68
+ else {
69
+ valueLabels
70
+ .attr('x', d => attrs.x(d))
71
+ .attr('y', d => attrs.y(d));
72
+ }
73
+ }
74
+ setClasses(textLabels, cssClasses, vfIndex) {
75
+ textLabels.classed(ChartValueLabels.valueLabelClass, true);
76
+ textLabels.classed(CLASSES.dataLabel, true);
77
+ DomHelper.setCssClasses(textLabels, Helper.getCssClassesWithElementIndex(cssClasses, vfIndex));
78
+ }
79
+ }
80
+ ChartValueLabels.valueLabelClass = NamesHelper.getClassName("value-label");
81
+ export class CanvasValueLabels {
82
+ constructor(options) {
83
+ this.options = options;
84
+ this.chartsValueLabels = [];
85
+ }
86
+ render(scales, charts, data, dataOptions) {
87
+ const chartsWithLabels = charts.filter(chart => { var _a; return (_a = chart.valueLabels) === null || _a === void 0 ? void 0 : _a.show; });
88
+ if (chartsWithLabels.length === 0)
89
+ return;
90
+ chartsWithLabels.forEach(chart => {
91
+ const chartScales = this.getChartScales(scales, chart);
92
+ const chartValueLabels = new ChartValueLabels(this.options, chart);
93
+ this.chartsValueLabels.push(chartValueLabels);
94
+ chartValueLabels.render(chartScales, data[dataOptions.dataSource]);
95
+ });
96
+ if (this.options.canvas.valueLabels.collision.mode === 'hide') {
97
+ this.hideValueLabelsCollision();
98
+ }
99
+ }
100
+ update(scales, charts, data, dataOptions) {
101
+ const chartsWithLabels = charts.filter(chart => { var _a; return (_a = chart.valueLabels) === null || _a === void 0 ? void 0 : _a.show; });
102
+ if (chartsWithLabels.length === 0)
103
+ return;
104
+ if (this.options.canvas.valueLabels.collision.mode === 'hide')
105
+ this.toggleOldValueLabelsVisibility();
106
+ const chartsUpdatePromises = chartsWithLabels.map((chart, index) => {
107
+ const chartScales = this.getChartScales(scales, chart);
108
+ return this.chartsValueLabels[index].update(chartScales, data[dataOptions.dataSource]);
109
+ });
110
+ if (this.options.canvas.valueLabels.collision.mode === 'hide') {
111
+ Promise.all(chartsUpdatePromises).then(() => {
112
+ this.hideValueLabelsCollision();
113
+ });
114
+ }
115
+ }
116
+ toggleOldValueLabelsVisibility() {
117
+ const oldValueLabels = this.getAllValueLabels();
118
+ oldValueLabels.each(function () {
119
+ if (this.style.display === 'none')
120
+ select(this).style('display', 'block');
121
+ });
122
+ }
123
+ hideValueLabelsCollision() {
124
+ const newValueLabels = this.getAllValueLabels();
125
+ const valueLabelElementsRectInfo = ValueLabelsCollision.getValueLabelElementsRectInfo(newValueLabels);
126
+ ValueLabelsCollision.toggleValueLabelElementsVisibility(valueLabelElementsRectInfo);
127
+ }
128
+ getAllValueLabels() {
129
+ const block = this.options.elementAccessors.getBlock().svg.getChartBlock();
130
+ return block
131
+ .selectAll(`.${ChartValueLabels.getChartValueLabelsClassName()}`);
132
+ }
133
+ getChartScales(scales, chart) {
134
+ return {
135
+ key: scales.key,
136
+ value: chart.data.valueGroup === "secondary" ? scales.valueSecondary : scales.value
137
+ };
138
+ }
139
+ }
@@ -0,0 +1,6 @@
1
+ import { ValueLabelAttrs, ValueLabelsOptions } from "../../../engine/features/valueLabels/valueLabels";
2
+ import { TwoDimChartValueLabelsOptions, ValueField } from "../../../model/model";
3
+ import { Scales } from "../../../engine/features/scale/scale";
4
+ export declare class ValueLabelsHelper {
5
+ static getValueLabelsAttrs(globalOptions: ValueLabelsOptions, valueLabels: TwoDimChartValueLabelsOptions, scales: Scales, valueField: ValueField): ValueLabelAttrs;
6
+ }
@@ -0,0 +1,21 @@
1
+ import { Scale } from "../../../engine/features/scale/scale";
2
+ export class ValueLabelsHelper {
3
+ static getValueLabelsAttrs(globalOptions, valueLabels, scales, valueField) {
4
+ let attrs = {
5
+ x: null,
6
+ y: null,
7
+ dominantBaseline: valueLabels.dominantBaseline,
8
+ textAnchor: valueLabels.textAnchor
9
+ };
10
+ const orient = globalOptions.canvas.keyAxisOrient;
11
+ if (orient === 'left' || orient === 'right') {
12
+ attrs.x = d => valueLabels.handleX(scales.value(d[valueField.name]));
13
+ attrs.y = d => valueLabels.handleY(Scale.getScaledValue(scales.key, d[globalOptions.data.keyFieldName]));
14
+ }
15
+ else if (orient === 'bottom' || orient === 'top') {
16
+ attrs.x = d => valueLabels.handleX(Scale.getScaledValue(scales.key, d[globalOptions.data.keyFieldName]));
17
+ attrs.y = d => valueLabels.handleY(scales.value(d[valueField.name]));
18
+ }
19
+ return attrs;
20
+ }
21
+ }
@@ -0,0 +1,23 @@
1
+ import { Selection } from "d3-selection";
2
+ export declare type ValueLabelOnCanvasIndex = number;
3
+ export interface BoundingRect {
4
+ x: number;
5
+ y: number;
6
+ width: number;
7
+ height: number;
8
+ }
9
+ export interface ValueLabelElementRectInfo {
10
+ index: ValueLabelOnCanvasIndex;
11
+ boundingClientRect: BoundingRect;
12
+ }
13
+ export interface ValueLabelElement extends ValueLabelElementRectInfo {
14
+ svgElement: SVGTextElement;
15
+ }
16
+ export interface LabelVisibility {
17
+ index: ValueLabelOnCanvasIndex;
18
+ isVisible: boolean;
19
+ }
20
+ export declare class ValueLabelsCollision {
21
+ static getValueLabelElementsRectInfo(valueLabels: Selection<SVGTextElement, unknown, SVGGElement, unknown>): ValueLabelElement[];
22
+ static toggleValueLabelElementsVisibility(elements: ValueLabelElement[]): void;
23
+ }
@@ -0,0 +1,24 @@
1
+ import { select } from "d3-selection";
2
+ import { ValueLabelsCollisionHelper } from "../../../engine/features/valueLabelsCollision/valueLabelsCollisionHelper";
3
+ export class ValueLabelsCollision {
4
+ static getValueLabelElementsRectInfo(valueLabels) {
5
+ let ValueLabelElementsReactInfo = [];
6
+ valueLabels.each(function (_, index) {
7
+ const { x, y, height, width } = this.getBoundingClientRect();
8
+ ValueLabelElementsReactInfo.push({
9
+ index,
10
+ svgElement: this,
11
+ boundingClientRect: { x, y, width, height }
12
+ });
13
+ });
14
+ return ValueLabelElementsReactInfo;
15
+ }
16
+ static toggleValueLabelElementsVisibility(elements) {
17
+ const labelsVisibility = ValueLabelsCollisionHelper.calculateValueLabelsVisibility(elements);
18
+ labelsVisibility.forEach(label => {
19
+ const labelInfo = elements.find(element => element.index === label.index);
20
+ if (labelInfo && !label.isVisible)
21
+ select(labelInfo.svgElement).style('display', 'none');
22
+ });
23
+ }
24
+ }
@@ -0,0 +1,5 @@
1
+ import { LabelVisibility, ValueLabelElementRectInfo } from "../../../engine/features/valueLabelsCollision/valueLabelsCollision";
2
+ export declare class ValueLabelsCollisionHelper {
3
+ static calculateValueLabelsVisibility(elements: ValueLabelElementRectInfo[]): Map<number, LabelVisibility>;
4
+ private static isOverlapping;
5
+ }
@@ -0,0 +1,47 @@
1
+ export class ValueLabelsCollisionHelper {
2
+ static calculateValueLabelsVisibility(elements) {
3
+ const sortedLabels = elements.sort((label1, label2) => label1.boundingClientRect.x - label2.boundingClientRect.x);
4
+ const activeLabels = [];
5
+ const labelsVisibility = new Map();
6
+ elements.forEach(label => {
7
+ labelsVisibility.set(label.index, { index: label.index, isVisible: true });
8
+ });
9
+ sortedLabels.forEach(currentLabel => {
10
+ for (let i = activeLabels.length - 1; i >= 0; i--) {
11
+ const activeLabel = activeLabels[i];
12
+ if (activeLabel.boundingClientRect.x + activeLabel.boundingClientRect.width < currentLabel.boundingClientRect.x) {
13
+ activeLabels.splice(i, 1);
14
+ }
15
+ }
16
+ for (const activeLabel of activeLabels) {
17
+ if (this.isOverlapping(currentLabel.boundingClientRect, activeLabel.boundingClientRect)) {
18
+ if (currentLabel.boundingClientRect.x > activeLabel.boundingClientRect.x) {
19
+ labelsVisibility.get(currentLabel.index).isVisible = false;
20
+ break;
21
+ }
22
+ else if (currentLabel.boundingClientRect.x === activeLabel.boundingClientRect.x) {
23
+ if (currentLabel.boundingClientRect.y > activeLabel.boundingClientRect.y) {
24
+ labelsVisibility.get(currentLabel.index).isVisible = false;
25
+ break;
26
+ }
27
+ else
28
+ labelsVisibility.get(activeLabel.index).isVisible = false;
29
+ }
30
+ else
31
+ labelsVisibility.get(activeLabel.index).isVisible = false;
32
+ }
33
+ }
34
+ if (labelsVisibility.get(currentLabel.index).isVisible) {
35
+ activeLabels.push(currentLabel);
36
+ }
37
+ });
38
+ return labelsVisibility;
39
+ }
40
+ static isOverlapping(rect1, rect2) {
41
+ return !(rect1.x + rect1.width < rect2.x ||
42
+ rect1.x > rect2.x + rect2.width ||
43
+ rect1.y + rect1.height < rect2.y ||
44
+ rect1.y > rect2.y + rect2.height);
45
+ }
46
+ ;
47
+ }