mdt-charts 1.37.1 → 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.
- package/lib/engine/features/markDots/markDotsHelper.js +4 -2
- package/lib/engine/features/scale/scale.d.ts +1 -2
- package/lib/engine/features/scale/scale.js +1 -27
- package/lib/engine/features/tolltip/tooltipHelper.js +8 -6
- package/lib/engine/features/valueLabels/valueLabels.js +2 -2
- package/lib/engine/features/valueLabels/valueLabelsHelper.d.ts +1 -1
- package/lib/engine/features/valueLabels/valueLabelsHelper.js +5 -6
- package/lib/engine/twoDimensionalNotation/area/areaHelper.js +4 -4
- package/lib/engine/twoDimensionalNotation/bar/bar.d.ts +2 -2
- package/lib/engine/twoDimensionalNotation/bar/bar.js +14 -15
- package/lib/engine/twoDimensionalNotation/bar/barHelper.d.ts +3 -28
- package/lib/engine/twoDimensionalNotation/bar/barHelper.js +6 -47
- package/lib/engine/twoDimensionalNotation/dot/dotChart.js +6 -7
- package/lib/engine/twoDimensionalNotation/line/lineHelper.js +4 -4
- package/lib/engine/twoDimensionalNotation/twoDimensionalManager.js +2 -3
- package/lib/model/featuresModel/bandLikeCharts/bandLikeChartSettings.d.ts +3 -0
- package/lib/model/featuresModel/bandLikeCharts/bandLikeChartSettings.js +10 -0
- package/lib/model/featuresModel/bandLikeCharts/barChartSettingsStore.d.ts +11 -0
- package/lib/model/featuresModel/bandLikeCharts/barChartSettingsStore.js +14 -0
- package/lib/model/featuresModel/bandLikeCharts/dotChartSettingsStore.d.ts +9 -0
- package/lib/model/featuresModel/bandLikeCharts/dotChartSettingsStore.js +11 -0
- package/lib/model/featuresModel/scaleModel/scaleModel.js +2 -1
- package/lib/model/featuresModel/valueLabelsModel/valueLabelsModel.d.ts +6 -3
- package/lib/model/featuresModel/valueLabelsModel/valueLabelsModel.js +10 -5
- package/lib/model/model.d.ts +14 -3
- package/lib/model/modelInstance/canvasModel/legendCanvasModel.js +1 -1
- package/lib/model/notations/twoDimensional/styles.d.ts +1 -0
- package/lib/model/notations/twoDimensional/styles.js +11 -1
- package/lib/model/notations/twoDimensionalModel.js +22 -9
- 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.
|
|
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.
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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.
|
|
72
|
-
attributes.x2 = Math.ceil(Scale.
|
|
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.
|
|
80
|
-
attributes.y2 = Scale.
|
|
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(
|
|
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(
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
25
|
-
update(block: Block, newData: MdtChartsDataRow[], scales: Scales, margin: BlockMargin, keyAxisOrient: Orient, chart: TwoDimensionalChartModel, blockSize: Size,
|
|
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
|
|
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,
|
|
22
|
+
this.renderSegmented(block, scales, data, keyField, margin, keyAxisOrient, chart, barSettings);
|
|
24
23
|
else
|
|
25
|
-
this.renderGrouped(block, scales, data, keyField, margin, keyAxisOrient, chart,
|
|
24
|
+
this.renderGrouped(block, scales, data, keyField, margin, keyAxisOrient, chart, blockSize, barSettings);
|
|
26
25
|
}
|
|
27
|
-
update(block, newData, scales, margin, keyAxisOrient, chart, blockSize,
|
|
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,
|
|
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,
|
|
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,
|
|
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],
|
|
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,
|
|
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],
|
|
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,
|
|
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],
|
|
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,
|
|
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],
|
|
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 {
|
|
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,
|
|
42
|
-
static getStackedBarAttr(keyAxisOrient: Orient, scales: Scales, margin: BlockMargin, keyField: string, barIndex: number,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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.
|
|
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.
|
|
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
|
|
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 =
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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,
|
|
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
|
+
}
|
|
@@ -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)
|
package/lib/model/model.d.ts
CHANGED
|
@@ -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("
|
|
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
|
|
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
|
-
|
|
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
|
}
|