mdt-charts 1.40.1 → 1.41.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 (36) hide show
  1. package/lib/config/config.d.ts +3 -0
  2. package/lib/config/valueLabelsConfig.d.ts +19 -0
  3. package/lib/config/valueLabelsConfig.js +1 -0
  4. package/lib/engine/colorReader/colorReader.d.ts +0 -4
  5. package/lib/engine/colorReader/colorReader.js +0 -12
  6. package/lib/engine/elementHighlighter/elementHighlighter.d.ts +6 -7
  7. package/lib/engine/elementHighlighter/elementHighlighter.js +3 -3
  8. package/lib/engine/elementHighlighter/selectHighlighter.d.ts +3 -4
  9. package/lib/engine/elementHighlighter/selectHighlighter.js +1 -1
  10. package/lib/engine/features/legend/legendEventsManager.js +4 -4
  11. package/lib/engine/features/tolltip/tooltip.js +6 -6
  12. package/lib/engine/filterManager/filterEventManager.js +2 -2
  13. package/lib/engine/helpers/domSelectionHelper.d.ts +3 -1
  14. package/lib/engine/helpers/domSelectionHelper.js +8 -0
  15. package/lib/engine/polarNotation/donut/donut.d.ts +11 -12
  16. package/lib/engine/polarNotation/donut/donut.js +70 -45
  17. package/lib/engine/polarNotation/donut/donutHelper.d.ts +7 -4
  18. package/lib/engine/polarNotation/donut/donutHelper.js +9 -16
  19. package/lib/engine/polarNotation/polarManager.d.ts +1 -0
  20. package/lib/engine/polarNotation/polarManager.js +8 -3
  21. package/lib/engine/sunburstNotation/sunburst.d.ts +2 -1
  22. package/lib/engine/sunburstNotation/sunburst.js +30 -6
  23. package/lib/engine/sunburstNotation/sunburstSegmentLabel.d.ts +20 -0
  24. package/lib/engine/sunburstNotation/sunburstSegmentLabel.js +86 -0
  25. package/lib/model/featuresModel/tooltipModel/contentByNotations/polarInitialRowsProvider.d.ts +2 -5
  26. package/lib/model/featuresModel/tooltipModel/contentByNotations/polarInitialRowsProvider.js +4 -8
  27. package/lib/model/model.d.ts +10 -0
  28. package/lib/model/modelTypes/valueLabelsModel.d.ts +15 -0
  29. package/lib/model/modelTypes/valueLabelsModel.js +1 -0
  30. package/lib/model/notations/polar/polarModel.js +31 -15
  31. package/lib/model/notations/polar/segmentModelBuilder/segmentModelBuilder.d.ts +15 -0
  32. package/lib/model/notations/polar/segmentModelBuilder/segmentModelBuilder.js +19 -0
  33. package/lib/model/notations/sunburst/levelModelBuilder/levelModelBuilder.js +60 -40
  34. package/lib/style/charts-main.css +8 -0
  35. package/lib/style/charts-main.less +8 -0
  36. package/package.json +1 -1
@@ -1,4 +1,5 @@
1
1
  import { MdtChartsDonutThicknessOptions } from "../designer/designerConfig";
2
+ import { DonutChartValueLabelsConfig, SunburstChartValueLabelsConfig } from "./valueLabelsConfig";
2
3
  declare type DataType = string;
3
4
  export declare type MdtChartsIconElement = () => HTMLElement;
4
5
  export declare type ItemPositionByOrientation = "start" | "end";
@@ -104,6 +105,7 @@ export interface MdtChartsSunburstLevel {
104
105
  canvas?: {
105
106
  thickness?: MdtChartsDonutThicknessOptions;
106
107
  };
108
+ valueLabels?: SunburstChartValueLabelsConfig;
107
109
  }
