mdt-charts 1.37.2 → 1.37.3

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 (29) hide show
  1. package/lib/engine/features/markDots/markDotsHelper.js +4 -2
  2. package/lib/engine/features/scale/scale.d.ts +1 -2
  3. package/lib/engine/features/scale/scale.js +1 -27
  4. package/lib/engine/features/tolltip/tooltipHelper.js +8 -6
  5. package/lib/engine/features/valueLabels/valueLabels.js +2 -2
  6. package/lib/engine/features/valueLabels/valueLabelsHelper.d.ts +1 -1
  7. package/lib/engine/features/valueLabels/valueLabelsHelper.js +5 -6
  8. package/lib/engine/twoDimensionalNotation/area/areaHelper.js +4 -4
  9. package/lib/engine/twoDimensionalNotation/bar/bar.d.ts +2 -2
  10. package/lib/engine/twoDimensionalNotation/bar/bar.js +14 -15
  11. package/lib/engine/twoDimensionalNotation/bar/barHelper.d.ts +3 -28
  12. package/lib/engine/twoDimensionalNotation/bar/barHelper.js +6 -47
  13. package/lib/engine/twoDimensionalNotation/dot/dotChart.js +6 -7
  14. package/lib/engine/twoDimensionalNotation/line/lineHelper.js +4 -4
  15. package/lib/engine/twoDimensionalNotation/twoDimensionalManager.js +2 -3
  16. package/lib/model/featuresModel/bandLikeCharts/bandLikeChartSettings.d.ts +3 -0
  17. package/lib/model/featuresModel/bandLikeCharts/bandLikeChartSettings.js +10 -0
  18. package/lib/model/featuresModel/bandLikeCharts/barChartSettingsStore.d.ts +11 -0
  19. package/lib/model/featuresModel/bandLikeCharts/barChartSettingsStore.js +14 -0
  20. package/lib/model/featuresModel/bandLikeCharts/dotChartSettingsStore.d.ts +9 -0
  21. package/lib/model/featuresModel/bandLikeCharts/dotChartSettingsStore.js +11 -0
  22. package/lib/model/featuresModel/scaleModel/scaleModel.js +2 -1
  23. package/lib/model/featuresModel/valueLabelsModel/valueLabelsModel.d.ts +6 -3
  24. package/lib/model/featuresModel/valueLabelsModel/valueLabelsModel.js +10 -5
  25. package/lib/model/model.d.ts +14 -3
  26. package/lib/model/notations/twoDimensional/styles.d.ts +1 -0
  27. package/lib/model/notations/twoDimensional/styles.js +11 -1
  28. package/lib/model/notations/twoDimensionalModel.js +22 -9
  29. package/package.json +1 -1
@@ -5,10 +5,12 @@ export class MarkDotHelper {
5
5
  const attrs = { cx: null, cy: null };
6
6
  if (keyAxisOrient === "left" || keyAxisOrient === "right") {
7
7
  attrs.cx = (d) => scales.value(d[valueField]) + margin.left;
8
- attrs.cy = (d) => Scale.getScaledValue(scales.key, Helper.getKeyFieldValue(d, keyField, isSegmented)) + margin.top;
8
+ attrs.cy = (d) => Scale.getScaledValueOnMiddleOfItem(scales.key, Helper.getKeyFieldValue(d, keyField, isSegmented)) +
9
+ margin.top;
9
10
  }
10
11
  else if (keyAxisOrient === "bottom" || keyAxisOrient === "top") {
11
- attrs.cx = (d) => Scale.getScaledValue(scales.key, Helper.getKeyFieldValue(d, keyField, isSegmented)) + margin.left;
12
+ attrs.cx = (d) => Scale.getScaledValueOnMiddleOfItem(scales.key, Helper.getKeyFieldValue(d, keyField, isSegmented)) +
13
+ margin.left;
12
14
  attrs.cy = (d) => scales.value(d[valueField]) + margin.top;
13
15
  }
14
16
  return attrs;
@@ -14,9 +14,8 @@ export declare class Scale {
14
14
  static getScaleValue(scaleValue: ScaleValueModel): ScaleLinear<number, number, number>;
15
15
  static getScaleBandWidth(scale: AxisScale<any>): number;
16
16
  static getScaleStep(scale: AxisScale<any>): number;
17
- static getScaledValue(scale: AxisScale<any>, value: any): number;
17
+ static getScaledValueOnMiddleOfItem(scale: AxisScale<any>, value: any): number;
18
18
  static getScaleBandNew(scaleKey: ScaleBandModel): ScaleBand<string>;
19
- private static getScaleBand;
20
19
  private static getScaleLinear;
21
20
  private static getScalePoint;
22
21
  }
@@ -34,7 +34,7 @@ export class Scale {
34
34
  return scale.step();
35
35
  }
36
36
  }
