mdt-charts 1.21.2 → 1.23.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 (50) hide show
  1. package/lib/config/config.d.ts +51 -15
  2. package/lib/engine/features/axis/axis.js +2 -0
  3. package/lib/engine/features/gridLine/gridLine.d.ts +3 -5
  4. package/lib/engine/features/gridLine/gridLine.js +15 -32
  5. package/lib/engine/features/legend/legend.d.ts +3 -0
  6. package/lib/engine/features/legend/legend.js +3 -0
  7. package/lib/engine/features/legend/legendHelper.d.ts +1 -0
  8. package/lib/engine/features/legend/legendHelper.js +11 -2
  9. package/lib/engine/features/legend/legendHelperService.d.ts +0 -1
  10. package/lib/engine/features/legend/legendHelperService.js +0 -3
  11. package/lib/engine/features/legend/legendMarkerCreator.js +7 -4
  12. package/lib/engine/features/valueLabels/valueLabels.d.ts +0 -1
  13. package/lib/engine/features/valueLabels/valueLabels.js +9 -14
  14. package/lib/engine/features/valueLabelsCollision/valueLabelsCollision.d.ts +7 -2
  15. package/lib/engine/features/valueLabelsCollision/valueLabelsCollision.js +25 -1
  16. package/lib/engine/twoDimensionalNotation/bar/bar.d.ts +1 -0
  17. package/lib/engine/twoDimensionalNotation/bar/bar.js +14 -9
  18. package/lib/engine/twoDimensionalNotation/bar/barHelper.d.ts +38 -6
  19. package/lib/engine/twoDimensionalNotation/bar/barHelper.js +67 -22
  20. package/lib/engine/twoDimensionalNotation/dot/dotChart.d.ts +36 -0
  21. package/lib/engine/twoDimensionalNotation/dot/dotChart.js +106 -0
  22. package/lib/engine/twoDimensionalNotation/line/lineHelper.js +4 -0
  23. package/lib/engine/twoDimensionalNotation/twoDimensionalManager.d.ts +1 -0
  24. package/lib/engine/twoDimensionalNotation/twoDimensionalManager.js +22 -2
  25. package/lib/model/dataManagerModel/dataManagerModel.d.ts +1 -2
  26. package/lib/model/dataManagerModel/dataManagerModel.js +15 -33
  27. package/lib/model/featuresModel/axisModel.d.ts +0 -1
  28. package/lib/model/featuresModel/axisModel.js +12 -32
  29. package/lib/model/featuresModel/legendModel/legendCanvasModel.d.ts +0 -1
  30. package/lib/model/featuresModel/legendModel/legendCanvasModel.js +0 -18
  31. package/lib/model/featuresModel/legendModel/legendModel.js +1 -1
  32. package/lib/model/featuresModel/legendModel/twoDimLegendModel.d.ts +2 -2
  33. package/lib/model/featuresModel/legendModel/twoDimLegendModel.js +3 -1
  34. package/lib/model/featuresModel/scaleModel/scaleModel.d.ts +1 -1
  35. package/lib/model/featuresModel/scaleModel/scaleModel.js +5 -5
  36. package/lib/model/featuresModel/scaleModel/scaleModelServices.d.ts +1 -1
  37. package/lib/model/featuresModel/scaleModel/scaleModelServices.js +15 -9
  38. package/lib/model/featuresModel/valueLabelsModel/valueLabelsModel.d.ts +6 -0
  39. package/lib/model/featuresModel/valueLabelsModel/valueLabelsModel.js +13 -0
  40. package/lib/model/model.d.ts +66 -6
  41. package/lib/model/modelBuilder.js +1 -3
  42. package/lib/model/modelInstance/configReader.js +5 -5
  43. package/lib/model/notations/polar/polarModel.js +11 -3
  44. package/lib/model/notations/twoDimensional/styles.d.ts +4 -1
  45. package/lib/model/notations/twoDimensional/styles.js +61 -4
  46. package/lib/model/notations/twoDimensionalModel.d.ts +2 -1
  47. package/lib/model/notations/twoDimensionalModel.js +66 -16
  48. package/lib/style/charts-main.css +9 -8
  49. package/lib/style/charts-main.less +9 -8
  50. package/package.json +1 -1
@@ -1,6 +1,7 @@
1
- import { BarChartSettings, BlockMargin, Orient, TwoDimensionalChartModel } from "../../../model/model";
1
+ import { AxisScale } from "d3-axis";
2
+ import { BarBorderRadius, BarChartSettings, BlockMargin, Orient, TwoDimensionalChartModel } from "../../../model/model";
2
3
  import { Scales } from "../../features/scale/scale";
3
- import { MdtChartsDataRow, Size } from "../../../config/config";
4
+ import { MdtChartsDataRow } from "../../../config/config";
4
5
  import { Pipeline } from "../../helpers/pipeline/Pipeline";
5
6
  import { BaseType, Selection } from "d3-selection";
