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.
Files changed (68) hide show
  1. package/lib/config/config.d.ts +25 -0
  2. package/lib/engine/block/blockSvg.d.ts +1 -1
  3. package/lib/engine/block/blockSvg.js +1 -1
  4. package/lib/engine/block/defs/LinearGradientDef.d.ts +6 -0
  5. package/lib/engine/block/defs/LinearGradientDef.js +28 -0
  6. package/lib/engine/elementHighlighter/elementHighlighter.d.ts +0 -1
  7. package/lib/engine/elementHighlighter/elementHighlighter.js +5 -8
  8. package/lib/engine/elementHighlighter/selectHighlighter.js +11 -10
  9. package/lib/engine/features/legend/legendMarkerCreator.js +1 -1
  10. package/lib/engine/features/markDots/markDot.d.ts +11 -3
  11. package/lib/engine/features/markDots/markDot.js +21 -10
  12. package/lib/engine/features/tolltip/tooltip.js +5 -4
  13. package/lib/engine/features/valueLabels/valueLabels.d.ts +45 -0
  14. package/lib/engine/features/valueLabels/valueLabels.js +139 -0
  15. package/lib/engine/features/valueLabels/valueLabelsHelper.d.ts +6 -0
  16. package/lib/engine/features/valueLabels/valueLabelsHelper.js +21 -0
  17. package/lib/engine/features/valueLabelsCollision/valueLabelsCollision.d.ts +23 -0
  18. package/lib/engine/features/valueLabelsCollision/valueLabelsCollision.js +24 -0
  19. package/lib/engine/features/valueLabelsCollision/valueLabelsCollisionHelper.d.ts +5 -0
  20. package/lib/engine/features/valueLabelsCollision/valueLabelsCollisionHelper.js +47 -0
  21. package/lib/engine/helpers/domHelper.d.ts +1 -0
  22. package/lib/engine/helpers/domHelper.js +4 -0
  23. package/lib/engine/twoDimensionalNotation/area/area.d.ts +26 -11
  24. package/lib/engine/twoDimensionalNotation/area/area.js +100 -34
  25. package/lib/engine/twoDimensionalNotation/area/areaGenerator.d.ts +14 -0
  26. package/lib/engine/twoDimensionalNotation/area/areaGenerator.js +22 -0
  27. package/lib/engine/twoDimensionalNotation/area/areaHelper.d.ts +7 -7
  28. package/lib/engine/twoDimensionalNotation/area/areaHelper.js +30 -31
  29. package/lib/engine/twoDimensionalNotation/bar/barHelper.js +1 -1
  30. package/lib/engine/twoDimensionalNotation/bar/stackedData/dataStacker.d.ts +4 -2
  31. package/lib/engine/twoDimensionalNotation/bar/stackedData/dataStacker.js +2 -5
  32. package/lib/engine/twoDimensionalNotation/line/line.d.ts +2 -7
  33. package/lib/engine/twoDimensionalNotation/line/line.js +6 -6
  34. package/lib/engine/twoDimensionalNotation/line/lineGenerator.d.ts +4 -7
  35. package/lib/engine/twoDimensionalNotation/line/lineGenerator.js +2 -16
  36. package/lib/engine/twoDimensionalNotation/line/lineHelper.d.ts +4 -13
  37. package/lib/engine/twoDimensionalNotation/line/lineHelper.js +22 -10
  38. package/lib/engine/twoDimensionalNotation/lineLike/generatorFactory/lineLikeGeneratorFactory.d.ts +12 -0
  39. package/lib/engine/twoDimensionalNotation/lineLike/generatorFactory/lineLikeGeneratorFactory.js +1 -0
  40. package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorCurveMiddleware.d.ts +14 -0
  41. package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorCurveMiddleware.js +21 -0
  42. package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorDefineMiddleware.d.ts +20 -0
  43. package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorDefineMiddleware.js +9 -0
  44. package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorMiddleware.d.ts +5 -0
  45. package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorMiddleware.js +1 -0
  46. package/lib/engine/twoDimensionalNotation/twoDimensionalManager.d.ts +2 -0
  47. package/lib/engine/twoDimensionalNotation/twoDimensionalManager.js +26 -3
  48. package/lib/model/chartStyleModel/twoDimensionalChartStyleModel.js +5 -1
  49. package/lib/model/featuresModel/axisModel.js +3 -1
  50. package/lib/model/featuresModel/valueLabelsModel/valueLabelsModel.d.ts +9 -0
  51. package/lib/model/featuresModel/valueLabelsModel/valueLabelsModel.js +33 -0
  52. package/lib/model/helpers/modelHelper.d.ts +1 -0
  53. package/lib/model/helpers/modelHelper.js +3 -2
  54. package/lib/model/helpers/twoDimensionalModelHelper.d.ts +8 -0
  55. package/lib/model/helpers/twoDimensionalModelHelper.js +56 -0
  56. package/lib/model/model.d.ts +66 -6
  57. package/lib/model/modelInstance/configReader.d.ts +2 -1
  58. package/lib/model/modelInstance/configReader.js +17 -0
  59. package/lib/model/notations/polar/polarModel.js +2 -1
  60. package/lib/model/notations/twoDimensional/styles.d.ts +3 -1
  61. package/lib/model/notations/twoDimensional/styles.js +20 -0
  62. package/lib/model/notations/twoDimensionalModel.js +30 -25
  63. package/lib/style/charts-main.css +17 -2
  64. package/lib/style/charts-main.less +17 -2
  65. package/package.json +2 -2
  66. package/lib/style/css-vars.css +0 -3
  67. /package/lib/engine/block/{defs.d.ts → defs/hatchPattern.d.ts} +0 -0
  68. /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 render(block: Block, scales: Scales, data: MdtChartsDataRow[], keyField: Field, margin: BlockMargin, keyAxisOrient: Orient, chart: TwoDimensionalChartModel, blockSize: Size): void;
