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.
- package/lib/config/config.d.ts +4 -0
- package/lib/engine/features/valueLabels/valueLabels.d.ts +4 -2
- package/lib/engine/features/valueLabels/valueLabels.js +54 -32
- package/lib/engine/features/valueLabels/valueLabelsHelper.d.ts +5 -3
- package/lib/engine/features/valueLabels/valueLabelsHelper.js +6 -6
- package/lib/engine/twoDimensionalNotation/bar/bar.d.ts +2 -2
- package/lib/engine/twoDimensionalNotation/bar/bar.js +10 -10
- package/lib/engine/twoDimensionalNotation/twoDimensionalManager.js +2 -2
- package/lib/model/featuresModel/valueLabelsModel/valueLabelsModel.d.ts +10 -4
- package/lib/model/featuresModel/valueLabelsModel/valueLabelsModel.js +39 -27
- package/lib/model/model.d.ts +1 -0
- package/lib/model/notations/twoDimensionalModel.js +23 -13
- package/package.json +1 -1
package/lib/config/config.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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 {
|
|
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.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
this.
|
|
33
|
-
|
|
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.
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
|
|
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
|
-
|
|
58
|
-
|
|
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.
|
|
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
|
|
2
|
+
import { TwoDimChartValueLabelsOptions } from "../../../model/model";
|
|
3
3
|
import { Scales } from "../../../engine/features/scale/scale";
|
|
4
|
-
|
|
5
|
-
|
|
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
|
|
3
|
-
|
|
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
|
|
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
|
|
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[]
|
|
25
|
-
update(block: Block, newData: MdtChartsDataRow[], scales: Scales, margin: BlockMargin, keyAxisOrient: Orient, chart: TwoDimensionalChartModel, blockSize: Size, barsAmounts: number[], keyField: Field,
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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)
|
|
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,
|
|
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
|
|
11
|
-
|
|
12
|
-
|
|
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
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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) {
|
package/lib/model/model.d.ts
CHANGED
|
@@ -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,
|
|
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: (
|
|
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: (
|
|
95
|
-
borderSize: `${(
|
|
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((
|
|
102
|
-
strokeWidth: (
|
|
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: (
|
|
110
|
-
handleX: (scaledValue) => getValueLabelX(scaledValue
|
|
111
|
-
handleY: (scaledValue) => getValueLabelY(scaledValue
|
|
112
|
-
|
|
113
|
-
|
|
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: (
|
|
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
|
});
|