mdt-charts 1.21.1 → 1.22.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 (36) hide show
  1. package/lib/config/config.d.ts +17 -11
  2. package/lib/engine/features/legend/legendHelperService.js +1 -1
  3. package/lib/engine/features/legend/legendMarkerCreator.js +2 -2
  4. package/lib/engine/twoDimensionalNotation/bar/bar.js +6 -6
  5. package/lib/engine/twoDimensionalNotation/bar/barHelper.d.ts +31 -4
  6. package/lib/engine/twoDimensionalNotation/bar/barHelper.js +54 -21
  7. package/lib/engine/twoDimensionalNotation/dot/dotChart.d.ts +36 -0
  8. package/lib/engine/twoDimensionalNotation/dot/dotChart.js +106 -0
  9. package/lib/engine/twoDimensionalNotation/twoDimensionalManager.d.ts +1 -0
  10. package/lib/engine/twoDimensionalNotation/twoDimensionalManager.js +20 -0
  11. package/lib/model/dataManagerModel/dataManagerModel.d.ts +1 -2
  12. package/lib/model/dataManagerModel/dataManagerModel.js +14 -32
  13. package/lib/model/featuresModel/axisModel.d.ts +0 -1
  14. package/lib/model/featuresModel/axisModel.js +1 -28
  15. package/lib/model/featuresModel/legendModel/legendCanvasModel.d.ts +0 -1
  16. package/lib/model/featuresModel/legendModel/legendCanvasModel.js +0 -18
  17. package/lib/model/featuresModel/legendModel/twoDimLegendModel.d.ts +0 -1
  18. package/lib/model/featuresModel/legendModel/twoDimLegendModel.js +0 -4
  19. package/lib/model/featuresModel/scaleModel/scaleModel.d.ts +1 -1
  20. package/lib/model/featuresModel/scaleModel/scaleModel.js +5 -5
  21. package/lib/model/featuresModel/scaleModel/scaleModelServices.d.ts +1 -1
  22. package/lib/model/featuresModel/scaleModel/scaleModelServices.js +15 -9
  23. package/lib/model/helpers/twoDimensionalModelHelper.d.ts +1 -0
  24. package/lib/model/helpers/twoDimensionalModelHelper.js +16 -8
  25. package/lib/model/margin/twoDim/twoDimMarginModel.d.ts +2 -2
  26. package/lib/model/margin/twoDim/twoDimMarginModel.js +2 -2
  27. package/lib/model/model.d.ts +14 -2
  28. package/lib/model/modelBuilder.js +1 -3
  29. package/lib/model/modelInstance/configReader.js +5 -5
  30. package/lib/model/notations/polar/polarModel.js +1 -1
  31. package/lib/model/notations/twoDimensional/styles.js +4 -3
  32. package/lib/model/notations/twoDimensionalModel.d.ts +1 -1
  33. package/lib/model/notations/twoDimensionalModel.js +32 -11
  34. package/lib/style/charts-main.css +2 -2
  35. package/lib/style/charts-main.less +2 -2
  36. package/package.json +1 -1
@@ -4,7 +4,7 @@ export declare type AxisPosition = 'start' | 'end';
4
4
  export declare type ChartOrientation = 'vertical' | 'horizontal';
5
5
  export declare type ChartNotation = '2d' | 'polar' | 'interval';
6
6
  export declare type ChartType = 'bar' | 'line' | 'area' | 'donut' | 'gantt';
7
- export declare type TwoDimensionalChartType = 'line' | 'bar' | 'area';
7
+ export declare type TwoDimensionalChartType = 'line' | 'bar' | 'area' | 'dot';
8
8
  export declare type PolarChartType = 'donut';
9
9
  export declare type IntervalChartType = 'gantt';
10
10
  export declare type EmbeddedLabelType = 'none' | 'key' | 'value';
@@ -186,12 +186,6 @@ export interface IntervalAxis {
186
186
  }
187
187
  interface DateAxisOptions extends AxisOptions {
188
188
  }