6
7
  export interface BarAttrsHelper {
@@ -9,9 +10,36 @@ export interface BarAttrsHelper {
9
10
  width: (dataRow: MdtChartsDataRow) => number;
10
11
  height: (dataRow: MdtChartsDataRow) => number;
11
12
  }
13
+ export interface GroupBarsSegment {
14
+ segmentIndex: number;
15
+ chart: TwoDimensionalChartModel;
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 {
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
+ }
12
40
  export declare class BarHelper {
13
- static getGroupedBarAttrs(keyAxisOrient: Orient, scales: Scales, margin: BlockMargin, keyField: string, valueFieldName: string, blockSize: Size, barIndex: number, barsAmount: number, barSettings: BarChartSettings): BarAttrsHelper;
14
- static getStackedBarAttr(keyAxisOrient: Orient, scales: Scales, margin: BlockMargin, keyField: string, blockSize: Size, barIndex: number, barsAmount: number, barSettings: BarChartSettings): BarAttrsHelper;
41
+ static getGroupedBarAttrs(keyAxisOrient: Orient, scales: Scales, margin: BlockMargin, keyField: string, valueFieldName: string, barIndex: number, barsAmount: number, barSettings: BarChartSettings): BarAttrsHelper;
42
+ static getStackedBarAttr(keyAxisOrient: Orient, scales: Scales, margin: BlockMargin, keyField: string, barIndex: number, barsAmount: number, barSettings: BarChartSettings): BarAttrsHelper;
15
43
  static getBarsInGroupAmount(charts: TwoDimensionalChartModel[]): number[];
16
44
  /**
17
45
  * Получение индекса бара среди всх графиков и value-филдов. Используется для того, чтобы узнать, какой по счету в группе
@@ -20,8 +48,12 @@ export declare class BarHelper {
20
48
  * @param chartIndex
21
49
  */
22
50
  static getBarIndex(barsAmounts: number[], chartIndex: number): number;
23
- private static setBarAttrsByKey;
51
+ static setBarAttrsByKey(attrs: BarAttrsHelper, keyAxisOrient: Orient, scaleKey: AxisScale<any>, margin: BlockMargin, keyField: string, barIndex: number, settingsStore: BandLikeChartSettingsStore, isSegmented: boolean): void;
24
52
  private static setGroupedBarAttrsByValue;
53
+ static getBandItemValueStretch(scaleValue: AxisScale<any>, valueFieldName: string): (dataRow: MdtChartsDataRow) => number;
54
+ static setGroupedBandStartCoordinateAttr(attrs: BarAttrsHelper, keyAxisOrient: Orient, scaleValue: AxisScale<any>, margin: BlockMargin, valueFieldName: string): void;
25
55
  private static setSegmentedBarAttrsByValue;
26
56
  }
27
- export declare function onBarChartInit(createBarPipeline: Pipeline<Selection<SVGRectElement, any, BaseType, any>, TwoDimensionalChartModel>): void;
57
+ export declare function onBarChartInit(createBarPipeline: Pipeline<Selection<SVGRectElement, any, BaseType, any>, TwoDimensionalChartModel>, createSegmentGroupBarsPipeline: Pipeline<Selection<SVGRectElement, any, BaseType, any>, GroupBarsSegment>): void;
58
+ export declare function getClipPathValue({ topLeft, topRight, bottomLeft, bottomRight }: BarBorderRadius): string;
59
+ export {};
@@ -1,27 +1,56 @@
1
1
  import { Scale } from "../../features/scale/scale";
2
2
  import { Helper } from "../../helpers/helper";
3
3
  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)) / this.canvasConfig.barsAmount; // Space for one bar
