mdt-charts 1.35.1 → 1.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/lib/config/config.d.ts +19 -0
  2. package/lib/engine/block/blockSvg.js +1 -1
  3. package/lib/engine/features/groupLabels/groupLabels.d.ts +3 -3
  4. package/lib/engine/features/groupLabels/groupLabels.js +4 -8
  5. package/lib/engine/features/groupLines/groupLines.d.ts +23 -0
  6. package/lib/engine/features/groupLines/groupLines.js +67 -0
  7. package/lib/engine/features/scale/scale.js +1 -1
  8. package/lib/engine/twoDimensionalNotation/bar/barHelper.d.ts +1 -1
  9. package/lib/engine/twoDimensionalNotation/twoDimensionalManager.d.ts +2 -1
  10. package/lib/engine/twoDimensionalNotation/twoDimensionalManager.js +22 -7
  11. package/lib/model/featuresModel/grouping/groupingDataAmountCalculator/groupingDataAmountCalculator.d.ts +15 -0
  12. package/lib/model/featuresModel/grouping/groupingDataAmountCalculator/groupingDataAmountCalculator.js +22 -0
  13. package/lib/model/featuresModel/grouping/groupingEdgeLines/groupingEdgeLinesGenerator.d.ts +15 -0
  14. package/lib/model/featuresModel/grouping/groupingEdgeLines/groupingEdgeLinesGenerator.js +51 -0
  15. package/lib/model/featuresModel/grouping/groupingLabels/groupingLabelsCoordinateHandlers.d.ts +4 -7
  16. package/lib/model/featuresModel/grouping/groupingLabels/groupingLabelsCoordinateHandlers.js +4 -18
  17. package/lib/model/featuresModel/grouping/groupingLabels/groupingLabelsScaler.d.ts +5 -13
  18. package/lib/model/featuresModel/grouping/groupingLabels/groupingLabelsScaler.js +8 -35
  19. package/lib/model/featuresModel/grouping/groupingLabels/staticCoordinateCalculator.d.ts +17 -0
  20. package/lib/model/featuresModel/grouping/groupingLabels/staticCoordinateCalculator.js +27 -0
  21. package/lib/model/featuresModel/grouping/groupingSplitLines/groupingSplitLines.d.ts +19 -0
  22. package/lib/model/featuresModel/grouping/groupingSplitLines/groupingSplitLines.js +45 -0
  23. package/lib/model/featuresModel/legendModel/twoDimLegendModel.d.ts +1 -1
  24. package/lib/model/featuresModel/scaleModel/scaleModel.d.ts +1 -1
  25. package/lib/model/featuresModel/scaleModel/scaleModel.js +4 -5
  26. package/lib/model/featuresModel/scaleModel/sizaCalculators/keyTotalSpaceCalculator.d.ts +11 -0
  27. package/lib/model/featuresModel/scaleModel/sizaCalculators/keyTotalSpaceCalculator.js +16 -0
  28. package/lib/model/featuresModel/scaleModel/sizaCalculators/scaleCanvasSizesCalculator.d.ts +14 -0
  29. package/lib/model/featuresModel/scaleModel/sizaCalculators/scaleCanvasSizesCalculator.js +25 -0
  30. package/lib/model/margin/twoDim/twoDimMarginModel.d.ts +1 -1
  31. package/lib/model/margin/twoDim/twoDimMarginModel.js +3 -1
  32. package/lib/model/model.d.ts +17 -11
  33. package/lib/model/modelBuilder.js +1 -1
  34. package/lib/model/modelInstance/canvasModel/canvasModel.d.ts +1 -1
  35. package/lib/model/modelInstance/configReader/baseConfigReader.js +1 -1
  36. package/lib/model/modelInstance/configReader/{twoDimConfigReader.ts → twoDimConfigReader}/groupingConfigReader/groupingConfigReader.d.ts +7 -8
  37. package/lib/model/modelInstance/configReader/{twoDimConfigReader.ts → twoDimConfigReader}/groupingConfigReader/groupingConfigReader.js +10 -27
  38. package/lib/model/modelInstance/configReader/{twoDimConfigReader.ts → twoDimConfigReader}/twoDimConfigReader.js +2 -2
  39. package/lib/model/notations/twoDimensionalModel.d.ts +1 -1
  40. package/lib/model/notations/twoDimensionalModel.js +61 -28
  41. package/lib/style/charts-main.css +6 -0
  42. package/lib/style/charts-main.less +6 -0
  43. package/package.json +1 -1
  44. /package/lib/model/modelInstance/configReader/{twoDimConfigReader.ts → twoDimConfigReader}/twoDimConfigReader.d.ts +0 -0
@@ -54,6 +54,25 @@ export interface MdtChartsTwoDimensionalOptions extends GraphicNotationOptions {
54
54
  orientation: ChartOrientation;
55
55
  valueLabels?: MdtChartsTwoDimensionalValueLabels;
56
56
  grouping?: TwoDimGroupingOptions;
57
+ events?: TwoDimensionalEvents;
58
+ }
59
+ interface TwoDimensionalEvents {
60
+ drawComplete?: (event: TwoDimensionalDrawCompleteEvent) => void;
61
+ }
62
+ interface TwoDimensionalDrawCompleteEvent {
63
+ canvas: {
64
+ keyItems: CanvasKeyItemOptions[];
65
+ plotAreaMargin: BlockMargin;
66
+ };
67
+ }
68
+ export interface BlockMargin {
69
+ top: number;
70
+ bottom: number;
71
+ left: number;
72
+ right: number;
73
+ }
74
+ export interface CanvasKeyItemOptions {
75
+ totalSize: number;
57
76
  }
