mdt-charts 1.26.1 → 1.27.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.
@@ -290,8 +290,12 @@ export interface TwoDimensionalChartData {
290
290
  valueFields: TwoDimValueField[];
291
291
  valueGroup?: TwoDimensionalValueGroup;
292
292
  }
293
+ export declare type ValueLabelsPositionMode = "after" | "center";
293
294
  export interface TwoDimensionalChartValueLabels {
294
295
  on: boolean;
296
+ position?: {
297
+ mode?: ValueLabelsPositionMode;
298
+ };
295
299
  format?: ValueLabelsFormatter;
296
300
  }
297
301
  export declare type ValueLabelsFormatter = (value: number) => string;
@@ -24,12 +24,14 @@ export interface ValueLabelAttrs {
24
24
  export declare class ChartValueLabels {
25
25
  private readonly globalOptions;
26
26
  private readonly chart;
27
- private static readonly valueLabelClass;
27
+ static readonly valueLabelClass: string;
28
28
  private readonly renderPipeline;
29
+ private readonly attrsProvider;
29
30
  constructor(globalOptions: ValueLabelsOptions, chart: TwoDimensionalChartModel);
30
31
  render(scales: Scales, data: MdtChartsDataRow[]): void;
31
32
  update(scales: Scales, newData: MdtChartsDataRow[]): Promise<void[]>;
32
- static getChartValueLabelsClassName(): string;
33
+ private renderByGroupIndex;
34
+ private updateByGroupIndex;
33
35
  private getAllValueLabelsOfChart;
34
36
  private setAttrs;
35
37
  private setClasses;
@@ -1,16 +1,18 @@
1
1
  import { NamesHelper } from "../../../engine/helpers/namesHelper";
2
- import { ValueLabelsHelper } from "../../../engine/features/valueLabels/valueLabelsHelper";
2
+ import { ValueLabelsAttrsProvider } from "../../../engine/features/valueLabels/valueLabelsHelper";
3
3
  import { Helper } from "../../../engine/helpers/helper";
4
4
  import { select } from "d3-selection";
5
5
  import { DomHelper } from "../../../engine/helpers/domHelper";
6
6
  import { CLASSES } from "../../../model/modelBuilder";
7
7
  import { ValueLabelsCollision } from "../../../engine/features/valueLabelsCollision/valueLabelsCollision";
8
8
  import { Pipeline } from "../../helpers/pipeline/Pipeline";
9
+ import { getStackedData } from "../../twoDimensionalNotation/line/lineHelper";
9
10
  export class ChartValueLabels {
10
11
  constructor(globalOptions, chart) {
11
12
  this.globalOptions = globalOptions;
12
13
  this.chart = chart;
13
14
  this.renderPipeline = new Pipeline();
15
+ this.attrsProvider = new ValueLabelsAttrsProvider();
14
16
  this.renderPipeline.push((valueLabels, { style }) => {
15
17
  valueLabels
16
18
  .attr('fill', 'currentColor')
@@ -22,50 +24,70 @@ export class ChartValueLabels {
22
24
  });
23
25
  }
24
26
  render(scales, data) {
25
- this.chart.data.valueFields.forEach((valueField, vfIndex) => {
26
- let valueLabels = this.getAllValueLabelsOfChart(vfIndex)
27
- .data(data)
28
- .enter()
29
- .append('text');
30
- valueLabels = this.renderPipeline.execute(valueLabels, { style: this.globalOptions.canvas.style });
31
- const attrs = ValueLabelsHelper.getValueLabelsAttrs(this.globalOptions, this.chart.valueLabels, scales, valueField);
32
- this.setAttrs(valueLabels, attrs, valueField.name, this.chart.valueLabels.format);
33
- this.setClasses(valueLabels, this.chart.cssClasses, vfIndex);
34
- });
27
+ if (this.chart.isSegmented) {
28
+ const preparedData = getStackedData(data, this.chart);
29
+ preparedData.forEach((segment, segmentIndex) => {
30
+ this.renderByGroupIndex(scales, segmentIndex, segment, segment[0].fieldName, '1', d => d.data);
31
+ });
32
+ }
33
+ else {
34
+ this.chart.data.valueFields.forEach((valueField, vfIndex) => {
35
+ this.renderByGroupIndex(scales, vfIndex, data, valueField.name, valueField.name, d => d);
36
+ });
37
+ }
35
38
  }
36
39
  update(scales, newData) {
37
40
  const updatePromises = [];
38
- this.chart.data.valueFields.forEach((valueField, vfIndex) => {
39
- const updateProms = new Promise((resolve) => {
40
- const valueLabels = this.getAllValueLabelsOfChart(vfIndex)
41
- .data(newData);
42
- valueLabels.exit().remove();
43
- const attrs = ValueLabelsHelper.getValueLabelsAttrs(this.globalOptions, this.chart.valueLabels, scales, valueField);
44
- let newValueLabels = valueLabels
45
- .enter()
46
- .append('text');
47
- newValueLabels = this.renderPipeline.execute(newValueLabels, { style: this.globalOptions.canvas.style });
48
- const mergedValueLabels = newValueLabels.merge(valueLabels);
49
- this.setAttrs(newValueLabels, attrs, valueField.name, this.chart.valueLabels.format);
50
- this.setClasses(mergedValueLabels, this.chart.cssClasses, vfIndex);
51
- this.setAttrs(valueLabels, attrs, valueField.name, this.chart.valueLabels.format, true, resolve);
41
+ if (this.chart.isSegmented) {
42
+ const preparedData = getStackedData(newData, this.chart);
43
+ preparedData.forEach((segment, segmentIndex) => {
44
+ const promise = this.updateByGroupIndex(scales, segmentIndex, segment, segment[0].fieldName, '1', d => d.data);
45
+ updatePromises.push(promise);
52
46
  });
53
- updatePromises.push(updateProms);
54
- });
47
+ }
48
+ else {
49
+ this.chart.data.valueFields.forEach((valueField, vfIndex) => {
50
+ const promise = this.updateByGroupIndex(scales, vfIndex, newData, valueField.name, valueField.name, d => d);
51
+ updatePromises.push(promise);
52
+ });
53
+ }
55
54
  return Promise.all(updatePromises);
56
55
  }
57
- static getChartValueLabelsClassName() {
58
- return ChartValueLabels.valueLabelClass;
56
+ renderByGroupIndex(scales, groupIndex, data, valueFieldName, datumField, dataRowAccessor) {
57
+ let valueLabels = this.getAllValueLabelsOfChart(groupIndex)
58
+ .data(data)
59
+ .enter()
60
+ .append('text');
61
+ valueLabels = this.renderPipeline.execute(valueLabels, { style: this.globalOptions.canvas.style });
62
+ const attrs = this.attrsProvider.getAttrs(this.globalOptions, this.chart.valueLabels, scales, datumField, dataRowAccessor);
63
+ this.setAttrs(valueLabels, attrs, valueFieldName, this.chart.valueLabels.format, dataRowAccessor);
64
+ this.setClasses(valueLabels, this.chart.cssClasses, groupIndex);
65
+ }
66
+ updateByGroupIndex(scales, groupIndex, data, valueFieldName, datumField, dataRowAccessor) {
67
+ return new Promise((resolve) => {
68
+ const valueLabels = this.getAllValueLabelsOfChart(groupIndex)
69
+ .data(data);
70
+ valueLabels.exit().remove();
71
+ const attrs = this.attrsProvider.getAttrs(this.globalOptions, this.chart.valueLabels, scales, datumField, dataRowAccessor);
72
+ let newValueLabels = valueLabels
73
+ .enter()
74
+ .append('text');
75
+ newValueLabels = this.renderPipeline.execute(newValueLabels, { style: this.globalOptions.canvas.style });
76
+ const mergedValueLabels = newValueLabels.merge(valueLabels);
77
+ this.setAttrs(newValueLabels, attrs, valueFieldName, this.chart.valueLabels.format, dataRowAccessor);
78
+ this.setClasses(mergedValueLabels, this.chart.cssClasses, groupIndex);
79
+ this.setAttrs(valueLabels, attrs, valueFieldName, this.chart.valueLabels.format, dataRowAccessor, true, resolve);
80
+ });
59
81
  }
60
82
  getAllValueLabelsOfChart(vfIndex) {
61
83
  const block = this.globalOptions.elementAccessors.getBlock().svg.getChartBlock();
62
84
  return block
63
85
  .selectAll(`.${ChartValueLabels.valueLabelClass}.${CLASSES.dataLabel}${Helper.getCssClassesLine(this.chart.cssClasses)}.chart-element-${vfIndex}`);
64
86
  }
65
- setAttrs(valueLabels, attrs, valueFieldName, formatter, animate = false, onEndAnimation) {
87
+ setAttrs(valueLabels, attrs, valueFieldName, formatter, dataRowAccessor, animate = false, onEndAnimation) {
66
88
  const animationName = 'labels-updating';
67
89
  valueLabels
68
- .text(d => formatter(d[valueFieldName]))
90
+ .text(d => formatter(dataRowAccessor(d)[valueFieldName]))
69
91
  .attr('dominant-baseline', attrs.dominantBaseline)
70
92
  .attr('text-anchor', attrs.textAnchor);
71
93
  if (animate) {
@@ -136,7 +158,7 @@ export class CanvasValueLabels {
136
158
  getAllValueLabels() {
137
159
  const block = this.options.elementAccessors.getBlock().svg.getChartBlock();
138
160
  return block
139
- .selectAll(`.${ChartValueLabels.getChartValueLabelsClassName()}`);
161
+ .selectAll(`.${ChartValueLabels.valueLabelClass}`);
140
162
  }
141
163
  getChartScales(scales, chart) {
142
164
  return {
@@ -1,6 +1,8 @@
1
1
  import { ValueLabelAttrs, ValueLabelsOptions } from "../../../engine/features/valueLabels/valueLabels";
2
- import { TwoDimChartValueLabelsOptions, ValueField } from "../../../model/model";
2
+ import { TwoDimChartValueLabelsOptions } from "../../../model/model";
3
3
  import { Scales } from "../../../engine/features/scale/scale";
4
- export declare class ValueLabelsHelper {
5
- static getValueLabelsAttrs(globalOptions: ValueLabelsOptions, valueLabels: TwoDimChartValueLabelsOptions, scales: Scales, valueField: ValueField): ValueLabelAttrs;
4
+ import { Segment } from "../../twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorDefineMiddleware";
5
+ import { MdtChartsDataRow } from "../../../config/config";
6
+ export declare class ValueLabelsAttrsProvider {
7
+ getAttrs(globalOptions: ValueLabelsOptions, valueLabels: TwoDimChartValueLabelsOptions, scales: Scales, datumField: string, dataRowAccessor: (d: MdtChartsDataRow | Segment) => MdtChartsDataRow): ValueLabelAttrs;
6
8
  }
@@ -1,6 +1,6 @@
1
1
  import { Scale } from "../../../engine/features/scale/scale";
2
- export class ValueLabelsHelper {
3
- static getValueLabelsAttrs(globalOptions, valueLabels, scales, valueField) {
2
+ export class ValueLabelsAttrsProvider {
3
+ getAttrs(globalOptions, valueLabels, scales, datumField, dataRowAccessor) {
4
4
  let attrs = {
5
5
  x: null,
6
6
  y: null,
@@ -9,12 +9,12 @@ export class ValueLabelsHelper {
9
9
  };
10
10
  const orient = globalOptions.canvas.keyAxisOrient;
11
11
  if (orient === 'left' || orient === 'right') {
12
- attrs.x = d => valueLabels.handleX(scales.value(d[valueField.name]));
13
- attrs.y = d => valueLabels.handleY(Scale.getScaledValue(scales.key, d[globalOptions.data.keyFieldName]));
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]));
14
14
  }
15
15
  else if (orient === 'bottom' || orient === 'top') {
16
- attrs.x = d => valueLabels.handleX(Scale.getScaledValue(scales.key, d[globalOptions.data.keyFieldName]));
17
- attrs.y = d => valueLabels.handleY(scales.value(d[valueField.name]));
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)));
18
18
  }
19
19
  return attrs;
20
20
  }
@@ -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[], firstBarIndex: number): void;
25
- update(block: Block, newData: MdtChartsDataRow[], scales: Scales, margin: BlockMargin, keyAxisOrient: Orient, chart: TwoDimensionalChartModel, blockSize: Size, barsAmounts: number[], keyField: Field, firstBarIndex: number, barSettings: BarChartSettings): Promise<any>[];
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>[];
26
26
  updateColors(block: Block, chart: TwoDimensionalChartModel): void;
27
27
  getAllBarsForChart(block: Block, chartCssClasses: string[]): Selection<BaseType, MdtChartsDataRow, BaseType, unknown>;
28
28
  private renderGrouped;
@@ -18,19 +18,19 @@ export class Bar {
18
18
  static get() {
19
19
  return new Bar();
20
20
  }
21
- render(block, scales, data, keyField, margin, keyAxisOrient, chart, blockSize, barSettings, barsAmounts, firstBarIndex) {
21
+ render(block, scales, data, keyField, margin, keyAxisOrient, chart, blockSize, barSettings, barsAmounts) {
22
22
  if (chart.isSegmented)
23
- this.renderSegmented(block, scales, data, keyField, margin, keyAxisOrient, chart, barsAmounts, firstBarIndex, barSettings);
23
+ this.renderSegmented(block, scales, data, keyField, margin, keyAxisOrient, chart, barsAmounts, barSettings);
24
24
  else
25
- this.renderGrouped(block, scales, data, keyField, margin, keyAxisOrient, chart, barsAmounts, blockSize, firstBarIndex, barSettings);
25
+ this.renderGrouped(block, scales, data, keyField, margin, keyAxisOrient, chart, barsAmounts, blockSize, barSettings);
26
26
  }
27
- update(block, newData, scales, margin, keyAxisOrient, chart, blockSize, barsAmounts, keyField, firstBarIndex, barSettings) {
27
+ update(block, newData, scales, margin, keyAxisOrient, chart, blockSize, barsAmounts, keyField, barSettings) {
28
28
  let promises;
29
29
  if (chart.isSegmented) {
30
- promises = this.updateSegmented(block, newData, scales, margin, keyAxisOrient, chart, blockSize, barsAmounts, keyField, firstBarIndex, barSettings);
30
+ promises = this.updateSegmented(block, newData, scales, margin, keyAxisOrient, chart, barsAmounts, keyField, barSettings);
31
31
  }
32
32
  else {
33
- promises = this.updateGrouped(block, newData, scales, margin, keyAxisOrient, chart, blockSize, barsAmounts, keyField, firstBarIndex, barSettings);
33
+ promises = this.updateGrouped(block, newData, scales, margin, keyAxisOrient, chart, blockSize, barsAmounts, keyField, barSettings);
34
34
  }
35
35
  return promises;
36
36
  }
@@ -44,7 +44,7 @@ export class Bar {
44
44
  getAllBarsForChart(block, chartCssClasses) {
45
45
  return block.getSvg().selectAll(`rect.${this.barItemClass}${Helper.getCssClassesLine(chartCssClasses)}`);
46
46
  }
47
- renderGrouped(block, scales, data, keyField, margin, keyAxisOrient, chart, barsAmounts, blockSize, firstBarIndex, barSettings) {
47
+ renderGrouped(block, scales, data, keyField, margin, keyAxisOrient, chart, barsAmounts, blockSize, barSettings) {
48
48
  chart.data.valueFields.forEach((field, index) => {
49
49
  let bars = block.svg.getChartGroup(chart.index)
50
50
  .selectAll(`.${this.barItemClass}${Helper.getCssClassesLine(chart.cssClasses)}${Helper.getCssClassesLine(Helper.getCssClassesWithElementIndex(chart.cssClasses, index))}`)
@@ -63,7 +63,7 @@ export class Bar {
63
63
  EmbeddedLabels.render(block, bars, barAttrs, EmbeddedLabelsHelper.getLabelField(chart.embeddedLabels, chart.data.valueFields, keyField, index), chart.embeddedLabels, keyAxisOrient, blockSize, margin, index, chart.cssClasses);
64
64
  });
65
65
  }
66
- renderSegmented(block, scales, data, keyField, margin, keyAxisOrient, chart, barsAmounts, firstBarIndex, barSettings) {
66
+ renderSegmented(block, scales, data, keyField, margin, keyAxisOrient, chart, barsAmounts, barSettings) {
67
67
  const stackedData = getStackedDataWithOwn(data, chart.data.valueFields.map(field => field.name));
68
68
  let groups = block.svg.getChartGroup(chart.index)
69
69
  .selectAll(`g.${this.barSegmentGroupClass}${Helper.getCssClassesLine(chart.cssClasses)}`)
@@ -95,7 +95,7 @@ export class Bar {
95
95
  thisClass.setSegmentColor(select(this).selectAll(Helper.getCssClassesLine(chart.cssClasses)), chart.style.elementColors, i);
96
96
  });
97
97
  }
98
- updateGrouped(block, newData, scales, margin, keyAxisOrient, chart, blockSize, barsAmounts, keyField, firstBarIndex, barSettings) {
98
+ updateGrouped(block, newData, scales, margin, keyAxisOrient, chart, blockSize, barsAmounts, keyField, barSettings) {
99
99
  const promises = [];
100
100
  chart.data.valueFields.forEach((valueField, index) => {
101
101
  const indexesOfRemoved = [];
@@ -144,7 +144,7 @@ export class Bar {
144
144
  });
145
145
  return promises;
146
146
  }
147
- updateSegmented(block, newData, scales, margin, keyAxisOrient, chart, blockSize, barsAmounts, keyField, firstBarIndex, barSettings) {
147
+ updateSegmented(block, newData, scales, margin, keyAxisOrient, chart, barsAmounts, keyField, barSettings) {
148
148
  const stackedData = getStackedDataWithOwn(newData, chart.data.valueFields.map(field => field.name));
149
149
  block.svg.getChartGroup(chart.index)
150
150
  .selectAll(`.${this.barItemClass}${Helper.getCssClassesLine(chart.cssClasses)}`)
@@ -124,7 +124,7 @@ export class TwoDimensionalManager {
124
124
  charts.forEach((chart) => {
125
125
  const chartScales = { key: scales.key, value: chart.data.valueGroup === "secondary" ? scales.valueSecondary : scales.value };
126
126
  if (chart.type === 'bar')
127
- Bar.get().render(block, chartScales, data[dataOptions.dataSource], dataOptions.keyField, margin, keyAxisOrient, chart, blockSize, chartSettings.bar, BarHelper.getBarsInGroupAmount(charts), charts.findIndex(ch => ch.type === 'bar'));
127
+ Bar.get().render(block, chartScales, data[dataOptions.dataSource], dataOptions.keyField, margin, keyAxisOrient, chart, blockSize, chartSettings.bar, BarHelper.getBarsInGroupAmount(charts));
128
128
  else if (chart.type === 'line')
129
129
  Line.get({ staticSettings: chartSettings.lineLike }).render(block, chartScales, data[dataOptions.dataSource], dataOptions.keyField, margin, keyAxisOrient, chart);
130
130
  else if (chart.type === 'area')
@@ -141,7 +141,7 @@ export class TwoDimensionalManager {
141
141
  const chartScales = { key: scales.key, value: chart.data.valueGroup === "secondary" ? scales.valueSecondary : scales.value };
142
142
  let proms;
143
143
  if (chart.type === 'bar') {
144
- proms = Bar.get().update(block, data[dataOptions.dataSource], chartScales, margin, keyAxisOrient, chart, blockSize, BarHelper.getBarsInGroupAmount(charts), dataOptions.keyField, charts.findIndex(ch => ch.type === 'bar'), chartSettings.bar);
144
+ proms = Bar.get().update(block, data[dataOptions.dataSource], chartScales, margin, keyAxisOrient, chart, blockSize, BarHelper.getBarsInGroupAmount(charts), dataOptions.keyField, chartSettings.bar);
145
145
  }
146
146
  else if (chart.type === 'line') {
147
147
  proms = Line.get({ staticSettings: chartSettings.lineLike }).update(block, chartScales, data[dataOptions.dataSource], dataOptions.keyField, margin, keyAxisOrient, chart);
@@ -1,15 +1,21 @@
1
1
  import { BlockMargin, Orient, ValueLabelAnchor, ValueLabelDominantBaseline } from "../../model";
2
2
  import { BoundingRect } from "../../../engine/features/valueLabelsCollision/valueLabelsCollision";
3
- import { Size } from "../../../config/config";
3
+ import { Size, ValueLabelsPositionMode } from "../../../config/config";
4
4
  interface ValueLabelAlignment {
5
5
  dominantBaseline: ValueLabelDominantBaseline;
6
6
  textAnchor: ValueLabelAnchor;
7
7
  }
8
8
  export declare const OFFSET_SIZE_PX = 10;
9
9
  export declare const BORDER_OFFSET_SIZE_PX = 2;
10
- export declare function getValueLabelY(scaledValue: number, keyAxisOrient: Orient, margin: BlockMargin): number;
11
- export declare function getValueLabelX(scaledValue: number, keyAxisOrient: Orient, margin: BlockMargin): number;
12
- export declare function calculateValueLabelAlignment(keyAxisOrient: Orient): ValueLabelAlignment;
10
+ export declare class ValueLabelCoordinateCalculator {
11
+ private readonly keyAxisOrient;
12
+ private readonly margin;
13
+ private readonly offsetSizePx;
14
+ constructor(positionMode: ValueLabelsPositionMode | undefined, keyAxisOrient: Orient, margin: BlockMargin);
15
+ getValueLabelY(scaledValue: number): number;
16
+ getValueLabelX(scaledValue: number): number;
17
+ }
18
+ export declare function calculateValueLabelAlignment(keyAxisOrient: Orient, positionMode?: ValueLabelsPositionMode): ValueLabelAlignment;
13
19
  export declare function hasCollisionLeftSide(labelClientRect: BoundingRect, margin: BlockMargin): boolean;
14
20
  export declare function hasCollisionRightSide(labelClientRect: BoundingRect, blockSize: Size, margin: BlockMargin): boolean;
15
21
  export declare function hasCollisionTopSide(labelClientRect: BoundingRect, margin: BlockMargin): boolean;
@@ -1,35 +1,47 @@
1
1
  export const OFFSET_SIZE_PX = 10;
2
2
  export const BORDER_OFFSET_SIZE_PX = 2;
3
- export function getValueLabelY(scaledValue, keyAxisOrient, margin) {
4
- switch (keyAxisOrient) {
5
- case 'bottom':
6
- return scaledValue - OFFSET_SIZE_PX + margin.top;
7
- case 'top':
8
- return scaledValue + OFFSET_SIZE_PX + margin.top;
9
- default:
10
- return scaledValue + margin.top;
3
+ export class ValueLabelCoordinateCalculator {
4
+ constructor(positionMode, keyAxisOrient, margin) {
5
+ this.keyAxisOrient = keyAxisOrient;
6
+ this.margin = margin;
7
+ this.offsetSizePx = positionMode === "center" ? 0 : OFFSET_SIZE_PX;
11
8
  }
12
- }
13
- export function getValueLabelX(scaledValue, keyAxisOrient, margin) {
14
- switch (keyAxisOrient) {
15
- case 'right':
16
- return scaledValue - OFFSET_SIZE_PX + margin.left;
17
- case 'left':
18
- return scaledValue + OFFSET_SIZE_PX + margin.left;
19
- default:
20
- return scaledValue + margin.left;
9
+ getValueLabelY(scaledValue) {
10
+ switch (this.keyAxisOrient) {
11
+ case 'bottom':
12
+ return scaledValue - this.offsetSizePx + this.margin.top;
13
+ case 'top':
14
+ return scaledValue + this.offsetSizePx + this.margin.top;
15
+ default:
16
+ return scaledValue + this.margin.top;
17
+ }
18
+ }
19
+ getValueLabelX(scaledValue) {
20
+ switch (this.keyAxisOrient) {
21
+ case 'right':
22
+ return scaledValue - this.offsetSizePx + this.margin.left;
23
+ case 'left':
24
+ return scaledValue + this.offsetSizePx + this.margin.left;
25
+ default:
26
+ return scaledValue + this.margin.left;
27
+ }
21
28
  }
22
29
  }
23
- export function calculateValueLabelAlignment(keyAxisOrient) {
24
- switch (keyAxisOrient) {
25
- case 'top':
26
- return { dominantBaseline: "hanging", textAnchor: "middle" };
27
- case "bottom":
28
- return { dominantBaseline: "auto", textAnchor: "middle" };
29
- case "left":
30
- return { dominantBaseline: "middle", textAnchor: "start" };
31
- case "right":
32
- return { dominantBaseline: "middle", textAnchor: "end" };
30
+ export function calculateValueLabelAlignment(keyAxisOrient, positionMode) {
31
+ if (!positionMode || positionMode === "after") {
32
+ switch (keyAxisOrient) {
33
+ case 'top':
34
+ return { dominantBaseline: "hanging", textAnchor: "middle" };
35
+ case "bottom":
36
+ return { dominantBaseline: "auto", textAnchor: "middle" };
37
+ case "left":
38
+ return { dominantBaseline: "middle", textAnchor: "start" };
39
+ case "right":
40
+ return { dominantBaseline: "middle", textAnchor: "end" };
41
+ }
42
+ }
43
+ else {
44
+ return { dominantBaseline: "middle", textAnchor: "middle" };
33
45
  }
34
46
  }
35
47
  export function hasCollisionLeftSide(labelClientRect, margin) {
@@ -380,6 +380,7 @@ export interface TwoDimChartValueLabelsOptions {
380
380
  textAnchor: ValueLabelAnchor;
381
381
  dominantBaseline: ValueLabelDominantBaseline;
382
382
  format: ValueLabelsFormatter;
383
+ handleScaledValue: (dataRow: MdtChartsDataRow, datumField: string) => number;
383
384
  }
384
385
  export declare type ValueLabelsFormatter = (value: number) => string;
385
386
  export interface MarkersOptions {
@@ -4,7 +4,7 @@ import { AxisModel } from "../featuresModel/axisModel";
4
4
  import { ScaleAxisRecalcer } from "../featuresModel/scaleModel/scaleAxisRecalcer";
5
5
  import { ScaleModel } from "../featuresModel/scaleModel/scaleModel";
6
6
  import { calculateBarIndexes, getAreaViewOptions, getBarViewOptions, getLegendMarkerOptions, LINE_CHART_DEFAULT_WIDTH, parseDashStyles, parseShape } from "./twoDimensional/styles";
7
- import { calculateValueLabelAlignment, getValueLabelX, getValueLabelY } from "../../model/featuresModel/valueLabelsModel/valueLabelsModel";
7
+ import { calculateValueLabelAlignment, ValueLabelCoordinateCalculator } from "../../model/featuresModel/valueLabelsModel/valueLabelsModel";
8
8
  import { TwoDimensionalModelHelper } from "../helpers/twoDimensionalModelHelper";
9
9
  import { TitleConfigReader } from "../modelInstance/titleConfigReader";
10
10
  export class TwoDimensionalModel {
@@ -73,8 +73,9 @@ export class TwoDimensionalModel {
73
73
  const styleModel = new TwoDimensionalChartStyleModel(charts, designerConfig.chartStyle);
74
74
  const chartsModel = [];
75
75
  charts.forEach((chart, index) => {
76
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
76
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
77
77
  const style = styleModel.getChartStyle(chart, index);
78
+ const valueLabelsCoordinateCalculator = new ValueLabelCoordinateCalculator((_b = (_a = chart.valueLabels) === null || _a === void 0 ? void 0 : _a.position) === null || _b === void 0 ? void 0 : _b.mode, keyAxisOrient, canvasModel.getMargin());
78
79
  chartsModel.push({
79
80
  type: chart.type,
80
81
  isSegmented: chart.isSegmented,
@@ -87,30 +88,39 @@ export class TwoDimensionalModel {
87
88
  show: ({ row, valueFieldName }) => TwoDimensionalModelHelper.shouldMarkerShow(chart, dataModelRep.getRawRows(), valueFieldName, row, keyFieldName),
88
89
  styles: {
89
90
  highlighted: {
90
- size: { radius: (_c = (_b = (_a = designerConfig.canvas.markers) === null || _a === void 0 ? void 0 : _a.highlighted) === null || _b === void 0 ? void 0 : _b.radius) !== null && _c !== void 0 ? _c : 4, borderSize: '3.5px' }
91
+ size: { radius: (_e = (_d = (_c = designerConfig.canvas.markers) === null || _c === void 0 ? void 0 : _c.highlighted) === null || _d === void 0 ? void 0 : _d.radius) !== null && _e !== void 0 ? _e : 4, borderSize: '3.5px' }
91
92
  },
92
93
  normal: {
93
94
  size: {
94
- radius: (_f = (_e = (_d = designerConfig.canvas.markers) === null || _d === void 0 ? void 0 : _d.normal) === null || _e === void 0 ? void 0 : _e.radius) !== null && _f !== void 0 ? _f : 3,
95
- borderSize: `${(_j = (_h = (_g = designerConfig.canvas.markers) === null || _g === void 0 ? void 0 : _g.normal) === null || _h === void 0 ? void 0 : _h.borderSize) !== null && _j !== void 0 ? _j : 2}px`
95
+ radius: (_h = (_g = (_f = designerConfig.canvas.markers) === null || _f === void 0 ? void 0 : _f.normal) === null || _g === void 0 ? void 0 : _g.radius) !== null && _h !== void 0 ? _h : 3,
96
+ borderSize: `${(_l = (_k = (_j = designerConfig.canvas.markers) === null || _j === void 0 ? void 0 : _j.normal) === null || _k === void 0 ? void 0 : _k.borderSize) !== null && _l !== void 0 ? _l : 2}px`
96
97
  }
97
98
  }
98
99
  }
99
100
  },
100
101
  lineLikeViewOptions: {
101
- dashedStyles: parseDashStyles((_k = chart.lineStyles) === null || _k === void 0 ? void 0 : _k.dash),
102
- strokeWidth: (_m = (_l = chart.lineStyles) === null || _l === void 0 ? void 0 : _l.width) !== null && _m !== void 0 ? _m : LINE_CHART_DEFAULT_WIDTH,
102
+ dashedStyles: parseDashStyles((_m = chart.lineStyles) === null || _m === void 0 ? void 0 : _m.dash),
103
+ strokeWidth: (_p = (_o = chart.lineStyles) === null || _o === void 0 ? void 0 : _o.width) !== null && _p !== void 0 ? _p : LINE_CHART_DEFAULT_WIDTH,
103
104
  renderForKey: (dataRow, valueFieldName) => dataRow[valueFieldName] !== null && dataRow[valueFieldName] !== undefined
104
105
  },
105
106
  barViewOptions: getBarViewOptions(chart, keyAxisOrient, calculateBarIndexes(charts, chart, index)),
106
107
  legend: getLegendMarkerOptions(chart),
107
108
  index,
108
109
  valueLabels: {
109
- show: (_p = (_o = chart.valueLabels) === null || _o === void 0 ? void 0 : _o.on) !== null && _p !== void 0 ? _p : false,
110
- handleX: (scaledValue) => getValueLabelX(scaledValue, keyAxisOrient, canvasModel.getMargin()),
111
- handleY: (scaledValue) => getValueLabelY(scaledValue, keyAxisOrient, canvasModel.getMargin()),
112
- textAnchor: calculateValueLabelAlignment(keyAxisOrient).textAnchor,
113
- dominantBaseline: calculateValueLabelAlignment(keyAxisOrient).dominantBaseline,
110
+ show: (_r = (_q = chart.valueLabels) === null || _q === void 0 ? void 0 : _q.on) !== null && _r !== void 0 ? _r : false,
111
+ handleX: (scaledValue) => valueLabelsCoordinateCalculator.getValueLabelX(scaledValue),
112
+ handleY: (scaledValue) => valueLabelsCoordinateCalculator.getValueLabelY(scaledValue),
113
+ handleScaledValue: (dataRow, datumField) => {
114
+ var _a, _b, _c, _d;
115
+ if (!((_b = (_a = chart.valueLabels) === null || _a === void 0 ? void 0 : _a.position) === null || _b === void 0 ? void 0 : _b.mode) || ((_d = (_c = chart.valueLabels) === null || _c === void 0 ? void 0 : _c.position) === null || _d === void 0 ? void 0 : _d.mode) === 'after')
116
+ return dataRow[datumField];
117
+ if (chart.isSegmented)
118
+ return dataRow[datumField] - (dataRow[datumField] - dataRow['0']) / 2;
119
+ else
120
+ return dataRow[datumField] / 2;
121
+ },
122
+ textAnchor: calculateValueLabelAlignment(keyAxisOrient, (_t = (_s = chart.valueLabels) === null || _s === void 0 ? void 0 : _s.position) === null || _t === void 0 ? void 0 : _t.mode).textAnchor,
123
+ dominantBaseline: calculateValueLabelAlignment(keyAxisOrient, (_v = (_u = chart.valueLabels) === null || _u === void 0 ? void 0 : _u.position) === null || _v === void 0 ? void 0 : _v.mode).dominantBaseline,
114
124
  format: configReader.getValueLabelFormatterForChart(index),
115
125
  },
116
126
  areaViewOptions: getAreaViewOptions(chart, index, style),
@@ -119,7 +129,7 @@ export class TwoDimensionalModel {
119
129
  type: "line",
120
130
  handleEndCoordinate: (v) => v + 2,
121
131
  handleStartCoordinate: (v) => v - 2,
122
- width: (_s = (_r = (_q = chart.dotLikeStyles) === null || _q === void 0 ? void 0 : _q.shape) === null || _r === void 0 ? void 0 : _r.width) !== null && _s !== void 0 ? _s : LINE_CHART_DEFAULT_WIDTH
132
+ width: (_y = (_x = (_w = chart.dotLikeStyles) === null || _w === void 0 ? void 0 : _w.shape) === null || _x === void 0 ? void 0 : _x.width) !== null && _y !== void 0 ? _y : LINE_CHART_DEFAULT_WIDTH
123
133
  }
124
134
  }
125
135
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mdt-charts",
3
- "version": "1.26.1",
3
+ "version": "1.27.0",
4
4
  "description": "",
5
5
  "main": "lib/main.js",
6
6
  "scripts": {