189
- interface ChartSettings {
190
- tooltip: Tooltip;
191
- }
192
- interface Tooltip {
193
- show: boolean;
194
- }
195
189
  interface MdtChartsLineLikeChart {
196
190
  markers: MarkersOptions;
197
191
  lineStyles?: MdtChartsLineLikeChartStyles;
@@ -217,6 +211,7 @@ export interface AreaStylesBorderLine {
217
211
  }
218
212
  interface MdtChartsBarLikeChart {
219
213
  barStyles?: MdtChartsBarLikeChartStyles;
214
+ embeddedLabels: EmbeddedLabelType;
220
215
  }
221
216
  interface MdtChartsBarLikeChartStyles {
222
217
  hatch?: MdtChartsBarLikeChartHatchedStyles;
@@ -224,19 +219,30 @@ interface MdtChartsBarLikeChartStyles {
224
219
  interface MdtChartsBarLikeChartHatchedStyles {
225
220
  on: boolean;
226
221
  }
227
- export interface MdtChartsTwoDimensionalChart extends ChartSettings, MdtChartsLineLikeChart, MdtChartsBarLikeChart {
222
+ interface MdtChartsDotChart {
223
+ /** @alpha */
224
+ dotLikeStyles?: MdtChartsDotLikeChartStyles;
225
+ }
226
+ interface MdtChartsDotLikeChartStyles {
227
+ shape?: MdtChartsDotLikeChartShape;
228
+ }
229
+ interface MdtChartsDotLikeChartShape {
230
+ type: "line";
231
+ width?: number;
232
+ }
233
+ export interface MdtChartsTwoDimensionalChart extends MdtChartsLineLikeChart, MdtChartsBarLikeChart, MdtChartsDotChart {
234
+ /** @alpha dot type has no full support */
228
235
  type: TwoDimensionalChartType;
229
236
  data: TwoDimensionalChartData;
230
- embeddedLabels: EmbeddedLabelType;
231
237
  isSegmented: boolean;
232
238
  valueLabels?: TwoDimensionalChartValueLabels;
233
239
  }
234
- export interface PolarChart extends ChartSettings {
240
+ export interface PolarChart {
235
241
  type: PolarChartType;
236
242
  data: PolarChartData;
237
243
  aggregator?: MdtChartsDonutAggregator;
238
244
  }
239
- export interface IntervalChart extends ChartSettings {
245
+ export interface IntervalChart {
240
246
  type: IntervalChartType;
241
247
  data: IntervalChartData;
242
248
  }
@@ -25,6 +25,6 @@ export class LegendHelperService {
25
25
  return "row";
26
26
  }
27
27
  doesLegendInTopBy2d(legendPosition, chartNotation) {
28
- return legendPosition === 'top' && chartNotation === "2d";
28
+ return (legendPosition === 'top' || legendPosition === 'bottom') && chartNotation === "2d";
29
29
  }
30
30
  }
@@ -34,7 +34,7 @@ class SvgMarkerCreator {
34
34
  renderSvg(selection) {
35
35
  return selection.append('svg')
36
36
  .style("display", "inline-block")
37
- .style("height", '10px')
37
+ .style("height", '8px')
38
38
  .classed(Legend.markerClass, true);
39
39
  }
40
40
  }
@@ -49,7 +49,7 @@ class BarMarkerCreator extends SvgMarkerCreator {
49
49
  .append('rect')
50
50
  .attr('x', 0)
51
51
  .attr('y', 0)
52
- .attr('height', 10)
52
+ .attr('height', this.options.width)
53
53
  .attr('width', this.options.width)
54
54
  .style('fill', color);
55
55
  if (this.options.hatch.on) {
@@ -19,7 +19,7 @@ export class Bar {
19
19
  }
20
20
  render(block, scales, data, keyField, margin, keyAxisOrient, chart, blockSize, barSettings, barsAmounts, isSegmented, firstBarIndex) {
21
21
  if (isSegmented)
22
- this.renderSegmented(block, scales, data, keyField, margin, keyAxisOrient, chart, barsAmounts, blockSize, firstBarIndex, barSettings);
22
+ this.renderSegmented(block, scales, data, keyField, margin, keyAxisOrient, chart, barsAmounts, firstBarIndex, barSettings);
23
23
  else
24
24
  this.renderGrouped(block, scales, data, keyField, margin, keyAxisOrient, chart, barsAmounts, blockSize, firstBarIndex, barSettings);
25
25
  }
@@ -53,7 +53,7 @@ export class Bar {
53
53
  .attr('class', this.barItemClass)
54
54
  .style('clip-path', `url(#${block.svg.getClipPathId()})`);
55
55
  bars = this.createBarPipeline.execute(bars, chart);
56
- const barAttrs = BarHelper.getGroupedBarAttrs(keyAxisOrient, scales, margin, keyField.name, field.name, blockSize, BarHelper.getBarIndex(barsAmounts, chart.index - firstBarIndex) + index, sum(barsAmounts), barSettings);
56
+ const barAttrs = BarHelper.getGroupedBarAttrs(keyAxisOrient, scales, margin, keyField.name, field.name, BarHelper.getBarIndex(barsAmounts, chart.index - firstBarIndex) + index, sum(barsAmounts), barSettings);
57
57
  this.fillBarAttrs(bars, barAttrs);
58
58
  DomHelper.setCssClasses(bars, Helper.getCssClassesWithElementIndex(chart.cssClasses, index));
59
59
  DomHelper.setChartStyle(bars, chart.style, index, 'fill');
@@ -62,7 +62,7 @@ export class Bar {
62
62
  EmbeddedLabels.render(block, bars, barAttrs, EmbeddedLabelsHelper.getLabelField(chart.embeddedLabels, chart.data.valueFields, keyField, index), chart.embeddedLabels, keyAxisOrient, blockSize, margin, index, chart.cssClasses);
63
63
  });
64
64
  }
65
- renderSegmented(block, scales, data, keyField, margin, keyAxisOrient, chart, barsAmounts, blockSize, firstBarIndex, barSettings) {
65
+ renderSegmented(block, scales, data, keyField, margin, keyAxisOrient, chart, barsAmounts, firstBarIndex, barSettings) {
66
66
  const stackedData = getStackedDataWithOwn(data, chart.data.valueFields.map(field => field.name));
67
67
  let groups = block.svg.getChartGroup(chart.index)
68
68
  .selectAll(`g.${this.barSegmentGroupClass}${Helper.getCssClassesLine(chart.cssClasses)}`)
@@ -81,7 +81,7 @@ export class Bar {
81
81
  .attr('class', this.barItemClass)
82
82
  .style('clip-path', `url(#${block.svg.getClipPathId()})`);
83
83
  bars = this.createBarPipeline.execute(bars, chart);
84
- const barAttrs = BarHelper.getStackedBarAttr(keyAxisOrient, scales, margin, keyField.name, blockSize, BarHelper.getBarIndex(barsAmounts, chart.index) - firstBarIndex, sum(barsAmounts), barSettings);
84
+ const barAttrs = BarHelper.getStackedBarAttr(keyAxisOrient, scales, margin, keyField.name, BarHelper.getBarIndex(barsAmounts, chart.index) - firstBarIndex, sum(barsAmounts), barSettings);
85
85
  this.fillBarAttrs(bars, barAttrs);
86
86
  this.setInitialAttrsInfo(bars, keyAxisOrient, barSettings);
87
87
  DomHelper.setCssClasses(groups, chart.cssClasses);
@@ -120,7 +120,7 @@ export class Bar {
120
120
  .attr('class', this.barItemClass)
121
121
  .style('clip-path', `url(#${block.svg.getClipPathId()})`);
122
122
  newBars = this.createBarPipeline.execute(newBars, chart);
123
- const barAttrs = BarHelper.getGroupedBarAttrs(keyAxisOrient, scales, margin, keyField.name, valueField.name, blockSize, BarHelper.getBarIndex(barsAmounts, chart.index) + index - firstBarIndex, sum(barsAmounts), barSettings);
123
+ const barAttrs = BarHelper.getGroupedBarAttrs(keyAxisOrient, scales, margin, keyField.name, valueField.name, BarHelper.getBarIndex(barsAmounts, chart.index) + index - firstBarIndex, sum(barsAmounts), barSettings);
124
124
  const prom = this.fillBarAttrs(bars, barAttrs, block.transitionManager.durations.chartUpdate)
125
125
  .then(() => {
126
126
  bars.style('opacity', null);
@@ -163,7 +163,7 @@ export class Bar {
163
163
  .attr('class', this.barItemClass)
164
164
  .style('clip-path', `url(#${block.svg.getClipPathId()})`);
165
165
  newBars = this.createBarPipeline.execute(newBars, chart);
166
- const barAttrs = BarHelper.getStackedBarAttr(keyAxisOrient, scales, margin, keyField.name, blockSize, BarHelper.getBarIndex(barsAmounts, chart.index) - firstBarIndex, sum(barsAmounts), barSettings);
166
+ const barAttrs = BarHelper.getStackedBarAttr(keyAxisOrient, scales, margin, keyField.name, BarHelper.getBarIndex(barsAmounts, chart.index) - firstBarIndex, sum(barsAmounts), barSettings);
167
167
  const prom = this.fillBarAttrs(bars, barAttrs, block.transitionManager.durations.chartUpdate)
168
168
  .then(() => {
169
169
  this.setInitialAttrsInfo(bars, keyAxisOrient, barSettings);
@@ -1,6 +1,7 @@
1
+ import { AxisScale } from "d3-axis";
1
2
  import { 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,32 @@ export interface BarAttrsHelper {
9
10
  width: (dataRow: MdtChartsDataRow) => number;
10
11
  height: (dataRow: MdtChartsDataRow) => number;
11
12
  }
13
+ interface BandLikeChartSettingsStore {
14
+ getBandItemSize(): number;
15
+ getBandItemPad(bandItemIndex: number): number;
16
+ }
17
+ export declare class DotChartSettingsStore implements BandLikeChartSettingsStore {
18
+ private readonly canvasConfig;
19
+ constructor(canvasConfig: {
20
+ scaleBandWidth: number;
21
+ });
22
+ getBandItemSize(): number;
23
+ getBandItemPad(): number;
24
+ }
25
+ export declare class BarSettingsStore {
26
+ private readonly modelSettings;
27
+ private readonly canvasConfig;
28
+ constructor(modelSettings: BarChartSettings, canvasConfig: {
29
+ scaleBandWidth: number;
30
+ barsAmount: number;
31
+ });
32
+ getBandItemSize(): number;
33
+ getBandItemPad(barIndex: number): number;
34
+ private getBarStep;
35
+ }
12
36
  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;
37
+ static getGroupedBarAttrs(keyAxisOrient: Orient, scales: Scales, margin: BlockMargin, keyField: string, valueFieldName: string, barIndex: number, barsAmount: number, barSettings: BarChartSettings): BarAttrsHelper;
38
+ static getStackedBarAttr(keyAxisOrient: Orient, scales: Scales, margin: BlockMargin, keyField: string, barIndex: number, barsAmount: number, barSettings: BarChartSettings): BarAttrsHelper;
15
39
  static getBarsInGroupAmount(charts: TwoDimensionalChartModel[]): number[];
16
40
  /**
17
41
  * Получение индекса бара среди всх графиков и value-филдов. Используется для того, чтобы узнать, какой по счету в группе
@@ -20,8 +44,11 @@ export declare class BarHelper {
20
44
  * @param chartIndex
21
45
  */
22
46
  static getBarIndex(barsAmounts: number[], chartIndex: number): number;
23
- private static setBarAttrsByKey;
47
+ static setBarAttrsByKey(attrs: BarAttrsHelper, keyAxisOrient: Orient, scaleKey: AxisScale<any>, margin: BlockMargin, keyField: string, barIndex: number, settingsStore: BandLikeChartSettingsStore, isSegmented: boolean): void;
24
48
  private static setGroupedBarAttrsByValue;
49
+ static getBandItemValueStretch(scaleValue: AxisScale<any>, valueFieldName: string): (dataRow: MdtChartsDataRow) => number;
50
+ static setGroupedBandStartCoordinateAttr(attrs: BarAttrsHelper, keyAxisOrient: Orient, scaleValue: AxisScale<any>, margin: BlockMargin, valueFieldName: string): void;
25
51
  private static setSegmentedBarAttrsByValue;
26
52
  }
27
53
  export declare function onBarChartInit(createBarPipeline: Pipeline<Selection<SVGRectElement, any, BaseType, any>, TwoDimensionalChartModel>): void;
54
+ 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();
91
+ }
92
+ }
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);
66
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));
67
104
  }
68
- static setGroupedBarAttrsByValue(attrs, keyAxisOrient, margin, scaleValue, valueFieldName, blockSize) {
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]));
@@ -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
+ }
@@ -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;
@@ -23,6 +24,20 @@ export class TwoDimensionalManager {
23
24
  engine.block.svg.render(model.blockCanvas.size);
24
25
  Axis.render(engine.block, scales, options.scale, options.axis, model.blockCanvas.size);
25
26
  GridLine.render(engine.block, options.additionalElements.gridLine.flag, 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);
@@ -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);
@@ -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,5 +1,5 @@
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";
@@ -105,33 +105,6 @@ export class AxisModel {
105
105
  width: longestLabelWidth > labelMaxWidth ? labelMaxWidth : longestLabelWidth
106
106
  };
107
107
  }
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
108
  static getRoundValue(value) {
136
109
  const absValue = Math.abs(value);
137
110
  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
  }
@@ -1,23 +1,5 @@
1
1
  import { CLASSES } from "../../modelBuilder";
2
2
  export class LegendCanvasModel {
3
- static getLegendItemWidth(text) {
4
- const itemWrapper = document.createElement('div');
5
- itemWrapper.style.opacity = '0';
6
- const colorBlock = document.createElement('span');
7
- const textBlock = document.createElement('span');
8
- itemWrapper.style.display = 'inline-block';
9
- itemWrapper.classList.add(CLASSES.legendItem);
10
- colorBlock.classList.add(CLASSES.legendColor);
11
- textBlock.classList.add(CLASSES.legendLabel);
12
- textBlock.textContent = text;
13
- itemWrapper.append(colorBlock, textBlock);
14
- document.body.append(itemWrapper);
15
- const sumWidth = itemWrapper.getBoundingClientRect().width
16
- + parseFloat(window.getComputedStyle(itemWrapper, null).getPropertyValue('margin-left'))
17
- + parseFloat(window.getComputedStyle(itemWrapper, null).getPropertyValue('margin-right'));
18
- itemWrapper.remove();
19
- return sumWidth;
20
- }
21
3
  //TODO: find better solution
22
4
  static findElementsAmountByLegendSize(items, position, legendBlockWidth, legendBlockHeight) {
23
5
  const legendWrapper = this.getLegendWrapperEl(legendBlockWidth, position === "right" ? "column" : "row");
@@ -6,6 +6,5 @@ export declare class TwoDimLegendModel {
6
6
  private configReader;
7
7
  constructor(configReader: TwoDimConfigReader);
8
8
  recalcMarginWith2DLegend(modelInstance: ModelInstance, legendBlockModel: LegendBlockModel, legendOptions: Legend): void;
9
- private getLegendSizeLegacy;
10
9
  private getLegendModel;
11
10
  }
@@ -23,10 +23,6 @@ export class TwoDimLegendModel {
23
23
  legendBlockModel.coordinate[legendPosition].size = legendSize;
24
24
  }
25
25
  }
26
- getLegendSizeLegacy() {
27
- const heightOfLegendItemWithoutWordWrapping = 20;
28
- return heightOfLegendItemWithoutWordWrapping;
29
- }
30
26
  getLegendModel(legendOptions) {
31
27
  const position = legendOptions.show ? "top" : "off";
32
28
  return {
@@ -7,7 +7,7 @@ export declare enum ScaleType {
7
7
  Value = 1
8
8
  }
9
9
  export declare class ScaleModel {
10
- getScaleKey(allowableKeys: string[], orient: ChartOrientation, canvasModel: CanvasModel, charts: MdtChartsTwoDimensionalChart[], barCharts: MdtChartsTwoDimensionalChart[]): ScaleKeyModel;
10
+ getScaleKey(allowableKeys: string[], orient: ChartOrientation, canvasModel: CanvasModel, charts: MdtChartsTwoDimensionalChart[], bandLikeCharts: MdtChartsTwoDimensionalChart[]): ScaleKeyModel;
11
11
  getScaleLinear(options: MdtChartsTwoDimensionalOptions, dataRows: MdtChartsDataRow[], canvasModel: CanvasModel, configReader?: TwoDimConfigReader): ScaleValueModel;
12
12
  getScaleSecondaryLinear(options: MdtChartsTwoDimensionalOptions, dataRows: MdtChartsDataRow[], canvasModel: CanvasModel, configReader?: TwoDimConfigReader): ScaleValueModel;
13
13
  private getScaleKeyType;
@@ -6,7 +6,7 @@ export var ScaleType;
6
6
  ScaleType[ScaleType["Value"] = 1] = "Value";
7
7
  })(ScaleType || (ScaleType = {}));
8
8
  export class ScaleModel {
9
- getScaleKey(allowableKeys, orient, canvasModel, charts, barCharts) {
9
+ getScaleKey(allowableKeys, orient, canvasModel, charts, bandLikeCharts) {
10
10
  return {
11
11
  domain: allowableKeys,
12
12
  range: {
@@ -14,7 +14,7 @@ export class ScaleModel {
14
14
  end: getScaleKeyRangePeek(orient, canvasModel)
15
15
  },
16
16
  type: this.getScaleKeyType(charts),
17
- elementsAmount: getElementsAmountForScale(barCharts)
17
+ elementsAmount: getElementsAmountForScale(bandLikeCharts)
18
18
  };
19
19
  }
20
20
  getScaleLinear(options, dataRows, canvasModel, configReader) {
@@ -42,8 +42,8 @@ export class ScaleModel {
42
42
  };
43
43
  }
44
44
  getScaleKeyType(charts) {
45
- if (charts.findIndex((chart) => chart.type === 'bar') === -1)
46
- return 'point';
47
- return 'band';
45
+ if (charts.some((chart) => chart.type === 'bar' || chart.type === 'dot'))
46
+ return 'band';
47
+ return 'point';
48
48
  }
49
49
  }
@@ -2,4 +2,4 @@ import { ChartOrientation, MdtChartsTwoDimensionalChart } from "../../../config/
2
2
  import { CanvasSizesModel } from "../../modelInstance/canvasModel/canvasSizesModel/canvasSizeModel";
3
3
  export declare function getScaleKeyRangePeek(chartOrientation: ChartOrientation, canvasModel: CanvasSizesModel): number;
4
4
  export declare function getScaleValueRangePeek(chartOrientation: string, canvasModel: CanvasSizesModel): number;
5
- export declare function getElementsAmountForScale(barCharts: MdtChartsTwoDimensionalChart[]): number;
5
+ export declare function getElementsAmountForScale(bandLikeCharts: MdtChartsTwoDimensionalChart[]): number;
@@ -8,15 +8,21 @@ export function getScaleValueRangePeek(chartOrientation, canvasModel) {
8
8
  return canvasModel.getChartBlockHeight();
9
9
  return canvasModel.getChartBlockWidth();
10
10
  }
11
- export function getElementsAmountForScale(barCharts) {
12
- if (barCharts.length === 0)
11
+ export function getElementsAmountForScale(bandLikeCharts) {
12
+ if (bandLikeCharts.length === 0)
13
13
  return 1;
14
- let barsAmount = 0;
15
- barCharts.forEach(chart => {
16
- if (chart.isSegmented)
17
- barsAmount += 1; // Если бар сегментированный, то все valueFields являются частями одного бара
18
- else
19
- barsAmount += chart.data.valueFields.length;
14
+ let barAmounts = {};
15
+ bandLikeCharts.forEach(chart => {
16
+ if (!barAmounts[chart.type])
17
+ barAmounts[chart.type] = 0;
18
+ if (chart.type === 'dot')
19
+ barAmounts[chart.type] = 1;
20
+ if (chart.type === 'bar') {
21
+ if (chart.isSegmented)
22
+ barAmounts[chart.type] += 1;
23
+ else
24
+ barAmounts[chart.type] += chart.data.valueFields.length;
25
+ }
20
26
  });
21
- return barsAmount;
27
+ return Math.max(...Object.values(barAmounts));
22
28
  }
@@ -5,4 +5,5 @@ export declare class TwoDimensionalModelHelper {
5
5
  static getGradientDefs(charts: TwoDimensionalChartModel[], keyAxisOrient: Orient, chartOrient: ChartOrientation): GradientDef[];
6
6
  private static getGradientItems;
7
7
  private static calculateOpacityItem;
8
+ private static getGradientItemColor;
8
9
  }
@@ -37,20 +37,28 @@ export class TwoDimensionalModelHelper {
37
37
  return gradients;
38
38
  }
39
39
  static getGradientItems(gradientId, elementColor, keyAxisOrient) {
40
- return [0, 1].map(indexItem => ({
41
- id: gradientId + `-item-${indexItem}`,
42
- color: elementColor,
43
- offset: indexItem,
44
- opacity: this.calculateOpacityItem(indexItem, keyAxisOrient)
40
+ return [0, 1].map(itemIndex => ({
41
+ id: gradientId + `-item-${itemIndex}`,
42
+ color: this.getGradientItemColor(itemIndex, keyAxisOrient, elementColor),
43
+ offset: itemIndex,
44
+ opacity: this.calculateOpacityItem(itemIndex, keyAxisOrient)
45
45
  }));
46
46
  }
47
- static calculateOpacityItem(indexItem, orientation) {
47
+ static calculateOpacityItem(itemIndex, orientation) {
48
48
  const maxOpacity = 0.3;
49
49
  const minOpacity = 0;
50
50
  if (orientation === 'bottom' || orientation === 'right')
51
- return indexItem === 0 ? maxOpacity : minOpacity;
51
+ return itemIndex === 0 ? maxOpacity : minOpacity;
52
52
  else
53
- return indexItem === 0 ? minOpacity : maxOpacity;
53
+ return itemIndex === 0 ? minOpacity : maxOpacity;
54
54
  }
55
55
  ;
56
+ static getGradientItemColor(itemIndex, orientation, elementColor) {
57
+ const maxColor = elementColor;
58
+ const minColor = "white";
59
+ if (orientation === 'bottom' || orientation === 'right')
60
+ return itemIndex === 0 ? maxColor : minColor;
61
+ else
62
+ return itemIndex === 0 ? minColor : maxColor;
63
+ }
56
64
  }
@@ -2,8 +2,8 @@ import { DesignerConfig } from "../../../designer/designerConfig";
2
2
  import { OtherCommonComponents } from "../../model";
3
3
  import { TwoDimConfigReader } from "../../modelInstance/configReader";
4
4
  import { ModelInstance } from "../../modelInstance/modelInstance";
5
- export declare const AXIS_HORIZONTAL_LABEL_PADDING = 15;
6
- export declare const AXIS_VERTICAL_LABEL_PADDING = 10;
5
+ export declare const AXIS_HORIZONTAL_LABEL_PADDING = 20;
6
+ export declare const AXIS_VERTICAL_LABEL_PADDING = 8;
7
7
  export declare class TwoDimMarginModel {
8
8
  private designerConfig;
9
9
  private configReader;
@@ -3,8 +3,8 @@ import { TwoDimLegendModel } from "../../featuresModel/legendModel/twoDimLegendM
3
3
  import { keyAxisLabelHorizontalLog, keyAxisLabelVerticalLog } from "../../featuresModel/scaleModel/scaleAxisRecalcer";
4
4
  import { AxisType } from "../../modelBuilder";
5
5
  import { TwoDimensionalModel } from "../../notations/twoDimensionalModel";
6
- export const AXIS_HORIZONTAL_LABEL_PADDING = 15;
7
- export const AXIS_VERTICAL_LABEL_PADDING = 10;
6
+ export const AXIS_HORIZONTAL_LABEL_PADDING = 20;
7
+ export const AXIS_VERTICAL_LABEL_PADDING = 8;
8
8
  export class TwoDimMarginModel {
9
9
  constructor(designerConfig, configReader) {
10
10
  this.designerConfig = designerConfig;
@@ -272,14 +272,26 @@ export interface AreaViewBorderLine {
272
272
  on: boolean;
273
273
  colorStyle: ChartStyle;
274
274
  }
275
- export interface TwoDimensionalChartModel extends ChartModel, TwoDimensionalLineLikeChartModel, TwoDimensionalBarLikeChartModel, TwoDimensionalAreaChartModel {
275
+ export interface DotChartModel {
276
+ dotViewOptions: DotChartViewModel;
277
+ }
278
+ export interface DotChartViewModel {
279
+ shape: DotChartShapeOptions;
280
+ }
281
+ interface DotChartShapeOptions {
282
+ type: "line";
283
+ handleStartCoordinate: (calculatedBandItemStartCoordinate: number) => number;
284
+ handleEndCoordinate: (calculatedBandItemSize: number) => number;
285
+ width: number;
286
+ }
287
+ export interface TwoDimensionalChartModel extends ChartModel, TwoDimensionalLineLikeChartModel, TwoDimensionalBarLikeChartModel, TwoDimensionalAreaChartModel, DotChartModel, DotChartModel {
276
288
  type: TwoDimensionalChartType;
277
289
  data: TwoDimensionalChartDataModel;
278
290
  index: number;
279
291
  embeddedLabels: EmbeddedLabelTypeModel;
280
292
  isSegmented: boolean;
281
293
  legend: ChartLegendModel;
282
- valueLabels?: TwoDimChartValueLabelsOptions;
294
+ valueLabels: TwoDimChartValueLabelsOptions;
283
295
  }
284
296
  export interface IntervalChartModel extends Omit<ChartModel, "legend"> {
285
297
  type: IntervalChartType;
@@ -76,12 +76,10 @@ export function assembleModel(config, data, designerConfig) {
76
76
  options: null,
77
77
  dataSettings: null
78
78
  };
79
- const dataRows = modelInstance.dataModel.repository.getRawRows();
80
- const resolvedTitle = getResolvedTitle(config.options.title, dataRows);
81
79
  const otherComponents = OtherComponentsModel.getOtherComponentsModel({
82
80
  elementsOptions: designerConfig.elementsOptions,
83
81
  legendConfig: designerConfig.canvas.legendBlock,
84
- title: resolvedTitle
82
+ title: getResolvedTitle(config.options.title, modelInstance.dataModel.repository.getRawRows())
85
83
  }, modelInstance);
86
84
  const marginModel = new MarginModel(designerConfig, config);
87
85
  marginModel.initMargin(otherComponents, modelInstance);
@@ -55,18 +55,18 @@ export class TwoDimConfigReader {
55
55
  return !!this.options.axis.valueSecondary && this.options.charts.some(chart => chart.data.valueGroup === 'secondary');
56
56
  }
57
57
  getValueLabelFormatterForChart(chartIndex) {
58
- var _a, _b, _c;
58
+ var _a, _b, _c, _d;
59
59
  const chart = this.options.charts[chartIndex];
60
60
  const axis = this.options.axis;
61
- if (chart.valueLabels.format)
61
+ if ((_a = chart.valueLabels) === null || _a === void 0 ? void 0 : _a.format)
62
62
  return chart.valueLabels.format;
63
63
  if (chart.data.valueGroup === "secondary") {
64
- if ((_a = axis.valueSecondary.labels) === null || _a === void 0 ? void 0 : _a.format)
64
+ if ((_b = axis.valueSecondary.labels) === null || _b === void 0 ? void 0 : _b.format)
65
65
  return axis.valueSecondary.labels.format;
66
- else if ((_b = axis.value.labels) === null || _b === void 0 ? void 0 : _b.format)
66
+ else if ((_c = axis.value.labels) === null || _c === void 0 ? void 0 : _c.format)
67
67
  return axis.value.labels.format;
68
68
  }
69
- else if ((_c = axis.value.labels) === null || _c === void 0 ? void 0 : _c.format)
69
+ else if ((_d = axis.value.labels) === null || _d === void 0 ? void 0 : _d.format)
70
70
  return axis.value.labels.format;
71
71
  const valueFieldFormat = chart.data.valueFields[0].format;
72
72
  return (v) => this.designerConfig.dataFormat.formatters(v, { type: valueFieldFormat });
@@ -47,7 +47,7 @@ export class PolarModel {
47
47
  chartsModel.push({
48
48
  type: chart.type,
49
49
  data: Object.assign({}, chart.data),
50
- tooltip: chart.tooltip,
50
+ tooltip: { show: true },
51
51
  cssClasses: ChartStyleModelService.getCssClasses(0),
52
52
  style: ChartStyleModelService.getChartStyle(dataLength, chartStyleConfig),
53
53
  legend: {
@@ -32,7 +32,8 @@ export function getLegendMarkerOptions(chart) {
32
32
  const shapeByType = {
33
33
  area: "default",
34
34
  bar: "bar",
35
- line: "line"
35
+ line: "line",
36
+ dot: "default"
36
37
  };
37
38
  return {
38
39
  markerShape: shapeByType[chart.type],
@@ -42,9 +43,9 @@ export function getLegendMarkerOptions(chart) {
42
43
  }
43
44
  export function getWidthOfLegendMarkerByType(chartType) {
44
45
  if (chartType === "bar")
45
- return 10;
46
+ return 8;
46
47
  if (chartType === "line")
47
- return 30;
48
+ return 24;
48
49
  if (chartType === "area")
49
50
  return styledElementValues.defaultLegendMarkerSizes.widthPx;
50
51
  }
@@ -17,5 +17,5 @@ export declare class TwoDimensionalModel {
17
17
  private static findChartsWithEmbeddedKeyLabels;
18
18
  private static getEmbeddedLabelType;
19
19
  private static getAdditionalElements;
20
- private static getChartsByType;
20
+ private static getChartsByTypes;
21
21
  }
@@ -10,13 +10,13 @@ import { TwoDimensionalModelHelper } from "../helpers/twoDimensionalModelHelper"
10
10
  export class TwoDimensionalModel {
11
11
  static getOptions(configReader, designerConfig, modelInstance) {
12
12
  var _a;
13
- let secondaryScaleValueInfo;
14
13
  const options = configReader.options;
15
14
  const canvasModel = modelInstance.canvasModel;
16
15
  const scaleModel = new ScaleModel();
17
16
  const scaleMarginRecalcer = new ScaleAxisRecalcer(() => scaleModel.getScaleLinear(options, modelInstance.dataModel.repository.getScopedRows(), canvasModel, configReader));
18
17
  scaleMarginRecalcer.recalculateMargin(canvasModel, options.orientation, options.axis.key);
19
18
  const scaleValueInfo = scaleMarginRecalcer.getScaleValue();
19
+ let secondaryScaleValueInfo;
20
20
  if (configReader.containsSecondaryAxis()) {
21
21
  const secondaryScaleMarginRecalcer = new ScaleAxisRecalcer(() => scaleModel.getScaleSecondaryLinear(options, modelInstance.dataModel.repository.getScopedRows(), canvasModel, configReader));
22
22
  secondaryScaleMarginRecalcer.recalculateMargin(canvasModel, options.orientation, options.axis.key);
@@ -29,7 +29,7 @@ export class TwoDimensionalModel {
29
29
  title: getResolvedTitle(options.title, modelInstance.dataModel.repository.getRawRows()),
30
30
  selectable: !!options.selectable,
31
31
  orient: options.orientation,
32
- scale: Object.assign({ key: scaleModel.getScaleKey(modelInstance.dataModel.getAllowableKeys(), options.orientation, canvasModel, options.charts, this.getChartsByType(options.charts, 'bar')), value: scaleValueInfo.scale }, (configReader.containsSecondaryAxis() && { valueSecondary: secondaryScaleValueInfo.scale })),
32
+ scale: Object.assign({ key: scaleModel.getScaleKey(modelInstance.dataModel.getAllowableKeys(), options.orientation, canvasModel, options.charts, this.getChartsByTypes(options.charts, ['bar', 'dot'])), value: scaleValueInfo.scale }, (configReader.containsSecondaryAxis() && { valueSecondary: secondaryScaleValueInfo.scale })),
33
33
  axis: Object.assign({ key: keyAxis, value: AxisModel.getMainValueAxis(options.orientation, options.axis.value.position, options.axis.value, designerConfig.canvas.axisLabel, canvasModel) }, (configReader.containsSecondaryAxis() && { valueSecondary: AxisModel.getSecondaryValueAxis(options.orientation, options.axis.value.position, options.axis.valueSecondary, designerConfig.canvas.axisLabel, canvasModel) })),
34
34
  type: options.type,
35
35
  data: Object.assign({}, options.data),
@@ -55,7 +55,7 @@ export class TwoDimensionalModel {
55
55
  * @param charts Чарты из конфига
56
56
  */
57
57
  static sortCharts(charts) {
58
- const chartOrder = ['area', 'bar', 'line'];
58
+ const chartOrder = ['area', 'bar', 'line', 'dot'];
59
59
  charts.sort((chart1, chart2) => chartOrder.indexOf(chart1.type) - chartOrder.indexOf(chart2.type));
60
60
  }
61
61
  static getChartsSettings(chartOptions, chartOrientation) {
@@ -70,9 +70,17 @@ export class TwoDimensionalModel {
70
70
  this.sortCharts(charts);
71
71
  const chartsModel = [];
72
72
  charts.forEach((chart, index) => {
73
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
73
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
74
74
  const style = styleModel.getChartStyle(chart, index);
75
- chartsModel.push(Object.assign(Object.assign({ type: chart.type, isSegmented: chart.isSegmented, data: Object.assign({}, chart.data), tooltip: chart.tooltip, cssClasses: ChartStyleModelService.getCssClasses(index), style, embeddedLabels: this.getEmbeddedLabelType(chart, chartOrientation), markersOptions: {
75
+ chartsModel.push({
76
+ type: chart.type,
77
+ isSegmented: chart.isSegmented,
78
+ data: Object.assign({}, chart.data),
79
+ tooltip: { show: true },
80
+ cssClasses: ChartStyleModelService.getCssClasses(index),
81
+ style,
82
+ embeddedLabels: this.getEmbeddedLabelType(chart, chartOrientation),
83
+ markersOptions: {
76
84
  show: ({ row, valueFieldName }) => TwoDimensionalModelHelper.shouldMarkerShow(chart, dataModelRep.getRawRows(), valueFieldName, row, keyFieldName),
77
85
  styles: {
78
86
  highlighted: {
@@ -85,19 +93,32 @@ export class TwoDimensionalModel {
85
93
  }
86
94
  }
87
95
  }
88
- }, lineLikeViewOptions: {
96
+ },
97
+ lineLikeViewOptions: {
89
98
  dashedStyles: parseDashStyles((_k = chart.lineStyles) === null || _k === void 0 ? void 0 : _k.dash),
90
99
  renderForKey: (dataRow, valueFieldName) => dataRow[valueFieldName] !== null && dataRow[valueFieldName] !== undefined
91
- }, barViewOptions: { hatch: { on: (_o = (_m = (_l = chart.barStyles) === null || _l === void 0 ? void 0 : _l.hatch) === null || _m === void 0 ? void 0 : _m.on) !== null && _o !== void 0 ? _o : false } }, legend: getLegendMarkerOptions(chart), index }, (((_p = chart.valueLabels) === null || _p === void 0 ? void 0 : _p.on) && {
100
+ },
101
+ barViewOptions: { hatch: { on: (_o = (_m = (_l = chart.barStyles) === null || _l === void 0 ? void 0 : _l.hatch) === null || _m === void 0 ? void 0 : _m.on) !== null && _o !== void 0 ? _o : false } },
102
+ legend: getLegendMarkerOptions(chart),
103
+ index,
92
104
  valueLabels: {
93
- show: true,
105
+ show: (_q = (_p = chart.valueLabels) === null || _p === void 0 ? void 0 : _p.on) !== null && _q !== void 0 ? _q : false,
94
106
  handleX: (scaledValue) => getValueLabelX(scaledValue, keyAxisOrient, canvasModel.getMargin()),
95
107
  handleY: (scaledValue) => getValueLabelY(scaledValue, keyAxisOrient, canvasModel.getMargin()),
96
108
  textAnchor: calculateValueLabelAlignment(keyAxisOrient).textAnchor,
97
109
  dominantBaseline: calculateValueLabelAlignment(keyAxisOrient).dominantBaseline,
98
110
  format: configReader.getValueLabelFormatterForChart(index),
111
+ },
112
+ areaViewOptions: getAreaViewOptions(chart, index, style),
113
+ dotViewOptions: {
114
+ shape: {
115
+ type: "line",
116
+ handleEndCoordinate: (v) => v + 2,
117
+ handleStartCoordinate: (v) => v - 2,
118
+ width: (_t = (_s = (_r = chart.dotLikeStyles) === null || _r === void 0 ? void 0 : _r.shape) === null || _s === void 0 ? void 0 : _s.width) !== null && _t !== void 0 ? _t : 2
119
+ }
99
120
  }
100
- })), { areaViewOptions: getAreaViewOptions(chart, index, style) }));
121
+ });
101
122
  });
102
123
  return chartsModel;
103
124
  }
@@ -119,7 +140,7 @@ export class TwoDimensionalModel {
119
140
  gridLine: options.additionalElements.gridLine
120
141
  };
121
142
  }
122
- static getChartsByType(charts, type) {
123
- return charts.filter(chart => chart.type === type);
143
+ static getChartsByTypes(charts, types) {
144
+ return charts.filter(chart => types.includes(chart.type));
124
145
  }
125
146
  }
@@ -1,5 +1,5 @@
1
1
  :root {
2
- --chart-base-font-size: 13px;
2
+ --chart-base-font-size: 12px;
3
3
  }
4
4
 
5
5
  .wrapper {
@@ -80,7 +80,7 @@
80
80
  text-overflow: ellipsis;
81
81
  }
82
82
  .legend-wrapper-without-wrap .legend-item-inline:not(:last-of-type) {
83
- margin-right: 12px
83
+ margin-right: 16px
84
84
  }
85
85
  .legend-wrapper-with-wrap .legend-item-inline {
86
86
  margin: 2px;
@@ -1,5 +1,5 @@
1
1
  :root {
2
- --chart-base-font-size: 13px;
2
+ --chart-base-font-size: 12px;
3
3
  }
4
4
 
5
5
  .wrapper {
@@ -80,7 +80,7 @@
80
80
  text-overflow: ellipsis;
81
81
  }
82
82
  .legend-wrapper-without-wrap .legend-item-inline:not(:last-of-type) {
83
- margin-right: 12px
83
+ margin-right: 16px
84
84
  }
85
85
  .legend-wrapper-with-wrap .legend-item-inline {
86
86
  margin: 2px;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mdt-charts",
3
- "version": "1.21.1",
3
+ "version": "1.22.0",
4
4
  "description": "",
5
5
  "main": "lib/main.js",
6
6
  "scripts": {