31
+ }
32
+ }
4
33
  export class BarHelper {
5
- static getGroupedBarAttrs(keyAxisOrient, scales, margin, keyField, valueFieldName, blockSize, barIndex, barsAmount, barSettings) {
34
+ static getGroupedBarAttrs(keyAxisOrient, scales, margin, keyField, valueFieldName, barIndex, barsAmount, barSettings) {
6
35
  const attrs = {
7
36
  x: null,
8
37
  y: null,
9
38
  width: null,
10
39
  height: null
11
40
  };
12
- this.setBarAttrsByKey(attrs, keyAxisOrient, scales.key, margin, keyField, barIndex, barsAmount, barSettings, false);
13
- this.setGroupedBarAttrsByValue(attrs, keyAxisOrient, margin, scales.value, valueFieldName, blockSize);
41
+ this.setBarAttrsByKey(attrs, keyAxisOrient, scales.key, margin, keyField, barIndex, new BarSettingsStore(barSettings, { scaleBandWidth: Scale.getScaleBandWidth(scales.key), barsAmount }), false);
42
+ this.setGroupedBarAttrsByValue(attrs, keyAxisOrient, margin, scales.value, valueFieldName);
14
43
  return attrs;
15
44
  }
16
- static getStackedBarAttr(keyAxisOrient, scales, margin, keyField, blockSize, barIndex, barsAmount, barSettings) {
45
+ static getStackedBarAttr(keyAxisOrient, scales, margin, keyField, barIndex, barsAmount, barSettings) {
17
46
  const attrs = {
18
47
  x: null,
19
48
  y: null,
20
49
  width: null,
21
50
  height: null
22
51
  };
23
- this.setBarAttrsByKey(attrs, keyAxisOrient, scales.key, margin, keyField, barIndex, barsAmount, barSettings, true);
24
- this.setSegmentedBarAttrsByValue(attrs, keyAxisOrient, scales.value, margin, blockSize);
52
+ this.setBarAttrsByKey(attrs, keyAxisOrient, scales.key, margin, keyField, barIndex, new BarSettingsStore(barSettings, { scaleBandWidth: Scale.getScaleBandWidth(scales.key), barsAmount }), true);
53
+ this.setSegmentedBarAttrsByValue(attrs, keyAxisOrient, scales.value, margin);
25
54
  return attrs;
26
55
  }
27
56
  static getBarsInGroupAmount(charts) {
@@ -51,39 +80,43 @@ export class BarHelper {
51
80
  });
52
81
  return index;
53
82
  }
54
- static setBarAttrsByKey(attrs, keyAxisOrient, scaleKey, margin, keyField, barIndex, barsAmount, barSettings, isSegmented) {
55
- const barStep = (Scale.getScaleBandWidth(scaleKey) - barSettings.barDistance * (barsAmount - 1)) / barsAmount; // Space for one bar
56
- const barSize = barStep > barSettings.maxBarWidth ? barSettings.maxBarWidth : barStep;
57
- const barDiff = (barStep - barSize) * barsAmount / 2; // if bar bigger than maxWidth, diff for x coordinate
58
- const barPad = barSize * barIndex + barSettings.barDistance * barIndex + barDiff; // Отступ бара от края. Зависит от количества баров в одной группе и порядке текущего бара
83
+ static setBarAttrsByKey(attrs, keyAxisOrient, scaleKey, margin, keyField, barIndex, settingsStore, isSegmented) {
59
84
  if (keyAxisOrient === 'top' || keyAxisOrient === 'bottom') {
60
- attrs.x = d => scaleKey(Helper.getKeyFieldValue(d, keyField, isSegmented)) + margin.left + barPad;
61
- attrs.width = d => barSize;
85
+ attrs.x = d => scaleKey(Helper.getKeyFieldValue(d, keyField, isSegmented)) + margin.left + settingsStore.getBandItemPad(barIndex);
86
+ attrs.width = d => settingsStore.getBandItemSize();
62
87
  }
63
88
  if (keyAxisOrient === 'left' || keyAxisOrient === 'right') {
64
- attrs.y = d => scaleKey(Helper.getKeyFieldValue(d, keyField, isSegmented)) + margin.top + barPad;
65
- attrs.height = d => barSize;
89
+ attrs.y = d => scaleKey(Helper.getKeyFieldValue(d, keyField, isSegmented)) + margin.top + settingsStore.getBandItemPad(barIndex);
90
+ attrs.height = d => settingsStore.getBandItemSize();
66
91
  }
67
92
  }
68
- static setGroupedBarAttrsByValue(attrs, keyAxisOrient, margin, scaleValue, valueFieldName, blockSize) {
93
+ static setGroupedBarAttrsByValue(attrs, keyAxisOrient, margin, scaleValue, valueFieldName) {
94
+ this.setGroupedBandStartCoordinateAttr(attrs, keyAxisOrient, scaleValue, margin, valueFieldName);
95
+ if (keyAxisOrient === 'top' || keyAxisOrient === 'bottom') {
96
+ attrs.height = this.getBandItemValueStretch(scaleValue, valueFieldName);
97
+ }
98
+ if (keyAxisOrient === 'left' || keyAxisOrient === 'right') {
99
+ attrs.width = this.getBandItemValueStretch(scaleValue, valueFieldName);
100
+ }
101
+ }
102
+ static getBandItemValueStretch(scaleValue, valueFieldName) {
103
+ return d => Math.abs(scaleValue(d[valueFieldName]) - scaleValue(0));
104
+ }
105
+ static setGroupedBandStartCoordinateAttr(attrs, keyAxisOrient, scaleValue, margin, valueFieldName) {
69
106
  if (keyAxisOrient === 'top') {
70
107
  attrs.y = d => scaleValue(Math.min(d[valueFieldName], 0)) + margin.top;
71
- attrs.height = d => Math.abs(scaleValue(d[valueFieldName]) - scaleValue(0));
72
108
  }
73
109
  if (keyAxisOrient === 'bottom') {
74
110
  attrs.y = d => scaleValue(Math.max(d[valueFieldName], 0)) + margin.top;
75
- attrs.height = d => Math.abs(scaleValue(d[valueFieldName]) - scaleValue(0));
76
111
  }
77
112
  if (keyAxisOrient === 'left') {
78
113
  attrs.x = d => scaleValue(Math.min(d[valueFieldName], 0)) + margin.left;
79
- attrs.width = d => Math.abs(scaleValue(d[valueFieldName]) - scaleValue(0));
80
114
  }
81
115
  if (keyAxisOrient === 'right') {
82
116
  attrs.x = d => scaleValue(Math.max(d[valueFieldName], 0)) + margin.left;
83
- attrs.width = d => Math.abs(scaleValue(d[valueFieldName]) - scaleValue(0));
84
117
  }
85
118
  }
86
- static setSegmentedBarAttrsByValue(attrs, keyAxisOrient, scaleValue, margin, blockSize) {
119
+ static setSegmentedBarAttrsByValue(attrs, keyAxisOrient, scaleValue, margin) {
87
120
  if (keyAxisOrient === 'top') {
88
121
  attrs.y = d => scaleValue(Math.min(d[1], d[0])) + margin.top;
89
122
  attrs.height = d => Math.abs(scaleValue(d[1]) - scaleValue(d[0]));
@@ -102,8 +135,20 @@ export class BarHelper {
102
135
  }
103
136
  }
104
137
  }
105
- export function onBarChartInit(createBarPipeline) {
138
+ export function onBarChartInit(createBarPipeline, createSegmentGroupBarsPipeline) {
106
139
  createBarPipeline.push(hatchBar);
140
+ createBarPipeline.push(roundGroupedBars);
141
+ createSegmentGroupBarsPipeline.push(roundSegmentedBars);
142
+ }
143
+ function roundSegmentedBars(bars, segment) {
144
+ const radiusValues = segment.chart.barViewOptions.borderRadius.segmented.handle(segment.segmentIndex);
145
+ return bars.style('clip-path', getClipPathValue(radiusValues));
146
+ }
147
+ function roundGroupedBars(bars, chart) {
148
+ return bars.style('clip-path', getClipPathValue(chart.barViewOptions.borderRadius.grouped));
149
+ }
150
+ export function getClipPathValue({ topLeft, topRight, bottomLeft, bottomRight }) {
151
+ return `inset(0px round ${topLeft}px ${topRight}px ${bottomRight}px ${bottomLeft}px)`;
107
152
  }
108
153
  function hatchBar(bars, chart) {
109
154
  if (chart.barViewOptions.hatch.on)
@@ -0,0 +1,36 @@
1
+ import { MdtChartsDataRow } from "../../../config/config";
2
+ import { BarChartSettings, BlockMargin, Orient, TwoDimensionalChartModel } from "../../../model/model";
3
+ import { Block } from "../../block/block";
4
+ import { Scales } from "../../features/scale/scale";
5
+ export interface CanvasDotChartOptions {
6
+ elementAccessors: {
7
+ getBlock: () => Block;
8
+ };
9
+ dataOptions: {
10
+ keyFieldName: string;
11
+ };
12
+ canvas: {
13
+ keyAxisOrient: Orient;
14
+ };
15
+ bandOptions: {
16
+ settings: BarChartSettings;
17
+ };
18
+ }
19
+ export interface DotItemAttrGetters {
20
+ x1: (dataRow: MdtChartsDataRow) => number;
21
+ y1: (dataRow: MdtChartsDataRow) => number;
22
+ x2: (dataRow: MdtChartsDataRow) => number;
23
+ y2: (dataRow: MdtChartsDataRow) => number;
24
+ }
25
+ /**
26
+ * @alpha experimental feature. Need to refactor.
27
+ */
28
+ export declare class CanvasDotChart {
29
+ private readonly options;
30
+ private readonly dotChartItemClass;
31
+ private renderedChart;
32
+ constructor(options: CanvasDotChartOptions);
33
+ render(scales: Scales, chart: TwoDimensionalChartModel, records: MdtChartsDataRow[], margin: BlockMargin): void;
34
+ update(scales: Scales, newRecords: MdtChartsDataRow[], margin: BlockMargin): Promise<void>[];
35
+ private getAttrs;
36
+ }
@@ -0,0 +1,106 @@
1
+ import { Scale } from "../../features/scale/scale";
2
+ import { DomHelper } from "../../helpers/domHelper";
3
+ import { Helper } from "../../helpers/helper";
4
+ import { NamesHelper } from "../../helpers/namesHelper";
5
+ import { BarHelper, DotChartSettingsStore } from "../bar/barHelper";
6
+ /**
7
+ * @alpha experimental feature. Need to refactor.
8
+ */
9
+ export class CanvasDotChart {
10
+ constructor(options) {
11
+ this.options = options;
12
+ this.dotChartItemClass = NamesHelper.getClassName("dot-chart-item");
13
+ this.renderedChart = undefined;
14
+ }
15
+ render(scales, chart, records, margin) {
16
+ if (this.renderedChart)
17
+ return;
18
+ const valueFieldIndex = 0;
19
+ const elements = this.options.elementAccessors.getBlock().svg.getChartGroup(chart.index)
20
+ .selectAll(`.${this.dotChartItemClass}${Helper.getCssClassesLine(chart.cssClasses)}${Helper.getCssClassesLine(Helper.getCssClassesWithElementIndex(chart.cssClasses, valueFieldIndex))}`)
21
+ .data(records)
22
+ .enter()
23
+ .append('line')
24
+ .style("stroke-width", chart.dotViewOptions.shape.width)
25
+ .attr('class', this.dotChartItemClass);
26
+ const attrs = this.getAttrs(scales, chart, chart.data.valueFields[0], margin);
27
+ elements.attr('x1', d => attrs.x1(d))
28
+ .attr('y1', d => attrs.y1(d))
29
+ .attr('x2', d => attrs.x2(d))
30
+ .attr('y2', d => attrs.y2(d));
31
+ DomHelper.setCssClasses(elements, Helper.getCssClassesWithElementIndex(chart.cssClasses, valueFieldIndex));
32
+ DomHelper.setChartStyle(elements, chart.style, valueFieldIndex, 'stroke');
33
+ this.renderedChart = chart;
34
+ }
35
+ update(scales, newRecords, margin) {
36
+ if (!this.renderedChart)
37
+ return;
38
+ const valueFieldIndex = 0;
39
+ const elements = this.options.elementAccessors.getBlock().svg.getChartGroup(this.renderedChart.index)
40
+ .selectAll(`.${this.dotChartItemClass}${Helper.getCssClassesLine(this.renderedChart.cssClasses)}${Helper.getCssClassesLine(Helper.getCssClassesWithElementIndex(this.renderedChart.cssClasses, valueFieldIndex))}`)
41
+ .data(newRecords);
42
+ elements.exit().remove();
43
+ const newElements = elements
44
+ .enter()
45
+ .append('line')
46
+ .style("stroke-width", this.renderedChart.dotViewOptions.shape.width)
47
+ .attr('class', this.dotChartItemClass);
48
+ const attrs = this.getAttrs(scales, this.renderedChart, this.renderedChart.data.valueFields[0], margin);
49
+ newElements.attr('x1', d => attrs.x1(d))
50
+ .attr('y1', d => attrs.y1(d))
51
+ .attr('x2', d => attrs.x2(d))
52
+ .attr('y2', d => attrs.y2(d));
53
+ DomHelper.setCssClasses(newElements, Helper.getCssClassesWithElementIndex(this.renderedChart.cssClasses, valueFieldIndex));
54
+ DomHelper.setChartStyle(newElements, this.renderedChart.style, valueFieldIndex, 'stroke');
55
+ return [
56
+ new Promise(resolve => {
57
+ elements
58
+ .interrupt()
59
+ .transition()
60
+ .duration(this.options.elementAccessors.getBlock().transitionManager.durations.chartUpdate)
61
+ .attr('x1', d => attrs.x1(d))
62
+ .attr('y1', d => attrs.y1(d))
63
+ .attr('x2', d => attrs.x2(d))
64
+ .attr('y2', d => attrs.y2(d))
65
+ .on('end', () => resolve());
66
+ })
67
+ ];
68
+ }
69
+ getAttrs(scales, chart, field, margin) {
70
+ const attrs = {
71
+ x1: null,
72
+ y1: null,
73
+ x2: null,
74
+ y2: null
75
+ };
76
+ const settingsStore = new DotChartSettingsStore({ scaleBandWidth: Scale.getScaleBandWidth(scales.key) });
77
+ // TODO: refactor
78
+ if (this.options.canvas.keyAxisOrient === 'top' || this.options.canvas.keyAxisOrient === 'bottom') {
79
+ const handleBase = d => scales.key(Helper.getKeyFieldValue(d, this.options.dataOptions.keyFieldName, false)) + margin.left + settingsStore.getBandItemPad();
80
+ attrs.x1 = d => chart.dotViewOptions.shape.handleStartCoordinate(handleBase(d));
81
+ attrs.x2 = d => chart.dotViewOptions.shape.handleEndCoordinate(handleBase(d) + settingsStore.getBandItemSize());
82
+ }
83
+ if (this.options.canvas.keyAxisOrient === 'left' || this.options.canvas.keyAxisOrient === 'right') {
84
+ const handleBase = d => scales.key(Helper.getKeyFieldValue(d, this.options.dataOptions.keyFieldName, false)) + margin.top + settingsStore.getBandItemPad();
85
+ attrs.y1 = d => chart.dotViewOptions.shape.handleStartCoordinate(handleBase(d));
86
+ attrs.y2 = d => chart.dotViewOptions.shape.handleEndCoordinate(handleBase(d) + settingsStore.getBandItemSize());
87
+ }
88
+ if (this.options.canvas.keyAxisOrient === 'top') {
89
+ attrs.y1 = d => scales.value(Math.min(d[field.name], 0)) + margin.top + BarHelper.getBandItemValueStretch(scales.value, field.name)(d);
90
+ attrs.y2 = d => scales.value(Math.min(d[field.name], 0)) + margin.top + BarHelper.getBandItemValueStretch(scales.value, field.name)(d);
91
+ }
92
+ if (this.options.canvas.keyAxisOrient === 'bottom') {
93
+ attrs.y1 = d => scales.value(Math.max(d[field.name], 0)) + margin.top;
94
+ attrs.y2 = d => scales.value(Math.max(d[field.name], 0)) + margin.top;
95
+ }
96
+ if (this.options.canvas.keyAxisOrient === 'left') {
97
+ attrs.x1 = d => scales.value(Math.min(d[field.name], 0)) + margin.left + BarHelper.getBandItemValueStretch(scales.value, field.name)(d);
98
+ attrs.x2 = d => scales.value(Math.min(d[field.name], 0)) + margin.left + BarHelper.getBandItemValueStretch(scales.value, field.name)(d);
99
+ }
100
+ if (this.options.canvas.keyAxisOrient === 'right') {
101
+ attrs.x1 = d => scales.value(Math.max(d[field.name], 0)) + margin.left;
102
+ attrs.x2 = d => scales.value(Math.max(d[field.name], 0)) + margin.left;
103
+ }
104
+ return attrs;
105
+ }
106
+ }
@@ -45,6 +45,10 @@ export function onLineChartInit(creatingPipeline) {
45
45
  }
46
46
  return path;
47
47
  });
48
+ creatingPipeline.push(setStrokeWidth);
49
+ }
50
+ function setStrokeWidth(path, chart) {
51
+ return path.style('stroke-width', chart.lineLikeViewOptions.strokeWidth);
48
52
  }
49
53
  export function applyLineDash(lineSelection, dashSize, gapSize) {
50
54
  return lineSelection.style('stroke-dasharray', `${dashSize} ${gapSize}`);
@@ -6,6 +6,7 @@ import { Engine } from "../engine";
6
6
  export declare class TwoDimensionalManager implements ChartContentManager {
7
7
  private canvasValueLabels?;
8
8
  private linearGradientDef?;
9
+ private dotChart;
9
10
  render(engine: Engine, model: Model<TwoDimensionalOptionsModel>): void;
10
11
  updateData(block: Block, model: Model<TwoDimensionalOptionsModel>, data: MdtChartsDataSource): void;
11
12
  updateColors(block: Block, model: Model<TwoDimensionalOptionsModel>): void;
@@ -15,6 +15,7 @@ import { TwoDimRecordOverflowAlert } from "./extenders/twoDimRecordOverflowAlert
15
15
  import { Line } from "./line/line";
16
16
  import { CanvasValueLabels } from "../../engine/features/valueLabels/valueLabels";
17
17
  import { LinearGradientDef } from "../../engine/block/defs/LinearGradientDef";
18
+ import { CanvasDotChart } from "./dot/dotChart";
18
19
  export class TwoDimensionalManager {
19
20
  render(engine, model) {
20
21
  const options = model.options;
@@ -22,7 +23,21 @@ export class TwoDimensionalManager {
22
23
  engine.block.scales = scales;
23
24
  engine.block.svg.render(model.blockCanvas.size);
24
25
  Axis.render(engine.block, scales, options.scale, options.axis, model.blockCanvas.size);
25
- GridLine.render(engine.block, options.additionalElements.gridLine.flag, options.axis, model.blockCanvas.size, model.chartBlock.margin, scales);
26
+ GridLine.render(engine.block, options.additionalElements.gridLine, options.axis, model.blockCanvas.size, model.chartBlock.margin, scales);
27
+ this.dotChart = new CanvasDotChart({
28
+ elementAccessors: {
29
+ getBlock: () => engine.block,
30
+ },
31
+ canvas: {
32
+ keyAxisOrient: options.axis.key.orient,
33
+ },
34
+ dataOptions: {
35
+ keyFieldName: options.data.keyField.name
36
+ },
37
+ bandOptions: {
38
+ settings: options.chartSettings.bar
39
+ }
40
+ });
26
41
  this.renderCharts(engine.block, options.charts, scales, engine.data, options.data, model.chartBlock.margin, options.axis.key.orient, options.chartSettings, model.blockCanvas.size);
27
42
  Axis.raiseKeyAxis(engine.block, options.axis.key);
28
43
  engine.block.filterEventManager.registerEventFor2D(scales.key, model.chartBlock.margin, model.blockCanvas.size, options);
@@ -70,7 +85,7 @@ export class TwoDimensionalManager {
70
85
  const keyDomainEquality = Helper.checkDomainsEquality(block.scales.key.domain(), scales.key.domain());
71
86
  block.scales = scales;
72
87
  Axis.update(block, scales, options.scale, options.axis, model.blockCanvas.size, keyDomainEquality);
73
- GridLine.update(block, options.additionalElements.gridLine.flag, options.axis, model.blockCanvas.size, model.chartBlock.margin, scales);
88
+ GridLine.update(block, options.additionalElements.gridLine, options.axis, model.blockCanvas.size, model.chartBlock.margin, scales);
74
89
  const promises = this.updateCharts(block, options.charts, scales, data, model.options.data, model.chartBlock.margin, options.axis.key.orient, model.blockCanvas.size, options.chartSettings);
75
90
  Promise.all(promises)
76
91
  .then(() => {
@@ -110,6 +125,8 @@ export class TwoDimensionalManager {
110
125
  Line.get({ staticSettings: chartSettings.lineLike }).render(block, chartScales, data[dataOptions.dataSource], dataOptions.keyField, margin, keyAxisOrient, chart);
111
126
  else if (chart.type === 'area')
112
127
  Area.get({ staticSettings: chartSettings.lineLike }).render(block, chartScales, data[dataOptions.dataSource], dataOptions.keyField, margin, keyAxisOrient, chart, blockSize);
128
+ else if (chart.type === 'dot')
129
+ this.dotChart.render(chartScales, chart, data[dataOptions.dataSource], margin);
113
130
  });
114
131
  EmbeddedLabels.raiseGroups(block);
115
132
  }
@@ -128,6 +145,9 @@ export class TwoDimensionalManager {
128
145
  else if (chart.type === 'area') {
129
146
  proms = Area.get({ staticSettings: chartSettings.lineLike }).update(block, chartScales, data[dataOptions.dataSource], dataOptions.keyField, margin, chart, keyAxisOrient, blockSize);
130
147
  }
148
+ else if (chart.type === 'dot') {
149
+ proms = this.dotChart.update(chartScales, data[dataOptions.dataSource], margin);
150
+ }
131
151
  promises.push(...proms);
132
152
  });
133
153
  return promises;
@@ -27,9 +27,8 @@ export declare class DataManagerModel {
27
27
  * @param chartsLength
28
28
  */
29
29
  private static getElementsInGroupAmount;
30
- private static getBarChartsInGroupAmount;
30
+ private static getBarLikeChartsInGroupAmount;
31
31
  private static getScopedData;
32
32
  private static getScopedChartData;
33
- private static getTypedData;
34
33
  private static getDataLimitByItemSize;
35
34
  }
@@ -28,24 +28,13 @@ export class DataManagerModel {
28
28
  }
29
29
  static initDataScopeFor2D(configOptions, modelInstance, data, designerConfig) {
30
30
  modelInstance.dataModel.initMaxRecordsAmount(configOptions.data.maxRecordsAmount);
31
- let itemsLength = 1;
32
- itemsLength = (configOptions.charts)
33
- .filter((chart) => chart.type === 'bar').length;
34
- if (itemsLength === 0)
35
- itemsLength = 1; // Если баров нет, то для одной записи выделяется столько же места, сколько для одного столбика
36
- if (itemsLength !== 0) {
37
- const axisLength = AxisModel.getAxisLength(configOptions.orientation, modelInstance.canvasModel);
38
- const uniqueKeys = ModelHelper.getUniqueValues(data[configOptions.data.dataSource].map(d => d[configOptions.data.keyField.name]));
39
- const dataLength = uniqueKeys.length;
40
- const limit = this.getDataLimitByItemSize(this.getElementsInGroupAmount(configOptions, itemsLength), dataLength, axisLength, designerConfig.canvas.chartOptions.bar);
41
- const allowableKeys = uniqueKeys.slice(0, limit);
42
- const hidedRecordsAmount = dataLength - allowableKeys.length;
43
- modelInstance.dataModel.initScope(this.limitAllowableKeys(allowableKeys, hidedRecordsAmount, modelInstance.dataModel));
44
- }
45
- else {
46
- const allKeys = this.getDataValuesByKeyField(data, configOptions.data.dataSource, configOptions.data.keyField.name);
47
- modelInstance.dataModel.initScope(this.getMaximumPossibleScope(allKeys, modelInstance.dataModel));
48
- }
31
+ const axisLength = AxisModel.getAxisLength(configOptions.orientation, modelInstance.canvasModel);
32
+ const uniqueKeys = ModelHelper.getUniqueValues(data[configOptions.data.dataSource].map(d => d[configOptions.data.keyField.name]));
33
+ const dataLength = uniqueKeys.length;
34
+ const limit = this.getDataLimitByItemSize(this.getElementsInGroupAmount(configOptions), dataLength, axisLength, designerConfig.canvas.chartOptions.bar);
35
+ const allowableKeys = uniqueKeys.slice(0, limit);
36
+ const hidedRecordsAmount = dataLength - allowableKeys.length;
37
+ modelInstance.dataModel.initScope(this.limitAllowableKeys(allowableKeys, hidedRecordsAmount, modelInstance.dataModel));
49
38
  }
50
39
  static initDataScopeForPolar(configOptions, modelInstance, data, legendBlock, legendCanvas) {
51
40
  modelInstance.dataModel.initMaxRecordsAmount(configOptions.data.maxRecordsAmount);
@@ -83,7 +72,7 @@ export class DataManagerModel {
83
72
  wrapperSize: { marginRightPx: styledElementValues.legend.inlineDynamicItemWrapperMarginRightPx }
84
73
  }));
85
74
  if (position === 'right') {
86
- return LegendCanvasModel.findElementsAmountByLegendSize(legendItemContentOptions, position, this.polarMarginCalculator.getMaxLegendWidth(legendCanvas, canvasModel.getBlockSize().width), canvasModel.getChartBlockHeight() - legendBlock.coordinate.bottom.margin.bottom);
75
+ return LegendCanvasModel.findElementsAmountByLegendSize(legendItemContentOptions, position, this.polarMarginCalculator.getMaxLegendWidth(legendCanvas, canvasModel.getBlockSize().width), canvasModel.getChartBlockHeight() - legendBlock.coordinate.right.margin.bottom);
87
76
  }
88
77
  else {
89
78
  return LegendCanvasModel.findElementsAmountByLegendSize(legendItemContentOptions, position, canvasModel.getChartBlockWidth() - legendBlock.coordinate.bottom.margin.left - legendBlock.coordinate.bottom.margin.right, canvasModel.getChartBlockHeight() - legendBlock.coordinate.bottom.margin.bottom - legendBlock.coordinate.bottom.margin.top - MIN_DONUT_BLOCK_SIZE);
@@ -100,17 +89,17 @@ export class DataManagerModel {
100
89
  * @param configOptions
101
90
  * @param chartsLength
102
91
  */
103
- static getElementsInGroupAmount(configOptions, chartsLength) {
104
- if (configOptions.type === '2d')
105
- return this.getBarChartsInGroupAmount(configOptions.charts);
106
- return chartsLength;
92
+ static getElementsInGroupAmount(configOptions) {
93
+ const bars = this.getBarLikeChartsInGroupAmount(configOptions.charts, 'bar');
94
+ const dots = configOptions.charts.some(chart => chart.type === 'dot') ? 1 : 0;
95
+ return Math.max(bars, dots);
107
96
  }
108
- static getBarChartsInGroupAmount(charts) {
97
+ static getBarLikeChartsInGroupAmount(charts, type) {
109
98
  let barsAmount = 0;
110
99
  charts.forEach(chart => {
111
- if (chart.type === 'bar' && chart.isSegmented)
100
+ if (chart.type === type && chart.isSegmented)
112
101
  barsAmount += 1; // в сегментированном баре все valueFields находятся внутри одного бара, поэтому бар всегда один.
113
- else if (chart.type === 'bar')
102
+ else if (chart.type === type)
114
103
  barsAmount += chart.data.valueFields.length;
115
104
  });
116
105
  return barsAmount;
@@ -123,13 +112,6 @@ export class DataManagerModel {
123
112
  static getScopedChartData(data, allowableKeys, keyFieldName) {
124
113
  return data.filter(d => allowableKeys.findIndex(key => key === d[keyFieldName]) !== -1);
125
114
  }
126
- static getTypedData(data, field) {
127
- if (field.format === 'date')
128
- data.forEach(d => {
129
- d[field.name] = new Date(d[field.name]);
130
- });
131
- return data;
132
- }
133
115
  static getDataLimitByItemSize(elementsInGroupAmount, dataLength, axisLength, barOptions) {
134
116
  let sumSize = dataLength * (elementsInGroupAmount * barOptions.minBarWidth + (elementsInGroupAmount - 1) * barOptions.barDistance + barOptions.groupMinDistance);
135
117
  while (dataLength !== 0 && axisLength < sumSize) {
@@ -21,7 +21,6 @@ export declare class AxisModel {
21
21
  static getAxisTranslateY(axisType: AxisType, chartOrientation: ChartOrientation, axisPosition: AxisPosition, canvasModel: CanvasModel): number;
22
22
  static getKeyAxisLabelPosition(canvasModel: CanvasModel, scopedDataLength: number, axisConfig?: DiscreteAxisOptions): AxisLabelPosition;
23
23
  static getLabelSize(labelMaxWidth: number, labelTexts: string[]): LabelSize;
24
- static getLabelSizeLegacy(labelMaxWidth: number, labelTexts: string[]): LabelSize;
25
24
  static getRoundValue(value: number): number;
26
25
  private static getKeyAxisTranslateModel;
27
26
  }
@@ -1,13 +1,14 @@
1
1
  import { ModelHelper } from "../helpers/modelHelper";
2
- import { AxisType, CLASSES } from "../modelBuilder";
2
+ import { AxisType } from "../modelBuilder";
3
3
  import { DataManagerModel } from "../dataManagerModel/dataManagerModel";
4
4
  import { TwoDimensionalModel } from "../notations/twoDimensionalModel";
5
5
  import { AxisModelService, AxisModelTickCalculator, showAllTicks } from "./axisModelService";
6
6
  export const MINIMAL_VERTICAL_STEP_SIZE = 60;
7
7
  export const MINIMAL_HORIZONTAL_STEP_SIZE = 100;
8
+ const DEFAULT_AXIS_LINE_VISIBLE = true;
8
9
  export class AxisModel {
9
10
  static getKeyAxis(options, data, labelConfig, canvasModel, tooltipSettings, getZeroCoordinate) {
10
- var _a;
11
+ var _a, _b, _c;
11
12
  const { charts, orientation, data: dataOptions } = options;
12
13
  const axisConfig = options.axis.key;
13
14
  const translate = this.getKeyAxisTranslateModel(orientation, axisConfig.position, canvasModel, getZeroCoordinate);
@@ -26,7 +27,10 @@ export class AxisModel {
26
27
  showTick: tickCalculator.createFunctionCalculator(this.getAxisLength(orientation, canvasModel)),
27
28
  linearTickStep: MINIMAL_HORIZONTAL_STEP_SIZE
28
29
  },
29
- visibility: axisConfig.visibility
30
+ visibility: axisConfig.visibility,
31
+ line: {
32
+ visible: (_c = (_b = axisConfig.line) === null || _b === void 0 ? void 0 : _b.visible) !== null && _c !== void 0 ? _c : DEFAULT_AXIS_LINE_VISIBLE
33
+ }
30
34
  };
31
35
  }
32
36
  static getMainValueAxis(orient, position, axisConfig, labelConfig, canvasModel) {
@@ -36,7 +40,7 @@ export class AxisModel {
36
40
  return this.getValueAxis(orient, mainAxisPosition === "start" ? "end" : "start", 'value-secondary-axis', axisConfig, labelConfig, canvasModel);
37
41
  }
38
42
  static getValueAxis(orient, position, cssClass, axisConfig, labelConfig, canvasModel) {
39
- var _a, _b;
43
+ var _a, _b, _c, _d;
40
44
  return {
41
45
  type: 'value',
42
46
  orient: AxisModel.getAxisOrient(AxisType.Value, orient, position),
@@ -54,7 +58,10 @@ export class AxisModel {
54
58
  showTick: showAllTicks,
55
59
  linearTickStep: (_b = (_a = axisConfig.labels) === null || _a === void 0 ? void 0 : _a.stepSize) !== null && _b !== void 0 ? _b : (orient === "horizontal" ? MINIMAL_HORIZONTAL_STEP_SIZE : MINIMAL_VERTICAL_STEP_SIZE)
56
60
  },
57
- visibility: axisConfig.visibility
61
+ visibility: axisConfig.visibility,
62
+ line: {
63
+ visible: (_d = (_c = axisConfig.line) === null || _c === void 0 ? void 0 : _c.visible) !== null && _d !== void 0 ? _d : DEFAULT_AXIS_LINE_VISIBLE
64
+ }
58
65
  };
59
66
  }
60
67
  static getAxisLength(chartOrientation, canvasModel) {
@@ -105,33 +112,6 @@ export class AxisModel {
105
112
  width: longestLabelWidth > labelMaxWidth ? labelMaxWidth : longestLabelWidth
106
113
  };
107
114
  }
108
- static getLabelSizeLegacy(labelMaxWidth, labelTexts) {
109
- const labelSize = {
110
- width: 0,
111
- height: 0
112
- };
113
- const textBlock = document.createElement('span');
114
- textBlock.style.opacity = '0';
115
- textBlock.style.position = 'absolute';
116
- textBlock.style.whiteSpace = 'nowrap';
117
- textBlock.classList.add(CLASSES.dataLabel);
118
- let maxLabel = '';
119
- let biggestScore = 0;
120
- let maxWidth = 0;
121
- labelTexts.forEach((text) => {
122
- if (ModelHelper.getStringScore(text) > biggestScore) {
123
- maxLabel = text;
124
- biggestScore = ModelHelper.getStringScore(text);
125
- }
126
- });
127
- textBlock.textContent = maxLabel === '0000' ? maxLabel : maxLabel;
128
- document.body.append(textBlock);
129
- maxWidth = Math.ceil(textBlock.getBoundingClientRect().width);
130
- labelSize.height = textBlock.getBoundingClientRect().height;
131
- labelSize.width = maxWidth > labelMaxWidth ? labelMaxWidth : maxWidth;
132
- textBlock.remove();
133
- return labelSize;
134
- }
135
115
  static getRoundValue(value) {
136
116
  const absValue = Math.abs(value);
137
117
  const sign = Math.sign(value);
@@ -13,7 +13,6 @@ export interface LegendItemContentOptions {
13
13
  };
14
14
  }
15
15
  export declare class LegendCanvasModel {
16
- static getLegendItemWidth(text: string): number;
17
16
  static findElementsAmountByLegendSize(items: LegendItemContentOptions[], position: LegendPosition, legendBlockWidth: number, legendBlockHeight: number): DataLegendParams;
18
17
  private static getLegendWrapperEl;
19
18
  }