58
77
  export interface MdtChartsPolarOptions extends GraphicNotationOptions {
59
78
  type: "polar";
@@ -4,7 +4,7 @@ import { HatchPatternDef } from "./defs/hatchPattern";
4
4
  export class BlockSvg {
5
5
  constructor(options) {
6
6
  this.hatchPatternDef = new HatchPatternDef();
7
- this.chartBlockClass = "chart-block";
7
+ this.chartBlockClass = "plot-area";
8
8
  this.chartGroupClass = "chart-group";
9
9
  this.svgCssClasses = options.svgCssClasses;
10
10
  this.parentBlockId = options.parentBlockId;
@@ -1,4 +1,4 @@
1
- import { TwoDimGroupingModel } from "../../../model/model";
1
+ import { GroupingItemLabelsModel } from "../../../model/model";
2
2
  import { Block } from "../../block/block";
3
3
  interface GroupAxisLabelsOptions {
4
4
  elementAccessors: {
@@ -10,8 +10,8 @@ export declare class GroupAxisLabels {
10
10
  private readonly renderPipeline;
11
11
  private groupsForLabels;
12
12
  constructor(options: GroupAxisLabelsOptions);
13
- render(model: TwoDimGroupingModel): void;
14
- update(model: TwoDimGroupingModel): void;
13
+ render(items: GroupingItemLabelsModel[]): void;
14
+ update(items: GroupingItemLabelsModel[]): void;
15
15
  private setAttrs;
16
16
  }
17
17
  export {};
@@ -8,10 +8,8 @@ export class GroupAxisLabels {
8
8
  return this.setAttrs(groupLabels.classed("group-label data-label", true), item);
9
9
  });
10
10
  }
11
- render(model) {
12
- if (!model.enabled)
13
- return;
14
- model.items.forEach((item, index) => {
11
+ render(items) {
12
+ items.forEach((item, index) => {
15
13
  const group = this.options.elementAccessors
16
14
  .getBlock()
17
15
  .getSvg()
@@ -27,10 +25,8 @@ export class GroupAxisLabels {
27
25
  this.renderPipeline.execute(labels, { item });
28
26
  });
29
27
  }
30
- update(model) {
31
- if (!model.enabled)
32
- return;
33
- model.items.forEach((item, index) => {
28
+ update(items) {
29
+ items.forEach((item, index) => {
34
30
  const group = this.groupsForLabels[index];
35
31
  if (!group)
36
32
  return;
@@ -0,0 +1,23 @@
1
+ import { GroupingSplitLineAttributes } from "../../../model/model";
2
+ import { Block } from "../../block/block";
3
+ interface GroupLinesOptions {
4
+ elementAccessors: {
5
+ getBlock: () => Block;
6
+ };
7
+ }
8
+ export declare class GroupLines {
9
+ private readonly options;
10
+ private edgeLinesGroup;
11
+ private splitLinesGroups;
12
+ private readonly edgeLinesGroupCssClass;
13
+ private readonly splitLinesGroupCssClass;
14
+ constructor(options: GroupLinesOptions);
15
+ render(edgeLines: GroupingSplitLineAttributes[], splitLinesByItems: GroupingSplitLineAttributes[][]): void;
16
+ update(edgeLines: GroupingSplitLineAttributes[], splitLinesByItems: GroupingSplitLineAttributes[][]): void;
17
+ private renderEdgeLines;
18
+ private renderSplitLines;
19
+ private updateEdgeLines;
20
+ private updateSplitLines;
21
+ private setAttrs;
22
+ }
23
+ export {};
@@ -0,0 +1,67 @@
1
+ export class GroupLines {
2
+ constructor(options) {
3
+ this.options = options;
4
+ this.splitLinesGroups = [];
5
+ this.edgeLinesGroupCssClass = "group-edge-lines";
6
+ this.splitLinesGroupCssClass = "group-split-lines";
7
+ }
8
+ render(edgeLines, splitLinesByItems) {
9
+ this.renderEdgeLines(edgeLines);
10
+ this.renderSplitLines(splitLinesByItems);
11
+ }
12
+ update(edgeLines, splitLinesByItems) {
13
+ this.updateEdgeLines(edgeLines);
14
+ this.updateSplitLines(splitLinesByItems);
15
+ }
16
+ renderEdgeLines(edgeLines) {
17
+ const block = this.options.elementAccessors.getBlock();
18
+ this.edgeLinesGroup = block.getSvg().append("g").classed(this.edgeLinesGroupCssClass, true);
19
+ const lines = this.edgeLinesGroup.selectAll("line").data(edgeLines).enter().append("line");
20
+ this.setAttrs(lines);
21
+ }
22
+ renderSplitLines(splitLinesByItems) {
23
+ splitLinesByItems.forEach((splitLines) => {
24
+ const group = this.options.elementAccessors
25
+ .getBlock()
26
+ .getSvg()
27
+ .append("g")
28
+ .classed(this.splitLinesGroupCssClass, true);
29
+ this.splitLinesGroups.push(group);
30
+ const lines = group.selectAll("line").data(splitLines).enter().append("line");
31
+ this.setAttrs(lines);
32
+ });
33
+ }
34
+ updateEdgeLines(edgeLines) {
35
+ const animationName = "grouping-edge-lines-animation";
36
+ const lines = this.edgeLinesGroup
37
+ .selectAll("line")
38
+ .data(edgeLines)
39
+ .interrupt(animationName)
40
+ .transition(animationName)
41
+ .duration(this.options.elementAccessors.getBlock().transitionManager.durations.chartUpdate);
42
+ this.setAttrs(lines);
43
+ }
44
+ updateSplitLines(splitLinesByItems) {
45
+ splitLinesByItems.forEach((splitLines, index) => {
46
+ const existedLines = this.splitLinesGroups[index]
47
+ .selectAll("line")
48
+ .data(splitLines);
49
+ existedLines.exit().remove();
50
+ const newLines = existedLines.enter().append("line");
51
+ this.setAttrs(newLines);
52
+ const animationName = "grouping-split-lines-animation";
53
+ this.setAttrs(existedLines
54
+ .interrupt(animationName)
55
+ .transition(animationName)
56
+ .duration(this.options.elementAccessors.getBlock().transitionManager.durations.chartUpdate));
57
+ });
58
+ }
59
+ setAttrs(lines) {
60
+ //TODO: make though render and update pipeline
61
+ return lines
62
+ .attr("x1", (d) => d.x1)
63
+ .attr("y1", (d) => d.y1)
64
+ .attr("x2", (d) => d.x2)
65
+ .attr("y2", (d) => d.y2);
66
+ }
67
+ }
@@ -44,7 +44,7 @@ export class Scale {
44
44
  return scaleBand()
45
45
  .domain(scaleKey.domain)
46
46
  .range([scaleKey.range.start, scaleKey.range.end])
47
- .paddingInner(scaleKey.sizes.paddingInner / scaleKey.sizes.bandSize)
47
+ .paddingInner(scaleKey.sizes.paddingInner / scaleKey.sizes.oneKeyTotalSpace)
48
48
  .paddingOuter(scaleKey.sizes.paddingOuter / scaleKey.sizes.recalculatedStepSize);
49
49
  }
50
50
  //TODO: remove after tests of new way to create scale band
@@ -26,7 +26,7 @@ export declare class DotChartSettingsStore implements BandLikeChartSettingsStore
26
26
  getBandItemSize(): number;
27
27
  getBandItemPad(): number;
28
28
  }
29
- export declare class BarSettingsStore {
29
+ export declare class BarSettingsStore implements BandLikeChartSettingsStore {
30
30
  private readonly modelSettings;
31
31
  private readonly canvasConfig;
32
32
  constructor(modelSettings: BarChartSettings, canvasConfig: {
@@ -8,7 +8,8 @@ export declare class TwoDimensionalManager implements ChartContentManager {
8
8
  private canvasValueLabels?;
9
9
  private linearGradientDef?;
10
10
  private dotChart;
11
- private groupLabels;
11
+ private groupLabels?;
12
+ private groupLines?;
12
13
  render(engine: Engine, model: Model<TwoDimensionalOptionsModel>): void;
13
14
  updateData(block: Block, model: Model<TwoDimensionalOptionsModel>, data: MdtChartsDataSource): void;
14
15
  updateColors(block: Block, model: Model<TwoDimensionalOptionsModel>): void;
@@ -17,6 +17,7 @@ import { LinearGradientDef } from "../../engine/block/defs/LinearGradientDef";
17
17
  import { CanvasDotChart } from "./dot/dotChart";
18
18
  import { RecordOverflowAlertCore } from "../features/recordOverflowAlert/recordOverflowAlertCore";
19
19
  import { GroupAxisLabels } from "../features/groupLabels/groupLabels";
20
+ import { GroupLines } from "../features/groupLines/groupLines";
20
21
  export class TwoDimensionalManager {
21
22
  render(engine, model) {
22
23
  const options = model.options;
@@ -39,12 +40,20 @@ export class TwoDimensionalManager {
39
40
  settings: options.chartSettings.bar
40
41
  }
41
42
  });
42
- this.groupLabels = new GroupAxisLabels({
43
- elementAccessors: {
44
- getBlock: () => engine.block
45
- }
46
- });
47
- this.groupLabels.render(options.grouping);
43
+ if (options.grouping.enabled) {
44
+ this.groupLabels = new GroupAxisLabels({
45
+ elementAccessors: {
46
+ getBlock: () => engine.block
47
+ }
48
+ });
49
+ this.groupLabels.render(options.grouping.items.map((item) => item.labels));
50
+ this.groupLines = new GroupLines({
51
+ elementAccessors: {
52
+ getBlock: () => engine.block
53
+ }
54
+ });
55
+ this.groupLines.render(options.grouping.edgeLines, options.grouping.items.map((item) => item.splitLines));
56
+ }
48
57
  this.renderCharts(engine.block, options.charts, scales, engine.data, options.data, model.chartBlock.margin, options.axis.key.orient, options.chartSettings, model.blockCanvas.size);
49
58
  Axis.raiseKeyAxis(engine.block, options.axis.key);
50
59
  engine.block.filterEventManager.registerEventFor2D(scales.key, model.chartBlock.margin, model.blockCanvas.size, options);
@@ -76,8 +85,10 @@ export class TwoDimensionalManager {
76
85
  this.linearGradientDef = new LinearGradientDef();
77
86
  this.linearGradientDef.render(engine.block.svg.ensureDefsRendered(), options.defs.gradients);
78
87
  }
88
+ model.options.canvasEvents.drawCompleted();
79
89
  }
80
90
  updateData(block, model, data) {
91
+ var _a, _b;
81
92
  block.transitionManager.interruptTransitions();
82
93
  block.filterEventManager.updateData(data[model.options.data.dataSource]);
83
94
  Title.updateData(block, model.options.title);
@@ -90,12 +101,16 @@ export class TwoDimensionalManager {
90
101
  block.scales = scales;
91
102
  Axis.update(block, scales, options.scale, options.axis, model.blockCanvas.size, keyDomainEquality);
92
103
  GridLine.update(block, options.additionalElements.gridLine, options.axis, model.blockCanvas.size, model.chartBlock.margin, scales);
93
- this.groupLabels.update(options.grouping);
104
+ if (options.grouping.enabled) {
105
+ (_a = this.groupLabels) === null || _a === void 0 ? void 0 : _a.update(options.grouping.items.map((item) => item.labels));
106
+ (_b = this.groupLines) === null || _b === void 0 ? void 0 : _b.update(options.grouping.edgeLines, options.grouping.items.map((item) => item.splitLines));
107
+ }
94
108
  const promises = this.updateCharts(block, options.charts, scales, data, model.options.data, model.chartBlock.margin, options.axis.key.orient, model.blockCanvas.size, options.chartSettings);
95
109
  Promise.all(promises).then(() => {
96
110
  block.filterEventManager.event2DUpdate(options);
97
111
  block.filterEventManager.registerEventFor2D(scales.key, model.chartBlock.margin, model.blockCanvas.size, options);
98
112
  Tooltip.render(block, model, model.otherComponents.tooltipBlock, scales);
113
+ model.options.canvasEvents.drawCompleted();
99
114
  });
100
115
  RecordOverflowAlertCore.update(block, options.recordOverflowAlert);
101
116
  if (this.canvasValueLabels)
@@ -0,0 +1,15 @@
1
+ import { MdtChartsBaseField, MdtChartsDataRow } from "../../../../config/config";
2
+ import { GroupingLabelKey } from "../../../model";
3
+ interface GroupingCanvasCalculatorOptions {
4
+ dataRows: MdtChartsDataRow[];
5
+ field: MdtChartsBaseField;
6
+ }
7
+ export declare class GroupingDataAmountCalculator {
8
+ private readonly options;
9
+ constructor(options: GroupingCanvasCalculatorOptions);
10
+ calculate(): {
11
+ rowsCountsPerGroups: number[];
12
+ groupDomain: GroupingLabelKey[];
13
+ };
14
+ }
15
+ export {};
@@ -0,0 +1,22 @@
1
+ export class GroupingDataAmountCalculator {
2
+ constructor(options) {
3
+ this.options = options;
4
+ }
5
+ calculate() {
6
+ const domainWithRowsCount = new Map();
7
+ this.options.dataRows.forEach((row) => {
8
+ const key = row[this.options.field.name];
9
+ if (key) {
10
+ if (domainWithRowsCount.has(key))
11
+ domainWithRowsCount.set(key, domainWithRowsCount.get(key) + 1);
12
+ else
13
+ domainWithRowsCount.set(key, 1);
14
+ }
15
+ });
16
+ const rowsCounts = Array.from(domainWithRowsCount.values());
17
+ return {
18
+ rowsCountsPerGroups: rowsCounts,
19
+ groupDomain: Array.from(domainWithRowsCount.keys())
20
+ };
21
+ }
22
+ }
@@ -0,0 +1,15 @@
1
+ import { GroupingSplitLineAttributes, Orient } from "../../../model";
2
+ import { CanvasModel } from "../../../modelInstance/canvasModel/canvasModel";
3
+ import { GroupingStaticCoordinateCalculator } from "../groupingLabels/staticCoordinateCalculator";
4
+ interface GroupingEdgeLinesGeneratorOptions {
5
+ orients: Iterable<Orient>;
6
+ staticCoordinateCalculator: GroupingStaticCoordinateCalculator;
7
+ canvasModel: CanvasModel;
8
+ lineWidth: number;
9
+ }
10
+ export declare class GroupingEdgeLinesGenerator {
11
+ private readonly options;
12
+ constructor(options: GroupingEdgeLinesGeneratorOptions);
13
+ generate(): GroupingSplitLineAttributes[];
14
+ }
15
+ export {};
@@ -0,0 +1,51 @@
1
+ export class GroupingEdgeLinesGenerator {
2
+ constructor(options) {
3
+ this.options = options;
4
+ }
5
+ generate() {
6
+ let edgeLines = [];
7
+ for (const orient of this.options.orients) {
8
+ if (orient === "top") {
9
+ const y1 = this.options.staticCoordinateCalculator.calculate(orient, 0);
10
+ const y2 = this.options.canvasModel.getMarginSide("top");
11
+ const leftX = this.options.canvasModel.getMarginSide("left");
12
+ const rightX = this.options.canvasModel.getBlockSize().width - this.options.canvasModel.getMarginSide("right");
13
+ edgeLines = edgeLines.concat([
14
+ { x1: leftX + this.options.lineWidth / 2, x2: leftX + this.options.lineWidth / 2, y1, y2 },
15
+ { x1: rightX - this.options.lineWidth / 2, x2: rightX - this.options.lineWidth / 2, y1, y2 }
16
+ ]);
17
+ }
18
+ if (orient === "bottom") {
19
+ const y1 = this.options.canvasModel.getBlockSize().height - this.options.canvasModel.getMarginSide("bottom");
20
+ const y2 = this.options.staticCoordinateCalculator.calculate(orient, 0);
21
+ const leftX = this.options.canvasModel.getMarginSide("left");
22
+ const rightX = this.options.canvasModel.getBlockSize().width - this.options.canvasModel.getMarginSide("right");
23
+ edgeLines = edgeLines.concat([
24
+ { x1: leftX + this.options.lineWidth / 2, x2: leftX + this.options.lineWidth / 2, y1, y2 },
25
+ { x1: rightX - this.options.lineWidth / 2, x2: rightX - this.options.lineWidth / 2, y1, y2 }
26
+ ]);
27
+ }
28
+ if (orient === "left") {
29
+ const x1 = this.options.staticCoordinateCalculator.calculate(orient, 0);
30
+ const x2 = this.options.canvasModel.getMarginSide("left");
31
+ const topY = this.options.canvasModel.getMarginSide("top");
32
+ const bottomY = this.options.canvasModel.getBlockSize().height - this.options.canvasModel.getMarginSide("bottom");
33
+ edgeLines = edgeLines.concat([
34
+ { x1, x2, y1: topY + this.options.lineWidth / 2, y2: topY + this.options.lineWidth / 2 },
35
+ { x1, x2, y1: bottomY - this.options.lineWidth / 2, y2: bottomY - this.options.lineWidth / 2 }
36
+ ]);
37
+ }
38
+ if (orient === "right") {
39
+ const x1 = this.options.canvasModel.getBlockSize().width - this.options.canvasModel.getMarginSide("right");
40
+ const x2 = this.options.staticCoordinateCalculator.calculate(orient, 0);
41
+ const topY = this.options.canvasModel.getMarginSide("top");
42
+ const bottomY = this.options.canvasModel.getBlockSize().height - this.options.canvasModel.getMarginSide("bottom");
43
+ edgeLines = edgeLines.concat([
44
+ { x1, x2, y1: topY + this.options.lineWidth / 2, y2: topY + this.options.lineWidth / 2 },
45
+ { x1, x2, y1: bottomY - this.options.lineWidth / 2, y2: bottomY - this.options.lineWidth / 2 }
46
+ ]);
47
+ }
48
+ }
49
+ return edgeLines;
50
+ }
51
+ }
@@ -1,19 +1,16 @@
1
1
  import { Orient } from "../../../model";
2
2
  import { CanvasModel } from "../../../modelInstance/canvasModel/canvasModel";
3
+ import { GroupingStaticCoordinateCalculator } from "./staticCoordinateCalculator";
3
4
  interface GroupingLabelsCoordinateHandlerOptions {
4
5
  orient: Orient;
5
6
  sideIndex: number;
6
- otherComponentSizes: {
7
- titleTotalNeededSpace: number;
8
- legendTotalNeededSpace: number;
9
- };
7
+ staticCoordinateCalculator: GroupingStaticCoordinateCalculator;
8
+ canvasModel: CanvasModel;
10
9
  }
11
10
  export declare class GroupingLabelsCoordinateHandler {
12
- private readonly canvasModel;
13
11
  private readonly options;
14
12
  private readonly staticCoordinate;
15
- private readonly verticalLabelSize;
16
- constructor(canvasModel: CanvasModel, options: GroupingLabelsCoordinateHandlerOptions);
13
+ constructor(options: GroupingLabelsCoordinateHandlerOptions);
17
14
  handleX(scaledCoordinate: number): number;
18
15
  handleY(scaledCoordinate: number): number;
19
16
  }
@@ -1,26 +1,12 @@
1
1
  export class GroupingLabelsCoordinateHandler {
2
- constructor(canvasModel, options) {
3
- this.canvasModel = canvasModel;
2
+ constructor(options) {
4
3
  this.options = options;
5
- this.verticalLabelSize = 20;
6
- if (this.options.orient === "top")
7
- this.staticCoordinate =
8
- options.otherComponentSizes.titleTotalNeededSpace + this.verticalLabelSize * this.options.sideIndex;
9
- if (this.options.orient === "bottom")
10
- this.staticCoordinate =
11
- this.canvasModel.getBlockSize().height -
12
- options.otherComponentSizes.legendTotalNeededSpace -
13
- this.verticalLabelSize * this.options.sideIndex;
14
- //TODO: padding should be got from other components
15
- if (this.options.orient === "left")
16
- this.staticCoordinate = 20 * this.options.sideIndex;
17
- if (this.options.orient === "right")
18
- this.staticCoordinate = this.canvasModel.getBlockSize().width - 20 * this.options.sideIndex;
4
+ this.staticCoordinate = this.options.staticCoordinateCalculator.calculate(this.options.orient, this.options.sideIndex);
19
5
  }
20
6
  handleX(scaledCoordinate) {
21
7
  let x;
22
8
  if (this.options.orient === "top" || this.options.orient === "bottom")
23
- x = scaledCoordinate + this.canvasModel.getMarginSide("left");
9
+ x = scaledCoordinate + this.options.canvasModel.getMarginSide("left");
24
10
  else
25
11
  x = this.staticCoordinate;
26
12
  return x;
@@ -28,7 +14,7 @@ export class GroupingLabelsCoordinateHandler {
28
14
  handleY(scaledCoordinate) {
29
15
  let y;
30
16
  if (this.options.orient === "left" || this.options.orient === "right")
31
- y = scaledCoordinate + this.canvasModel.getMarginSide("top");
17
+ y = scaledCoordinate + this.options.canvasModel.getMarginSide("top");
32
18
  else
33
19
  y = this.staticCoordinate;
34
20
  return y;
@@ -1,18 +1,10 @@
1
- import { MdtChartsBaseField, MdtChartsDataRow } from "../../../../config/config";
2
- import { GroupingLabelKey, RangeModel } from "../../../model";
1
+ import { GroupingLabelKey } from "../../../model";
2
+ import { GroupingDataAmountCalculator } from "../groupingDataAmountCalculator/groupingDataAmountCalculator";
3
+ import { ScaleCanvasSizesCalculator } from "../../scaleModel/sizaCalculators/scaleCanvasSizesCalculator";
3
4
  interface GroupingLabelsCoordinateScalerOptions {
4
- dataRows: MdtChartsDataRow[];
5
- field: MdtChartsBaseField;
6
- keyScaleInfo: KeyScaleInfoForGroupingLabelsScaler;
7
- range: RangeModel;
5
+ dataAmountCalculator: GroupingDataAmountCalculator;
6
+ sizesCalculator: ScaleCanvasSizesCalculator;
8
7
  }
9
- export declare type KeyScaleInfoForGroupingLabelsScaler = {
10
- type: "band";
11
- keyAxisOuterPadding: number;
12
- keyAxisInnerPadding: number;
13
- } | {
14
- type: "point";
15
- };
16
8
  export declare class GroupingLabelsCoordinateScaler {
17
9
  private readonly options;
18
10
  private readonly scaleFn;
@@ -2,45 +2,18 @@ import { scaleOrdinal } from "d3-scale";
2
2
  export class GroupingLabelsCoordinateScaler {
3
3
  constructor(options) {
4
4
  this.options = options;
5
- let keyAxisInnerPadding = 0;
6
- let keyAxisOuterPadding = 0;
7
- if (this.options.keyScaleInfo.type === "band") {
8
- keyAxisInnerPadding = this.options.keyScaleInfo.keyAxisInnerPadding;
9
- keyAxisOuterPadding = this.options.keyScaleInfo.keyAxisOuterPadding;
10
- }
11
- else {
12
- keyAxisInnerPadding =
13
- (this.options.range.end - this.options.range.start) / (this.options.dataRows.length - 1);
14
- keyAxisOuterPadding = 0;
15
- }
16
- const domainWithRowsCount = new Map();
17
- this.options.dataRows.forEach((row) => {
18
- const key = row[this.options.field.name];
19
- if (key) {
20
- if (domainWithRowsCount.has(key))
21
- domainWithRowsCount.set(key, domainWithRowsCount.get(key) + 1);
22
- else
23
- domainWithRowsCount.set(key, 1);
24
- }
25
- });
26
- const rangeOfKeyAxis = Math.abs(this.options.range.end - this.options.range.start) -
27
- keyAxisOuterPadding * 2 -
28
- keyAxisInnerPadding * (this.options.dataRows.length - 1);
29
- const totalShares = Array.from(domainWithRowsCount.values()).reduce((acc, curr) => acc + curr, 0);
30
- const oneShareSize = rangeOfKeyAxis / totalShares;
31
- const coordinates = [];
5
+ const { innerPadding, oneKeyPureSize, outerPadding } = this.options.sizesCalculator.calculate();
6
+ const { rowsCountsPerGroups, groupDomain } = this.options.dataAmountCalculator.calculate();
32
7
  let previousTotalShares = 0;
33
- const rowsCounts = Array.from(domainWithRowsCount.values());
34
- for (let rowIndex = 0; rowIndex < rowsCounts.length; rowIndex++) {
35
- const rowsAmount = rowsCounts[rowIndex];
36
- let previousShift = previousTotalShares * (oneShareSize + keyAxisInnerPadding);
37
- const centerOfDomainItem = previousShift +
38
- (rowsAmount * oneShareSize + (rowsAmount - 1) * keyAxisInnerPadding) / 2 +
39
- keyAxisOuterPadding;
8
+ const coordinates = [];
9
+ for (let rowIndex = 0; rowIndex < rowsCountsPerGroups.length; rowIndex++) {
10
+ const rowsAmount = rowsCountsPerGroups[rowIndex];
11
+ let previousShift = previousTotalShares * (oneKeyPureSize + innerPadding);
12
+ const centerOfDomainItem = previousShift + (rowsAmount * oneKeyPureSize + (rowsAmount - 1) * innerPadding) / 2 + outerPadding;
40
13
  coordinates.push(centerOfDomainItem);
41
14
  previousTotalShares += rowsAmount;
42
15
  }
43
- const d3Scale = scaleOrdinal(domainWithRowsCount.keys(), coordinates);
16
+ const d3Scale = scaleOrdinal(groupDomain, coordinates);
44
17
  this.scaleFn = (key) => d3Scale(key);
45
18
  }
46
19
  scaleForKey(groupingKey) {
@@ -0,0 +1,17 @@
1
+ import { Orient } from "../../../model";
2
+ import { CanvasModel } from "../../../modelInstance/canvasModel/canvasModel";
3
+ import { GroupingItemSize } from "../../../modelInstance/configReader/twoDimConfigReader/groupingConfigReader/groupingConfigReader";
4
+ interface GroupingStaticCoordinateCalculatorOptions {
5
+ otherComponentSizes: {
6
+ titleTotalNeededSpace: number;
7
+ legendTotalNeededSpace: number;
8
+ };
9
+ groupingItemSizes: GroupingItemSize[];
10
+ canvasModel: CanvasModel;
11
+ }
12
+ export declare class GroupingStaticCoordinateCalculator {
13
+ private readonly options;
14
+ constructor(options: GroupingStaticCoordinateCalculatorOptions);
15
+ calculate(orient: Orient, sideIndex: number): number;
16
+ }
17
+ export {};
@@ -0,0 +1,27 @@
1
+ export class GroupingStaticCoordinateCalculator {
2
+ constructor(options) {
3
+ this.options = options;
4
+ }
5
+ calculate(orient, sideIndex) {
6
+ const slicesSizesByCurrentOrient = this.options.groupingItemSizes.filter((item) => item.orient === orient);
7
+ const prevSlicesSizes = slicesSizesByCurrentOrient
8
+ .slice(0, sideIndex)
9
+ .reduce((acc, item) => acc + item.size, 0);
10
+ let staticCoordinate;
11
+ if (orient === "top")
12
+ staticCoordinate = this.options.otherComponentSizes.titleTotalNeededSpace + prevSlicesSizes * sideIndex;
13
+ if (orient === "bottom")
14
+ staticCoordinate =
15
+ this.options.canvasModel.getBlockSize().height -
16
+ this.options.otherComponentSizes.legendTotalNeededSpace -
17
+ prevSlicesSizes * sideIndex;
18
+ if (orient === "left")
19
+ staticCoordinate = prevSlicesSizes * sideIndex;
20
+ if (orient === "right")
21
+ staticCoordinate = this.options.canvasModel.getBlockSize().width - prevSlicesSizes * sideIndex;
22
+ if (staticCoordinate === undefined) {
23
+ throw new Error(`Static coordinate for orient ${orient} and sideIndex ${sideIndex} is undefined`);
24
+ }
25
+ return staticCoordinate;
26
+ }
27
+ }
@@ -0,0 +1,19 @@
1
+ import { GroupingSplitLineAttributes, Orient } from "../../../model";
2
+ import { CanvasModel } from "../../../modelInstance/canvasModel/canvasModel";
3
+ import { ScaleCanvasSizesCalculator } from "../../scaleModel/sizaCalculators/scaleCanvasSizesCalculator";
4
+ import { GroupingDataAmountCalculator } from "../groupingDataAmountCalculator/groupingDataAmountCalculator";
5
+ import { GroupingStaticCoordinateCalculator } from "../groupingLabels/staticCoordinateCalculator";
6
+ interface GroupingSplitLinesGeneratorOptions {
7
+ dataAmountCalculator: GroupingDataAmountCalculator;
8
+ sizesCalculator: ScaleCanvasSizesCalculator;
9
+ orient: Orient;
10
+ sideIndex: number;
11
+ staticCoordinateCalculator: GroupingStaticCoordinateCalculator;
12
+ canvasModel: CanvasModel;
13
+ }
14
+ export declare class GroupingSplitLinesGenerator {
15
+ private readonly options;
16
+ constructor(options: GroupingSplitLinesGeneratorOptions);
17
+ generate(): GroupingSplitLineAttributes[];
18
+ }
19
+ export {};
@@ -0,0 +1,45 @@
1
+ export class GroupingSplitLinesGenerator {
2
+ constructor(options) {
3
+ this.options = options;
4
+ }
5
+ generate() {
6
+ let previousTotalShares = 0;
7
+ const coordinates = [];
8
+ const { innerPadding, outerPadding, oneKeyPureSize } = this.options.sizesCalculator.calculate();
9
+ const { rowsCountsPerGroups } = this.options.dataAmountCalculator.calculate();
10
+ for (let rowIndex = 0; rowIndex < rowsCountsPerGroups.length - 1; rowIndex++) {
11
+ const rowsAmount = rowsCountsPerGroups[rowIndex];
12
+ let previousShift = previousTotalShares * (oneKeyPureSize + innerPadding);
13
+ const coordinate = previousShift + outerPadding + rowsAmount * (oneKeyPureSize + innerPadding) - innerPadding / 2;
14
+ coordinates.push(coordinate);
15
+ previousTotalShares += rowsAmount;
16
+ }
17
+ return coordinates.map((coordinate) => {
18
+ if (this.options.orient === "bottom") {
19
+ const y1 = this.options.canvasModel.getBlockSize().height - this.options.canvasModel.getMarginSide("bottom");
20
+ const y2 = this.options.staticCoordinateCalculator.calculate(this.options.orient, this.options.sideIndex);
21
+ const coordinateWithMargin = coordinate + this.options.canvasModel.getMarginSide("left");
22
+ return { x1: coordinateWithMargin, x2: coordinateWithMargin, y1, y2 };
23
+ }
24
+ if (this.options.orient === "top") {
25
+ const y1 = this.options.staticCoordinateCalculator.calculate(this.options.orient, this.options.sideIndex);
26
+ const y2 = this.options.canvasModel.getMarginSide("top");
27
+ const coordinateWithMargin = coordinate + this.options.canvasModel.getMarginSide("left");
28
+ return { x1: coordinateWithMargin, x2: coordinateWithMargin, y1, y2 };
29
+ }
30
+ if (this.options.orient === "left") {
31
+ const x1 = this.options.staticCoordinateCalculator.calculate(this.options.orient, this.options.sideIndex);
32
+ const x2 = this.options.canvasModel.getMarginSide("left");
33
+ const coordinateWithMargin = coordinate + this.options.canvasModel.getMarginSide("top");
34
+ return { x1, x2, y1: coordinateWithMargin, y2: coordinateWithMargin };
35
+ }
36
+ if (this.options.orient === "right") {
37
+ const x1 = this.options.staticCoordinateCalculator.calculate(this.options.orient, this.options.sideIndex);
38
+ const x2 = this.options.canvasModel.getBlockSize().width - this.options.canvasModel.getMarginSide("right");
39
+ const coordinateWithMargin = coordinate + this.options.canvasModel.getMarginSide("top");
40
+ return { x1, x2, y1: coordinateWithMargin, y2: coordinateWithMargin };
41
+ }
42
+ throw new Error("Got unknown orient when generate grouping split lines");
43
+ });
44
+ }
45
+ }
@@ -1,6 +1,6 @@
1
1
  import { MdtChartsTwoDimLegend } from "../../../config/config";
2
2
  import { LegendBlockModel } from "../../model";
3
- import { TwoDimConfigReader } from "../../modelInstance/configReader/twoDimConfigReader.ts/twoDimConfigReader";
3
+ import { TwoDimConfigReader } from "../../modelInstance/configReader/twoDimConfigReader/twoDimConfigReader";
4
4
  import { ModelInstance } from "../../modelInstance/modelInstance";
5
5
  export declare class TwoDimLegendModel {
6
6
  private configReader;
@@ -1,7 +1,7 @@
1
1
  import { ScaleKeyModel, ScaleValueModel } from "../../model";
2
2
  import { MdtChartsTwoDimensionalOptions, MdtChartsDataRow } from "../../../config/config";
3
3
  import { CanvasModel } from "../../modelInstance/canvasModel/canvasModel";
4
- import { TwoDimConfigReader } from "../../modelInstance/configReader/twoDimConfigReader.ts/twoDimConfigReader";
4
+ import { TwoDimConfigReader } from "../../modelInstance/configReader/twoDimConfigReader/twoDimConfigReader";
5
5
  import { BarOptionsCanvas } from "../../../designer/designerConfig";
6
6
  export declare enum ScaleType {
7
7
  Key = 0,
@@ -25,8 +25,7 @@ export class ScaleModel {
25
25
  return Object.assign(Object.assign({}, baseModel), { type: "point" });
26
26
  }
27
27
  if (type === "band") {
28
- const elementsInGroupAmount = getElementsAmountForScale(bandLikeCharts);
29
- return Object.assign(Object.assign({}, baseModel), { type: "band", elementsAmount: elementsInGroupAmount, sizes: this.getBandScaleSizeParams(baseModel.domain, baseModel.range, elementsInGroupAmount) });
28
+ return Object.assign(Object.assign({}, baseModel), { type: "band", sizes: this.getBandScaleSizeParams(baseModel.domain, baseModel.range, getElementsAmountForScale(bandLikeCharts)) });
30
29
  }
31
30
  throw new Error("Unknown scale key type");
32
31
  }
@@ -61,8 +60,8 @@ export class ScaleModel {
61
60
  };
62
61
  const getStepSize = () => (Math.abs(range.end - range.start) + paddings.inner - 2 * paddings.outer) / domainValues.length;
63
62
  const getBandSize = () => getStepSize() - paddings.inner;
64
- const initialBandSize = getBandSize();
65
- if (this.barCanvas.groupMinDistance < initialBandSize) {
63
+ const oneKeyTotalSpace = getBandSize();
64
+ if (this.barCanvas.groupMinDistance < oneKeyTotalSpace) {
66
65
  paddings.inner = this.barCanvas.groupMinDistance;
67
66
  paddings.outer = this.barCanvas.groupMinDistance / 2;
68
67
  }
@@ -84,7 +83,7 @@ export class ScaleModel {
84
83
  return {
85
84
  paddingInner: paddings.inner,
86
85
  paddingOuter: paddings.outer,
87
- bandSize: initialBandSize,
86
+ oneKeyTotalSpace,
88
87
  recalculatedStepSize: getStepSize()
89
88
  };
90
89
  }
@@ -0,0 +1,11 @@
1
+ import { CanvasKeyItemOptions } from "../../../../config/config";
2
+ import { ScaleCanvasSizesCalculator } from "./scaleCanvasSizesCalculator";
3
+ interface KeyTotalSpaceCalculatorOptions {
4
+ scaleSizesCalculator: ScaleCanvasSizesCalculator;
5
+ }
6
+ export declare class KeyTotalSpaceCalculator {
7
+ private readonly options;
8
+ constructor(options: KeyTotalSpaceCalculatorOptions);
9
+ calculate(): CanvasKeyItemOptions[];
10
+ }
11
+ export {};
@@ -0,0 +1,16 @@
1
+ export class KeyTotalSpaceCalculator {
2
+ constructor(options) {
3
+ this.options = options;
4
+ }
5
+ calculate() {
6
+ const sizes = this.options.scaleSizesCalculator.calculate();
7
+ const items = new Array(sizes.keysAmount);
8
+ for (let i = 0; i < sizes.keysAmount; i++) {
9
+ if (i === 0 || i === sizes.keysAmount - 1)
10
+ items[i] = { totalSize: sizes.outerPadding + sizes.oneKeyPureSize + sizes.innerPadding / 2 };
11
+ else
12
+ items[i] = { totalSize: sizes.oneKeyPureSize + sizes.innerPadding };
13
+ }
14
+ return items;
15
+ }
16
+ }
@@ -0,0 +1,14 @@
1
+ import { ScaleKeyModel } from "../../../model";
2
+ export interface KeyScaleCanvasSizes {
3
+ innerPadding: number;
4
+ outerPadding: number;
5
+ oneKeyPureSize: number;
6
+ keysAmount: number;
7
+ }
8
+ export declare class ScaleCanvasSizesCalculator {
9
+ private readonly options;
10
+ constructor(options: {
11
+ keyScale: ScaleKeyModel;
12
+ });
13
+ calculate(): KeyScaleCanvasSizes;
14
+ }
@@ -0,0 +1,25 @@
1
+ export class ScaleCanvasSizesCalculator {
2
+ constructor(options) {
3
+ this.options = options;
4
+ }
5
+ calculate() {
6
+ if (this.options.keyScale.type === "band") {
7
+ const rangeOfKeyAxis = Math.abs(this.options.keyScale.range.end - this.options.keyScale.range.start) -
8
+ this.options.keyScale.sizes.paddingOuter * 2 -
9
+ this.options.keyScale.sizes.paddingInner * (this.options.keyScale.domain.length - 1);
10
+ return {
11
+ innerPadding: this.options.keyScale.sizes.paddingInner,
12
+ outerPadding: this.options.keyScale.sizes.paddingOuter,
13
+ oneKeyPureSize: rangeOfKeyAxis / this.options.keyScale.domain.length,
14
+ keysAmount: this.options.keyScale.domain.length
15
+ };
16
+ }
17
+ return {
18
+ innerPadding: (this.options.keyScale.range.end - this.options.keyScale.range.start) /
19
+ (this.options.keyScale.domain.length - 1),
20
+ outerPadding: 0,
21
+ oneKeyPureSize: 0,
22
+ keysAmount: this.options.keyScale.domain.length
23
+ };
24
+ }
25
+ }
@@ -1,6 +1,6 @@
1
1
  import { DesignerConfig } from "../../../designer/designerConfig";
2
2
  import { OtherCommonComponents } from "../../model";
3
- import { TwoDimConfigReader } from "../../modelInstance/configReader/twoDimConfigReader.ts/twoDimConfigReader";
3
+ import { TwoDimConfigReader } from "../../modelInstance/configReader/twoDimConfigReader/twoDimConfigReader";
4
4
  import { ModelInstance } from "../../modelInstance/modelInstance";
5
5
  export declare const AXIS_HORIZONTAL_LABEL_PADDING = 12;
6
6
  export declare const AXIS_VERTICAL_LABEL_PADDING = 8;
@@ -113,7 +113,9 @@ export class TwoDimMarginModel {
113
113
  top: "bottom",
114
114
  bottom: "top"
115
115
  };
116
- canvasModel.increaseMarginSide(axisMarginMapping[keyAxisOrient], valueLabelFontSize + VALUE_LABEL_OFFSET_ABS_SIZE_PX);
116
+ canvasModel.increaseMarginSide(axisMarginMapping[keyAxisOrient],
117
+ //TODO: calculate according to offsetSize from config for each chart
118
+ valueLabelFontSize + VALUE_LABEL_OFFSET_ABS_SIZE_PX);
117
119
  }
118
120
  getValueAxisLabels(scaleModel) {
119
121
  const scale = Scale.getScaleValue(scaleModel);
@@ -1,4 +1,4 @@
1
- import { ChartOrientation, MdtChartsColorField, PolarChartType, Size, TwoDimensionalChartType, AxisLabelPosition, ShowTickFn, MdtChartsDataRow, TwoDimensionalValueGroup, ValueLabelsCollisionMode, ValueLabelsRotationOptions, ValueLabelsHandleElement, MdtChartsFieldName } from "../config/config";
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, TooltipSettings, Transitions } from "../designer/designerConfig";
3
3
  import { BoundingRect } from "../engine/features/valueLabelsCollision/valueLabelsCollision";
4
4
  declare type AxisType = "key" | "value";
@@ -30,12 +30,7 @@ export interface BlockCanvas {
30
30
  export interface ChartBlockModel {
31
31
  margin: BlockMargin;
32
32
  }
33
- export interface BlockMargin {
34
- top: number;
35
- bottom: number;
36
- left: number;
37
- right: number;
38
- }
33
+ export declare type BlockMargin = ConfigBlockMargin;
39
34
  export interface TooltipBasicModel {
40
35
  getContent: (keyFieldValue: string) => TooltipContent;
41
36
  }
@@ -81,6 +76,9 @@ export interface TwoDimensionalOptionsModel extends GraphicNotationOptionsModel
81
76
  chartSettings: TwoDimChartElementsSettings;
82
77
  valueLabels: TwoDimensionalValueLabels;
83
78
  grouping: TwoDimGroupingModel;
79
+ canvasEvents: {
80
+ drawCompleted: () => void;
81
+ };
84
82
  }
85
83
  export interface PolarOptionsModel extends GraphicNotationOptionsModel {
86
84
  type: "polar";
@@ -135,13 +133,11 @@ export declare type ScaleKeyModel = ScaleBandModel | ScalePointModel;
135
133
  export interface ScaleBandModel extends BaseScaleKeyModel {
136
134
  type: "band";
137
135
  sizes: ScaleBandModelSizeParams;
138
- /** @deprecated Use sizes instead */
139
- elementsAmount: number;
140
136
  }
141
137
  export interface ScaleBandModelSizeParams {
142
138
  paddingOuter: number;
143
139
  paddingInner: number;
144
- bandSize: number;
140
+ oneKeyTotalSpace: number;
145
141
  recalculatedStepSize: number;
146
142
  }
147
143
  export interface ScalePointModel extends BaseScaleKeyModel {
@@ -312,6 +308,7 @@ export declare type ValueLabelsChartBlockSide = {
312
308
  export interface TwoDimGroupingModel {
313
309
  enabled: boolean;
314
310
  items: TwoDimGroupingItemModel[];
311
+ edgeLines: GroupingSplitLineAttributes[];
315
312
  }
316
313
  export interface GroupingLabelCoordinate {
317
314
  x: number;
@@ -319,8 +316,11 @@ export interface GroupingLabelCoordinate {
319
316
  }
320
317
  export declare type GroupingLabelKey = string | number;
321
318
  export interface TwoDimGroupingItemModel {
319
+ labels: GroupingItemLabelsModel;
320
+ splitLines: GroupingSplitLineAttributes[];
321
+ }
322
+ export interface GroupingItemLabelsModel {
322
323
  domain: GroupingLabelKey[];
323
- orient: Orient;
324
324
  textAnchor: TextAnchor;
325
325
  dominantBaseline: DominantBaseline;
326
326
  coordinate: {
@@ -328,6 +328,12 @@ export interface TwoDimGroupingItemModel {
328
328
  handleY: (key: GroupingLabelKey) => number;
329
329
  };
330
330
  }
331
+ export interface GroupingSplitLineAttributes {
332
+ x1: number;
333
+ x2: number;
334
+ y1: number;
335
+ y2: number;
336
+ }
331
337
  export interface DonutChartSettings extends Omit<DonutOptionsCanvas, "aggregatorPad" | "thickness"> {
332
338
  aggregator: DonutAggregatorModel;
333
339
  thickness: DonutThicknessOptions;
@@ -5,7 +5,7 @@ import { DataManagerModel } from "./dataManagerModel/dataManagerModel";
5
5
  import { OtherComponentsModel } from "./featuresModel/otherComponents";
6
6
  import { ConfigValidator } from "./configsValidator/configValidator";
7
7
  import { ModelInstance } from "./modelInstance/modelInstance";
8
- import { TwoDimConfigReader } from "./modelInstance/configReader/twoDimConfigReader.ts/twoDimConfigReader";
8
+ import { TwoDimConfigReader } from "./modelInstance/configReader/twoDimConfigReader/twoDimConfigReader";
9
9
  import { TitleConfigReader } from "./modelInstance/titleConfigReader";
10
10
  export var AxisType;
11
11
  (function (AxisType) {
@@ -13,7 +13,7 @@ export declare class CanvasModel implements CanvasMarginModel, CanvasSizesModel
13
13
  private margin;
14
14
  constructor();
15
15
  initMargin(margin: BlockMargin): void;
16
- getMargin(): BlockMargin;
16
+ getMargin(): import("../../../config/config").BlockMargin;
17
17
  getMarginSide(side: MarginSide): number;
18
18
  setMarginSide(side: MarginSide, size: number): void;
19
19
  increaseMarginSide(side: MarginSide, byValue: number, key?: string): void;
@@ -1,5 +1,5 @@
1
1
  import { PolarConfigReader } from "./polarConfigReader/polarConfigReader";
2
- import { TwoDimConfigReader } from "./twoDimConfigReader.ts/twoDimConfigReader";
2
+ import { TwoDimConfigReader } from "./twoDimConfigReader/twoDimConfigReader";
3
3
  export function getConfigReader(config, designerConfig) {
4
4
  if (config.options.type === "2d")
5
5
  return new TwoDimConfigReader(config, designerConfig);
@@ -1,5 +1,9 @@
1
1
  import { ChartOrientation, DiscreteAxisOptions, MdtChartsBaseField, MdtChartsDataRow, TwoDimGroupingOptions } from "../../../../../config/config";
2
2
  import { DominantBaseline, Orient, TextAnchor } from "../../../../model";
3
+ export interface GroupingItemSize {
4
+ orient: Orient;
5
+ size: number;
6
+ }
3
7
  export declare class GroupingConfigReader {
4
8
  private readonly keyAxisOptions;
5
9
  private readonly chartOrientation;
@@ -7,14 +11,9 @@ export declare class GroupingConfigReader {
7
11
  private readonly maxLabelSize;
8
12
  constructor(keyAxisOptions: DiscreteAxisOptions, chartOrientation: ChartOrientation, groupingOptions?: TwoDimGroupingOptions);
9
13
  isEnabled(): boolean;
10
- getSlicesByOrients(): {
11
- orient: Orient;
12
- amount: number;
13
- }[];
14
- getSlicesSizesByOrients(dataRows: MdtChartsDataRow[]): {
15
- orient: Orient;
16
- size: number;
17
- }[];
14
+ getLineWidth(): number;
15
+ getUsingOrients(): Set<Orient>;
16
+ getSlicesSizesByOrients(dataRows: MdtChartsDataRow[]): GroupingItemSize[];
18
17
  getPreparedOptions(scopedDatasourceRows: MdtChartsDataRow[]): {
19
18
  domain: string[];
20
19
  orient: Orient;
@@ -7,35 +7,18 @@ export class GroupingConfigReader {
7
7
  this.maxLabelSize = 60;
8
8
  }
9
9
  isEnabled() {
10
- return Boolean(this.groupingOptions) && this.groupingOptions.items.length > 0;
10
+ return !!this.groupingOptions && this.groupingOptions.items.length > 0;
11
11
  }
12
- getSlicesByOrients() {
13
- var _a, _b, _c, _d;
14
- const slices = [];
15
- const slicesAmountFromKeyAxisSide = (_b = (_a = this.groupingOptions) === null || _a === void 0 ? void 0 : _a.items.filter((item) => { var _a; return this.getLabelPosition((_a = item.labels) === null || _a === void 0 ? void 0 : _a.position) === this.keyAxisOptions.position; }).length) !== null && _b !== void 0 ? _b : 0;
16
- const slicesAmountOppositeToKeyAxisSide = (_d = (_c = this.groupingOptions) === null || _c === void 0 ? void 0 : _c.items.filter((item) => { var _a; return this.getLabelPosition((_a = item.labels) === null || _a === void 0 ? void 0 : _a.position) !== this.keyAxisOptions.position; }).length) !== null && _d !== void 0 ? _d : 0;
17
- const pushIfAmountIsNotZero = (orient, amount) => {
18
- if (amount > 0) {
19
- slices.push({ orient, amount });
20
- }
21
- };
22
- if (this.chartOrientation === "vertical") {
23
- pushIfAmountIsNotZero("top", this.keyAxisOptions.position === "start"
24
- ? slicesAmountFromKeyAxisSide
25
- : slicesAmountOppositeToKeyAxisSide);
26
- pushIfAmountIsNotZero("bottom", this.keyAxisOptions.position === "start"
27
- ? slicesAmountOppositeToKeyAxisSide
28
- : slicesAmountFromKeyAxisSide);
29
- }
30
- else {
31
- pushIfAmountIsNotZero("left", this.keyAxisOptions.position === "start"
32
- ? slicesAmountFromKeyAxisSide
33
- : slicesAmountOppositeToKeyAxisSide);
34
- pushIfAmountIsNotZero("right", this.keyAxisOptions.position === "start"
35
- ? slicesAmountOppositeToKeyAxisSide
36
- : slicesAmountFromKeyAxisSide);
12
+ getLineWidth() {
13
+ return 1;
14
+ }
15
+ getUsingOrients() {
16
+ var _a, _b, _c;
17
+ const usingOrients = new Set();
18
+ for (const item of (_b = (_a = this.groupingOptions) === null || _a === void 0 ? void 0 : _a.items) !== null && _b !== void 0 ? _b : []) {
19
+ usingOrients.add(this.getLabelOrient((_c = item.labels) === null || _c === void 0 ? void 0 : _c.position));
37
20
  }
38
- return slices;
21
+ return usingOrients;
39
22
  }
40
23
  getSlicesSizesByOrients(dataRows) {
41
24
  var _a;
@@ -9,8 +9,8 @@ export class TwoDimConfigReader {
9
9
  const defaultBlockMargin = {
10
10
  top: 5,
11
11
  bottom: 0,
12
- left: 0,
13
- right: 0
12
+ left: 5,
13
+ right: 5
14
14
  };
15
15
  return Object.assign(Object.assign({}, defaultBlockMargin), this.designerConfig.canvas.chartBlockMargin);
16
16
  }
@@ -1,7 +1,7 @@
1
1
  import { ChartOrientation, MdtChartsTwoDimensionalChart } from "../../config/config";
2
2
  import { ChartOptionsCanvas, DesignerConfig } from "../../designer/designerConfig";
3
3
  import { TwoDimensionalOptionsModel, TwoDimChartElementsSettings } from "../model";
4
- import { TwoDimConfigReader } from "../modelInstance/configReader/twoDimConfigReader.ts/twoDimConfigReader";
4
+ import { TwoDimConfigReader } from "../modelInstance/configReader/twoDimConfigReader/twoDimConfigReader";
5
5
  import { ModelInstance } from "../modelInstance/modelInstance";
6
6
  export declare class TwoDimensionalModel {
7
7
  static getOptions(configReader: TwoDimConfigReader, designerConfig: DesignerConfig, modelInstance: ModelInstance): TwoDimensionalOptionsModel;
@@ -12,6 +12,12 @@ import { TwoDimTooltipContentGenerator } from "../featuresModel/tooltipModel/too
12
12
  import { TwoDimInitialRowsProvider } from "../featuresModel/tooltipModel/contentByNotations/twoDimInitialRowsProvider";
13
13
  import { GroupingLabelsCoordinateHandler } from "../featuresModel/grouping/groupingLabels/groupingLabelsCoordinateHandlers";
14
14
  import { GroupingLabelsCoordinateScaler } from "../featuresModel/grouping/groupingLabels/groupingLabelsScaler";
15
+ import { GroupingStaticCoordinateCalculator } from "../featuresModel/grouping/groupingLabels/staticCoordinateCalculator";
16
+ import { GroupingEdgeLinesGenerator } from "../featuresModel/grouping/groupingEdgeLines/groupingEdgeLinesGenerator";
17
+ import { GroupingSplitLinesGenerator } from "../featuresModel/grouping/groupingSplitLines/groupingSplitLines";
18
+ import { GroupingDataAmountCalculator } from "../featuresModel/grouping/groupingDataAmountCalculator/groupingDataAmountCalculator";
19
+ import { ScaleCanvasSizesCalculator } from "../featuresModel/scaleModel/sizaCalculators/scaleCanvasSizesCalculator";
20
+ import { KeyTotalSpaceCalculator } from "../featuresModel/scaleModel/sizaCalculators/keyTotalSpaceCalculator";
15
21
  export class TwoDimensionalModel {
16
22
  static getOptions(configReader, designerConfig, modelInstance) {
17
23
  const options = configReader.options;
@@ -31,51 +37,78 @@ export class TwoDimensionalModel {
31
37
  const titleConfig = TitleConfigReader.create(options.title, modelInstance);
32
38
  const keyScale = scaleModel.getScaleKey(modelInstance.dataModel.getAllowableKeys());
33
39
  const isHorizontal = options.orientation === "horizontal";
40
+ const groupingStaticCoordinateCalculator = new GroupingStaticCoordinateCalculator({
41
+ canvasModel,
42
+ otherComponentSizes: {
43
+ titleTotalNeededSpace: canvasModel.titleCanvas.getAllNeededSpace(),
44
+ legendTotalNeededSpace: canvasModel.legendCanvas.getAllNeededSpace()
45
+ },
46
+ groupingItemSizes: configReader.grouping.getSlicesSizesByOrients(modelInstance.dataModel.repository.getScopedRows())
47
+ });
48
+ const groupingEdgeLinesGenerator = new GroupingEdgeLinesGenerator({
49
+ canvasModel,
50
+ orients: configReader.grouping.getUsingOrients(),
51
+ staticCoordinateCalculator: groupingStaticCoordinateCalculator,
52
+ lineWidth: configReader.grouping.getLineWidth()
53
+ });
54
+ const scaleSizesCalculator = new ScaleCanvasSizesCalculator({ keyScale });
55
+ const keyTotalSpaceCalculator = new KeyTotalSpaceCalculator({ scaleSizesCalculator });
34
56
  return {
35
57
  legend: canvasModel.legendCanvas.getModel(),
58
+ canvasEvents: {
59
+ drawCompleted: () => {
60
+ var _a, _b;
61
+ (_b = (_a = options.events) === null || _a === void 0 ? void 0 : _a.drawComplete) === null || _b === void 0 ? void 0 : _b.call(_a, {
62
+ canvas: {
63
+ plotAreaMargin: canvasModel.getMargin(),
64
+ keyItems: keyTotalSpaceCalculator.calculate()
65
+ }
66
+ });
67
+ }
68
+ },
36
69
  title: {
37
70
  textContent: titleConfig.getTextContent(),
38
71
  fontSize: titleConfig.getFontSize()
39
72
  },
40
73
  grouping: {
41
74
  enabled: configReader.grouping.isEnabled(),
75
+ edgeLines: groupingEdgeLinesGenerator.generate(),
42
76
  items: configReader.grouping
43
77
  .getPreparedOptions(modelInstance.dataModel.repository.getScopedRows())
44
78
  .map((prepared) => {
45
- let keyScaleInfo;
46
- if (keyScale.type === "band") {
47
- keyScaleInfo = {
48
- type: keyScale.type,
49
- keyAxisOuterPadding: keyScale.sizes.paddingOuter,
50
- keyAxisInnerPadding: keyScale.sizes.paddingInner
51
- };
52
- }
53
- else {
54
- keyScaleInfo = { type: "point" };
55
- }
56
- const scaler = new GroupingLabelsCoordinateScaler({
79
+ const groupingDataAmountCalculator = new GroupingDataAmountCalculator({
57
80
  dataRows: modelInstance.dataModel.repository.getScopedRows(),
58
- field: prepared.field,
59
- keyScaleInfo,
60
- range: keyScale.range
81
+ field: prepared.field
61
82
  });
62
- const coordinateHandler = new GroupingLabelsCoordinateHandler(canvasModel, {
83
+ const scaler = new GroupingLabelsCoordinateScaler({
84
+ dataAmountCalculator: groupingDataAmountCalculator,
85
+ sizesCalculator: scaleSizesCalculator
86
+ });
87
+ const coordinateHandler = new GroupingLabelsCoordinateHandler({
88
+ canvasModel,
63
89
  orient: prepared.orient,
64
90
  sideIndex: prepared.sideIndex,
65
- otherComponentSizes: {
66
- titleTotalNeededSpace: canvasModel.titleCanvas.getAllNeededSpace(),
67
- legendTotalNeededSpace: canvasModel.legendCanvas.getAllNeededSpace()
68
- }
91
+ staticCoordinateCalculator: groupingStaticCoordinateCalculator
69
92
  });
70
- return {
93
+ const splitLinesGenerator = new GroupingSplitLinesGenerator({
94
+ canvasModel,
71
95
  orient: prepared.orient,
72
- domain: prepared.domain,
73
- textAnchor: prepared.textAnchor,
74
- dominantBaseline: prepared.dominantBaseline,
75
- coordinate: {
76
- handleX: (groupKey) => coordinateHandler.handleX(scaler.scaleForKey(groupKey)),
77
- handleY: (groupKey) => coordinateHandler.handleY(scaler.scaleForKey(groupKey))
78
- }
96
+ sideIndex: prepared.sideIndex,
97
+ staticCoordinateCalculator: groupingStaticCoordinateCalculator,
98
+ dataAmountCalculator: groupingDataAmountCalculator,
99
+ sizesCalculator: scaleSizesCalculator
100
+ });
101
+ return {
102
+ labels: {
103
+ domain: prepared.domain,
104
+ textAnchor: prepared.textAnchor,
105
+ dominantBaseline: prepared.dominantBaseline,
106
+ coordinate: {
107
+ handleX: (groupKey) => coordinateHandler.handleX(scaler.scaleForKey(groupKey)),
108
+ handleY: (groupKey) => coordinateHandler.handleY(scaler.scaleForKey(groupKey))
109
+ }
110
+ },
111
+ splitLines: splitLinesGenerator.generate()
79
112
  };
80
113
  })
81
114
  },
@@ -213,6 +213,12 @@
213
213
  stroke: rgba(231, 229, 228, 0.8);
214
214
  }
215
215
 
216
+ /* Group lines */
217
+ .group-edge-lines line,
218
+ .group-split-lines line {
219
+ stroke: rgba(231, 229, 228, 0.8);
220
+ }
221
+
216
222
  /* Aggregator */
217
223
  .aggregator-value, .aggregator-name {
218
224
  color: #000000;
@@ -213,6 +213,12 @@
213
213
  stroke: rgba(231, 229, 228, 0.8);
214
214
  }
215
215
 
216
+ /* Group lines */
217
+ .group-edge-lines line,
218
+ .group-split-lines line {
219
+ stroke: rgba(231, 229, 228, 0.8);
220
+ }
221
+
216
222
  /* Aggregator */
217
223
  .aggregator-value, .aggregator-name {
218
224
  color: #000000;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mdt-charts",
3
- "version": "1.35.1",
3
+ "version": "1.37.0",
4
4
  "description": "",
5
5
  "main": "lib/main.js",
6
6
  "scripts": {