108
110
  export interface Legend {
109
111
  show: boolean;
@@ -373,6 +375,7 @@ export interface DonutChart {
373
375
  type: "donut";
374
376
  data: PolarChartData;
375
377
  aggregator?: MdtChartsDonutAggregator;
378
+ valueLabels?: DonutChartValueLabelsConfig;
376
379
  }
377
380
  export interface TwoDimensionalChartData {
378
381
  valueFields: TwoDimValueField[];
@@ -0,0 +1,19 @@
1
+ import { MdtChartsDataRow } from "./config";
2
+ export interface DonutChartValueLabelsConfig {
3
+ on: boolean;
4
+ rotation?: {
5
+ type: "none" | "tangential";
6
+ };
7
+ cssClass?: string;
8
+ content?: (dataRow: MdtChartsDataRow) => string;
9
+ }
10
+ export interface SunburstChartValueLabelsConfig {
11
+ on: boolean;
12
+ rotation?: {
13
+ type: "none" | "tangential";
14
+ };
15
+ cssClass?: string;
16
+ content?: (segment: {
17
+ attachedDataRows: MdtChartsDataRow[];
18
+ }) => string;
19
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,10 +1,6 @@
1
- import { MdtChartsDataRow } from "../../config/config";
2
1
  import { DonutChartModel } from "../../model/model";
3
2
  export declare class ColorReaderClass {
4
- getColorForArc(row: MdtChartsDataRow, chart: DonutChartModel, arcIndex: number): any;
5
3
  getChartColorField(chart: DonutChartModel): string;
6
4
  isNeedReadFromData(chart: DonutChartModel): boolean;
7
- private getColorFromData;
8
- private getColorFromPalette;
9
5
  }
10
6
  export declare const ColorReader: ColorReaderClass;
@@ -1,21 +1,9 @@
1
1
  export class ColorReaderClass {
2
- getColorForArc(row, chart, arcIndex) {
3
- if (chart.data.colorField) {
4
- return this.getColorFromData(row, chart.data.colorField);
5
- }
6
- return this.getColorFromPalette(chart.style.elementColors, arcIndex);
7
- }
8
2
  getChartColorField(chart) {
9
3
  return chart.data.colorField;
10
4
  }
11
5
  isNeedReadFromData(chart) {
12
6
  return !!this.getChartColorField(chart);
13
7
  }
14
- getColorFromData(row, colorField) {
15
- return row[colorField];
16
- }
17
- getColorFromPalette(colorPalette, arcIndex) {
18
- return colorPalette[arcIndex % colorPalette.length];
19
- }
20
8
  }
21
9
  export const ColorReader = new ColorReaderClass();
@@ -1,8 +1,7 @@
1
1
  import { Selection, BaseType } from "d3-selection";
2
2
  import { PieArcDatum } from "d3-shape";
3
- import { DonutChartSizesModel, TwoDimensionalChartModel } from "../../model/model";
3
+ import { DonutChartSizesModel, PolarSegmentModel, TwoDimensionalChartModel } from "../../model/model";
4
4
  import { Block } from "../block/block";
5
- import { MdtChartsDataRow } from "../../config/config";
6
5
  export declare class ElementHighlighter {
7
6
  private static inactiveElemClass;
8
7
  static toggleActivityStyle(elementSelection: Selection<BaseType, unknown, BaseType, unknown>, isActive: boolean): void;
@@ -11,12 +10,12 @@ export declare class ElementHighlighter {
11
10
  */
12
11
  static setShadowFilter(elemSelection: Selection<BaseType, any, BaseType, any>, blurPercent?: number): void;
13
12
  static removeFilter(elemSelection: Selection<BaseType, any, BaseType, any>): void;
14
- static removeShadowClone(block: Block, keyFieldName: string, selectedSegment: Selection<SVGGElement, PieArcDatum<MdtChartsDataRow>, BaseType, unknown>, chartSizes: DonutChartSizesModel): void;
15
- static removeCloneForElem(block: Block, keyFieldName: string, selectedSegment: Selection<SVGGElement, PieArcDatum<MdtChartsDataRow>, BaseType, unknown>): void;
13
+ static removeShadowClone(block: Block, keyFieldName: string, selectedSegment: Selection<SVGGElement, PieArcDatum<PolarSegmentModel>, BaseType, unknown>, chartSizes: DonutChartSizesModel): void;
14
+ static removeCloneForElem(block: Block, keyFieldName: string, selectedSegment: Selection<SVGGElement, PieArcDatum<PolarSegmentModel>, BaseType, unknown>): void;
16
15
  static removeDonutArcClones(block: Block): void;
17
- static renderArcCloneAndHighlight(block: Block, arcSelection: Selection<SVGGElement, PieArcDatum<MdtChartsDataRow>, BaseType, unknown>, chartSizes: DonutChartSizesModel): void;
18
- static toggleDonutHighlightState(segment: Selection<SVGGElement, PieArcDatum<MdtChartsDataRow>, BaseType, unknown>, chartSizes: DonutChartSizesModel, transitionDuration: number, on: boolean): Promise<any>;
19
- static removeDonutHighlightingByKeys(arcSegments: Selection<SVGGElement, PieArcDatum<MdtChartsDataRow>, BaseType, unknown>, keyFieldName: string, keyValues: string[], chartSizes: DonutChartSizesModel): void;
16
+ static renderArcCloneAndHighlight(block: Block, arcSelection: Selection<SVGGElement, PieArcDatum<PolarSegmentModel>, BaseType, unknown>, chartSizes: DonutChartSizesModel): void;
17
+ static toggleDonutHighlightState(segment: Selection<SVGGElement, PieArcDatum<PolarSegmentModel>, BaseType, unknown>, chartSizes: DonutChartSizesModel, transitionDuration: number, on: boolean): Promise<any>;
18
+ static removeDonutHighlightingByKeys(arcSegments: Selection<SVGGElement, PieArcDatum<PolarSegmentModel>, BaseType, unknown>, keyFieldName: string, keyValues: string[], chartSizes: DonutChartSizesModel): void;
20
19
  static setInactiveFor2D(block: Block, keyFieldName: string, charts: TwoDimensionalChartModel[]): void;
21
20
  static remove2DChartsFullHighlighting(block: Block, charts: TwoDimensionalChartModel[], transitionDuration?: number): void;
22
21
  static removeUnselected2DHighlight(block: Block, keyFieldName: string, charts: TwoDimensionalChartModel[], transitionDuration: number): void;
@@ -28,12 +28,12 @@ export class ElementHighlighter {
28
28
  elemSelection.style("filter", null);
29
29
  }
30
30
  static removeShadowClone(block, keyFieldName, selectedSegment, chartSizes) {
31
- const shadowClone = Donut.getAllArcShadows(block).filter((d) => d.data[keyFieldName] === selectedSegment.datum().data[keyFieldName]);
31
+ const shadowClone = Donut.getAllArcShadows(block).filter((d) => d.data.key === selectedSegment.datum().data.key);
32
32
  this.removeFilter(shadowClone.select("path"));
33
33
  this.toggleDonutHighlightState(shadowClone, chartSizes, block.transitionManager.durations.higlightedScale, false).then(() => shadowClone.remove());
34
34
  }
35
35
  static removeCloneForElem(block, keyFieldName, selectedSegment) {
36
- const clone = Donut.getAllArcClones(block).filter((d) => d.data[keyFieldName] === selectedSegment.datum().data[keyFieldName]);
36
+ const clone = Donut.getAllArcClones(block).filter((d) => d.data.key === selectedSegment.datum().data.key);
37
37
  clone.remove();
38
38
  }
39
39
  static removeDonutArcClones(block) {
@@ -66,7 +66,7 @@ export class ElementHighlighter {
66
66
  });
67
67
  }
68
68
  static removeDonutHighlightingByKeys(arcSegments, keyFieldName, keyValues, chartSizes) {
69
- const segments = DomSelectionHelper.getChartElementsByKeys(arcSegments, true, keyFieldName, keyValues, SelectionCondition.Exclude);
69
+ const segments = DomSelectionHelper.getChartElementsByKeysForPolar(arcSegments, keyValues, SelectionCondition.Exclude);
70
70
  this.toggleDonutHighlightState(segments, chartSizes, 0, false);
71
71
  }
72
72
  static setInactiveFor2D(block, keyFieldName, charts) {
@@ -1,11 +1,10 @@
1
1
  import { BaseType, Selection } from "d3-selection";
2
2
  import { PieArcDatum } from "d3-shape";
3
- import { MdtChartsDataRow } from "../../config/config";
4
- import { PolarOptionsModel, TwoDimensionalOptionsModel } from "../../model/model";
3
+ import { PolarOptionsModel, PolarSegmentModel, TwoDimensionalOptionsModel } from "../../model/model";
5
4
  import { Block } from "../block/block";
6
5
  export declare class SelectHighlighter {
7
6
  static click2DHandler(multySelection: boolean, appendKey: boolean, keyValue: string, selectedKeys: string[], block: Block, options: TwoDimensionalOptionsModel): void;
8
- static clickPolarHandler(multySelection: boolean, appendKey: boolean, selectedSegment: Selection<SVGGElement, PieArcDatum<MdtChartsDataRow>, BaseType, unknown>, selectedKeys: string[], block: Block, options: PolarOptionsModel, arcItems: Selection<SVGGElement, PieArcDatum<MdtChartsDataRow>, SVGGElement, unknown>): void;
7
+ static clickPolarHandler(multySelection: boolean, appendKey: boolean, selectedSegment: Selection<SVGGElement, PieArcDatum<PolarSegmentModel>, BaseType, unknown>, selectedKeys: string[], block: Block, options: PolarOptionsModel, arcItems: Selection<SVGGElement, PieArcDatum<PolarSegmentModel>, SVGGElement, unknown>): void;
9
8
  static clear2D(block: Block, options: TwoDimensionalOptionsModel): void;
10
- static clearPolar(block: Block, options: PolarOptionsModel, arcItems: Selection<SVGGElement, PieArcDatum<MdtChartsDataRow>, SVGGElement, unknown>): void;
9
+ static clearPolar(block: Block, options: PolarOptionsModel, arcItems: Selection<SVGGElement, PieArcDatum<PolarSegmentModel>, SVGGElement, unknown>): void;
11
10
  }
@@ -60,7 +60,7 @@ export class SelectHighlighter {
60
60
  ElementHighlighter.removeShadowClone(block, options.data.keyField.name, selectedSegment, options.charts[0].sizes);
61
61
  ElementHighlighter.renderArcCloneAndHighlight(block, selectedSegment, options.charts[0].sizes);
62
62
  ElementHighlighter.toggleActivityStyle(selectedSegment, true);
63
- ElementHighlighter.toggleActivityStyle(DomSelectionHelper.getChartElementsByKeys(Donut.getAllArcGroups(block), true, options.data.keyField.name, selectedKeys, SelectionCondition.Exclude), false);
63
+ ElementHighlighter.toggleActivityStyle(DomSelectionHelper.getChartElementsByKeysForPolar(Donut.getAllArcGroups(block), selectedKeys, SelectionCondition.Exclude), false);
64
64
  }
65
65
  else {
66
66
  ElementHighlighter.removeDonutHighlightingByKeys(arcItems, options.data.keyField.name, selectedKeys, options.charts[0].sizes);
@@ -11,7 +11,7 @@ export class LegendEventsManager {
11
11
  const arcItems = Donut.getAllArcGroups(block);
12
12
  legendItems.on("mousemove", function (e, keyValue) {
13
13
  arcItems
14
- .filter((row) => row.data[keyFieldName] === keyValue.textContent)
14
+ .filter((row) => row.data.key === keyValue.textContent)
15
15
  .dispatch("mousemove", {
16
16
  bubbles: false,
17
17
  cancelable: true,
@@ -22,11 +22,11 @@ export class LegendEventsManager {
22
22
  });
23
23
  });
24
24
  legendItems.on("mouseover", function (e, keyValue) {
25
- arcItems.filter((row) => row.data[keyFieldName] === keyValue.textContent).dispatch("mouseover");
25
+ arcItems.filter((row) => row.data.key === keyValue.textContent).dispatch("mouseover");
26
26
  ElementHighlighter.toggleActivityStyle(select(this), true);
27
27
  });
28
28
  legendItems.on("mouseleave", function (e, keyValue) {
29
- arcItems.filter((row) => row.data[keyFieldName] === keyValue.textContent).dispatch("mouseleave");
29
+ arcItems.filter((row) => row.data.key === keyValue.textContent).dispatch("mouseleave");
30
30
  if (!block.filterEventManager.isSelected(keyValue.textContent) &&
31
31
  block.filterEventManager.getSelectedKeys().length > 0)
32
32
  ElementHighlighter.toggleActivityStyle(select(this), false);
@@ -36,7 +36,7 @@ export class LegendEventsManager {
36
36
  const arcItems = Donut.getAllArcGroups(block);
37
37
  legendItems.on("click", (e, keyValue) => {
38
38
  arcItems
39
- .filter((row) => row.data[keyFieldName] === keyValue.textContent)
39
+ .filter((row) => row.data.key === keyValue.textContent)
40
40
  .dispatch("click", {
41
41
  bubbles: false,
42
42
  cancelable: true,
@@ -85,18 +85,18 @@ export class Tooltip {
85
85
  const tooltipBlock = TooltipComponentsManager.renderTooltipBlock(block);
86
86
  const tooltipContent = TooltipComponentsManager.renderTooltipContentBlock(tooltipBlock);
87
87
  this.attachTooltipMoveOnElements(elements, block, tooltipBlock, {
88
- mouseover: function (e, dataRow) {
89
- TooltipDomHelper.fillContent(tooltipContent, tooltipOptions.getContent(dataRow.data[dataOptions.keyField.name]));
88
+ mouseover: function (e, segment) {
89
+ TooltipDomHelper.fillContent(tooltipContent, tooltipOptions.getContent(segment.data.key));
90
90
  ElementHighlighter.toggleActivityStyle(select(this), true);
91
- const clones = Donut.getAllArcClones(block).filter((d) => d.data[dataOptions.keyField.name] === dataRow.data[dataOptions.keyField.name]);
91
+ const clones = Donut.getAllArcClones(block).filter((d) => d.data.key === segment.data.key);
92
92
  if (clones.nodes().length === 0 &&
93
93
  (block.filterEventManager.getSelectedKeys().length === 0 ||
94
- block.filterEventManager.isSelected(dataRow.data[dataOptions.keyField.name]))) {
94
+ block.filterEventManager.isSelected(segment.data.key))) {
95
95
  ElementHighlighter.renderArcCloneAndHighlight(block, select(this), chartSizes);
96
96
  }
97
97
  },
98
- mouseleave: function (e, dataRow) {
99
- if (!block.filterEventManager.isSelected(dataRow.data[dataOptions.keyField.name])) {
98
+ mouseleave: function (e, segment) {
99
+ if (!block.filterEventManager.isSelected(segment.data.key)) {
100
100
  ElementHighlighter.removeCloneForElem(block, dataOptions.keyField.name, select(this));
101
101
  ElementHighlighter.removeShadowClone(block, dataOptions.keyField.name, select(this), chartSizes);
102
102
  ElementHighlighter.toggleDonutHighlightState(select(this), chartSizes, block.transitionManager.durations.higlightedScale, false);
@@ -82,7 +82,7 @@ export class FilterEventManager {
82
82
  setListenerPolar(options) {
83
83
  if (this.filterable) {
84
84
  this.registerEventToDonut(options);
85
- const selectedElems = Donut.getAllArcGroups(this.block).filter((d) => this.selectedKeys.findIndex((sid) => sid === d.data[options.data.keyField.name]) !== -1);
85
+ const selectedElems = Donut.getAllArcGroups(this.block).filter((d) => this.selectedKeys.findIndex((sid) => sid === d.data.key) !== -1);
86
86
  this.selectedKeys = [];
87
87
  selectedElems.dispatch("click", { bubbles: false, cancelable: true, detail: { multySelect: true } });
88
88
  }
@@ -124,7 +124,7 @@ export class FilterEventManager {
124
124
  const thisClass = this;
125
125
  arcItems.on("click", function (e, dataRow) {
126
126
  const multySelect = thisClass.getMultySelectParam(e);
127
- const keyValue = dataRow.data[options.data.keyField.name];
127
+ const keyValue = dataRow.data.key;
128
128
  const appended = thisClass.processKey(multySelect, keyValue);
129
129
  SelectHighlighter.clickPolarHandler(multySelect, appended, select(this), thisClass.getSelectedKeys(), thisClass.block, options, arcItems);
130
130
  if (thisClass.callback) {
@@ -1,7 +1,8 @@
1
1
  import { Selection, BaseType } from "d3-selection";
2
2
  import { MdtChartsDataRow } from "../../config/config";
3
- import { ChartStyle, TwoDimensionalChartModel } from "../../model/model";
3
+ import { ChartStyle, PolarSegmentModel, TwoDimensionalChartModel } from "../../model/model";
4
4
  import { Block } from "../block/block";
5
+ import { PieArcDatum } from "d3-shape";
5
6
  declare type StyleColorType = "fill" | "stroke";
6
7
  export declare enum SelectionCondition {
7
8
  Include = 0,
@@ -24,6 +25,7 @@ export declare class DomSelectionHelper {
24
25
  * @returns Выборка по ключам
25
26
  */
26
27
  static getChartElementsByKeys<T extends BaseType>(initialSelection: Selection<T, MdtChartsDataRow, BaseType, unknown>, dataWrapped: boolean, keyFieldName: string, keyValues: string[], condition?: SelectionCondition): Selection<T, any, BaseType, unknown>;
28
+ static getChartElementsByKeysForPolar<T extends BaseType>(initialSelection: Selection<T, PieArcDatum<PolarSegmentModel>, BaseType, unknown>, keyValues: string[], condition?: SelectionCondition): Selection<T, any, BaseType, unknown>;
27
29
  private static setChartOpacity;
28
30
  }
29
31
  export {};
@@ -59,6 +59,14 @@ export class DomSelectionHelper {
59
59
  return condition === SelectionCondition.Exclude ? i === -1 : i !== -1;
60
60
  });
61
61
  }
62
+ //TODO: remove this method after refactoring
63
+ static getChartElementsByKeysForPolar(initialSelection, keyValues, condition = SelectionCondition.Include) {
64
+ return initialSelection.filter((d) => {
65
+ let i;
66
+ i = keyValues.findIndex((kv) => kv === d.data.key);
67
+ return condition === SelectionCondition.Exclude ? i === -1 : i !== -1;
68
+ });
69
+ }
62
70
  static setChartOpacity(elements, opacity) {
63
71
  elements.attr("opacity", opacity);
64
72
  }
@@ -1,8 +1,7 @@
1
1
  import { PieArcDatum } from "d3-shape";
2
2
  import { Selection } from "d3-selection";
3
- import { DonutChartSettings, DonutChartModel } from "../../../model/model";
3
+ import { DonutChartSettings, DonutChartModel, PolarSegmentModel } from "../../../model/model";
4
4
  import { Block } from "../../block/block";
5
- import { MdtChartsDataRow } from "../../../config/config";
6
5
  export interface Translate {
7
6
  x: number;
8
7
  y: number;
@@ -16,17 +15,17 @@ export declare class Donut {
16
15
  static readonly arcShadowsGroupClass = "arc-shadow-clones";
17
16
  static readonly arcCloneClass = "arc-clone";
18
17
  static readonly arcShadowClass = "arc-shadow-clone";
19
- static render(block: Block, data: MdtChartsDataRow[], chart: DonutChartModel, settings: DonutChartSettings): void;
20
- static update(block: Block, data: MdtChartsDataRow[], chart: DonutChartModel, donutSettings: DonutChartSettings, keyField: string): Promise<any>;
21
- static updateColors(block: Block, chart: DonutChartModel): void;
22
- static getAllArcGroups(block: Block): Selection<SVGGElement, PieArcDatum<MdtChartsDataRow>, SVGGElement, unknown>;
23
- static getAllArcClones(block: Block): Selection<SVGGElement, PieArcDatum<MdtChartsDataRow>, SVGGElement, unknown>;
24
- static getAllArcShadows(block: Block): Selection<SVGGElement, PieArcDatum<MdtChartsDataRow>, SVGGElement, unknown>;
25
- private static renderNewArcItems;
26
- private static setElementsColor;
18
+ static getAllArcGroups(block: Block): Selection<SVGGElement, PieArcDatum<PolarSegmentModel>, SVGGElement, unknown>;
19
+ static getAllArcClones(block: Block): Selection<SVGGElement, PieArcDatum<PolarSegmentModel>, SVGGElement, unknown>;
20
+ static getAllArcShadows(block: Block): Selection<SVGGElement, PieArcDatum<PolarSegmentModel>, SVGGElement, unknown>;
21
+ private segmentLabels;
22
+ render(block: Block, chart: DonutChartModel, settings: DonutChartSettings): void;
23
+ update(block: Block, chart: DonutChartModel, donutSettings: DonutChartSettings): Promise<any>;
24
+ updateColors(block: Block, chart: DonutChartModel, settings: DonutChartSettings): void;
25
+ private renderNewArcItems;
27
26
  /**
28
27
  * Рендер группы для клонов сегментов доната внутри donut-block. Объекдиняет в себе стили для клонов
29
28
  */
30
- private static renderClonesG;
31
- private static raiseClonesG;
29
+ private renderClonesG;
30
+ private raiseClonesG;
32
31
  }
@@ -1,42 +1,64 @@
1
1
  import { interpolate } from "d3-interpolate";
2
2
  import { DonutHelper } from "./donutHelper";
3
3
  import { DomSelectionHelper } from "../../helpers/domSelectionHelper";
4
- import { ColorReader } from "../../colorReader/colorReader";
4
+ import { SunburstSegmentLabel } from "../../sunburstNotation/sunburstSegmentLabel";
5
5
  export class Donut {
6
- static render(block, data, chart, settings) {
6
+ static getAllArcGroups(block) {
7
+ return block.getSvg().selectAll(`.${this.arcItemClass}`);
8
+ }
9
+ static getAllArcClones(block) {
10
+ return block.getSvg().selectAll(`.${Donut.arcCloneClass}`);
11
+ }
12
+ static getAllArcShadows(block) {
13
+ return block.getSvg().selectAll(`.${this.arcShadowClass}`);
14
+ }
15
+ render(block, chart, settings) {
7
16
  const arcGenerator = DonutHelper.getArcGenerator(chart.sizes.outerRadius, chart.sizes.innerRadius);
8
- const pieGenerator = DonutHelper.getPieGenerator(chart.data.valueField.name, settings.padAngle);
17
+ const pieGenerator = DonutHelper.getPieGenerator(settings.padAngle);
9
18
  const donutBlock = block
10
19
  .getSvg()
11
20
  .append("g")
12
- .attr("class", this.donutBlockClass)
21
+ .attr("class", Donut.donutBlockClass)
13
22
  .attr("x", chart.sizes.translate.x)
14
23
  .attr("y", chart.sizes.translate.y)
15
24
  .attr("transform", `translate(${chart.sizes.translate.x}, ${chart.sizes.translate.y})`);
16
- this.renderNewArcItems(arcGenerator, pieGenerator, donutBlock, data, chart);
25
+ this.renderNewArcItems(arcGenerator, pieGenerator, donutBlock, chart.data.segments, chart.cssClasses);
17
26
  this.renderClonesG(donutBlock);
27
+ if (chart.valueLabels.on) {
28
+ this.segmentLabels = new SunburstSegmentLabel(donutBlock);
29
+ this.segmentLabels.render({
30
+ sizesForGenerators: {
31
+ innerRadius: chart.sizes.innerRadius,
32
+ outerRadius: chart.sizes.outerRadius,
33
+ padAngle: settings.padAngle
34
+ }
35
+ }, chart.valueLabels.items);
36
+ }
18
37
  }
19
- static update(block, data, chart, donutSettings, keyField) {
38
+ update(block, chart, donutSettings) {
39
+ var _a;
20
40
  const arcGenerator = DonutHelper.getArcGenerator(chart.sizes.outerRadius, chart.sizes.innerRadius);
21
- const pieGenerator = DonutHelper.getPieGenerator(chart.data.valueField.name, donutSettings.padAngle);
22
- const oldData = block
41
+ const pieGenerator = DonutHelper.getPieGenerator(donutSettings.padAngle);
42
+ const oldSegments = block
23
43
  .getSvg()
24
- .selectAll(`.${this.donutBlockClass}`)
44
+ .selectAll(`.${Donut.donutBlockClass}`)
25
45
  .selectAll("path")
26
46
  .data()
27
47
  .map((d) => d.data);
28
- const dataNewZeroRows = DonutHelper.mergeDataWithZeros(data, oldData, keyField, ColorReader.getChartColorField(chart));
29
- const dataExtraZeroRows = DonutHelper.mergeDataWithZeros(oldData, data, keyField, ColorReader.getChartColorField(chart));
30
- const donutBlock = block.getSvg().select(`.${this.donutBlockClass}`);
48
+ const dataNewZeroRows = DonutHelper.mergeDataWithZeros(chart.data.segments, oldSegments);
49
+ const dataExtraZeroRows = DonutHelper.mergeDataWithZeros(oldSegments, chart.data.segments);
50
+ const donutBlock = block.getSvg().select(`.${Donut.donutBlockClass}`);
31
51
  donutBlock
32
52
  .attr("x", chart.sizes.translate.x)
33
53
  .attr("y", chart.sizes.translate.y)
34
54
  .attr("transform", `translate(${chart.sizes.translate.x}, ${chart.sizes.translate.y})`);
35
- this.renderNewArcItems(arcGenerator, pieGenerator, donutBlock, dataNewZeroRows, chart);
36
- const path = this.getAllArcGroups(block).data(pieGenerator(dataExtraZeroRows)).select("path");
37
- const items = this.getAllArcGroups(block).data(pieGenerator(data));
38
- this.setElementsColor(this.getAllArcGroups(block), chart);
39
- return new Promise((resolve) => {
55
+ this.renderNewArcItems(arcGenerator, pieGenerator, donutBlock, dataNewZeroRows, chart.cssClasses);
56
+ const path = Donut.getAllArcGroups(block)
57
+ .data(pieGenerator(dataExtraZeroRows), (d) => d.data.key)
58
+ .select("path");
59
+ const items = Donut.getAllArcGroups(block).data(pieGenerator(chart.data.segments), (d) => d.data.key);
60
+ items.select(`.${Donut.arcPathClass}`).style("fill", (d) => d.data.color);
61
+ const updateDonutPromise = new Promise((resolve) => {
40
62
  this.raiseClonesG(block);
41
63
  path.interrupt()
42
64
  .transition()
@@ -53,50 +75,53 @@ export class Donut {
53
75
  };
54
76
  });
55
77
  });
78
+ const promises = [updateDonutPromise];
79
+ if (chart.valueLabels.on) {
80
+ const updateLabelsPromise = (_a = this.segmentLabels) === null || _a === void 0 ? void 0 : _a.update({
81
+ sizesForGenerators: {
82
+ innerRadius: chart.sizes.innerRadius,
83
+ outerRadius: chart.sizes.outerRadius,
84
+ padAngle: donutSettings.padAngle
85
+ }
86
+ }, chart.valueLabels.items, block.transitionManager.durations.chartUpdate).then((labels) => labels.raise());
87
+ promises.push(updateLabelsPromise);
88
+ }
89
+ return Promise.all(promises);
56
90
  }
57
- static updateColors(block, chart) {
58
- this.setElementsColor(this.getAllArcGroups(block), chart);
91
+ updateColors(block, chart, settings) {
92
+ const pieGenerator = DonutHelper.getPieGenerator(settings.padAngle);
93
+ Donut.getAllArcGroups(block)
94
+ .data(pieGenerator(chart.data.segments), (d) => d.data.key)
95
+ .select(`.${Donut.arcPathClass}`)
96
+ .style("fill", (d) => d.data.color);
59
97
  }
60
- static getAllArcGroups(block) {
61
- return block.getSvg().selectAll(`.${this.arcItemClass}`);
62
- }
63
- static getAllArcClones(block) {
64
- return block.getSvg().selectAll(`.${Donut.arcCloneClass}`);
65
- }
66
- static getAllArcShadows(block) {
67
- return block.getSvg().selectAll(`.${this.arcShadowClass}`);
68
- }
69
- static renderNewArcItems(arcGenerator, pieGenerator, donutBlock, data, chart) {
98
+ renderNewArcItems(arcGenerator, pieGenerator, donutBlock, segments, cssClasses) {
70
99
  const items = donutBlock
71
- .selectAll(`.${this.arcItemClass}`)
72
- .data(pieGenerator(data))
100
+ .selectAll(`.${Donut.arcItemClass}`)
101
+ .data(pieGenerator(segments), (d) => d.data.key)
73
102
  .enter()
74
103
  .append("g")
75
- .attr("class", this.arcItemClass);
104
+ .attr("class", Donut.arcItemClass);
76
105
  const arcs = items
77
106
  .append("path")
78
107
  .attr("d", arcGenerator)
79
- .attr("class", this.arcPathClass)
108
+ .attr("class", Donut.arcPathClass)
109
+ .style("fill", (d) => d.data.color)
80
110
  .each(function (d) {
81
111
  this._currentData = d;
82
112
  }); // _currentData используется для получения текущих данных внутри функции обновления.
83
- DomSelectionHelper.setCssClasses(arcs, chart.cssClasses);
84
- this.setElementsColor(items, chart);
85
- }
86
- static setElementsColor(arcItems, chart) {
87
- arcItems.select("path").style("fill", ({ data }, i) => ColorReader.getColorForArc(data, chart, i));
113
+ DomSelectionHelper.setCssClasses(arcs, cssClasses);
88
114
  }
89
115
  /**
90
116
  * Рендер группы для клонов сегментов доната внутри donut-block. Объекдиняет в себе стили для клонов
91
117
  */
92
- static renderClonesG(donutBlock) {
93
- const clonesShadowsG = donutBlock.append("g").attr("class", this.arcShadowsGroupClass).raise();
94
- const clonesG = donutBlock.append("g").attr("class", this.arcClonesGroupClass).raise();
95
- // ElementHighlighter.setShadowFilter(clonesG);
118
+ renderClonesG(donutBlock) {
119
+ const clonesShadowsG = donutBlock.append("g").attr("class", Donut.arcShadowsGroupClass).raise();
120
+ const clonesG = donutBlock.append("g").attr("class", Donut.arcClonesGroupClass).raise();
96
121
  }
97
- static raiseClonesG(block) {
98
- block.getSvg().select(`.${this.donutBlockClass}`).select(`.${this.arcShadowsGroupClass}`).raise();
99
- block.getSvg().select(`.${this.donutBlockClass}`).select(`.${this.arcClonesGroupClass}`).raise();
122
+ raiseClonesG(block) {
123
+ block.getSvg().select(`.${Donut.donutBlockClass}`).select(`.${Donut.arcShadowsGroupClass}`).raise();
124
+ block.getSvg().select(`.${Donut.donutBlockClass}`).select(`.${Donut.arcClonesGroupClass}`).raise();
100
125
  }
101
126
  }
102
127
  Donut.donutBlockClass = "donut-block";
@@ -1,7 +1,10 @@
1
1
  import { PieArcDatum, Arc, Pie } from "d3-shape";
2
- import { MdtChartsDataRow, MdtChartsColorField } from "../../../config/config";
2
+ import { PolarSegmentModel } from "../../../model/model";
3
3
  export declare class DonutHelper {
4
- static getArcGenerator(outerRadius: number, innerRadius: number): Arc<any, PieArcDatum<MdtChartsDataRow>>;
5
- static getPieGenerator(valueField: string, padAngle: number): Pie<any, MdtChartsDataRow>;
6
- static mergeDataWithZeros(firstDataset: MdtChartsDataRow[], secondDataset: MdtChartsDataRow[], keyField: string, colorField: MdtChartsColorField): MdtChartsDataRow[];
4
+ static getArcGenerator(outerRadius: number, innerRadius: number): Arc<any, PieArcDatum<PolarSegmentModel>>;
5
+ static getPieGenerator(padAngle: number): Pie<any, PolarSegmentModel>;
6
+ static mergeDataWithZeros<R extends {
7
+ key: string | number;
8
+ value: number;
9
+ }>(firstDataset: R[], secondDataset: R[]): R[];
7
10
  }
@@ -4,29 +4,22 @@ export class DonutHelper {
4
4
  static getArcGenerator(outerRadius, innerRadius) {
5
5
  return arc().innerRadius(innerRadius).outerRadius(outerRadius);
6
6
  }
7
- static getPieGenerator(valueField, padAngle) {
7
+ static getPieGenerator(padAngle) {
8
8
  return pie()
9
9
  .padAngle(padAngle)
10
10
  .sort(null)
11
- .value((d) => d[valueField]);
11
+ .value((d) => d.value);
12
12
  }
13
- static mergeDataWithZeros(firstDataset, secondDataset, keyField, colorField) {
13
+ static mergeDataWithZeros(firstDataset, secondDataset) {
14
14
  const secondSet = new Set();
15
- secondDataset.forEach((dataRow) => {
16
- secondSet.add(dataRow[keyField]);
17
- });
15
+ secondDataset.forEach((segment) => secondSet.add(segment.key));
18
16
  const onlyNew = firstDataset
19
- .filter((d) => !secondSet.has(d[keyField]))
17
+ .filter((d) => !secondSet.has(d.key))
20
18
  .map((d, index, array) => {
21
- const data = {
22
- keyField: array[index][keyField],
23
- valueField: 0,
24
- [colorField]: array[index][colorField]
25
- //TODO: добавить цвет из ColorReader'а
26
- };
27
- return data;
19
+ const segmentToChangeToZero = Object.assign(Object.assign({}, d), { value: 0 });
20
+ return segmentToChangeToZero;
28
21
  });
29
- const sortedMerge = merge([secondDataset, onlyNew]);
30
- return sortedMerge;
22
+ const merged = merge([secondDataset, onlyNew]);
23
+ return merged;
31
24
  }
32
25
  }
@@ -5,6 +5,7 @@ import { MdtChartsDataSource } from "../../config/config";
5
5
  import { ChartContentManager } from "../contentManager/contentManagerFactory";
6
6
  import { ChartClearSelectionOptions, FilterEventManager } from "../filterManager/filterEventManager";
7
7
  export declare class PolarManager implements ChartContentManager {
8
+ private readonly donut;
8
9
  render(engine: Engine, model: Model<PolarOptionsModel>): void;
9
10
  updateData(block: Block, model: Model<PolarOptionsModel>, data: MdtChartsDataSource): void;
10
11
  updateColors(block: Block, model: Model<PolarOptionsModel>): void;
@@ -6,11 +6,14 @@ import { Donut } from "./donut/donut";
6
6
  import { RecordOverflowAlertCore } from "../features/recordOverflowAlert/recordOverflowAlertCore";
7
7
  import { Aggregator } from "../features/aggregator/aggregator";
8
8
  export class PolarManager {
9
+ constructor() {
10
+ this.donut = new Donut();
11
+ }
9
12
  render(engine, model) {
10
13
  const options = model.options;
11
14
  engine.block.svg.render(model.blockCanvas.size);
12
15
  Title.render(engine.block, options.title, model.otherComponents.titleBlock, model.blockCanvas.size);
13
- Donut.render(engine.block, engine.data[options.data.dataSource], options.charts[0], options.chartCanvas);
16
+ this.donut.render(engine.block, options.charts[0], options.chartCanvas);
14
17
  Aggregator.render(engine.block, options.charts[0].sizes.innerRadius, options.charts[0].sizes.translate, options.charts[0].sizes.thickness, options.chartCanvas.aggregator);
15
18
  Legend.get().render(engine.block, options, model);
16
19
  Tooltip.renderTooltipForDonut(engine.block, model.options.data, model.options.charts[0].sizes, model.options.tooltip);
@@ -32,7 +35,7 @@ export class PolarManager {
32
35
  ElementHighlighter.toggleActivityStyle(Donut.getAllArcGroups(block), true);
33
36
  Tooltip.hide(block);
34
37
  const options = model.options;
35
- Donut.update(block, data[options.data.dataSource], options.charts[0], options.chartCanvas, options.data.keyField.name).then(() => {
38
+ this.donut.update(block, options.charts[0], options.chartCanvas).then(() => {
36
39
  Tooltip.renderTooltipForDonut(block, model.options.data, model.options.charts[0].sizes, model.options.tooltip);
37
40
  block.filterEventManager.setListenerPolar(options);
38
41
  });
@@ -42,7 +45,9 @@ export class PolarManager {
42
45
  }
43
46
  updateColors(block, model) {
44
47
  Legend.get().updateColors(block, model.options);
45
- Donut.updateColors(block, model.options.charts[0]);
48
+ this.donut.updateColors(block, model.options.charts[0], model.options.chartCanvas);
49
+ //TODO: temp solution for updating marker colors in tooltip. In future should attach tooltip data to segments like in sunburst chart
50
+ Tooltip.renderTooltipForDonut(block, model.options.data, model.options.charts[0].sizes, model.options.tooltip);
46
51
  }
47
52
  clearSelection(filterEventManager, model, options) {
48
53
  filterEventManager.clearKeysForPolar(model.options, options);
@@ -7,8 +7,9 @@ export declare class Sunburst {
7
7
  private readonly block;
8
8
  static readonly donutBlockClassPrefix = "level-donut-block";
9
9
  static readonly arcItemClass = "arc";
10
- private static readonly arcItemNonHighlightedClass;
11
10
  static readonly arcPathClass = "arc-path";
11
+ private static readonly arcItemNonHighlightedClass;
12
+ private readonly sunburstSegmentLabels;
12
13
  static getAllArcGroups(block: Block): Selection<SVGGElement, PieArcDatum<SunburstLevelSegment>, SVGGElement, unknown>;
13
14
  static getLevelArcGroups(block: Block, levelIndex: number): Selection<SVGGElement, PieArcDatum<SunburstLevelSegment>, SVGGElement, unknown>;
14
15
  private readonly pagAngle;
@@ -1,9 +1,11 @@
1
1
  import { arc, pie } from "d3-shape";
2
2
  import { merge } from "d3-array";
3
3
  import { interpolate } from "d3-interpolate";
4
+ import { SunburstSegmentLabel } from "./sunburstSegmentLabel";
4
5
  export class Sunburst {
5
6
  constructor(block) {
6
7
  this.block = block;
8
+ this.sunburstSegmentLabels = {};
7
9
  this.pagAngle = 0.005;
8
10
  this.block = block;
9
11
  }
@@ -26,6 +28,16 @@ export class Sunburst {
26
28
  .attr("y", level.sizes.translate.y)
27
29
  .attr("transform", `translate(${level.sizes.translate.x}, ${level.sizes.translate.y})`);
28
30
  this.renderNewArcItems(levelDonutBlock, pieGenerator, arcGenerator, level.segments);
31
+ if (level.valueLabels.on) {
32
+ this.sunburstSegmentLabels[levelIndex] = new SunburstSegmentLabel(levelDonutBlock);
33
+ this.sunburstSegmentLabels[levelIndex].render({
34
+ sizesForGenerators: {
35
+ innerRadius: level.sizes.innerRadius,
36
+ outerRadius: level.sizes.outerRadius,
37
+ padAngle: this.pagAngle
38
+ }
39
+ }, level.valueLabels.items);
40
+ }
29
41
  });
30
42
  return Sunburst.getAllArcGroups(this.block);
31
43
  }
@@ -59,13 +71,25 @@ export class Sunburst {
59
71
  resolve();
60
72
  })
61
73
  .attrTween("d", function (d) {
62
- const interpolateFunc = interpolate(this._currentData, d);
74
+ const interpolateFunc = interpolate(this._currentDataForUsingOnUpdate, d);
63
75
  return (t) => {
64
- this._currentData = interpolateFunc(t);
65
- return arcGenerator(this._currentData);
76
+ this._currentDataForUsingOnUpdate = interpolateFunc(t);
77
+ return arcGenerator(this._currentDataForUsingOnUpdate);
66
78
  };
67
79
  });
68
80
  }));
81
+ if (level.valueLabels.on) {
82
+ const updateLabelsPromise = this.sunburstSegmentLabels[levelIndex]
83
+ .update({
84
+ sizesForGenerators: {
85
+ innerRadius: level.sizes.innerRadius,
86
+ outerRadius: level.sizes.outerRadius,
87
+ padAngle: this.pagAngle
88
+ }
89
+ }, level.valueLabels.items, this.block.transitionManager.durations.chartUpdate)
90
+ .then(() => undefined);
91
+ promises.push(updateLabelsPromise);
92
+ }
69
93
  });
70
94
  return Promise.all(promises).then(() => Sunburst.getAllArcGroups(this.block));
71
95
  }
@@ -111,8 +135,8 @@ export class Sunburst {
111
135
  .attr("d", arcGenerator)
112
136
  .attr("class", Sunburst.arcPathClass)
113
137
  .each(function (d) {
114
- this._currentData = d;
115
- }); // TODO: _currentData используется для получения текущих данных внутри функции обновления.
138
+ this._currentDataForUsingOnUpdate = d;
139
+ }); // TODO: _currentDataForUsingOnUpdate используется для получения текущих данных внутри функции обновления.
116
140
  return items;
117
141
  }
118
142
  getGenerators(level) {
@@ -140,5 +164,5 @@ export class Sunburst {
140
164
  }
141
165
  Sunburst.donutBlockClassPrefix = "level-donut-block";
142
166
  Sunburst.arcItemClass = "arc";
143
- Sunburst.arcItemNonHighlightedClass = "mdt-charts-arc-non-highlighted";
144
167
  Sunburst.arcPathClass = "arc-path";
168
+ Sunburst.arcItemNonHighlightedClass = "mdt-charts-arc-non-highlighted";
@@ -0,0 +1,20 @@
1
+ import { PieArcDatum } from "d3-shape";
2
+ import { BaseType, Selection } from "d3-selection";
3
+ import { PolarSegmentLabelDataItem } from "../../model/modelTypes/valueLabelsModel";
4
+ interface SunburstSegmentLabelOptions {
5
+ sizesForGenerators: {
6
+ innerRadius: number;
7
+ outerRadius: number;
8
+ padAngle?: number;
9
+ };
10
+ }
11
+ export declare class SunburstSegmentLabel {
12
+ private readonly parentSelection;
13
+ private static readonly arcLabelClass;
14
+ constructor(parentSelection: Selection<BaseType, unknown, BaseType, unknown>);
15
+ render(options: SunburstSegmentLabelOptions, segments: PolarSegmentLabelDataItem[]): void;
16
+ update(options: SunburstSegmentLabelOptions, segments: PolarSegmentLabelDataItem[], animationDuration: number): Promise<Selection<SVGTextElement, PieArcDatum<PolarSegmentLabelDataItem>, BaseType, unknown>>;
17
+ private getTransformAttrValue;
18
+ private getGenerators;
19
+ }
20
+ export {};
@@ -0,0 +1,86 @@
1
+ import { arc, pie } from "d3-shape";
2
+ import { select } from "d3-selection";
3
+ import { interpolate } from "d3-interpolate";
4
+ import { DonutHelper } from "../polarNotation/donut/donutHelper";
5
+ export class SunburstSegmentLabel {
6
+ constructor(parentSelection) {
7
+ this.parentSelection = parentSelection;
8
+ }
9
+ render(options, segments) {
10
+ const { arcGenerator, pieGenerator } = this.getGenerators(options);
11
+ this.parentSelection
12
+ .selectAll("text")
13
+ .data(pieGenerator(segments), (d) => d.data.key)
14
+ .enter()
15
+ .append("text")
16
+ .attr("transform", (d) => {
17
+ return this.getTransformAttrValue(arcGenerator, d);
18
+ })
19
+ .classed(SunburstSegmentLabel.arcLabelClass, true)
20
+ .text((d) => d.data.textContent)
21
+ .each(function (d) {
22
+ if (d.data.cssClass)
23
+ select(this).classed(d.data.cssClass, true);
24
+ this._currentDataForUsingOnUpdate = d;
25
+ });
26
+ }
27
+ update(options, segments, animationDuration) {
28
+ const oldLabels = this.parentSelection
29
+ .selectAll("text")
30
+ .data()
31
+ .map((d) => d.data);
32
+ const valueLabelsZeroRows = DonutHelper.mergeDataWithZeros(segments, oldLabels);
33
+ this.render(options, segments);
34
+ const { arcGenerator, pieGenerator } = this.getGenerators(options);
35
+ const labelsNewAndOld = this.parentSelection
36
+ .selectAll("text")
37
+ .data(pieGenerator(valueLabelsZeroRows), (d) => d.data.key);
38
+ const onlyNewLabels = this.parentSelection
39
+ .selectAll("text")
40
+ .data(pieGenerator(segments), (d) => d.data.key);
41
+ onlyNewLabels.text((d) => d.data.textContent);
42
+ const thisClass = this;
43
+ return new Promise((resolve) => {
44
+ labelsNewAndOld
45
+ .interrupt()
46
+ .transition()
47
+ .duration(animationDuration)
48
+ .on("end", () => {
49
+ onlyNewLabels.exit().remove();
50
+ resolve(onlyNewLabels);
51
+ })
52
+ .attrTween("transform", function (d) {
53
+ const interpolateFunc = interpolate(this._currentDataForUsingOnUpdate, d);
54
+ return (t) => {
55
+ this._currentDataForUsingOnUpdate = interpolateFunc(t);
56
+ return thisClass.getTransformAttrValue(arcGenerator, this._currentDataForUsingOnUpdate);
57
+ };
58
+ });
59
+ });
60
+ }
61
+ getTransformAttrValue(arcGenerator, d) {
62
+ const [x, y] = arcGenerator.centroid(d);
63
+ let attrValue = `translate(${x},${y})`;
64
+ if (d.data.rotation.type === "tangential") {
65
+ const a = (d.startAngle + d.endAngle) / 2;
66
+ let rotate = (a * 180) / Math.PI - 90;
67
+ if (rotate > 90)
68
+ rotate -= 180;
69
+ if (rotate < -90)
70
+ rotate += 180;
71
+ attrValue += ` rotate(${rotate})`;
72
+ }
73
+ return attrValue;
74
+ }
75
+ getGenerators(options) {
76
+ const arcGenerator = arc()
77
+ .innerRadius(options.sizesForGenerators.innerRadius)
78
+ .outerRadius(options.sizesForGenerators.outerRadius)
79
+ .padAngle(options.sizesForGenerators.padAngle);
80
+ const pieGenerator = pie()
81
+ .sort(null)
82
+ .value((d) => d.value);
83
+ return { arcGenerator, pieGenerator };
84
+ }
85
+ }
86
+ SunburstSegmentLabel.arcLabelClass = "mdt-charts-arc-label";
@@ -1,12 +1,9 @@
1
- import { MdtChartsDataRow } from "../../../../config/config";
2
- import { ValueField } from "../../../model";
1
+ import { PolarSegmentModel, ValueField } from "../../../model";
3
2
  import { TooltipContentInitialRow, TooltipContentInitialRowsProvider, TooltipContentInitialRowsProviderContext } from "./tooltipContentInitialRowsProvider";
4
3
  export interface PolarInitialRowsProviderOptions {
5
4
  valueField: ValueField;
6
- colorField?: string;
7
- datasource: MdtChartsDataRow[];
5
+ segments: PolarSegmentModel[];
8
6
  chartColors: string[];
9
- keyFieldName: string;
10
7
  }
11
8
  export declare class PolarInitialRowsProvider implements TooltipContentInitialRowsProvider {
12
9
  private readonly options;
@@ -4,17 +4,13 @@ export class PolarInitialRowsProvider {
4
4
  this.options = options;
5
5
  }
6
6
  getInitialRows(context) {
7
- const indexOfCurrentDataRow = this.options.datasource.findIndex((row) => row[this.options.keyFieldName] === context.keyFieldValue);
8
- let markerColor;
9
- if (this.options.colorField) {
10
- const currentDataRow = this.options.datasource[indexOfCurrentDataRow];
11
- markerColor = currentDataRow[this.options.colorField];
7
+ const currentSegment = this.options.segments.find((segment) => segment.key === context.keyFieldValue);
8
+ if (!currentSegment) {
9
+ throw new Error(`Segment with key ${context.keyFieldValue} not found`);
12
10
  }
13
- else
14
- markerColor = this.options.chartColors[indexOfCurrentDataRow];
15
11
  return [
16
12
  {
17
- marker: Object.assign(Object.assign({}, POLAR_LEGEND_MARKER), { color: markerColor }),
13
+ marker: Object.assign(Object.assign({}, POLAR_LEGEND_MARKER), { color: currentSegment.color }),
18
14
  valueField: this.options.valueField
19
15
  }
20
16
  ];
@@ -1,6 +1,7 @@
1
1
  import { ChartOrientation, MdtChartsColorField, PolarChartType, Size, TwoDimensionalChartType, AxisLabelPosition, ShowTickFn, MdtChartsDataRow, TwoDimensionalValueGroup, ValueLabelsCollisionMode, ValueLabelsRotationOptions, ValueLabelsHandleElement, MdtChartsFieldName, BlockMargin as ConfigBlockMargin } from "../config/config";
2
2
  import { DataType, DonutOptionsCanvas, Formatter, StaticLegendBlockCanvas, Transitions } from "../designer/designerConfig";
3
3
  import { BoundingRect } from "../engine/features/valueLabelsCollision/valueLabelsCollision";
4
+ import { PolarLikeChartValueLabelsModel } from "./modelTypes/valueLabelsModel";
4
5
  declare type AxisType = "key" | "value";
5
6
  export declare type Orient = "top" | "bottom" | "left" | "right";
6
7
  export declare type ScaleKeyType = (ScaleBandModel | ScalePointModel)["type"];
@@ -375,6 +376,7 @@ export interface DonutThicknessOptions {
375
376
  export interface SunburstLevel {
376
377
  segments: SunburstLevelSegment[];
377
378
  sizes: DonutChartSizesModel;
379
+ valueLabels: PolarLikeChartValueLabelsModel;
378
380
  }
379
381
  export interface SunburstLevelSegment {
380
382
  value: number;
@@ -483,6 +485,7 @@ export interface DonutChartModel extends ChartModel {
483
485
  type: PolarChartType;
484
486
  data: PolarChartDataModel;
485
487
  sizes: DonutChartSizesModel;
488
+ valueLabels: PolarLikeChartValueLabelsModel;
486
489
  }
487
490
  export interface DonutChartSizesModel {
488
491
  outerRadius: number;
@@ -549,6 +552,13 @@ interface MarkersBaseSizeOptions {
549
552
  export interface PolarChartDataModel {
550
553
  valueField: ValueField;
551
554
  colorField?: MdtChartsColorField;
555
+ segments: PolarSegmentModel[];
556
+ }
557
+ export interface PolarSegmentModel {
558
+ key: string;
559
+ value: number;
560
+ color: string;
561
+ attachedDataRow: MdtChartsDataRow;
552
562
  }
553
563
  export interface DataSettings {
554
564
  scope: DataScope;
@@ -0,0 +1,15 @@
1
+ export interface PolarSegmentLabelDataItem {
2
+ key: string | number;
3
+ value: number;
4
+ textContent: string;
5
+ rotation: {
6
+ type: "none" | "tangential";
7
+ };
8
+ cssClass?: string;
9
+ }
10
+ export declare type PolarLikeChartValueLabelsModel = {
11
+ on: false;
12
+ } | {
13
+ on: true;
14
+ items: PolarSegmentLabelDataItem[];
15
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -7,13 +7,14 @@ import { TwoDimTooltipContentGenerator } from "../../featuresModel/tooltipModel/
7
7
  import { PolarInitialRowsProvider } from "../../featuresModel/tooltipModel/contentByNotations/polarInitialRowsProvider";
8
8
  import { DonutThicknessCalculator } from "./donut/donutThicknessService";
9
9
  import { getDonutLikeOuterRadius, getDonutLikeTranslate } from "./donut/donutLikeSizesCalculator";
10
+ import { SegmentModelBuilder } from "./segmentModelBuilder/segmentModelBuilder";
10
11
  export const MIN_DONUT_BLOCK_SIZE = 120;
11
12
  export class PolarModel {
12
13
  static getOptions(options, designerConfig, modelInstance) {
13
14
  const titleConfig = TitleConfigReader.create(options.title, modelInstance);
14
15
  const donutSettings = this.donutModel.getSettings(designerConfig.canvas.chartOptions.donut, options.chart, modelInstance.dataModel.repository.getRawRows());
15
16
  const chartStyle = ChartStyleModelService.getChartStyle(modelInstance.dataModel.repository.getScopedRows().length, designerConfig.chartStyle);
16
- const chart = this.getChartsModel(donutSettings, modelInstance.canvasModel.getBlockSize(), modelInstance.canvasModel.getMargin(), options.chart, chartStyle);
17
+ const chart = this.getChartsModel(donutSettings, modelInstance.canvasModel.getBlockSize(), modelInstance.canvasModel.getMargin(), options.chart, chartStyle, modelInstance.dataModel.repository.getScopedRows(), options.data.keyField.name, options.chart.valueLabels);
17
18
  return {
18
19
  type: options.type,
19
20
  selectable: !!options.selectable,
@@ -25,16 +26,11 @@ export class PolarModel {
25
26
  charts: [chart],
26
27
  legend: {
27
28
  position: modelInstance.canvasModel.legendCanvas.getPosition(),
28
- items: modelInstance.dataModel.repository
29
- .getScopedRows()
30
- .map((record, index) => {
31
- let markerColor = chartStyle.elementColors[index % chartStyle.elementColors.length];
32
- if (options.chart.data.colorField)
33
- markerColor = record[options.chart.data.colorField];
29
+ items: chart.data.segments.map((segment, index) => {
34
30
  return {
35
31
  marker: POLAR_LEGEND_MARKER,
36
- markerColor,
37
- textContent: record[options.data.keyField.name]
32
+ markerColor: segment.color,
33
+ textContent: segment.key
38
34
  };
39
35
  })
40
36
  },
@@ -45,11 +41,9 @@ export class PolarModel {
45
41
  keyFieldName: options.data.keyField.name,
46
42
  publicOptions: options.tooltip,
47
43
  initialRowsProvider: new PolarInitialRowsProvider({
48
- datasource: modelInstance.dataModel.repository.getRawRows(),
44
+ segments: chart.data.segments,
49
45
  valueField: options.chart.data.valueField,
50
- keyFieldName: options.data.keyField.name,
51
- chartColors: chart.style.elementColors,
52
- colorField: options.chart.data.colorField
46
+ chartColors: chart.style.elementColors
53
47
  }),
54
48
  valueGlobalFormatter: designerConfig.dataFormat.formatters
55
49
  });
@@ -86,12 +80,34 @@ export class PolarModel {
86
80
  const heightForLegend = chartBlockHeight - bottomLegendMargin.bottom - bottomLegendMargin.top - MIN_DONUT_BLOCK_SIZE;
87
81
  return heightForLegend >= minHeightForLegend;
88
82
  }
89
- static getChartsModel(donutSettings, blockSize, margin, chart, chartStyle) {
83
+ static getChartsModel(donutSettings, blockSize, margin, chart, chartStyle, scopedDataRows, keyFieldName, valueLabels) {
84
+ var _a;
90
85
  const outerRadius = getDonutLikeOuterRadius(margin, blockSize);
91
86
  const thickness = DonutThicknessCalculator.getThickness(donutSettings.thickness, blockSize, margin);
87
+ const segmentModelBuilder = new SegmentModelBuilder({
88
+ scopedDataRows,
89
+ keyFieldName,
90
+ valueFieldName: chart.data.valueField.name,
91
+ chartPaletteColors: chartStyle.elementColors,
92
+ colorFieldName: chart.data.colorField
93
+ });
94
+ const segments = segmentModelBuilder.build();
92
95
  return {
93
96
  type: chart.type,
94
- data: Object.assign({}, chart.data),
97
+ data: Object.assign(Object.assign({}, chart.data), { segments }),
98
+ valueLabels: {
99
+ on: (_a = valueLabels === null || valueLabels === void 0 ? void 0 : valueLabels.on) !== null && _a !== void 0 ? _a : false,
100
+ items: segments.map((segment) => {
101
+ var _a, _b, _c;
102
+ return ({
103
+ key: segment.key,
104
+ value: segment.value,
105
+ textContent: (_b = (_a = valueLabels === null || valueLabels === void 0 ? void 0 : valueLabels.content) === null || _a === void 0 ? void 0 : _a.call(valueLabels, segment.attachedDataRow)) !== null && _b !== void 0 ? _b : segment.key.toString(),
106
+ rotation: (_c = valueLabels === null || valueLabels === void 0 ? void 0 : valueLabels.rotation) !== null && _c !== void 0 ? _c : { type: "tangential" },
107
+ cssClass: valueLabels === null || valueLabels === void 0 ? void 0 : valueLabels.cssClass
108
+ });
109
+ })
110
+ },
95
111
  cssClasses: ChartStyleModelService.getCssClasses(0),
96
112
  style: chartStyle,
97
113
  sizes: {
@@ -0,0 +1,15 @@
1
+ import { MdtChartsDataRow, MdtChartsFieldName } from "../../../../config/config";
2
+ import { PolarSegmentModel } from "../../../model";
3
+ interface SegmentModelBuilderConfig {
4
+ scopedDataRows: MdtChartsDataRow[];
5
+ keyFieldName: MdtChartsFieldName;
6
+ valueFieldName: MdtChartsFieldName;
7
+ chartPaletteColors: string[];
8
+ colorFieldName?: MdtChartsFieldName;
9
+ }
10
+ export declare class SegmentModelBuilder {
11
+ private readonly config;
12
+ constructor(config: SegmentModelBuilderConfig);
13
+ build(): PolarSegmentModel[];
14
+ }
15
+ export {};
@@ -0,0 +1,19 @@
1
+ export class SegmentModelBuilder {
2
+ constructor(config) {
3
+ this.config = config;
4
+ }
5
+ build() {
6
+ return this.config.scopedDataRows.map((row, index) => {
7
+ const paletteColor = this.config.chartPaletteColors[index % this.config.chartPaletteColors.length];
8
+ let color = paletteColor;
9
+ if (this.config.colorFieldName && row[this.config.colorFieldName])
10
+ color = row[this.config.colorFieldName];
11
+ return {
12
+ key: row[this.config.keyFieldName],
13
+ value: row[this.config.valueFieldName],
14
+ color,
15
+ attachedDataRow: row
16
+ };
17
+ });
18
+ }
19
+ }
@@ -23,6 +23,7 @@ export class LevelModelBuilder {
23
23
  return acc;
24
24
  }, {});
25
25
  return publicConfig.levels.map((level, levelIndex) => {
26
+ var _a, _b;
26
27
  const valuesForLevelKeys = new Map();
27
28
  this.config.scopedDataRows.forEach((row) => {
28
29
  var _a, _b, _c, _d;
@@ -39,49 +40,68 @@ export class LevelModelBuilder {
39
40
  attachedDataRows.push(row);
40
41
  valuesForLevelKeys.set(key, { value: newValue, color, parentLevelKey, attachedDataRows });
41
42
  });
42
- return {
43
- sizes: sizesByLevels[levelIndex],
44
- segments: Array.from(valuesForLevelKeys.entries()).map(([key, { value, color, parentLevelKey, attachedDataRows }]) => {
45
- var _a;
46
- let tooltipContentRows = [
47
- {
48
- type: "plainText",
49
- textContent: key,
50
- wrapperElOptions: { cssClassName: TOOLTIP_HEAD_WRAPPER_CSS_CLASSNAME }
43
+ const segments = Array.from(valuesForLevelKeys.entries()).map(([key, { value, color, parentLevelKey, attachedDataRows }]) => {
44
+ var _a;
45
+ let tooltipContentRows = [
46
+ {
47
+ type: "plainText",
48
+ textContent: key,
49
+ wrapperElOptions: { cssClassName: TOOLTIP_HEAD_WRAPPER_CSS_CLASSNAME }
50
+ },
51
+ {
52
+ type: "captionValue",
53
+ marker: {
54
+ shape: "circle",
55
+ color
51
56
  },
52
- {
53
- type: "captionValue",
54
- marker: {
55
- shape: "circle",
56
- color
57
- },
58
- caption: publicConfig.data.valueField.title,
59
- value: this.config.formatter(value, {
60
- type: publicConfig.data.valueField.format
61
- })
62
- }
63
- ];
64
- if ((_a = level.tooltip) === null || _a === void 0 ? void 0 : _a.overrideContent) {
65
- tooltipContentRows = level.tooltip.overrideContent({
66
- autoTooltipRows: tooltipContentRows,
67
- attachedDataRows
68
- }).rows;
57
+ caption: publicConfig.data.valueField.title,
58
+ value: this.config.formatter(value, {
59
+ type: publicConfig.data.valueField.format
60
+ })
69
61
  }
70
- return {
71
- value,
72
- key,
73
- levelIndex,
74
- parentLevelKey,
75
- attachedDataRows,
76
- color,
77
- tooltip: {
78
- content: {
79
- type: "rows",
80
- rows: tooltipPublicRowToModel(tooltipContentRows)
81
- }
62
+ ];
63
+ if ((_a = level.tooltip) === null || _a === void 0 ? void 0 : _a.overrideContent) {
64
+ tooltipContentRows = level.tooltip.overrideContent({
65
+ autoTooltipRows: tooltipContentRows,
66
+ attachedDataRows
67
+ }).rows;
68
+ }
69
+ return {
70
+ value,
71
+ key,
72
+ levelIndex,
73
+ parentLevelKey,
74
+ attachedDataRows,
75
+ color,
76
+ tooltip: {
77
+ content: {
78
+ type: "rows",
79
+ rows: tooltipPublicRowToModel(tooltipContentRows)
82
80
  }
83
- };
84
- })
81
+ }
82
+ };
83
+ });
84
+ const valueLabelsIsOn = (_b = (_a = level.valueLabels) === null || _a === void 0 ? void 0 : _a.on) !== null && _b !== void 0 ? _b : false;
85
+ return {
86
+ sizes: sizesByLevels[levelIndex],
87
+ segments,
88
+ valueLabels: valueLabelsIsOn
89
+ ? {
90
+ on: true,
91
+ items: segments.map((segment) => {
92
+ var _a, _b, _c, _d, _e, _f;
93
+ return {
94
+ key: segment.key,
95
+ value: segment.value,
96
+ rotation: (_b = (_a = level.valueLabels) === null || _a === void 0 ? void 0 : _a.rotation) !== null && _b !== void 0 ? _b : { type: "tangential" },
97
+ cssClass: (_c = level.valueLabels) === null || _c === void 0 ? void 0 : _c.cssClass,
98
+ textContent: (_f = (_e = (_d = level.valueLabels) === null || _d === void 0 ? void 0 : _d.content) === null || _e === void 0 ? void 0 : _e.call(_d, {
99
+ attachedDataRows: segment.attachedDataRows
100
+ })) !== null && _f !== void 0 ? _f : segment.key.toString()
101
+ };
102
+ })
103
+ }
104
+ : { on: false }
85
105
  };
86
106
  });
87
107
  }
@@ -298,4 +298,12 @@
298
298
 
299
299
  .mdt-charts-arc-non-highlighted {
300
300
  opacity: 0.6;
301
+ }
302
+
303
+ .mdt-charts-arc-label {
304
+ text-anchor: middle;
305
+ dominant-baseline: middle;
306
+ font-size: 10px;
307
+ fill: black;
308
+ pointer-events: none;
301
309
  }
@@ -298,4 +298,12 @@
298
298
 
299
299
  .mdt-charts-arc-non-highlighted {
300
300
  opacity: 0.6;
301
+ }
302
+
303
+ .mdt-charts-arc-label {
304
+ text-anchor: middle;
305
+ dominant-baseline: middle;
306
+ font-size: 10px;
307
+ fill: black;
308
+ pointer-events: none;
301
309
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mdt-charts",
3
- "version": "1.40.1",
3
+ "version": "1.41.1",
4
4
  "description": "",
5
5
  "main": "lib/main.js",
6
6
  "scripts": {