mdt-charts 1.20.0 → 1.21.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 +25 -0
- package/lib/engine/block/blockSvg.d.ts +1 -1
- package/lib/engine/block/blockSvg.js +1 -1
- package/lib/engine/block/defs/LinearGradientDef.d.ts +6 -0
- package/lib/engine/block/defs/LinearGradientDef.js +28 -0
- package/lib/engine/elementHighlighter/elementHighlighter.d.ts +0 -1
- package/lib/engine/elementHighlighter/elementHighlighter.js +5 -8
- package/lib/engine/elementHighlighter/selectHighlighter.js +11 -10
- package/lib/engine/features/legend/legendMarkerCreator.js +1 -1
- package/lib/engine/features/markDots/markDot.d.ts +11 -3
- package/lib/engine/features/markDots/markDot.js +21 -10
- package/lib/engine/features/tolltip/tooltip.js +5 -4
- package/lib/engine/features/valueLabels/valueLabels.d.ts +45 -0
- package/lib/engine/features/valueLabels/valueLabels.js +139 -0
- package/lib/engine/features/valueLabels/valueLabelsHelper.d.ts +6 -0
- package/lib/engine/features/valueLabels/valueLabelsHelper.js +21 -0
- package/lib/engine/features/valueLabelsCollision/valueLabelsCollision.d.ts +23 -0
- package/lib/engine/features/valueLabelsCollision/valueLabelsCollision.js +24 -0
- package/lib/engine/features/valueLabelsCollision/valueLabelsCollisionHelper.d.ts +5 -0
- package/lib/engine/features/valueLabelsCollision/valueLabelsCollisionHelper.js +47 -0
- package/lib/engine/helpers/domHelper.d.ts +1 -0
- package/lib/engine/helpers/domHelper.js +4 -0
- package/lib/engine/twoDimensionalNotation/area/area.d.ts +26 -11
- package/lib/engine/twoDimensionalNotation/area/area.js +100 -34
- package/lib/engine/twoDimensionalNotation/area/areaGenerator.d.ts +14 -0
- package/lib/engine/twoDimensionalNotation/area/areaGenerator.js +22 -0
- package/lib/engine/twoDimensionalNotation/area/areaHelper.d.ts +7 -7
- package/lib/engine/twoDimensionalNotation/area/areaHelper.js +30 -31
- package/lib/engine/twoDimensionalNotation/bar/barHelper.js +1 -1
- package/lib/engine/twoDimensionalNotation/bar/stackedData/dataStacker.d.ts +4 -2
- package/lib/engine/twoDimensionalNotation/bar/stackedData/dataStacker.js +2 -5
- package/lib/engine/twoDimensionalNotation/line/line.d.ts +2 -7
- package/lib/engine/twoDimensionalNotation/line/line.js +6 -6
- package/lib/engine/twoDimensionalNotation/line/lineGenerator.d.ts +4 -7
- package/lib/engine/twoDimensionalNotation/line/lineGenerator.js +2 -16
- package/lib/engine/twoDimensionalNotation/line/lineHelper.d.ts +4 -13
- package/lib/engine/twoDimensionalNotation/line/lineHelper.js +22 -10
- package/lib/engine/twoDimensionalNotation/lineLike/generatorFactory/lineLikeGeneratorFactory.d.ts +12 -0
- package/lib/engine/twoDimensionalNotation/lineLike/generatorFactory/lineLikeGeneratorFactory.js +1 -0
- package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorCurveMiddleware.d.ts +14 -0
- package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorCurveMiddleware.js +21 -0
- package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorDefineMiddleware.d.ts +20 -0
- package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorDefineMiddleware.js +9 -0
- package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorMiddleware.d.ts +5 -0
- package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorMiddleware.js +1 -0
- package/lib/engine/twoDimensionalNotation/twoDimensionalManager.d.ts +2 -0
- package/lib/engine/twoDimensionalNotation/twoDimensionalManager.js +26 -3
- package/lib/model/chartStyleModel/twoDimensionalChartStyleModel.js +5 -1
- package/lib/model/featuresModel/axisModel.js +3 -1
- package/lib/model/featuresModel/valueLabelsModel/valueLabelsModel.d.ts +9 -0
- package/lib/model/featuresModel/valueLabelsModel/valueLabelsModel.js +33 -0
- package/lib/model/helpers/modelHelper.d.ts +1 -0
- package/lib/model/helpers/modelHelper.js +3 -2
- package/lib/model/helpers/twoDimensionalModelHelper.d.ts +8 -0
- package/lib/model/helpers/twoDimensionalModelHelper.js +56 -0
- package/lib/model/model.d.ts +66 -6
- package/lib/model/modelInstance/configReader.d.ts +2 -1
- package/lib/model/modelInstance/configReader.js +17 -0
- package/lib/model/notations/polar/polarModel.js +2 -1
- package/lib/model/notations/twoDimensional/styles.d.ts +3 -1
- package/lib/model/notations/twoDimensional/styles.js +20 -0
- package/lib/model/notations/twoDimensionalModel.js +30 -25
- package/lib/style/charts-main.css +17 -2
- package/lib/style/charts-main.less +17 -2
- package/package.json +2 -2
- package/lib/style/css-vars.css +0 -3
- /package/lib/engine/block/{defs.d.ts → defs/hatchPattern.d.ts} +0 -0
- /package/lib/engine/block/{defs.js → defs/hatchPattern.js} +0 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export class ValueLabelsCollisionHelper {
|
|
2
|
+
static calculateValueLabelsVisibility(elements) {
|
|
3
|
+
const sortedLabels = elements.sort((label1, label2) => label1.boundingClientRect.x - label2.boundingClientRect.x);
|
|
4
|
+
const activeLabels = [];
|
|
5
|
+
const labelsVisibility = new Map();
|
|
6
|
+
elements.forEach(label => {
|
|
7
|
+
labelsVisibility.set(label.index, { index: label.index, isVisible: true });
|
|
8
|
+
});
|
|
9
|
+
sortedLabels.forEach(currentLabel => {
|
|
10
|
+
for (let i = activeLabels.length - 1; i >= 0; i--) {
|
|
11
|
+
const activeLabel = activeLabels[i];
|
|
12
|
+
if (activeLabel.boundingClientRect.x + activeLabel.boundingClientRect.width < currentLabel.boundingClientRect.x) {
|
|
13
|
+
activeLabels.splice(i, 1);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
for (const activeLabel of activeLabels) {
|
|
17
|
+
if (this.isOverlapping(currentLabel.boundingClientRect, activeLabel.boundingClientRect)) {
|
|
18
|
+
if (currentLabel.boundingClientRect.x > activeLabel.boundingClientRect.x) {
|
|
19
|
+
labelsVisibility.get(currentLabel.index).isVisible = false;
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
else if (currentLabel.boundingClientRect.x === activeLabel.boundingClientRect.x) {
|
|
23
|
+
if (currentLabel.boundingClientRect.y > activeLabel.boundingClientRect.y) {
|
|
24
|
+
labelsVisibility.get(currentLabel.index).isVisible = false;
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
else
|
|
28
|
+
labelsVisibility.get(activeLabel.index).isVisible = false;
|
|
29
|
+
}
|
|
30
|
+
else
|
|
31
|
+
labelsVisibility.get(activeLabel.index).isVisible = false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (labelsVisibility.get(currentLabel.index).isVisible) {
|
|
35
|
+
activeLabels.push(currentLabel);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
return labelsVisibility;
|
|
39
|
+
}
|
|
40
|
+
static isOverlapping(rect1, rect2) {
|
|
41
|
+
return !(rect1.x + rect1.width < rect2.x ||
|
|
42
|
+
rect1.x > rect2.x + rect2.width ||
|
|
43
|
+
rect1.y + rect1.height < rect2.y ||
|
|
44
|
+
rect1.y > rect2.y + rect2.height);
|
|
45
|
+
}
|
|
46
|
+
;
|
|
47
|
+
}
|
|
@@ -25,6 +25,7 @@ export declare class DomHelper {
|
|
|
25
25
|
* @returns Выборка по ключам
|
|
26
26
|
*/
|
|
27
27
|
static getChartElementsByKeys<T extends BaseType>(initialSelection: Selection<T, MdtChartsDataRow, BaseType, unknown>, dataWrapped: boolean, keyFieldName: string, keyValues: string[], condition?: SelectionCondition): Selection<T, any, BaseType, unknown>;
|
|
28
|
+
static setChartGradientStyle(element: Selection<BaseType, unknown, BaseType, unknown>, chartIndex: number, valueIndex: number): void;
|
|
28
29
|
private static setChartOpacity;
|
|
29
30
|
}
|
|
30
31
|
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { MarkDot } from "../features/markDots/markDot";
|
|
2
2
|
import { Bar } from "../twoDimensionalNotation/bar/bar";
|
|
3
|
+
import { getGradientId } from "../../model/notations/twoDimensional/styles";
|
|
3
4
|
export var SelectionCondition;
|
|
4
5
|
(function (SelectionCondition) {
|
|
5
6
|
SelectionCondition[SelectionCondition["Include"] = 0] = "Include";
|
|
@@ -62,6 +63,9 @@ export class DomHelper {
|
|
|
62
63
|
return condition === SelectionCondition.Exclude ? i === -1 : i !== -1;
|
|
63
64
|
});
|
|
64
65
|
}
|
|
66
|
+
static setChartGradientStyle(element, chartIndex, valueIndex) {
|
|
67
|
+
element.style('fill', `url(#${getGradientId(chartIndex, valueIndex)})`);
|
|
68
|
+
}
|
|
65
69
|
static setChartOpacity(elements, opacity) {
|
|
66
70
|
elements.attr('opacity', opacity);
|
|
67
71
|
}
|
|
@@ -1,17 +1,32 @@
|
|
|
1
|
-
import { BlockMargin, Field, Orient, TwoDimensionalChartModel } from "../../../model/model";
|
|
1
|
+
import { BlockMargin, Field, LineLikeChartSettings, Orient, TwoDimensionalChartModel } from "../../../model/model";
|
|
2
2
|
import { Scales } from "../../features/scale/scale";
|
|
3
3
|
import { Block } from "../../block/block";
|
|
4
4
|
import { MdtChartsDataRow, Size } from '../../../config/config';
|
|
5
|
+
interface AreaOptions {
|
|
6
|
+
staticSettings: LineLikeChartSettings;
|
|
7
|
+
}
|
|
5
8
|
export declare class Area {
|
|
9
|
+
private readonly options;
|
|
6
10
|
static readonly areaChartClass = "area";
|
|
7
|
-
static
|
|
8
|
-
static
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
private
|
|
14
|
-
private
|
|
15
|
-
private
|
|
16
|
-
private
|
|
11
|
+
static readonly areaBorderLineClass = "area-border-line";
|
|
12
|
+
static get(options: AreaOptions): Area;
|
|
13
|
+
constructor(options: AreaOptions);
|
|
14
|
+
render(block: Block, scales: Scales, data: MdtChartsDataRow[], keyField: Field, margin: BlockMargin, keyAxisOrient: Orient, chart: TwoDimensionalChartModel, blockSize: Size): void;
|
|
15
|
+
update(block: Block, scales: Scales, newData: MdtChartsDataRow[], keyField: Field, margin: BlockMargin, chart: TwoDimensionalChartModel, keyAxisOrient: Orient, blockSize: Size): Promise<any>[];
|
|
16
|
+
updateColors(block: Block, chart: TwoDimensionalChartModel): void;
|
|
17
|
+
private renderGrouped;
|
|
18
|
+
private renderSegmented;
|
|
19
|
+
private updateGrouped;
|
|
20
|
+
private updateSegmented;
|
|
21
|
+
private updateGroupedPath;
|
|
22
|
+
private updateSegmentedPath;
|
|
23
|
+
private setSegmentColor;
|
|
24
|
+
private setChartFillStyle;
|
|
25
|
+
private createAreaGeneratorFactory;
|
|
26
|
+
private createLineGeneratorFactory;
|
|
27
|
+
private renderArea;
|
|
28
|
+
private renderBorderLine;
|
|
29
|
+
private updateArea;
|
|
30
|
+
private updateBorderLine;
|
|
17
31
|
}
|
|
32
|
+
export {};
|
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
import { select } from 'd3-selection';
|
|
2
2
|
import { MarkDot } from "../../features/markDots/markDot";
|
|
3
|
-
import {
|
|
3
|
+
import { AreaGeneratorFactory } from './areaHelper';
|
|
4
4
|
import { DomHelper } from '../../helpers/domHelper';
|
|
5
5
|
import { Helper } from '../../helpers/helper';
|
|
6
6
|
import { getStackedDataWithOwn } from '../bar/stackedData/dataStacker';
|
|
7
|
+
import { LineGeneratorFactory } from "../../../engine/twoDimensionalNotation/line/lineHelper";
|
|
8
|
+
import { Line } from "../../../engine/twoDimensionalNotation/line/line";
|
|
7
9
|
export class Area {
|
|
8
|
-
|
|
10
|
+
constructor(options) {
|
|
11
|
+
this.options = options;
|
|
12
|
+
}
|
|
13
|
+
static get(options) {
|
|
14
|
+
return new Area(options);
|
|
15
|
+
}
|
|
16
|
+
render(block, scales, data, keyField, margin, keyAxisOrient, chart, blockSize) {
|
|
9
17
|
if (chart.isSegmented)
|
|
10
18
|
this.renderSegmented(block, scales, data, keyField, margin, keyAxisOrient, chart);
|
|
11
19
|
else
|
|
12
|
-
this.renderGrouped(block, scales, data, keyField, margin, keyAxisOrient, chart
|
|
20
|
+
this.renderGrouped(block, scales, data, keyField, margin, keyAxisOrient, chart);
|
|
13
21
|
}
|
|
14
|
-
|
|
22
|
+
update(block, scales, newData, keyField, margin, chart, keyAxisOrient, blockSize) {
|
|
15
23
|
let promises;
|
|
16
24
|
if (chart.isSegmented) {
|
|
17
25
|
promises = this.updateSegmented(block, scales, newData, keyField, margin, chart, keyAxisOrient);
|
|
@@ -21,38 +29,42 @@ export class Area {
|
|
|
21
29
|
}
|
|
22
30
|
return promises;
|
|
23
31
|
}
|
|
24
|
-
|
|
32
|
+
updateColors(block, chart) {
|
|
25
33
|
chart.data.valueFields.forEach((_vf, valueIndex) => {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
34
|
+
const chartGroup = block.svg.getChartGroup(chart.index);
|
|
35
|
+
const areaPath = chartGroup
|
|
36
|
+
.select(`.${Area.areaChartClass}${Helper.getCssClassesLine(chart.cssClasses)}.chart-element-${valueIndex}`);
|
|
37
|
+
this.setChartFillStyle(chart, areaPath, valueIndex);
|
|
38
|
+
if (chart.areaViewOptions.borderLine.on) {
|
|
39
|
+
const borderLinePath = chartGroup
|
|
40
|
+
.select(`.${Area.areaBorderLineClass}${Helper.getCssClassesLine(chart.cssClasses)}.chart-element-${valueIndex}`);
|
|
41
|
+
DomHelper.setChartElementColor(borderLinePath, chart.style.elementColors, valueIndex, 'stroke');
|
|
42
|
+
}
|
|
29
43
|
MarkDot.updateColors(block, chart, valueIndex);
|
|
30
44
|
});
|
|
31
45
|
}
|
|
32
|
-
|
|
46
|
+
renderGrouped(block, scales, data, keyField, margin, keyAxisOrient, chart) {
|
|
47
|
+
const areaGeneratorFactory = this.createAreaGeneratorFactory(chart, scales, margin, keyAxisOrient, keyField);
|
|
48
|
+
const lineGeneratorFactory = chart.areaViewOptions.borderLine.on
|
|
49
|
+
&& this.createLineGeneratorFactory(chart, scales, margin, keyAxisOrient, keyField);
|
|
33
50
|
chart.data.valueFields.forEach((field, valueIndex) => {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
.
|
|
37
|
-
.attr('d', area(data))
|
|
38
|
-
.attr('class', this.areaChartClass)
|
|
39
|
-
.style('clip-path', `url(#${block.svg.getClipPathId()})`)
|
|
40
|
-
.style('pointer-events', 'none');
|
|
41
|
-
DomHelper.setCssClasses(path, Helper.getCssClassesWithElementIndex(chart.cssClasses, valueIndex));
|
|
42
|
-
DomHelper.setChartStyle(path, chart.style, valueIndex, 'fill');
|
|
51
|
+
this.renderArea(areaGeneratorFactory, block, chart, data, field, valueIndex);
|
|
52
|
+
if (lineGeneratorFactory)
|
|
53
|
+
this.renderBorderLine(lineGeneratorFactory, block, chart, data, field, valueIndex);
|
|
43
54
|
MarkDot.render(block, data, keyAxisOrient, scales, margin, keyField.name, valueIndex, field.name, chart);
|
|
44
55
|
});
|
|
45
56
|
}
|
|
46
|
-
|
|
57
|
+
renderSegmented(block, scales, data, keyField, margin, keyAxisOrient, chart) {
|
|
47
58
|
const stackedData = getStackedDataWithOwn(data, chart.data.valueFields.map(field => field.name));
|
|
48
|
-
const
|
|
59
|
+
const areaGeneratorFactory = this.createAreaGeneratorFactory(chart, scales, margin, keyAxisOrient, keyField);
|
|
60
|
+
const areaGenerator = areaGeneratorFactory.getSegmentedAreaGenerator();
|
|
49
61
|
const areas = block.svg.getChartGroup(chart.index)
|
|
50
|
-
.selectAll(`.${
|
|
62
|
+
.selectAll(`.${Area.areaChartClass}${Helper.getCssClassesLine(chart.cssClasses)}`)
|
|
51
63
|
.data(stackedData)
|
|
52
64
|
.enter()
|
|
53
65
|
.append('path')
|
|
54
66
|
.attr('d', d => areaGenerator(d))
|
|
55
|
-
.attr('class',
|
|
67
|
+
.attr('class', Area.areaChartClass)
|
|
56
68
|
.style('clip-path', `url(#${block.svg.getClipPathId()})`)
|
|
57
69
|
.style('pointer-events', 'none');
|
|
58
70
|
areas.each(function (d, i) {
|
|
@@ -63,23 +75,29 @@ export class Area {
|
|
|
63
75
|
MarkDot.render(block, dataset, keyAxisOrient, scales, margin, keyField.name, index, '1', chart);
|
|
64
76
|
});
|
|
65
77
|
}
|
|
66
|
-
|
|
78
|
+
updateGrouped(block, scales, newData, keyField, margin, chart, keyAxisOrient, blockSize) {
|
|
67
79
|
const promises = [];
|
|
80
|
+
const areaGeneratorFactory = this.createAreaGeneratorFactory(chart, scales, margin, keyAxisOrient, keyField);
|
|
81
|
+
const lineGeneratorFactory = chart.areaViewOptions.borderLine.on
|
|
82
|
+
&& this.createLineGeneratorFactory(chart, scales, margin, keyAxisOrient, keyField);
|
|
68
83
|
chart.data.valueFields.forEach((field, valueIndex) => {
|
|
69
|
-
const
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
84
|
+
const chartGroup = block.svg.getChartGroup(chart.index);
|
|
85
|
+
const areaProm = this.updateArea(areaGeneratorFactory, chartGroup, block, field, chart, newData, valueIndex);
|
|
86
|
+
promises.push(areaProm);
|
|
87
|
+
if (lineGeneratorFactory) {
|
|
88
|
+
const lineProm = this.updateBorderLine(lineGeneratorFactory, chartGroup, block, field, chart, newData, valueIndex);
|
|
89
|
+
promises.push(lineProm);
|
|
90
|
+
}
|
|
74
91
|
MarkDot.update(block, newData, keyAxisOrient, scales, margin, keyField.name, valueIndex, field.name, chart);
|
|
75
92
|
});
|
|
76
93
|
return promises;
|
|
77
94
|
}
|
|
78
|
-
|
|
95
|
+
updateSegmented(block, scales, newData, keyField, margin, chart, keyAxisOrient) {
|
|
79
96
|
const stackedData = getStackedDataWithOwn(newData, chart.data.valueFields.map(field => field.name));
|
|
80
|
-
const
|
|
97
|
+
const generatorFactory = this.createAreaGeneratorFactory(chart, scales, margin, keyAxisOrient, keyField);
|
|
98
|
+
const areaGenerator = generatorFactory.getSegmentedAreaGenerator();
|
|
81
99
|
const areas = block.svg.getChartGroup(chart.index)
|
|
82
|
-
.selectAll(`path.${
|
|
100
|
+
.selectAll(`path.${Area.areaChartClass}${Helper.getCssClassesLine(chart.cssClasses)}`)
|
|
83
101
|
.data(stackedData);
|
|
84
102
|
const prom = this.updateSegmentedPath(block, areas, areaGenerator);
|
|
85
103
|
areas.each((dataset, index) => {
|
|
@@ -88,7 +106,7 @@ export class Area {
|
|
|
88
106
|
});
|
|
89
107
|
return [prom];
|
|
90
108
|
}
|
|
91
|
-
|
|
109
|
+
updateGroupedPath(block, areaObject, areaGenerator, newData) {
|
|
92
110
|
return new Promise(resolve => {
|
|
93
111
|
if (areaObject.size() === 0) {
|
|
94
112
|
resolve('');
|
|
@@ -106,7 +124,7 @@ export class Area {
|
|
|
106
124
|
resolve('');
|
|
107
125
|
});
|
|
108
126
|
}
|
|
109
|
-
|
|
127
|
+
updateSegmentedPath(block, areasObjects, areaGenerator) {
|
|
110
128
|
return new Promise(resolve => {
|
|
111
129
|
if (areasObjects.size() === 0) {
|
|
112
130
|
resolve('');
|
|
@@ -124,8 +142,56 @@ export class Area {
|
|
|
124
142
|
resolve('');
|
|
125
143
|
});
|
|
126
144
|
}
|
|
127
|
-
|
|
145
|
+
setSegmentColor(segments, colorPalette) {
|
|
128
146
|
segments.style('fill', (d, i) => colorPalette[i % colorPalette.length]);
|
|
129
147
|
}
|
|
148
|
+
setChartFillStyle(chart, path, valueIndex) {
|
|
149
|
+
if (chart.areaViewOptions.fill.type === 'gradient')
|
|
150
|
+
DomHelper.setChartGradientStyle(path, chart.index, valueIndex);
|
|
151
|
+
else
|
|
152
|
+
DomHelper.setChartStyle(path, chart.style, valueIndex, 'fill');
|
|
153
|
+
}
|
|
154
|
+
createAreaGeneratorFactory(chart, scales, margin, keyAxisOrient, keyField) {
|
|
155
|
+
return new AreaGeneratorFactory({ keyAxisOrient, scales, keyFieldName: keyField.name, margin, shouldRender: chart.lineLikeViewOptions.renderForKey, curve: this.options.staticSettings.shape.curve.type });
|
|
156
|
+
}
|
|
157
|
+
createLineGeneratorFactory(chart, scales, margin, keyAxisOrient, keyField) {
|
|
158
|
+
return new LineGeneratorFactory({ keyAxisOrient, scales, keyFieldName: keyField.name, margin, shouldRender: chart.lineLikeViewOptions.renderForKey, curve: this.options.staticSettings.shape.curve.type });
|
|
159
|
+
}
|
|
160
|
+
renderArea(areaGeneratorFactory, block, chart, data, field, valueIndex) {
|
|
161
|
+
const area = areaGeneratorFactory.getAreaGenerator(field.name);
|
|
162
|
+
const path = block.svg.getChartGroup(chart.index)
|
|
163
|
+
.append('path')
|
|
164
|
+
.attr('d', area(data))
|
|
165
|
+
.attr('class', Area.areaChartClass)
|
|
166
|
+
.style('clip-path', `url(#${block.svg.getClipPathId()})`)
|
|
167
|
+
.style('pointer-events', 'none');
|
|
168
|
+
DomHelper.setCssClasses(path, Helper.getCssClassesWithElementIndex(chart.cssClasses, valueIndex));
|
|
169
|
+
this.setChartFillStyle(chart, path, valueIndex);
|
|
170
|
+
}
|
|
171
|
+
renderBorderLine(lineGeneratorFactory, block, chart, data, field, valueIndex) {
|
|
172
|
+
const lineGenerator = lineGeneratorFactory.getLineGenerator(field.name);
|
|
173
|
+
const linePath = block.svg.getChartGroup(chart.index)
|
|
174
|
+
.append('path')
|
|
175
|
+
.attr('d', lineGenerator(data))
|
|
176
|
+
.attr('class', `${Area.areaBorderLineClass}`)
|
|
177
|
+
.style('fill', 'none')
|
|
178
|
+
.style('clip-path', `url(#${block.svg.getClipPathId()})`)
|
|
179
|
+
.style('pointer-events', 'none');
|
|
180
|
+
DomHelper.setCssClasses(linePath, Helper.getCssClassesWithElementIndex(chart.cssClasses, valueIndex));
|
|
181
|
+
DomHelper.setChartStyle(linePath, chart.areaViewOptions.borderLine.colorStyle, valueIndex, 'stroke');
|
|
182
|
+
}
|
|
183
|
+
updateArea(areaGeneratorFactory, chartGroup, block, field, chart, newData, valueIndex) {
|
|
184
|
+
const areaGenerator = areaGeneratorFactory.getAreaGenerator(field.name);
|
|
185
|
+
const areaObject = chartGroup
|
|
186
|
+
.select(`.${Area.areaChartClass}${Helper.getCssClassesLine(chart.cssClasses)}.chart-element-${valueIndex}`);
|
|
187
|
+
return this.updateGroupedPath(block, areaObject, areaGenerator, newData);
|
|
188
|
+
}
|
|
189
|
+
updateBorderLine(lineGeneratorFactory, chartGroup, block, field, chart, newData, valueIndex) {
|
|
190
|
+
const borderLineGenerator = lineGeneratorFactory.getLineGenerator(field.name);
|
|
191
|
+
const borderLineObject = chartGroup
|
|
192
|
+
.select(`.${Area.areaBorderLineClass}${Helper.getCssClassesLine(chart.cssClasses)}.chart-element-${valueIndex}`);
|
|
193
|
+
return Line.updateGroupedPath(block, borderLineObject, borderLineGenerator, newData);
|
|
194
|
+
}
|
|
130
195
|
}
|
|
131
196
|
Area.areaChartClass = 'area';
|
|
197
|
+
Area.areaBorderLineClass = 'area-border-line';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Area as IArea } from "d3-shape";
|
|
2
|
+
import { LineLikeGeneratorMiddleware } from "../lineLike/generatorMiddleware/lineLikeGeneratorMiddleware";
|
|
3
|
+
import { MdtChartsDataRow } from "../../../config/config";
|
|
4
|
+
import { CoordinateGetter } from "../lineLike/generatorFactory/lineLikeGeneratorFactory";
|
|
5
|
+
interface AreaGeneratorOptions {
|
|
6
|
+
middlewares: LineLikeGeneratorMiddleware[];
|
|
7
|
+
}
|
|
8
|
+
export declare class AreaGenerator {
|
|
9
|
+
private readonly options;
|
|
10
|
+
constructor(options: AreaGeneratorOptions);
|
|
11
|
+
getVertical(xValue: CoordinateGetter, y0Value: CoordinateGetter, y1Value: CoordinateGetter): IArea<MdtChartsDataRow>;
|
|
12
|
+
getHorizontal(x0Value: CoordinateGetter, x1Value: CoordinateGetter, yValue: CoordinateGetter): IArea<MdtChartsDataRow>;
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { area } from "d3-shape";
|
|
2
|
+
export class AreaGenerator {
|
|
3
|
+
constructor(options) {
|
|
4
|
+
this.options = options;
|
|
5
|
+
}
|
|
6
|
+
getVertical(xValue, y0Value, y1Value) {
|
|
7
|
+
const generator = area()
|
|
8
|
+
.x(xValue)
|
|
9
|
+
.y0(y0Value)
|
|
10
|
+
.y1(y1Value);
|
|
11
|
+
this.options.middlewares.forEach(middleware => middleware.handle(generator));
|
|
12
|
+
return generator;
|
|
13
|
+
}
|
|
14
|
+
getHorizontal(x0Value, x1Value, yValue) {
|
|
15
|
+
const generator = area()
|
|
16
|
+
.x0(x0Value)
|
|
17
|
+
.x1(x1Value)
|
|
18
|
+
.y(yValue);
|
|
19
|
+
this.options.middlewares.forEach(middleware => middleware.handle(generator));
|
|
20
|
+
return generator;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Area as IArea } from 'd3-shape';
|
|
2
|
-
import { MdtChartsDataRow
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
import { MdtChartsDataRow } from '../../../config/config';
|
|
3
|
+
import { LineLikeGeneratorFactoryOptions } from '../lineLike/generatorFactory/lineLikeGeneratorFactory';
|
|
4
|
+
export declare class AreaGeneratorFactory {
|
|
5
|
+
private readonly options;
|
|
6
|
+
constructor(options: LineLikeGeneratorFactoryOptions);
|
|
7
|
+
getAreaGenerator(valueFieldName: string): IArea<MdtChartsDataRow>;
|
|
8
|
+
getSegmentedAreaGenerator(): IArea<MdtChartsDataRow>;
|
|
9
9
|
}
|
|
@@ -1,40 +1,39 @@
|
|
|
1
|
-
import { area } from 'd3-shape';
|
|
2
1
|
import { Scale } from "../../features/scale/scale";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
.y1(d => scales.value(d[valueFieldName]) + margin.top);
|
|
10
|
-
if (keyAxisOrient === 'left' || keyAxisOrient === 'right')
|
|
11
|
-
return area()
|
|
12
|
-
.x0(d => scales.value(0) + margin.left)
|
|
13
|
-
.x1(d => scales.value(d[valueFieldName]) + margin.left)
|
|
14
|
-
.y(d => Scale.getScaledValue(scales.key, d[keyFieldName]) + margin.top);
|
|
2
|
+
import { LineLikeGeneratorDefinedMiddleware } from '../lineLike/generatorMiddleware/lineLikeGeneratorDefineMiddleware';
|
|
3
|
+
import { AreaGenerator } from './areaGenerator';
|
|
4
|
+
import { LineLikeGeneratorCurveMiddleware } from '../lineLike/generatorMiddleware/lineLikeGeneratorCurveMiddleware';
|
|
5
|
+
export class AreaGeneratorFactory {
|
|
6
|
+
constructor(options) {
|
|
7
|
+
this.options = options;
|
|
15
8
|
}
|
|
16
|
-
|
|
9
|
+
getAreaGenerator(valueFieldName) {
|
|
10
|
+
const { keyAxisOrient, scales, keyFieldName, margin, shouldRender } = this.options;
|
|
11
|
+
const generator = new AreaGenerator({
|
|
12
|
+
middlewares: [
|
|
13
|
+
new LineLikeGeneratorCurveMiddleware({ curve: this.options.curve }),
|
|
14
|
+
new LineLikeGeneratorDefinedMiddleware({ definedFn: shouldRender, valueFieldNameGetter: () => valueFieldName, dataRowGetter: (d) => d })
|
|
15
|
+
]
|
|
16
|
+
});
|
|
17
17
|
if (keyAxisOrient === 'bottom' || keyAxisOrient === 'top') {
|
|
18
|
-
return
|
|
19
|
-
.x(d => Scale.getScaledValue(scales.key, d.data[keyFieldName]) + margin.left)
|
|
20
|
-
.y0(d => scales.value(d[0]) + margin.top)
|
|
21
|
-
.y1(d => scales.value(d[1]) + margin.top);
|
|
18
|
+
return generator.getVertical(d => Scale.getScaledValue(scales.key, d[keyFieldName]) + margin.left, d => scales.value(0) + margin.top, d => scales.value(d[valueFieldName]) + margin.top);
|
|
22
19
|
}
|
|
23
20
|
if (keyAxisOrient === 'left' || keyAxisOrient === 'right') {
|
|
24
|
-
return
|
|
25
|
-
.x0(d => scales.value(d[0]) + margin.left)
|
|
26
|
-
.x1(d => scales.value(d[1]) + margin.left)
|
|
27
|
-
.y(d => Scale.getScaledValue(scales.key, d.data[keyFieldName]) + margin.top);
|
|
21
|
+
return generator.getHorizontal(d => scales.value(0) + margin.left, d => scales.value(d[valueFieldName]) + margin.left, d => Scale.getScaledValue(scales.key, d[keyFieldName]) + margin.top);
|
|
28
22
|
}
|
|
29
23
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
24
|
+
getSegmentedAreaGenerator() {
|
|
25
|
+
const { keyAxisOrient, scales, margin, keyFieldName, shouldRender } = this.options;
|
|
26
|
+
const generator = new AreaGenerator({
|
|
27
|
+
middlewares: [
|
|
28
|
+
new LineLikeGeneratorCurveMiddleware({ curve: this.options.curve }),
|
|
29
|
+
new LineLikeGeneratorDefinedMiddleware({ definedFn: shouldRender, valueFieldNameGetter: (d) => d.fieldName, dataRowGetter: (d) => d.data })
|
|
30
|
+
]
|
|
31
|
+
});
|
|
32
|
+
if (keyAxisOrient === 'bottom' || keyAxisOrient === 'top') {
|
|
33
|
+
return generator.getVertical(d => Scale.getScaledValue(scales.key, d.data[keyFieldName]) + margin.left, d => scales.value(d[0]) + margin.top, d => scales.value(d[1]) + margin.top);
|
|
34
|
+
}
|
|
35
|
+
if (keyAxisOrient === 'left' || keyAxisOrient === 'right') {
|
|
36
|
+
return generator.getHorizontal(d => scales.value(d[0]) + margin.left, d => scales.value(d[1]) + margin.left, d => Scale.getScaledValue(scales.key, d.data[keyFieldName]) + margin.top);
|
|
37
|
+
}
|
|
39
38
|
}
|
|
40
39
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Scale } from "../../features/scale/scale";
|
|
2
2
|
import { Helper } from "../../helpers/helper";
|
|
3
|
-
import { HatchPatternDef } from "../../block/defs";
|
|
3
|
+
import { HatchPatternDef } from "../../block/defs/hatchPattern";
|
|
4
4
|
export class BarHelper {
|
|
5
5
|
static getGroupedBarAttrs(keyAxisOrient, scales, margin, keyField, valueFieldName, blockSize, barIndex, barsAmount, barSettings) {
|
|
6
6
|
const attrs = {
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { MdtChartsDataRow } from "../../../../config/config";
|
|
2
|
-
export interface
|
|
2
|
+
export interface SegmentWithFieldName {
|
|
3
|
+
fieldName: string;
|
|
4
|
+
}
|
|
5
|
+
export interface StackedDataRow extends SegmentWithFieldName {
|
|
3
6
|
0: number;
|
|
4
7
|
1: number;
|
|
5
8
|
data: MdtChartsDataRow;
|
|
@@ -10,4 +13,3 @@ export declare class DataStacker {
|
|
|
10
13
|
getStackedData(rawData: MdtChartsDataRow[], valueFields: string[]): StackedDataFull;
|
|
11
14
|
}
|
|
12
15
|
export declare function getStackedDataWithOwn(rawData: MdtChartsDataRow[], valueFields: string[]): StackedDataFull;
|
|
13
|
-
export declare function getStackedDataWithD3(rawData: MdtChartsDataRow[], valueFields: string[]): StackedDataFull;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { stack } from "d3-shape";
|
|
2
1
|
import { DataStackerService } from "./dataStackerService";
|
|
3
2
|
export class DataStacker {
|
|
4
3
|
constructor() {
|
|
@@ -15,7 +14,8 @@ export class DataStacker {
|
|
|
15
14
|
fieldStack.push({
|
|
16
15
|
"0": value0,
|
|
17
16
|
"1": value1,
|
|
18
|
-
data: dataRow
|
|
17
|
+
data: dataRow,
|
|
18
|
+
fieldName: vField
|
|
19
19
|
});
|
|
20
20
|
});
|
|
21
21
|
stackedData.push(fieldStack);
|
|
@@ -27,6 +27,3 @@ export function getStackedDataWithOwn(rawData, valueFields) {
|
|
|
27
27
|
const stacker = new DataStacker();
|
|
28
28
|
return stacker.getStackedData(rawData, valueFields);
|
|
29
29
|
}
|
|
30
|
-
export function getStackedDataWithD3(rawData, valueFields) {
|
|
31
|
-
return stack().keys(valueFields)(rawData);
|
|
32
|
-
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Line as ILine } from 'd3-shape';
|
|
2
2
|
import { BaseType, Selection } from 'd3-selection';
|
|
3
3
|
import { BlockMargin, Field, LineLikeChartSettings, Orient, TwoDimensionalChartModel } from "../../../model/model";
|
|
4
4
|
import { Scales } from "../../features/scale/scale";
|
|
@@ -8,11 +8,6 @@ import { Pipeline } from '../../helpers/pipeline/Pipeline';
|
|
|
8
8
|
interface LineChartOptions {
|
|
9
9
|
staticSettings: LineLikeChartSettings;
|
|
10
10
|
}
|
|
11
|
-
export interface Segment extends SeriesPoint<{
|
|
12
|
-
[p: string]: number;
|
|
13
|
-
}> {
|
|
14
|
-
fieldName: string;
|
|
15
|
-
}
|
|
16
11
|
export declare class Line {
|
|
17
12
|
private options;
|
|
18
13
|
static readonly lineChartClass = "line";
|
|
@@ -27,7 +22,7 @@ export declare class Line {
|
|
|
27
22
|
private renderSegmented;
|
|
28
23
|
private updateGrouped;
|
|
29
24
|
private updateSegmented;
|
|
30
|
-
|
|
25
|
+
static updateGroupedPath(block: Block, lineObject: Selection<BaseType, any, BaseType, any>, lineGenerator: ILine<MdtChartsDataRow>, newData: MdtChartsDataRow[]): Promise<any>;
|
|
31
26
|
private updateSegmentedPath;
|
|
32
27
|
private setSegmentColor;
|
|
33
28
|
}
|
|
@@ -39,7 +39,7 @@ export class Line {
|
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
41
|
renderGrouped(block, scales, data, keyField, margin, keyAxisOrient, chart) {
|
|
42
|
-
const generatorFactory = new LineGeneratorFactory({ keyAxisOrient, scales, keyFieldName: keyField.name, margin, curve: this.options.staticSettings.shape.curve.type,
|
|
42
|
+
const generatorFactory = new LineGeneratorFactory({ keyAxisOrient, scales, keyFieldName: keyField.name, margin, curve: this.options.staticSettings.shape.curve.type, shouldRender: chart.lineLikeViewOptions.renderForKey });
|
|
43
43
|
chart.data.valueFields.forEach((valueField, valueIndex) => {
|
|
44
44
|
const lineGenerator = generatorFactory.getLineGenerator(valueField.name);
|
|
45
45
|
let path = block.svg.getChartGroup(chart.index)
|
|
@@ -57,7 +57,7 @@ export class Line {
|
|
|
57
57
|
}
|
|
58
58
|
renderSegmented(block, scales, data, keyField, margin, keyAxisOrient, chart) {
|
|
59
59
|
let stackedData = getStackedData(data, chart);
|
|
60
|
-
const generatorFactory = new LineGeneratorFactory({ keyAxisOrient, scales, keyFieldName: keyField.name, margin, curve: this.options.staticSettings.shape.curve.type,
|
|
60
|
+
const generatorFactory = new LineGeneratorFactory({ keyAxisOrient, scales, keyFieldName: keyField.name, margin, curve: this.options.staticSettings.shape.curve.type, shouldRender: chart.lineLikeViewOptions.renderForKey });
|
|
61
61
|
const lineGenerator = generatorFactory.getSegmentedLineGenerator();
|
|
62
62
|
let lines = block.svg.getChartGroup(chart.index)
|
|
63
63
|
.selectAll(`.${this.lineChartClass}${Helper.getCssClassesLine(chart.cssClasses)}`)
|
|
@@ -80,12 +80,12 @@ export class Line {
|
|
|
80
80
|
}
|
|
81
81
|
updateGrouped(block, scales, newData, keyField, margin, keyAxisOrient, chart) {
|
|
82
82
|
const promises = [];
|
|
83
|
-
const generatorFactory = new LineGeneratorFactory({ keyAxisOrient, scales, keyFieldName: keyField.name, margin, curve: this.options.staticSettings.shape.curve.type,
|
|
83
|
+
const generatorFactory = new LineGeneratorFactory({ keyAxisOrient, scales, keyFieldName: keyField.name, margin, curve: this.options.staticSettings.shape.curve.type, shouldRender: chart.lineLikeViewOptions.renderForKey });
|
|
84
84
|
chart.data.valueFields.forEach((valueField, valueFieldIndex) => {
|
|
85
85
|
const lineGenerator = generatorFactory.getLineGenerator(valueField.name);
|
|
86
86
|
const lineObject = block.svg.getChartGroup(chart.index)
|
|
87
87
|
.select(`.${this.lineChartClass}${Helper.getCssClassesLine(chart.cssClasses)}.chart-element-${valueFieldIndex}`);
|
|
88
|
-
const prom =
|
|
88
|
+
const prom = Line.updateGroupedPath(block, lineObject, lineGenerator, newData);
|
|
89
89
|
promises.push(prom);
|
|
90
90
|
MarkDot.update(block, newData, keyAxisOrient, scales, margin, keyField.name, valueFieldIndex, valueField.name, chart);
|
|
91
91
|
});
|
|
@@ -93,7 +93,7 @@ export class Line {
|
|
|
93
93
|
}
|
|
94
94
|
updateSegmented(block, scales, newData, keyField, margin, keyAxisOrient, chart) {
|
|
95
95
|
let stackedData = getStackedData(newData, chart);
|
|
96
|
-
const generatorFactory = new LineGeneratorFactory({ keyAxisOrient, scales, keyFieldName: keyField.name, margin, curve: this.options.staticSettings.shape.curve.type,
|
|
96
|
+
const generatorFactory = new LineGeneratorFactory({ keyAxisOrient, scales, keyFieldName: keyField.name, margin, curve: this.options.staticSettings.shape.curve.type, shouldRender: chart.lineLikeViewOptions.renderForKey });
|
|
97
97
|
const lineGenerator = generatorFactory.getSegmentedLineGenerator();
|
|
98
98
|
const lines = block.svg.getChartGroup(chart.index)
|
|
99
99
|
.selectAll(`path.${this.lineChartClass}${Helper.getCssClassesLine(chart.cssClasses)}`)
|
|
@@ -104,7 +104,7 @@ export class Line {
|
|
|
104
104
|
});
|
|
105
105
|
return [prom];
|
|
106
106
|
}
|
|
107
|
-
updateGroupedPath(block, lineObject, lineGenerator, newData) {
|
|
107
|
+
static updateGroupedPath(block, lineObject, lineGenerator, newData) {
|
|
108
108
|
return new Promise(resolve => {
|
|
109
109
|
if (lineObject.size() === 0) {
|
|
110
110
|
resolve('');
|
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
import { Line as ILine } from "d3-shape";
|
|
2
1
|
import { MdtChartsDataRow } from "../../../config/config";
|
|
3
|
-
import {
|
|
2
|
+
import { LineLikeGeneratorMiddleware } from "../lineLike/generatorMiddleware/lineLikeGeneratorMiddleware";
|
|
3
|
+
import { CoordinateGetter } from "../lineLike/generatorFactory/lineLikeGeneratorFactory";
|
|
4
4
|
interface LineGeneratorOptions {
|
|
5
|
-
|
|
5
|
+
middlewares: LineLikeGeneratorMiddleware[];
|
|
6
6
|
}
|
|
7
|
-
declare type CoordinateGetter = (dataRow: MdtChartsDataRow) => number;
|
|
8
7
|
export declare class LineGenerator {
|
|
9
8
|
private options;
|
|
10
|
-
private readonly curvies;
|
|
11
9
|
constructor(options: LineGeneratorOptions);
|
|
12
|
-
get(xValue: CoordinateGetter, yValue: CoordinateGetter):
|
|
13
|
-
private setCurve;
|
|
10
|
+
get(xValue: CoordinateGetter, yValue: CoordinateGetter): import("d3-shape").Line<MdtChartsDataRow>;
|
|
14
11
|
}
|
|
15
12
|
export {};
|
|
@@ -1,27 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { LineCurveType } from "../../../model/model";
|
|
1
|
+
import { line } from "d3-shape";
|
|
3
2
|
export class LineGenerator {
|
|
4
3
|
constructor(options) {
|
|
5
4
|
this.options = options;
|
|
6
|
-
this.curvies = {
|
|
7
|
-
[LineCurveType.monotoneX]: curveMonotoneX,
|
|
8
|
-
[LineCurveType.monotoneY]: curveMonotoneY,
|
|
9
|
-
[LineCurveType.basis]: curveBasis,
|
|
10
|
-
[LineCurveType.none]: undefined
|
|
11
|
-
};
|
|
12
5
|
}
|
|
13
6
|
get(xValue, yValue) {
|
|
14
7
|
const generator = line()
|
|
15
8
|
.x(xValue)
|
|
16
9
|
.y(yValue);
|
|
17
|
-
this.
|
|
10
|
+
this.options.middlewares.forEach(middleware => middleware.handle(generator));
|
|
18
11
|
return generator;
|
|
19
12
|
}
|
|
20
|
-
setCurve(generator) {
|
|
21
|
-
if (this.options.curve != null) {
|
|
22
|
-
const curve = this.curvies[this.options.curve];
|
|
23
|
-
if (curve)
|
|
24
|
-
generator.curve(curve);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
13
|
}
|