8
- static update(block: Block, scales: Scales, newData: MdtChartsDataRow[], keyField: Field, margin: BlockMargin, chart: TwoDimensionalChartModel, keyAxisOrient: Orient, blockSize: Size): Promise<any>[];
9
- static updateColors(block: Block, chart: TwoDimensionalChartModel): void;
10
- private static renderGrouped;
11
- private static renderSegmented;
12
- private static updateGrouped;
13
- private static updateSegmented;
14
- private static updateGroupedPath;
15
- private static updateSegmentedPath;
16
- private static setSegmentColor;
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 { AreaHelper } from './areaHelper';
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
- static render(block, scales, data, keyField, margin, keyAxisOrient, chart, blockSize) {
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, blockSize);
20
+ this.renderGrouped(block, scales, data, keyField, margin, keyAxisOrient, chart);
13
21
  }
14
- static update(block, scales, newData, keyField, margin, chart, keyAxisOrient, blockSize) {
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
- static updateColors(block, chart) {
32
+ updateColors(block, chart) {
25
33
  chart.data.valueFields.forEach((_vf, valueIndex) => {
26
- const path = block.svg.getChartGroup(chart.index)
27
- .select(`.${this.areaChartClass}${Helper.getCssClassesLine(chart.cssClasses)}.chart-element-${valueIndex}`);
28
- DomHelper.setChartStyle(path, chart.style, valueIndex, 'fill');
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
- static renderGrouped(block, scales, data, keyField, margin, keyAxisOrient, chart, blockSize) {
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
- const area = AreaHelper.getGroupedAreaGenerator(keyAxisOrient, scales, margin, keyField.name, field.name, blockSize);
35
- const path = block.svg.getChartGroup(chart.index)
36
- .append('path')
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
- static renderSegmented(block, scales, data, keyField, margin, keyAxisOrient, chart) {
57
+ renderSegmented(block, scales, data, keyField, margin, keyAxisOrient, chart) {
47
58
  const stackedData = getStackedDataWithOwn(data, chart.data.valueFields.map(field => field.name));
48
- const areaGenerator = AreaHelper.getSegmentedAreaGenerator(keyAxisOrient, scales, margin, keyField.name);
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(`.${this.areaChartClass}${Helper.getCssClassesLine(chart.cssClasses)}`)
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', this.areaChartClass)
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
- static updateGrouped(block, scales, newData, keyField, margin, chart, keyAxisOrient, blockSize) {
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 areaGenerator = AreaHelper.getGroupedAreaGenerator(keyAxisOrient, scales, margin, keyField.name, field.name, blockSize);
70
- const areaObject = block.svg.getChartGroup(chart.index)
71
- .select(`.${this.areaChartClass}${Helper.getCssClassesLine(chart.cssClasses)}.chart-element-${valueIndex}`);
72
- const prom = this.updateGroupedPath(block, areaObject, areaGenerator, newData);
73
- promises.push(prom);
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
- static updateSegmented(block, scales, newData, keyField, margin, chart, keyAxisOrient) {
95
+ updateSegmented(block, scales, newData, keyField, margin, chart, keyAxisOrient) {
79
96
  const stackedData = getStackedDataWithOwn(newData, chart.data.valueFields.map(field => field.name));
80
- const areaGenerator = AreaHelper.getSegmentedAreaGenerator(keyAxisOrient, scales, margin, keyField.name);
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.${this.areaChartClass}${Helper.getCssClassesLine(chart.cssClasses)}`)
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
- static updateGroupedPath(block, areaObject, areaGenerator, newData) {
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
- static updateSegmentedPath(block, areasObjects, areaGenerator) {
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
- static setSegmentColor(segments, colorPalette) {
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, Size } from '../../../config/config';
3
- import { BlockMargin, Orient } from "../../../model/model";
4
- import { Scales } from "../../features/scale/scale";
5
- export declare class AreaHelper {
6
- static getGroupedAreaGenerator(keyAxisOrient: Orient, scales: Scales, margin: BlockMargin, keyFieldName: string, valueFieldName: string, blockSize: Size): IArea<MdtChartsDataRow>;
7
- static getSegmentedAreaGenerator(keyAxisOrient: Orient, scales: Scales, margin: BlockMargin, keyFieldName: string): IArea<MdtChartsDataRow>;
8
- static getZeroCoordinate(axisOrient: Orient, margin: BlockMargin, blockSize: Size): number;
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
- export class AreaHelper {
4
- static getGroupedAreaGenerator(keyAxisOrient, scales, margin, keyFieldName, valueFieldName, blockSize) {
5
- if (keyAxisOrient === 'bottom' || keyAxisOrient === 'top')
6
- return area()
7
- .x(d => Scale.getScaledValue(scales.key, d[keyFieldName]) + margin.left)
8
- .y0(d => scales.value(0) + margin.top)
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
- static getSegmentedAreaGenerator(keyAxisOrient, scales, margin, keyFieldName) {
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 area()
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 area()
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
- static getZeroCoordinate(axisOrient, margin, blockSize) {
31
- if (axisOrient === 'bottom')
32
- return blockSize.height - margin.bottom;
33
- if (axisOrient === 'top')
34
- return margin.top;
35
- if (axisOrient === 'left')
36
- return margin.left;
37
- if (axisOrient === 'right')
38
- return blockSize.width - margin.right;
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 StackedDataRow {
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 { SeriesPoint } from 'd3-shape';
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
- private updateGroupedPath;
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, shouldRenderLine: chart.lineViewOptions.renderForKey });
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, shouldRenderLine: chart.lineViewOptions.renderForKey });
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, shouldRenderLine: chart.lineViewOptions.renderForKey });
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 = this.updateGroupedPath(block, lineObject, lineGenerator, newData);
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, shouldRenderLine: chart.lineViewOptions.renderForKey });
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 { LineCurveType } from "../../../model/model";
2
+ import { LineLikeGeneratorMiddleware } from "../lineLike/generatorMiddleware/lineLikeGeneratorMiddleware";
3
+ import { CoordinateGetter } from "../lineLike/generatorFactory/lineLikeGeneratorFactory";
4
4
  interface LineGeneratorOptions {
5
- curve?: LineCurveType;
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): ILine<MdtChartsDataRow>;
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 { curveBasis, curveMonotoneX, line, curveMonotoneY } from "d3-shape";
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.setCurve(generator);
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
  }