37
- static getScaledValue(scale, value) {
37
+ static getScaledValueOnMiddleOfItem(scale, value) {
38
38
  if (scale.bandwidth && scale.bandwidth() !== 0) {
39
39
  return scale(value) + this.getScaleBandWidth(scale) / 2;
40
40
  }
@@ -47,32 +47,6 @@ export class Scale {
47
47
  .paddingInner(scaleKey.sizes.paddingInner / scaleKey.sizes.oneKeyTotalSpace)
48
48
  .paddingOuter(scaleKey.sizes.paddingOuter / scaleKey.sizes.recalculatedStepSize);
49
49
  }
50
- //TODO: remove after tests of new way to create scale band
51
- static getScaleBand(domain, range, bandSettings, elementsInGroupAmount) {
52
- const scale = scaleBand().domain(domain).range([range.start, range.end]);
53
- const bandSize = scale.bandwidth();
54
- if (bandSettings.groupMinDistance < bandSize) {
55
- scale.paddingInner(bandSettings.groupMinDistance / bandSize);
56
- scale.paddingOuter(bandSettings.groupMinDistance / bandSize / 2);
57
- }
58
- // Padding inner = 10. If bandwidth more than needed, paddingInner is increased to number less than 35
59
- let paddingInner = bandSettings.groupMinDistance;
60
- while (scale.bandwidth() >
61
- bandSettings.maxBarWidth * elementsInGroupAmount +
62
- bandSettings.barDistance * (elementsInGroupAmount - 1) &&
63
- paddingInner < bandSettings.groupMaxDistance) {
64
- scale.paddingInner(++paddingInner / bandSize);
65
- }
66
- // if bandwidth more than all bars widths in group + distance between it + distance between groups
67
- let paddingOuter = 1;
68
- while (scale.step() >
69
- bandSettings.maxBarWidth * elementsInGroupAmount +
70
- bandSettings.groupMaxDistance +
71
- bandSettings.barDistance * (elementsInGroupAmount - 1)) {
72
- scale.paddingOuter(++paddingOuter / bandSize);
73
- }
74
- return scale;
75
- }
76
50
  static getScaleLinear(domain, range) {
77
51
  const scale = scaleLinear().domain(domain).range([range.start, range.end]);
78
52
  scale.unknown(scale(0));
@@ -37,14 +37,16 @@ export class TooltipHelper {
37
37
  left: null
38
38
  };
39
39
  if (keyAxisOrient === "bottom" || keyAxisOrient === "top") {
40
- coordinate.left = Scale.getScaledValue(scaleKey, keyValue) + margin.left - tooltipBoundingRect.width / 2;
40
+ coordinate.left =
41
+ Scale.getScaledValueOnMiddleOfItem(scaleKey, keyValue) + margin.left - tooltipBoundingRect.width / 2;
41
42
  if (keyAxisOrient === "bottom")
42
43
  coordinate.top = margin.top - 5 - tooltipBoundingRect.height;
43
44
  else
44
45
  coordinate.top = blockBoundingRect.height - margin.bottom;
45
46
  }
46
47
  if (keyAxisOrient === "left" || keyAxisOrient === "right") {
47
- coordinate.top = Scale.getScaledValue(scaleKey, keyValue) + margin.top - tooltipBoundingRect.height / 2;
48
+ coordinate.top =
49
+ Scale.getScaledValueOnMiddleOfItem(scaleKey, keyValue) + margin.top - tooltipBoundingRect.height / 2;
48
50
  if (keyAxisOrient === "left")
49
51
  coordinate.left = blockBoundingRect.width - margin.right;
50
52
  else
@@ -68,16 +70,16 @@ export class TooltipHelper {
68
70
  y2: 0
69
71
  };
70
72
  if (chartOrientation === "vertical") {
71
- attributes.x1 = Math.ceil(Scale.getScaledValue(scaleKey, key) + margin.left) - 0.5;
72
- attributes.x2 = Math.ceil(Scale.getScaledValue(scaleKey, key) + margin.left) - 0.5;
73
+ attributes.x1 = Math.ceil(Scale.getScaledValueOnMiddleOfItem(scaleKey, key) + margin.left) - 0.5;
74
+ attributes.x2 = Math.ceil(Scale.getScaledValueOnMiddleOfItem(scaleKey, key) + margin.left) - 0.5;
73
75
  attributes.y1 = margin.top - this.convexsize;
74
76
  attributes.y2 = blockSize.height - margin.bottom + this.convexsize * 2;
75
77
  }
76
78
  else {
77
79
  attributes.x1 = margin.left - this.convexsize;
78
80
  attributes.x2 = blockSize.width - margin.right + this.convexsize * 2;
79
- attributes.y1 = Scale.getScaledValue(scaleKey, key) + margin.top;
80
- attributes.y2 = Scale.getScaledValue(scaleKey, key) + margin.top;
81
+ attributes.y1 = Scale.getScaledValueOnMiddleOfItem(scaleKey, key) + margin.top;
82
+ attributes.y2 = Scale.getScaledValueOnMiddleOfItem(scaleKey, key) + margin.top;
81
83
  }
82
84
  return attributes;
83
85
  }
@@ -66,7 +66,7 @@ export class ChartValueLabels {
66
66
  renderByGroupIndex(scales, groupIndex, data, valueFieldName, datumField, dataRowAccessor) {
67
67
  let valueLabels = this.getAllValueLabelsOfChart(groupIndex).data(data).enter().append("text");
68
68
  valueLabels = this.renderPipeline.execute(valueLabels, { style: this.globalOptions.canvas.style });
69
- const attrs = this.attrsProvider.getAttrs(this.globalOptions, this.options, scales, datumField, dataRowAccessor);
69
+ const attrs = this.attrsProvider.getAttrs(this.globalOptions, this.options, scales, datumField, dataRowAccessor, groupIndex);
70
70
  this.setAttrs(valueLabels, attrs, valueFieldName, dataRowAccessor);
71
71
  this.setClasses(valueLabels, this.chart.cssClasses, groupIndex);
72
72
  }
@@ -74,7 +74,7 @@ export class ChartValueLabels {
74
74
  return new Promise((resolve) => {
75
75
  const valueLabels = this.getAllValueLabelsOfChart(groupIndex).data(data);
76
76
  valueLabels.exit().remove();
77
- const attrs = this.attrsProvider.getAttrs(this.globalOptions, this.options, scales, datumField, dataRowAccessor);
77
+ const attrs = this.attrsProvider.getAttrs(this.globalOptions, this.options, scales, datumField, dataRowAccessor, groupIndex);
78
78
  if (!valueFieldName) {
79
79
  resolve();
80
80
  return;
@@ -4,5 +4,5 @@ import { Scales } from "../../../engine/features/scale/scale";
4
4
  import { Segment } from "../../twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorDefineMiddleware";
5
5
  import { MdtChartsDataRow } from "../../../config/config";
6
6
  export declare class ValueLabelsAttrsProvider {
7
- getAttrs(globalOptions: ValueLabelsOptions, valueLabels: TwoDimChartValueLabelsOptions, scales: Scales, datumField: string, dataRowAccessor: (d: MdtChartsDataRow | Segment) => MdtChartsDataRow): ValueLabelAttrs;
7
+ getAttrs(globalOptions: ValueLabelsOptions, valueLabels: TwoDimChartValueLabelsOptions, scales: Scales, datumField: string, dataRowAccessor: (d: MdtChartsDataRow | Segment) => MdtChartsDataRow, fieldIndexInChart: number): ValueLabelAttrs;
8
8
  }
@@ -1,6 +1,5 @@
1
- import { Scale } from "../../../engine/features/scale/scale";
2
1
  export class ValueLabelsAttrsProvider {
3
- getAttrs(globalOptions, valueLabels, scales, datumField, dataRowAccessor) {
2
+ getAttrs(globalOptions, valueLabels, scales, datumField, dataRowAccessor, fieldIndexInChart) {
4
3
  let attrs = {
5
4
  x: null,
6
5
  y: null,
@@ -9,12 +8,12 @@ export class ValueLabelsAttrsProvider {
9
8
  };
10
9
  const orient = globalOptions.canvas.keyAxisOrient;
11
10
  if (orient === "left" || orient === "right") {
12
- attrs.x = (d) => valueLabels.handleX(scales.value(valueLabels.handleScaledValue(d, datumField)));
13
- attrs.y = (d) => valueLabels.handleY(Scale.getScaledValue(scales.key, dataRowAccessor(d)[globalOptions.data.keyFieldName]));
11
+ attrs.x = (d) => valueLabels.handleX(scales.value(valueLabels.handleScaledValue(d, datumField)), fieldIndexInChart);
12
+ attrs.y = (d) => valueLabels.handleY(scales.key(dataRowAccessor(d)[globalOptions.data.keyFieldName]), fieldIndexInChart);
14
13
  }
15
14
  else if (orient === "bottom" || orient === "top") {
16
- attrs.x = (d) => valueLabels.handleX(Scale.getScaledValue(scales.key, dataRowAccessor(d)[globalOptions.data.keyFieldName]));
17
- attrs.y = (d) => valueLabels.handleY(scales.value(valueLabels.handleScaledValue(d, datumField)));
15
+ attrs.x = (d) => valueLabels.handleX(scales.key(dataRowAccessor(d)[globalOptions.data.keyFieldName]), fieldIndexInChart);
16
+ attrs.y = (d) => valueLabels.handleY(scales.value(valueLabels.handleScaledValue(d, datumField)), fieldIndexInChart);
18
17
  }
19
18
  return attrs;
20
19
  }
@@ -19,10 +19,10 @@ export class AreaGeneratorFactory {
19
19
  ]
20
20
  });
21
21
  if (keyAxisOrient === "bottom" || keyAxisOrient === "top") {
22
- return generator.getVertical((d) => Scale.getScaledValue(scales.key, d[keyFieldName]) + margin.left, (d) => scales.value(0) + margin.top, (d) => scales.value(d[valueFieldName]) + margin.top);
22
+ return generator.getVertical((d) => Scale.getScaledValueOnMiddleOfItem(scales.key, d[keyFieldName]) + margin.left, (d) => scales.value(0) + margin.top, (d) => scales.value(d[valueFieldName]) + margin.top);
23
23
  }
24
24
  if (keyAxisOrient === "left" || keyAxisOrient === "right") {
25
- return generator.getHorizontal((d) => scales.value(0) + margin.left, (d) => scales.value(d[valueFieldName]) + margin.left, (d) => Scale.getScaledValue(scales.key, d[keyFieldName]) + margin.top);
25
+ return generator.getHorizontal((d) => scales.value(0) + margin.left, (d) => scales.value(d[valueFieldName]) + margin.left, (d) => Scale.getScaledValueOnMiddleOfItem(scales.key, d[keyFieldName]) + margin.top);
26
26
  }
27
27
  }
28
28
  getSegmentedAreaGenerator() {
@@ -38,10 +38,10 @@ export class AreaGeneratorFactory {
38
38
  ]
39
39
  });
40
40
  if (keyAxisOrient === "bottom" || keyAxisOrient === "top") {
41
- return generator.getVertical((d) => Scale.getScaledValue(scales.key, d.data[keyFieldName]) + margin.left, (d) => scales.value(d[0]) + margin.top, (d) => scales.value(d[1]) + margin.top);
41
+ return generator.getVertical((d) => Scale.getScaledValueOnMiddleOfItem(scales.key, d.data[keyFieldName]) + margin.left, (d) => scales.value(d[0]) + margin.top, (d) => scales.value(d[1]) + margin.top);
42
42
  }
43
43
  if (keyAxisOrient === "left" || keyAxisOrient === "right") {
44
- return generator.getHorizontal((d) => scales.value(d[0]) + margin.left, (d) => scales.value(d[1]) + margin.left, (d) => Scale.getScaledValue(scales.key, d.data[keyFieldName]) + margin.top);
44
+ return generator.getHorizontal((d) => scales.value(d[0]) + margin.left, (d) => scales.value(d[1]) + margin.left, (d) => Scale.getScaledValueOnMiddleOfItem(scales.key, d.data[keyFieldName]) + margin.top);
45
45
  }
46
46
  }
47
47
  }
@@ -21,8 +21,8 @@ export declare class Bar {
21
21
  private createBarPipeline;
22
22
  private createSegmentGroupBarsPipeline;
23
23
  constructor();
24
- render(block: Block, scales: Scales, data: MdtChartsDataRow[], keyField: Field, margin: BlockMargin, keyAxisOrient: Orient, chart: TwoDimensionalChartModel, blockSize: Size, barSettings: BarChartSettings, barsAmounts: number[]): void;
25
- update(block: Block, newData: MdtChartsDataRow[], scales: Scales, margin: BlockMargin, keyAxisOrient: Orient, chart: TwoDimensionalChartModel, blockSize: Size, barsAmounts: number[], keyField: Field, barSettings: BarChartSettings): Promise<any>[];
24
+ render(block: Block, scales: Scales, data: MdtChartsDataRow[], keyField: Field, margin: BlockMargin, keyAxisOrient: Orient, chart: TwoDimensionalChartModel, blockSize: Size, barSettings: BarChartSettings): void;
25
+ update(block: Block, newData: MdtChartsDataRow[], scales: Scales, margin: BlockMargin, keyAxisOrient: Orient, chart: TwoDimensionalChartModel, blockSize: Size, keyField: Field, barSettings: BarChartSettings): Promise<any>[];
26
26
  updateColors(block: Block, chart: TwoDimensionalChartModel): void;
27
27
  getAllBarsForChart(block: Block, chartCssClasses: string[]): Selection<BaseType, MdtChartsDataRow, BaseType, unknown>;
28
28
  private renderGrouped;
@@ -2,7 +2,6 @@ import { select } from "d3-selection";
2
2
  import { EmbeddedLabels } from "../../features/embeddedLabels/embeddedLabels";
3
3
  import { EmbeddedLabelsHelper } from "../../features/embeddedLabels/embeddedLabelsHelper";
4
4
  import { BarHelper, onBarChartInit } from "./barHelper";
5
- import { sum } from "d3-array";
6
5
  import { DomSelectionHelper } from "../../helpers/domSelectionHelper";
7
6
  import { Helper } from "../../helpers/helper";
8
7
  import { getStackedDataWithOwn } from "./stackedData/dataStacker";
@@ -18,19 +17,19 @@ export class Bar {
18
17
  static get() {
19
18
  return new Bar();
20
19
  }
21
- render(block, scales, data, keyField, margin, keyAxisOrient, chart, blockSize, barSettings, barsAmounts) {
20
+ render(block, scales, data, keyField, margin, keyAxisOrient, chart, blockSize, barSettings) {
22
21
  if (chart.isSegmented)
23
- this.renderSegmented(block, scales, data, keyField, margin, keyAxisOrient, chart, barsAmounts, barSettings);
22
+ this.renderSegmented(block, scales, data, keyField, margin, keyAxisOrient, chart, barSettings);
24
23
  else
25
- this.renderGrouped(block, scales, data, keyField, margin, keyAxisOrient, chart, barsAmounts, blockSize, barSettings);
24
+ this.renderGrouped(block, scales, data, keyField, margin, keyAxisOrient, chart, blockSize, barSettings);
26
25
  }
27
- update(block, newData, scales, margin, keyAxisOrient, chart, blockSize, barsAmounts, keyField, barSettings) {
26
+ update(block, newData, scales, margin, keyAxisOrient, chart, blockSize, keyField, barSettings) {
28
27
  let promises;
29
28
  if (chart.isSegmented) {
30
- promises = this.updateSegmented(block, newData, scales, margin, keyAxisOrient, chart, barsAmounts, keyField, barSettings);
29
+ promises = this.updateSegmented(block, newData, scales, margin, keyAxisOrient, chart, keyField, barSettings);
31
30
  }
32
31
  else {
33
- promises = this.updateGrouped(block, newData, scales, margin, keyAxisOrient, chart, blockSize, barsAmounts, keyField, barSettings);
32
+ promises = this.updateGrouped(block, newData, scales, margin, keyAxisOrient, chart, blockSize, keyField, barSettings);
34
33
  }
35
34
  return promises;
36
35
  }
@@ -45,7 +44,7 @@ export class Bar {
45
44
  getAllBarsForChart(block, chartCssClasses) {
46
45
  return block.getSvg().selectAll(`rect.${this.barItemClass}${Helper.getCssClassesLine(chartCssClasses)}`);
47
46
  }
48
- renderGrouped(block, scales, data, keyField, margin, keyAxisOrient, chart, barsAmounts, blockSize, barSettings) {
47
+ renderGrouped(block, scales, data, keyField, margin, keyAxisOrient, chart, blockSize, barSettings) {
49
48
  chart.data.valueFields.forEach((field, index) => {
50
49
  let bars = block.svg
51
50
  .getChartGroup(chart.index)
@@ -56,7 +55,7 @@ export class Bar {
56
55
  .attr("class", this.barItemClass)
57
56
  .style("clip-path", `url(#${block.svg.getClipPathId()})`);
58
57
  bars = this.createBarPipeline.execute(bars, chart);
59
- const barAttrs = BarHelper.getGroupedBarAttrs(keyAxisOrient, scales, margin, keyField.name, field.name, chart.barViewOptions.barIndexes[index], sum(barsAmounts), barSettings);
58
+ const barAttrs = BarHelper.getGroupedBarAttrs(keyAxisOrient, scales, margin, keyField.name, field.name, chart.barViewOptions.barIndexes[index], chart.bandLikeViewOptions.settingsStore);
60
59
  this.fillBarAttrs(bars, barAttrs);
61
60
  DomSelectionHelper.setCssClasses(bars, Helper.getCssClassesWithElementIndex(chart.cssClasses, index));
62
61
  DomSelectionHelper.setChartStyle(bars, chart.style, index, "fill");
@@ -65,7 +64,7 @@ export class Bar {
65
64
  EmbeddedLabels.render(block, bars, barAttrs, EmbeddedLabelsHelper.getLabelField(chart.embeddedLabels, chart.data.valueFields, keyField, index), chart.embeddedLabels, keyAxisOrient, blockSize, margin, index, chart.cssClasses);
66
65
  });
67
66
  }
68
- renderSegmented(block, scales, data, keyField, margin, keyAxisOrient, chart, barsAmounts, barSettings) {
67
+ renderSegmented(block, scales, data, keyField, margin, keyAxisOrient, chart, barSettings) {
69
68
  const stackedData = getStackedDataWithOwn(data, chart.data.valueFields.map((field) => field.name));
70
69
  let groups = block.svg
71
70
  .getChartGroup(chart.index)
@@ -81,7 +80,7 @@ export class Bar {
81
80
  .attr("class", this.barItemClass)
82
81
  .style("clip-path", `url(#${block.svg.getClipPathId()})`);
83
82
  bars = this.createBarPipeline.execute(bars, chart);
84
- const barAttrs = BarHelper.getStackedBarAttr(keyAxisOrient, scales, margin, keyField.name, chart.barViewOptions.barIndexes[0], sum(barsAmounts), barSettings);
83
+ const barAttrs = BarHelper.getStackedBarAttr(keyAxisOrient, scales, margin, keyField.name, chart.barViewOptions.barIndexes[0], chart.bandLikeViewOptions.settingsStore);
85
84
  this.fillBarAttrs(bars, barAttrs);
86
85
  this.setInitialAttrsInfo(bars, keyAxisOrient, barSettings);
87
86
  DomSelectionHelper.setCssClasses(groups, chart.cssClasses);
@@ -94,7 +93,7 @@ export class Bar {
94
93
  thisClass.setSegmentColor(select(this).selectAll(Helper.getCssClassesLine(chart.cssClasses)), chart.style.elementColors, i);
95
94
  });
96
95
  }
97
- updateGrouped(block, newData, scales, margin, keyAxisOrient, chart, blockSize, barsAmounts, keyField, barSettings) {
96
+ updateGrouped(block, newData, scales, margin, keyAxisOrient, chart, blockSize, keyField, barSettings) {
98
97
  const promises = [];
99
98
  chart.data.valueFields.forEach((valueField, index) => {
100
99
  const indexesOfRemoved = [];
@@ -124,7 +123,7 @@ export class Bar {
124
123
  .attr("class", this.barItemClass)
125
124
  .style("clip-path", `url(#${block.svg.getClipPathId()})`);
126
125
  newBars = this.createBarPipeline.execute(newBars, chart);
127
- const barAttrs = BarHelper.getGroupedBarAttrs(keyAxisOrient, scales, margin, keyField.name, valueField.name, chart.barViewOptions.barIndexes[index], sum(barsAmounts), barSettings);
126
+ const barAttrs = BarHelper.getGroupedBarAttrs(keyAxisOrient, scales, margin, keyField.name, valueField.name, chart.barViewOptions.barIndexes[index], chart.bandLikeViewOptions.settingsStore);
128
127
  const prom = this.fillBarAttrs(bars, barAttrs, block.transitionManager.durations.chartUpdate).then(() => {
129
128
  bars.style("opacity", null);
130
129
  this.setInitialAttrsInfo(bars, keyAxisOrient, barSettings);
@@ -144,7 +143,7 @@ export class Bar {
144
143
  });
145
144
  return promises;
146
145
  }
147
- updateSegmented(block, newData, scales, margin, keyAxisOrient, chart, barsAmounts, keyField, barSettings) {
146
+ updateSegmented(block, newData, scales, margin, keyAxisOrient, chart, keyField, barSettings) {
148
147
  const stackedData = getStackedDataWithOwn(newData, chart.data.valueFields.map((field) => field.name));
149
148
  block.svg
150
149
  .getChartGroup(chart.index)
@@ -169,7 +168,7 @@ export class Bar {
169
168
  .attr("class", this.barItemClass)
170
169
  .style("clip-path", `url(#${block.svg.getClipPathId()})`);
171
170
  newBars = this.createBarPipeline.execute(newBars, chart);
172
- const barAttrs = BarHelper.getStackedBarAttr(keyAxisOrient, scales, margin, keyField.name, chart.barViewOptions.barIndexes[0], sum(barsAmounts), barSettings);
171
+ const barAttrs = BarHelper.getStackedBarAttr(keyAxisOrient, scales, margin, keyField.name, chart.barViewOptions.barIndexes[0], chart.bandLikeViewOptions.settingsStore);
173
172
  const prom = this.fillBarAttrs(bars, barAttrs, block.transitionManager.durations.chartUpdate).then(() => {
174
173
  this.setInitialAttrsInfo(bars, keyAxisOrient, barSettings);
175
174
  bars.style("opacity", null);
@@ -1,5 +1,5 @@
1
1
  import { AxisScale } from "d3-axis";
2
- import { BarBorderRadius, BarChartSettings, BlockMargin, Orient, TwoDimensionalChartModel } from "../../../model/model";
2
+ import { BandLikeChartSettingsStore, BarBorderRadius, BlockMargin, Orient, TwoDimensionalChartModel } from "../../../model/model";
3
3
  import { Scales } from "../../features/scale/scale";
4
4
  import { MdtChartsDataRow } from "../../../config/config";
5
5
  import { Pipeline } from "../../helpers/pipeline/Pipeline";
@@ -14,33 +14,9 @@ export interface GroupBarsSegment {
14
14
  segmentIndex: number;
15
15
  chart: TwoDimensionalChartModel;
16
16
  }
17
- interface BandLikeChartSettingsStore {
18
- getBandItemSize(): number;
19
- getBandItemPad(bandItemIndex: number): number;
20
- }
21
- export declare class DotChartSettingsStore implements BandLikeChartSettingsStore {
22
- private readonly canvasConfig;
23
- constructor(canvasConfig: {
24
- scaleBandWidth: number;
25
- });
26
- getBandItemSize(): number;
27
- getBandItemPad(): number;
28
- }
29
- export declare class BarSettingsStore implements BandLikeChartSettingsStore {
30
- private readonly modelSettings;
31
- private readonly canvasConfig;
32
- constructor(modelSettings: BarChartSettings, canvasConfig: {
33
- scaleBandWidth: number;
34
- barsAmount: number;
35
- });
36
- getBandItemSize(): number;
37
- getBandItemPad(barIndex: number): number;
38
- private getBarStep;
39
- }
40
17
  export declare class BarHelper {
41
- static getGroupedBarAttrs(keyAxisOrient: Orient, scales: Scales, margin: BlockMargin, keyField: string, valueFieldName: string, barIndex: number, barsAmount: number, barSettings: BarChartSettings): BarAttrsHelper;
42
- static getStackedBarAttr(keyAxisOrient: Orient, scales: Scales, margin: BlockMargin, keyField: string, barIndex: number, barsAmount: number, barSettings: BarChartSettings): BarAttrsHelper;
43
- static getBarsInGroupAmount(charts: TwoDimensionalChartModel[]): number[];
18
+ static getGroupedBarAttrs(keyAxisOrient: Orient, scales: Scales, margin: BlockMargin, keyField: string, valueFieldName: string, barIndex: number, settingsStore: BandLikeChartSettingsStore): BarAttrsHelper;
19
+ static getStackedBarAttr(keyAxisOrient: Orient, scales: Scales, margin: BlockMargin, keyField: string, barIndex: number, settingsStore: BandLikeChartSettingsStore): BarAttrsHelper;
44
20
  static setBarAttrsByKey(attrs: BarAttrsHelper, keyAxisOrient: Orient, scaleKey: AxisScale<any>, margin: BlockMargin, keyField: string, barIndex: number, settingsStore: BandLikeChartSettingsStore, isSegmented: boolean): void;
45
21
  private static setGroupedBarAttrsByValue;
46
22
  static getBandItemValueStretch(scaleValue: AxisScale<any>, valueFieldName: string): (dataRow: MdtChartsDataRow) => number;
@@ -49,4 +25,3 @@ export declare class BarHelper {
49
25
  }
50
26
  export declare function onBarChartInit(createBarPipeline: Pipeline<Selection<SVGRectElement, any, BaseType, any>, TwoDimensionalChartModel>, createSegmentGroupBarsPipeline: Pipeline<Selection<SVGRectElement, any, BaseType, any>, GroupBarsSegment>): void;
51
27
  export declare function getClipPathValue({ topLeft, topRight, bottomLeft, bottomRight }: BarBorderRadius): string;
52
- export {};
@@ -1,81 +1,40 @@
1
- import { Scale } from "../../features/scale/scale";
2
1
  import { Helper } from "../../helpers/helper";
3
2
  import { HatchPatternDef } from "../../block/defs/hatchPattern";
4
- export class DotChartSettingsStore {
5
- constructor(canvasConfig) {
6
- this.canvasConfig = canvasConfig;
7
- }
8
- getBandItemSize() {
9
- return this.canvasConfig.scaleBandWidth;
10
- }
11
- getBandItemPad() {
12
- return 0;
13
- }
14
- }
15
- export class BarSettingsStore {
16
- constructor(modelSettings, canvasConfig) {
17
- this.modelSettings = modelSettings;
18
- this.canvasConfig = canvasConfig;
19
- }
20
- getBandItemSize() {
21
- const barSize = this.getBarStep() > this.modelSettings.maxBarWidth ? this.modelSettings.maxBarWidth : this.getBarStep();
22
- return barSize;
23
- }
24
- getBandItemPad(barIndex) {
25
- const barDiff = ((this.getBarStep() - this.getBandItemSize()) * this.canvasConfig.barsAmount) / 2; // if bar bigger than maxWidth, diff for x coordinate
26
- const barPad = this.getBandItemSize() * barIndex + this.modelSettings.barDistance * barIndex + barDiff; // Отступ бара от края. Зависит от количества баров в одной группе и порядке текущего бара
27
- return barPad;
28
- }
29
- getBarStep() {
30
- return ((this.canvasConfig.scaleBandWidth - this.modelSettings.barDistance * (this.canvasConfig.barsAmount - 1)) /
31
- this.canvasConfig.barsAmount); // Space for one bar
32
- }
33
- }
34
3
  export class BarHelper {
35
- static getGroupedBarAttrs(keyAxisOrient, scales, margin, keyField, valueFieldName, barIndex, barsAmount, barSettings) {
4
+ static getGroupedBarAttrs(keyAxisOrient, scales, margin, keyField, valueFieldName, barIndex, settingsStore) {
36
5
  const attrs = {
37
6
  x: null,
38
7
  y: null,
39
8
  width: null,
40
9
  height: null
41
10
  };
42
- this.setBarAttrsByKey(attrs, keyAxisOrient, scales.key, margin, keyField, barIndex, new BarSettingsStore(barSettings, { scaleBandWidth: Scale.getScaleBandWidth(scales.key), barsAmount }), false);
11
+ this.setBarAttrsByKey(attrs, keyAxisOrient, scales.key, margin, keyField, barIndex, settingsStore, false);
43
12
  this.setGroupedBarAttrsByValue(attrs, keyAxisOrient, margin, scales.value, valueFieldName);
44
13
  return attrs;
45
14
  }
46
- static getStackedBarAttr(keyAxisOrient, scales, margin, keyField, barIndex, barsAmount, barSettings) {
15
+ static getStackedBarAttr(keyAxisOrient, scales, margin, keyField, barIndex, settingsStore) {
47
16
  const attrs = {
48
17
  x: null,
49
18
  y: null,
50
19
  width: null,
51
20
  height: null
52
21
  };
53
- this.setBarAttrsByKey(attrs, keyAxisOrient, scales.key, margin, keyField, barIndex, new BarSettingsStore(barSettings, { scaleBandWidth: Scale.getScaleBandWidth(scales.key), barsAmount }), true);
22
+ this.setBarAttrsByKey(attrs, keyAxisOrient, scales.key, margin, keyField, barIndex, settingsStore, true);
54
23
  this.setSegmentedBarAttrsByValue(attrs, keyAxisOrient, scales.value, margin);
55
24
  return attrs;
56
25
  }
57
- static getBarsInGroupAmount(charts) {
58
- let amounts = [];
59
- charts.forEach((chart) => {
60
- if (chart.type === "bar" && chart.isSegmented)
61
- amounts.push(1); // Сегментированный бар содержит все свои valueFields в одном баре
62
- else if (chart.type === "bar")
63
- amounts.push(chart.data.valueFields.length);
64
- });
65
- return amounts;
66
- }
67
26
  static setBarAttrsByKey(attrs, keyAxisOrient, scaleKey, margin, keyField, barIndex, settingsStore, isSegmented) {
68
27
  if (keyAxisOrient === "top" || keyAxisOrient === "bottom") {
69
28
  attrs.x = (d) => scaleKey(Helper.getKeyFieldValue(d, keyField, isSegmented)) +
70
29
  margin.left +
71
30
  settingsStore.getBandItemPad(barIndex);
72
- attrs.width = (d) => settingsStore.getBandItemSize();
31
+ attrs.width = (d) => settingsStore.getBandSubItemSize();
73
32
  }
74
33
  if (keyAxisOrient === "left" || keyAxisOrient === "right") {
75
34
  attrs.y = (d) => scaleKey(Helper.getKeyFieldValue(d, keyField, isSegmented)) +
76
35
  margin.top +
77
36
  settingsStore.getBandItemPad(barIndex);
78
- attrs.height = (d) => settingsStore.getBandItemSize();
37
+ attrs.height = (d) => settingsStore.getBandSubItemSize();
79
38
  }
80
39
  }
81
40
  static setGroupedBarAttrsByValue(attrs, keyAxisOrient, margin, scaleValue, valueFieldName) {
@@ -1,8 +1,7 @@
1
- import { Scale } from "../../features/scale/scale";
2
1
  import { DomSelectionHelper } from "../../helpers/domSelectionHelper";
3
2
  import { Helper } from "../../helpers/helper";
4
3
  import { NamesHelper } from "../../helpers/namesHelper";
5
- import { BarHelper, DotChartSettingsStore } from "../bar/barHelper";
4
+ import { BarHelper } from "../bar/barHelper";
6
5
  /**
7
6
  * @alpha experimental feature. Need to refactor.
8
7
  */
@@ -79,21 +78,21 @@ export class CanvasDotChart {
79
78
  x2: null,
80
79
  y2: null
81
80
  };
82
- const settingsStore = new DotChartSettingsStore({ scaleBandWidth: Scale.getScaleBandWidth(scales.key) });
81
+ const settingsStore = chart.bandLikeViewOptions.settingsStore;
83
82
  // TODO: refactor
84
83
  if (this.options.canvas.keyAxisOrient === "top" || this.options.canvas.keyAxisOrient === "bottom") {
85
84
  const handleBase = (d) => scales.key(Helper.getKeyFieldValue(d, this.options.dataOptions.keyFieldName, false)) +
86
85
  margin.left +
87
- settingsStore.getBandItemPad();
86
+ settingsStore.getBandItemPad(0);
88
87
  attrs.x1 = (d) => chart.dotViewOptions.shape.handleStartCoordinate(handleBase(d));
89
- attrs.x2 = (d) => chart.dotViewOptions.shape.handleEndCoordinate(handleBase(d) + settingsStore.getBandItemSize());
88
+ attrs.x2 = (d) => chart.dotViewOptions.shape.handleEndCoordinate(handleBase(d) + settingsStore.getBandSubItemSize());
90
89
  }
91
90
  if (this.options.canvas.keyAxisOrient === "left" || this.options.canvas.keyAxisOrient === "right") {
92
91
  const handleBase = (d) => scales.key(Helper.getKeyFieldValue(d, this.options.dataOptions.keyFieldName, false)) +
93
92
  margin.top +
94
- settingsStore.getBandItemPad();
93
+ settingsStore.getBandItemPad(0);
95
94
  attrs.y1 = (d) => chart.dotViewOptions.shape.handleStartCoordinate(handleBase(d));
96
- attrs.y2 = (d) => chart.dotViewOptions.shape.handleEndCoordinate(handleBase(d) + settingsStore.getBandItemSize());
95
+ attrs.y2 = (d) => chart.dotViewOptions.shape.handleEndCoordinate(handleBase(d) + settingsStore.getBandSubItemSize());
97
96
  }
98
97
  if (this.options.canvas.keyAxisOrient === "top") {
99
98
  attrs.y1 = (d) => scales.value(Math.min(d[field.name], 0)) +
@@ -20,10 +20,10 @@ export class LineGeneratorFactory {
20
20
  ]
21
21
  });
22
22
  if (keyAxisOrient === "bottom" || keyAxisOrient === "top") {
23
- return generator.get((d) => Scale.getScaledValue(scales.key, d[keyFieldName]) + margin.left, (d) => scales.value(d[valueFieldName]) + margin.top);
23
+ return generator.get((d) => Scale.getScaledValueOnMiddleOfItem(scales.key, d[keyFieldName]) + margin.left, (d) => scales.value(d[valueFieldName]) + margin.top);
24
24
  }
25
25
  if (keyAxisOrient === "left" || keyAxisOrient === "right") {
26
- return generator.get((d) => scales.value(d[valueFieldName]) + margin.left, (d) => Scale.getScaledValue(scales.key, d[keyFieldName]) + margin.top);
26
+ return generator.get((d) => scales.value(d[valueFieldName]) + margin.left, (d) => Scale.getScaledValueOnMiddleOfItem(scales.key, d[keyFieldName]) + margin.top);
27
27
  }
28
28
  }
29
29
  getSegmentedLineGenerator() {
@@ -39,10 +39,10 @@ export class LineGeneratorFactory {
39
39
  ]
40
40
  });
41
41
  if (keyAxisOrient === "bottom" || keyAxisOrient === "top") {
42
- return generator.get((d) => Scale.getScaledValue(scales.key, d.data[keyFieldName]) + margin.left, (d) => scales.value(d[1]) + margin.top);
42
+ return generator.get((d) => Scale.getScaledValueOnMiddleOfItem(scales.key, d.data[keyFieldName]) + margin.left, (d) => scales.value(d[1]) + margin.top);
43
43
  }
44
44
  if (keyAxisOrient === "left" || keyAxisOrient === "right") {
45
- return generator.get((d) => scales.value(d[1]) + margin.left, (d) => Scale.getScaledValue(scales.key, d.data[keyFieldName]) + margin.top);
45
+ return generator.get((d) => scales.value(d[1]) + margin.left, (d) => Scale.getScaledValueOnMiddleOfItem(scales.key, d.data[keyFieldName]) + margin.top);
46
46
  }
47
47
  }
48
48
  }
@@ -10,7 +10,6 @@ import { Tooltip } from "../features/tolltip/tooltip";
10
10
  import { Helper } from "../helpers/helper";
11
11
  import { Area } from "./area/area";
12
12
  import { Bar } from "./bar/bar";
13
- import { BarHelper } from "./bar/barHelper";
14
13
  import { Line } from "./line/line";
15
14
  import { CanvasValueLabels } from "../../engine/features/valueLabels/valueLabels";
16
15
  import { LinearGradientDef } from "../../engine/block/defs/LinearGradientDef";
@@ -142,7 +141,7 @@ export class TwoDimensionalManager {
142
141
  value: chart.data.valueGroup === "secondary" ? scales.valueSecondary : scales.value
143
142
  };
144
143
  if (chart.type === "bar")
145
- Bar.get().render(block, chartScales, data[dataOptions.dataSource], dataOptions.keyField, margin, keyAxisOrient, chart, blockSize, chartSettings.bar, BarHelper.getBarsInGroupAmount(charts));
144
+ Bar.get().render(block, chartScales, data[dataOptions.dataSource], dataOptions.keyField, margin, keyAxisOrient, chart, blockSize, chartSettings.bar);
146
145
  else if (chart.type === "line")
147
146
  Line.get({ staticSettings: chartSettings.lineLike }).render(block, chartScales, data[dataOptions.dataSource], dataOptions.keyField, margin, keyAxisOrient, chart);
148
147
  else if (chart.type === "area")
@@ -162,7 +161,7 @@ export class TwoDimensionalManager {
162
161
  };
163
162
  let proms;
164
163
  if (chart.type === "bar") {
165
- proms = Bar.get().update(block, data[dataOptions.dataSource], chartScales, margin, keyAxisOrient, chart, blockSize, BarHelper.getBarsInGroupAmount(charts), dataOptions.keyField, chartSettings.bar);
164
+ proms = Bar.get().update(block, data[dataOptions.dataSource], chartScales, margin, keyAxisOrient, chart, blockSize, dataOptions.keyField, chartSettings.bar);
166
165
  }
167
166
  else if (chart.type === "line") {
168
167
  proms = Line.get({ staticSettings: chartSettings.lineLike }).update(block, chartScales, data[dataOptions.dataSource], dataOptions.keyField, margin, keyAxisOrient, chart);
@@ -0,0 +1,3 @@
1
+ import { TwoDimensionalChartType } from "../../../config/config";
2
+ import { BandLikeChartSettingsStore, BarChartSettings, ScaleKeyModel } from "../../model";
3
+ export declare function createBandLikeChartSettingsStore(chartType: TwoDimensionalChartType, modelSettings: BarChartSettings, oneKeyBarsAmount: number, keyScale: ScaleKeyModel): BandLikeChartSettingsStore | undefined;
@@ -0,0 +1,10 @@
1
+ import { BarSettingsStore } from "./barChartSettingsStore";
2
+ import { DotChartSettingsStore } from "./dotChartSettingsStore";
3
+ export function createBandLikeChartSettingsStore(chartType, modelSettings, oneKeyBarsAmount, keyScale) {
4
+ const scaleBandWidth = keyScale.type === "band" ? keyScale.sizes.bandSize : 0;
5
+ if (chartType === "bar")
6
+ return new BarSettingsStore(modelSettings, { oneKeyBarsAmount, scaleBandWidth });
7
+ if (chartType === "dot")
8
+ return new DotChartSettingsStore({ scaleBandWidth });
9
+ return undefined;
10
+ }
@@ -0,0 +1,11 @@
1
+ import { BandLikeChartSettingsStore, BarChartSettings } from "../../model";
2
+ export declare class BarSettingsStore implements BandLikeChartSettingsStore {
3
+ private readonly modelSettings;
4
+ private readonly canvasConfig;
5
+ constructor(modelSettings: BarChartSettings, canvasConfig: {
6
+ scaleBandWidth: number;
7
+ oneKeyBarsAmount: number;
8
+ });
9
+ getBandSubItemSize(): number;
10
+ getBandItemPad(barIndex: number): number;
11
+ }
@@ -0,0 +1,14 @@
1
+ export class BarSettingsStore {
2
+ constructor(modelSettings, canvasConfig) {
3
+ this.modelSettings = modelSettings;
4
+ this.canvasConfig = canvasConfig;
5
+ }
6
+ getBandSubItemSize() {
7
+ return ((this.canvasConfig.scaleBandWidth -
8
+ this.modelSettings.barDistance * (this.canvasConfig.oneKeyBarsAmount - 1)) /
9
+ this.canvasConfig.oneKeyBarsAmount); // Space for one bar
10
+ }
11
+ getBandItemPad(barIndex) {
12
+ return this.getBandSubItemSize() * barIndex + this.modelSettings.barDistance * barIndex; // Отступ бара от края. Зависит от количества баров в одной группе и порядке текущего бара
13
+ }
14
+ }
@@ -0,0 +1,9 @@
1
+ import { BandLikeChartSettingsStore } from "../../model";
2
+ export declare class DotChartSettingsStore implements BandLikeChartSettingsStore {
3
+ private readonly canvasConfig;
4
+ constructor(canvasConfig: {
5
+ scaleBandWidth: number;
6
+ });
7
+ getBandSubItemSize(): number;
8
+ getBandItemPad(): number;
9
+ }
@@ -0,0 +1,11 @@
1
+ export class DotChartSettingsStore {
2
+ constructor(canvasConfig) {
3
+ this.canvasConfig = canvasConfig;
4
+ }
5
+ getBandSubItemSize() {
6
+ return this.canvasConfig.scaleBandWidth;
7
+ }
8
+ getBandItemPad() {
9
+ return 0;
10
+ }
11
+ }
@@ -84,7 +84,8 @@ export class ScaleModel {
84
84
  paddingInner: paddings.inner,
85
85
  paddingOuter: paddings.outer,
86
86
  oneKeyTotalSpace,
87
- recalculatedStepSize: getStepSize()
87
+ recalculatedStepSize: getStepSize(),
88
+ bandSize: getBandSize()
88
89
  };
89
90
  }
90
91
  getChartsByTypes(charts, types) {
@@ -10,10 +10,13 @@ export declare const BORDER_OFFSET_SIZE_PX = 2;
10
10
  export declare class ValueLabelCoordinateCalculator {
11
11
  private readonly keyAxisOrient;
12
12
  private readonly margin;
13
+ private readonly isSegmented;
14
+ private readonly shiftCoordinateByKeyScale;
13
15
  private readonly offsetSizePx;
14
- constructor(positionOptions: ValueLabelsPositionOptions | undefined, keyAxisOrient: Orient, margin: BlockMargin);
15
- getValueLabelY(scaledValue: number): number;
16
- getValueLabelX(scaledValue: number): number;
16
+ constructor(positionOptions: ValueLabelsPositionOptions | undefined, keyAxisOrient: Orient, margin: BlockMargin, isSegmented: boolean, shiftCoordinateByKeyScale: (value: number, fieldIndex: number) => number);
17
+ getValueLabelY(scaledValue: number, fieldIndex: number): number;
18
+ getValueLabelX(scaledValue: number, fieldIndex: number): number;
19
+ private getOverrideFieldIndex;
17
20
  }
18
21
  export declare function calculateValueLabelAlignment(keyAxisOrient: Orient, positionMode?: ValueLabelsPositionMode, rotation?: ValueLabelsRotationOptions): ValueLabelAlignment;
19
22
  export declare function handleScaledValue(dataRow: MdtChartsDataRow, datumField: string, isSegmented: boolean, positionMode?: ValueLabelsPositionMode): number;
@@ -1,9 +1,11 @@
1
1
  export const VALUE_LABEL_OFFSET_ABS_SIZE_PX = 10;
2
2
  export const BORDER_OFFSET_SIZE_PX = 2;
3
3
  export class ValueLabelCoordinateCalculator {
4
- constructor(positionOptions, keyAxisOrient, margin) {
4
+ constructor(positionOptions, keyAxisOrient, margin, isSegmented, shiftCoordinateByKeyScale) {
5
5
  this.keyAxisOrient = keyAxisOrient;
6
6
  this.margin = margin;
7
+ this.isSegmented = isSegmented;
8
+ this.shiftCoordinateByKeyScale = shiftCoordinateByKeyScale;
7
9
  let offsetAbsSize = VALUE_LABEL_OFFSET_ABS_SIZE_PX;
8
10
  if (((positionOptions === null || positionOptions === void 0 ? void 0 : positionOptions.mode) === "beforeHead" || (positionOptions === null || positionOptions === void 0 ? void 0 : positionOptions.mode) === "afterHead") &&
9
11
  (positionOptions === null || positionOptions === void 0 ? void 0 : positionOptions.offsetSize) != null)
@@ -15,26 +17,29 @@ export class ValueLabelCoordinateCalculator {
15
17
  else
16
18
  this.offsetSizePx = 0;
17
19
  }
18
- getValueLabelY(scaledValue) {
20
+ getValueLabelY(scaledValue, fieldIndex) {
19
21
  switch (this.keyAxisOrient) {
20
22
  case "bottom":
21
23
  return scaledValue - this.offsetSizePx + this.margin.top;
22
24
  case "top":
23
25
  return scaledValue + this.offsetSizePx + this.margin.top;
24
26
  default:
25
- return scaledValue + this.margin.top;
27
+ return this.shiftCoordinateByKeyScale(scaledValue + this.margin.top, this.getOverrideFieldIndex(fieldIndex));
26
28
  }
27
29
  }
28
- getValueLabelX(scaledValue) {
30
+ getValueLabelX(scaledValue, fieldIndex) {
29
31
  switch (this.keyAxisOrient) {
30
32
  case "right":
31
33
  return scaledValue - this.offsetSizePx + this.margin.left;
32
34
  case "left":
33
35
  return scaledValue + this.offsetSizePx + this.margin.left;
34
36
  default:
35
- return scaledValue + this.margin.left;
37
+ return this.shiftCoordinateByKeyScale(scaledValue + this.margin.left, this.getOverrideFieldIndex(fieldIndex));
36
38
  }
37
39
  }
40
+ getOverrideFieldIndex(fieldIndex) {
41
+ return this.isSegmented ? 0 : fieldIndex;
42
+ }
38
43
  }
39
44
  export function calculateValueLabelAlignment(keyAxisOrient, positionMode, rotation) {
40
45
  if (rotation === null || rotation === void 0 ? void 0 : rotation.angle)
@@ -139,6 +139,7 @@ export interface ScaleBandModelSizeParams {
139
139
  paddingInner: number;
140
140
  oneKeyTotalSpace: number;
141
141
  recalculatedStepSize: number;
142
+ bandSize: number;
142
143
  }
143
144
  export interface ScalePointModel extends BaseScaleKeyModel {
144
145
  type: "point";
@@ -392,6 +393,16 @@ export declare type LineLikeChartRenderFn = (dataRow: MdtChartsDataRow, valueFie
392
393
  interface TwoDimensionalBarLikeChartModel {
393
394
  barViewOptions: TwoDimensionalBarLikeChartViewModel;
394
395
  }
396
+ interface BandLikeChartModel {
397
+ bandLikeViewOptions: BandLikeChartViewModel;
398
+ }
399
+ export interface BandLikeChartViewModel {
400
+ settingsStore?: BandLikeChartSettingsStore;
401
+ }
402
+ export interface BandLikeChartSettingsStore {
403
+ getBandSubItemSize(): number;
404
+ getBandItemPad(bandItemIndex: number): number;
405
+ }
395
406
  export interface TwoDimensionalBarLikeChartViewModel {
396
407
  hatch: BarLikeChartHatchOptions;
397
408
  borderRadius: BarLikeChartBorderRadius;
@@ -426,7 +437,7 @@ interface DotChartShapeOptions {
426
437
  handleEndCoordinate: (calculatedBandItemSize: number) => number;
427
438
  width: number;
428
439
  }
429
- export interface TwoDimensionalChartModel extends ChartModel, TwoDimensionalLineLikeChartModel, TwoDimensionalBarLikeChartModel, TwoDimensionalAreaChartModel, DotChartModel {
440
+ export interface TwoDimensionalChartModel extends ChartModel, TwoDimensionalLineLikeChartModel, TwoDimensionalBarLikeChartModel, TwoDimensionalAreaChartModel, DotChartModel, BandLikeChartModel {
430
441
  type: TwoDimensionalChartType;
431
442
  data: TwoDimensionalChartDataModel;
432
443
  index: number;
@@ -457,8 +468,8 @@ export declare type ValueLabelsInnerContentSetter = (options: ValueLabelsInnerCo
457
468
  export interface TwoDimChartValueLabelsOptions {
458
469
  enabled: boolean;
459
470
  showLabel: MarkerLikeElementVisibilityFn;
460
- handleX: (scaledValue: number) => number;
461
- handleY: (scaledValue: number) => number;
471
+ handleX: (scaledValue: number, fieldIndex: number) => number;
472
+ handleY: (scaledValue: number, fieldIndex: number) => number;
462
473
  textAnchor: TextAnchor;
463
474
  forFields: MdtChartsFieldName[];
464
475
  dominantBaseline: DominantBaseline;
@@ -5,6 +5,7 @@ export declare const LINE_CHART_DEFAULT_WIDTH = 2;
5
5
  export declare function parseShape(chartOrientation: ChartOrientation, configOptions?: MdtChartsLineLikeChartShape): LineLikeChartShapeOptions;
6
6
  export declare function parseDashStyles(configOptions?: MdtChartsLineLikeChartDashedStyles): LineLikeChartDashOptions;
7
7
  export declare function getBarViewOptions(chart: MdtChartsTwoDimensionalChart, keyAxisOrient: Orient, barIndexes: number[]): TwoDimensionalBarLikeChartViewModel;
8
+ export declare function getBarsAmount(allCharts: Pick<MdtChartsTwoDimensionalChart, "isSegmented" | "data" | "type">[]): number;
8
9
  export declare function calculateBarIndexes(allCharts: Pick<MdtChartsTwoDimensionalChart, "isSegmented" | "data" | "type">[], currentChart: Pick<MdtChartsTwoDimensionalChart, "isSegmented" | "data" | "type">, currentChartIndex: number): number[];
9
10
  export declare function getSegmentedRadiusValues(segmentsLength: number, segmentIndex: number, keyAxisOrient: Orient, defaultRadius: number): BarBorderRadius;
10
11
  export declare function getLegendMarkerOptions(chart: MdtChartsTwoDimensionalChart): ChartLegendMarkerModel;
@@ -41,6 +41,13 @@ export function getBarViewOptions(chart, keyAxisOrient, barIndexes) {
41
41
  };
42
42
  return { hatch, borderRadius, barIndexes };
43
43
  }
44
+ export function getBarsAmount(allCharts) {
45
+ return allCharts.reduce((acc, ch) => {
46
+ if (ch.type === "bar")
47
+ return acc + (ch.isSegmented ? 1 : ch.data.valueFields.length);
48
+ return acc;
49
+ }, 0);
50
+ }
44
51
  export function calculateBarIndexes(allCharts, currentChart, currentChartIndex) {
45
52
  const prevBarCharts = allCharts.slice(0, currentChartIndex).filter((ch) => ch.type === "bar");
46
53
  const startBarIndex = prevBarCharts.reduce((acc, ch) => acc + (ch.isSegmented ? 1 : ch.data.valueFields.length), 0);
@@ -107,7 +114,7 @@ export function getLineViewOptions(chart) {
107
114
  return {
108
115
  dashedStyles: { on: false, dashSize: 0, gapSize: 0 },
109
116
  strokeWidth: (_c = (_b = (_a = chart.dotLikeStyles) === null || _a === void 0 ? void 0 : _a.shape) === null || _b === void 0 ? void 0 : _b.width) !== null && _c !== void 0 ? _c : LINE_CHART_DEFAULT_WIDTH,
110
- length: getWidthOfLegendMarkerByType("line")
117
+ length: getWidthOfLegendMarkerByType("dot")
111
118
  };
112
119
  case "area":
113
120
  return {
@@ -130,6 +137,9 @@ export function getWidthOfLegendMarkerByType(chartType) {
130
137
  return 24;
131
138
  if (chartType === "area")
132
139
  return styledElementValues.defaultLegendMarkerSizes.widthPx;
140
+ if (chartType === "dot")
141
+ return 24;
142
+ throw new Error(`Got unknown chart type when getting width of legend marker: "${chartType}"`);
133
143
  }
134
144
  export function getAreaViewOptions(chart, chartIndex, style, chartBlockId) {
135
145
  var _a, _b, _c, _d, _e;
@@ -3,7 +3,7 @@ import { TwoDimensionalChartStyleModel } from "../chartStyleModel/twoDimensional
3
3
  import { AxisModel } from "../featuresModel/axis/axisModel";
4
4
  import { ScaleAxisRecalcer } from "../featuresModel/scaleModel/scaleAxisRecalcer";
5
5
  import { ScaleModel } from "../featuresModel/scaleModel/scaleModel";
6
- import { calculateBarIndexes, getAreaViewOptions, getBarViewOptions, getLegendMarkerOptions, LINE_CHART_DEFAULT_WIDTH, parseDashStyles, parseShape } from "./twoDimensional/styles";
6
+ import { calculateBarIndexes, getAreaViewOptions, getBarsAmount, getBarViewOptions, getLegendMarkerOptions, LINE_CHART_DEFAULT_WIDTH, parseDashStyles, parseShape } from "./twoDimensional/styles";
7
7
  import { calculateValueLabelAlignment, handleScaledValue, ValueLabelCoordinateCalculator } from "../../model/featuresModel/valueLabelsModel/valueLabelsModel";
8
8
  import { TwoDimensionalModelHelper } from "../helpers/twoDimensionalModelHelper";
9
9
  import { TitleConfigReader } from "../modelInstance/titleConfigReader";
@@ -18,6 +18,7 @@ import { GroupingSplitLinesGenerator } from "../featuresModel/grouping/groupingS
18
18
  import { GroupingDataAmountCalculator } from "../featuresModel/grouping/groupingDataAmountCalculator/groupingDataAmountCalculator";
19
19
  import { ScaleCanvasSizesCalculator } from "../featuresModel/scaleModel/sizaCalculators/scaleCanvasSizesCalculator";
20
20
  import { KeyTotalSpaceCalculator } from "../featuresModel/scaleModel/sizaCalculators/keyTotalSpaceCalculator";
21
+ import { createBandLikeChartSettingsStore } from "../featuresModel/bandLikeCharts/bandLikeChartSettings";
21
22
  export class TwoDimensionalModel {
22
23
  static getOptions(configReader, designerConfig, modelInstance) {
23
24
  const options = configReader.options;
@@ -33,9 +34,9 @@ export class TwoDimensionalModel {
33
34
  secondaryScaleValueInfo = secondaryScaleMarginRecalcer.getScaleValue();
34
35
  }
35
36
  const keyAxis = AxisModel.getKeyAxis(options, modelInstance.dataModel.repository.getScopedFullSource(), designerConfig.canvas.axisLabel, canvasModel, designerConfig.elementsOptions.tooltip, () => scaleValueInfo.scaleFn(0));
36
- const charts = this.getChartsModel(options.charts, configReader, options.orientation, designerConfig, modelInstance.dataModel.repository, keyAxis.orient, canvasModel, options.data.keyField.name, modelInstance);
37
- const titleConfig = TitleConfigReader.create(options.title, modelInstance);
38
37
  const keyScale = scaleModel.getScaleKey(modelInstance.dataModel.getAllowableKeys());
38
+ const charts = this.getChartsModel(options.charts, configReader, options.orientation, designerConfig, modelInstance.dataModel.repository, keyAxis.orient, canvasModel, options.data.keyField.name, modelInstance, keyScale);
39
+ const titleConfig = TitleConfigReader.create(options.title, modelInstance);
39
40
  const isHorizontal = options.orientation === "horizontal";
40
41
  const groupingStaticCoordinateCalculator = new GroupingStaticCoordinateCalculator({
41
42
  canvasModel,
@@ -169,13 +170,22 @@ export class TwoDimensionalModel {
169
170
  lineLike: { shape: parseShape(chartOrientation, (_a = chartOptions.line) === null || _a === void 0 ? void 0 : _a.shape) }
170
171
  };
171
172
  }
172
- static getChartsModel(charts, configReader, chartOrientation, designerConfig, dataModelRep, keyAxisOrient, canvasModel, keyFieldName, modelInstance) {
173
+ static getChartsModel(charts, configReader, chartOrientation, designerConfig, dataModelRep, keyAxisOrient, canvasModel, keyFieldName, modelInstance, keyScale) {
173
174
  const styleModel = new TwoDimensionalChartStyleModel(charts, designerConfig.chartStyle);
174
175
  const chartsModel = [];
175
176
  charts.forEach((chart, index) => {
176
177
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0;
177
178
  const style = styleModel.getChartStyle(chart, index);
178
- const valueLabelsCoordinateCalculator = new ValueLabelCoordinateCalculator((_a = chart.valueLabels) === null || _a === void 0 ? void 0 : _a.position, keyAxisOrient, canvasModel.getMargin());
179
+ const bandSettingsStore = createBandLikeChartSettingsStore(chart.type, designerConfig.canvas.chartOptions.bar, getBarsAmount(charts), keyScale);
180
+ const globalBarsIndicesMap = calculateBarIndexes(charts, chart, index);
181
+ const valueLabelsCoordinateCalculator = new ValueLabelCoordinateCalculator((_a = chart.valueLabels) === null || _a === void 0 ? void 0 : _a.position, keyAxisOrient, canvasModel.getMargin(), chart.isSegmented, (value, fieldIndex) => {
182
+ if (bandSettingsStore)
183
+ return (value +
184
+ bandSettingsStore.getBandItemPad(globalBarsIndicesMap[fieldIndex]) +
185
+ bandSettingsStore.getBandSubItemSize() / 2);
186
+ const keyScalePadToMiddle = keyScale.type === "band" ? keyScale.sizes.bandSize / 2 : 0;
187
+ return value + keyScalePadToMiddle;
188
+ });
179
189
  const valueLabelsAlignment = calculateValueLabelAlignment(keyAxisOrient, (_c = (_b = chart.valueLabels) === null || _b === void 0 ? void 0 : _b.position) === null || _c === void 0 ? void 0 : _c.mode, (_d = chart.valueLabels) === null || _d === void 0 ? void 0 : _d.rotation);
180
190
  chartsModel.push({
181
191
  type: chart.type,
@@ -212,7 +222,10 @@ export class TwoDimensionalModel {
212
222
  strokeWidth: (_r = (_q = chart.lineStyles) === null || _q === void 0 ? void 0 : _q.width) !== null && _r !== void 0 ? _r : LINE_CHART_DEFAULT_WIDTH,
213
223
  renderForKey: (dataRow, valueFieldName) => dataRow[valueFieldName] !== null && dataRow[valueFieldName] !== undefined
214
224
  },
215
- barViewOptions: getBarViewOptions(chart, keyAxisOrient, calculateBarIndexes(charts, chart, index)),
225
+ bandLikeViewOptions: {
226
+ settingsStore: bandSettingsStore
227
+ },
228
+ barViewOptions: getBarViewOptions(chart, keyAxisOrient, globalBarsIndicesMap),
216
229
  legend: getLegendMarkerOptions(chart),
217
230
  index,
218
231
  valueLabels: {
@@ -221,8 +234,8 @@ export class TwoDimensionalModel {
221
234
  const value = row[valueFieldName];
222
235
  return value != null && !Number.isNaN(value);
223
236
  },
224
- handleX: (scaledValue) => valueLabelsCoordinateCalculator.getValueLabelX(scaledValue),
225
- handleY: (scaledValue) => valueLabelsCoordinateCalculator.getValueLabelY(scaledValue),
237
+ handleX: (scaledValue, fieldIndex) => valueLabelsCoordinateCalculator.getValueLabelX(scaledValue, fieldIndex),
238
+ handleY: (scaledValue, fieldIndex) => valueLabelsCoordinateCalculator.getValueLabelY(scaledValue, fieldIndex),
226
239
  handleScaledValue: (dataRow, datumField) => {
227
240
  var _a, _b;
228
241
  return handleScaledValue(dataRow, datumField, chart.isSegmented, (_b = (_a = chart.valueLabels) === null || _a === void 0 ? void 0 : _a.position) === null || _b === void 0 ? void 0 : _b.mode);
@@ -248,8 +261,8 @@ export class TwoDimensionalModel {
248
261
  dotViewOptions: {
249
262
  shape: {
250
263
  type: "line",
251
- handleEndCoordinate: (v) => v + 2,
252
264
  handleStartCoordinate: (v) => v - 2,
265
+ handleEndCoordinate: (v) => v + 2,
253
266
  width: (_0 = (_z = (_y = chart.dotLikeStyles) === null || _y === void 0 ? void 0 : _y.shape) === null || _z === void 0 ? void 0 : _z.width) !== null && _0 !== void 0 ? _0 : LINE_CHART_DEFAULT_WIDTH
254
267
  }
255
268
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mdt-charts",
3
- "version": "1.37.2",
3
+ "version": "1.37.3",
4
4
  "description": "",
5
5
  "main": "lib/main.js",
6
6
  "scripts": {