mdt-charts 1.10.2 → 1.12.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 (65) hide show
  1. package/lib/config/config.d.ts +13 -5
  2. package/lib/designer/designerConfig.d.ts +8 -2
  3. package/lib/engine/features/aggregator/aggregator.d.ts +4 -3
  4. package/lib/engine/features/aggregator/aggregator.js +14 -11
  5. package/lib/engine/features/recordOverflowAlert/recordOverflowAlertCore.d.ts +28 -0
  6. package/lib/engine/features/recordOverflowAlert/recordOverflowAlertCore.js +50 -0
  7. package/lib/engine/features/title/title.js +2 -0
  8. package/lib/engine/features/tolltip/tooltip.js +1 -1
  9. package/lib/engine/filterManager/filterEventManager.d.ts +3 -3
  10. package/lib/engine/filterManager/filterEventManager.js +4 -4
  11. package/lib/engine/intervalNotation/intervalManager.js +2 -5
  12. package/lib/engine/polarNotation/donut/DonutHelper.d.ts +2 -0
  13. package/lib/engine/polarNotation/donut/DonutHelper.js +20 -3
  14. package/lib/engine/polarNotation/donut/donut.js +1 -1
  15. package/lib/engine/polarNotation/extenders/polarRecordOverflowAlert.d.ts +16 -0
  16. package/lib/engine/polarNotation/extenders/polarRecordOverflowAlert.js +48 -0
  17. package/lib/engine/polarNotation/polarManager.js +16 -12
  18. package/lib/engine/twoDimensionalNotation/extenders/twoDimRecordOverflowAlert.d.ts +15 -0
  19. package/lib/engine/twoDimensionalNotation/extenders/twoDimRecordOverflowAlert.js +32 -0
  20. package/lib/engine/twoDimensionalNotation/twoDimensionalManager.js +13 -7
  21. package/lib/model/chartStyleModel/TwoDimensionalChartStyleModel.d.ts +19 -0
  22. package/lib/model/chartStyleModel/TwoDimensionalChartStyleModel.js +61 -0
  23. package/lib/model/chartStyleModel/chartStyleModel.d.ts +9 -0
  24. package/lib/model/chartStyleModel/chartStyleModel.js +27 -0
  25. package/lib/model/dataManagerModel/dataManagerModel.d.ts +26 -0
  26. package/lib/model/dataManagerModel/dataManagerModel.js +132 -0
  27. package/lib/model/dataManagerModel/dataManagerModelService.d.ts +5 -0
  28. package/lib/model/dataManagerModel/dataManagerModelService.js +28 -0
  29. package/lib/model/dataManagerModel.d.ts +3 -2
  30. package/lib/model/dataManagerModel.js +12 -10
  31. package/lib/model/featuresModel/axisModel.d.ts +9 -8
  32. package/lib/model/featuresModel/axisModel.js +21 -21
  33. package/lib/model/featuresModel/legendModel/legendModel.d.ts +4 -5
  34. package/lib/model/featuresModel/legendModel/legendModel.js +6 -9
  35. package/lib/model/featuresModel/otherComponents.d.ts +9 -2
  36. package/lib/model/featuresModel/otherComponents.js +6 -4
  37. package/lib/model/featuresModel/scaleModel.d.ts +7 -6
  38. package/lib/model/featuresModel/scaleModel.js +9 -9
  39. package/lib/model/featuresModel/titleModel.d.ts +1 -1
  40. package/lib/model/featuresModel/titleModel.js +7 -5
  41. package/lib/model/marginModel.d.ts +5 -5
  42. package/lib/model/marginModel.js +41 -38
  43. package/lib/model/model.d.ts +24 -18
  44. package/lib/model/modelBuilder.js +26 -37
  45. package/lib/model/modelInstance/canvasModel/canvasModel.d.ts +24 -0
  46. package/lib/model/modelInstance/canvasModel/canvasModel.js +44 -0
  47. package/lib/model/modelInstance/canvasModel/legendCanvasModel.d.ts +7 -0
  48. package/lib/model/modelInstance/canvasModel/legendCanvasModel.js +13 -0
  49. package/lib/model/modelInstance/canvasModel/titleCanvas.d.ts +9 -0
  50. package/lib/model/modelInstance/canvasModel/titleCanvas.js +11 -0
  51. package/lib/model/modelInstance/dataModel.d.ts +11 -0
  52. package/lib/model/modelInstance/dataModel.js +23 -0
  53. package/lib/model/modelInstance/modelInstance.d.ts +10 -0
  54. package/lib/model/modelInstance/modelInstance.js +17 -0
  55. package/lib/model/notations/intervalModel.d.ts +2 -1
  56. package/lib/model/notations/intervalModel.js +17 -15
  57. package/lib/model/notations/polarModel.d.ts +9 -3
  58. package/lib/model/notations/polarModel.js +29 -8
  59. package/lib/model/notations/twoDimensionalModel.d.ts +7 -5
  60. package/lib/model/notations/twoDimensionalModel.js +19 -12
  61. package/lib/style/charts-main.css +2 -0
  62. package/lib/style/charts-main.less +2 -0
  63. package/package.json +3 -2
  64. package/lib/model/chartStyleModel.d.ts +0 -16
  65. package/lib/model/chartStyleModel.js +0 -67
@@ -16,7 +16,7 @@ export interface MdtChartsDataSource {
16
16
  }
17
17
  export interface MdtChartsConfig {
18
18
  canvas: ChartBlockCanvas;
19
- options: PolarOptions | TwoDimensionalOptions | IntervalOptions;
19
+ options: MdtChartsPolarOptions | MdtChartsTwoDimensionalOptions | IntervalOptions;
20
20
  }
21
21
  export interface ChartBlockCanvas {
22
22
  size: Size;
@@ -33,18 +33,18 @@ export interface NewSize {
33
33
  interface Options {
34
34
  legend: Legend;
35
35
  data: DataOptions;
36
- title: string;
36
+ title?: string;
37
37
  selectable: boolean;
38
38
  tooltip?: TooltipOptions;
39
39
  }
40
- export interface TwoDimensionalOptions extends Options {
40
+ export interface MdtChartsTwoDimensionalOptions extends Options {
41
41
  type: '2d';
42
42
  axis: TwoDimensionalAxis;
43
43
  additionalElements: AdditionalElements;
44
44
  charts: TwoDimensionalChart[];
45
45
  orientation: ChartOrientation;
46
46
  }
47
- export interface PolarOptions extends Options {
47
+ export interface MdtChartsPolarOptions extends Options {
48
48
  type: 'polar';
49
49
  chart: PolarChart;
50
50
  }
@@ -61,6 +61,7 @@ export interface Legend {
61
61
  export interface DataOptions {
62
62
  dataSource: string;
63
63
  keyField: MdtChartsField;
64
+ maxRecordsAmount?: number;
64
65
  }
65
66
  export interface MdtChartsField {
66
67
  name: string;
@@ -69,6 +70,9 @@ export interface MdtChartsField {
69
70
  export interface ValueField extends MdtChartsField {
70
71
  title: string;
71
72
  }
73
+ export interface TwoDimValueField extends ValueField {
74
+ color?: string;
75
+ }
72
76
  export interface TooltipOptions {
73
77
  html: TooltipHtml;
74
78
  }
@@ -125,13 +129,14 @@ export interface TwoDimensionalChart extends ChartSettings {
125
129
  export interface PolarChart extends ChartSettings {
126
130
  type: PolarChartType;
127
131
  data: PolarChartData;
132
+ aggregator: MdtChartsPolarChartAggregator;
128
133
  }
129
134
  export interface IntervalChart extends ChartSettings {
130
135
  type: IntervalChartType;
131
136
  data: IntervalChartData;
132
137
  }
133
138
  export interface TwoDimensionalChartData {
134
- valueFields: ValueField[];
139
+ valueFields: TwoDimValueField[];
135
140
  }
136
141
  interface MarkersOptions {
137
142
  show: boolean;
@@ -141,6 +146,9 @@ export interface PolarChartData {
141
146
  valueField: ValueField;
142
147
  colorField?: MdtChartsColorField;
143
148
  }
149
+ export interface MdtChartsPolarChartAggregator {
150
+ text: string;
151
+ }
144
152
  interface IntervalChartData {
145
153
  valueField1: ValueField;
146
154
  valueField2: ValueField;
@@ -4,6 +4,7 @@ export declare type DataTypeOptions = {
4
4
  };
5
5
  export declare type Formatter = (value: any, options?: any) => string;
6
6
  export declare type TooltipPosition = 'followCursor' | 'fixed';
7
+ export declare type MdtChartsDonutThicknessUnit = "px" | "%";
7
8
  export interface DesignerConfig {
8
9
  canvas: Canvas;
9
10
  dataFormat: DataFormat;
@@ -45,9 +46,14 @@ export interface BarOptionsCanvas {
45
46
  }
46
47
  export interface DonutOptionsCanvas {
47
48
  padAngle: number;
48
- minThickness: number;
49
- maxThickness: number;
50
49
  aggregatorPad: number;
50
+ thickness: MdtChartsDonutThicknessOptions;
51
+ }
52
+ export interface MdtChartsDonutThicknessOptions {
53
+ min: number;
54
+ max: number;
55
+ value: number;
56
+ unit: MdtChartsDonutThicknessUnit;
51
57
  }
52
58
  interface DataFormat {
53
59
  formatters: Formatter;
@@ -1,19 +1,20 @@
1
1
  import { MdtChartsDataRow } from '../../../config/config';
2
2
  import { DataType } from '../../../designer/designerConfig';
3
- import { Field } from "../../../model/model";
3
+ import { DonutChartAggreagorModel, Field } from "../../../model/model";
4
4
  import { Block } from "../../block/block";
5
5
  import { Translate } from "../../polarNotation/donut/donut";
6
6
  export interface AggregatorInfo {
7
7
  name: string;
8
8
  value: number;
9
9
  format: DataType;
10
+ margin: number;
10
11
  }
11
12
  export declare class Aggregator {
12
13
  static readonly aggregatorValueClass = "aggregator-value";
13
14
  private static readonly aggregatorNameClass;
14
15
  private static readonly aggregatorObjectClass;
15
- static render(block: Block, data: MdtChartsDataRow[], valueField: Field, innerRadius: number, translate: Translate, fontSize: number, pad: number): void;
16
- static update(block: Block, data: MdtChartsDataRow[], valueField: Field, pad: number): void;
16
+ static render(block: Block, data: MdtChartsDataRow[], valueField: Field, innerRadius: number, translate: Translate, fontSize: number, settings: DonutChartAggreagorModel): void;
17
+ static update(block: Block, data: MdtChartsDataRow[], valueField: Field, settings: DonutChartAggreagorModel): void;
17
18
  private static renderText;
18
19
  private static updateText;
19
20
  private static reCalculateAggregatorFontSize;
@@ -3,23 +3,25 @@ import { interpolateNumber } from 'd3-interpolate';
3
3
  import { Helper } from '../../helpers/helper';
4
4
  import { ValueFormatter } from '../../valueFormatter';
5
5
  export class Aggregator {
6
- static render(block, data, valueField, innerRadius, translate, fontSize, pad) {
6
+ static render(block, data, valueField, innerRadius, translate, fontSize, settings) {
7
7
  const aggregator = {
8
- name: 'Сумма',
8
+ name: settings.text,
9
9
  value: sum(data.map(d => d[valueField.name])),
10
- format: valueField.format
10
+ format: valueField.format,
11
+ margin: settings.margin
11
12
  };
12
- this.renderText(block, innerRadius, aggregator, translate, fontSize, pad);
13
+ this.renderText(block, innerRadius, aggregator, translate, fontSize);
13
14
  }
14
- static update(block, data, valueField, pad) {
15
+ static update(block, data, valueField, settings) {
15
16
  const aggregator = {
16
17
  name: 'Сумма',
17
18
  value: sum(data.map(d => d[valueField.name])),
18
- format: valueField.format
19
+ format: valueField.format,
20
+ margin: settings.margin
19
21
  };
20
- this.updateText(block, aggregator, pad);
22
+ this.updateText(block, aggregator);
21
23
  }
22
- static renderText(block, innerRadius, aggregatorInfo, translate, fontSize, pad) {
24
+ static renderText(block, innerRadius, aggregatorInfo, translate, fontSize) {
23
25
  if (innerRadius > 50) {
24
26
  const aggregatorObject = this.renderAggregatorObject(block, innerRadius, translate);
25
27
  const wrapper = this.renderWrapper(aggregatorObject);
@@ -32,13 +34,14 @@ export class Aggregator {
32
34
  wrapper
33
35
  .append('div')
34
36
  .attr('class', this.aggregatorNameClass)
37
+ .attr('title', aggregatorInfo.name)
35
38
  .style('text-align', 'center')
36
39
  .style('font-size', '18px')
37
40
  .text(aggregatorInfo.name);
38
- this.reCalculateAggregatorFontSize(aggregatorObject.node().getBoundingClientRect().width, block, pad);
41
+ this.reCalculateAggregatorFontSize(aggregatorObject.node().getBoundingClientRect().width, block, aggregatorInfo.margin);
39
42
  }
40
43
  }
41
- static updateText(block, newAggregator, pad) {
44
+ static updateText(block, newAggregator) {
42
45
  const aggregatorObject = block.getSvg()
43
46
  .select(`.${this.aggregatorObjectClass}`);
44
47
  const thisClass = this;
@@ -53,7 +56,7 @@ export class Aggregator {
53
56
  const interpolateFunc = interpolateNumber(oldValue, newAggregator.value);
54
57
  return t => {
55
58
  this.textContent = ValueFormatter.formatField(newAggregator.format, (interpolateFunc(t)).toFixed(precision));
56
- thisClass.reCalculateAggregatorFontSize(aggregatorObject.node().getBoundingClientRect().width, block, pad);
59
+ thisClass.reCalculateAggregatorFontSize(aggregatorObject.node().getBoundingClientRect().width, block, newAggregator.margin);
57
60
  };
58
61
  });
59
62
  }
@@ -0,0 +1,28 @@
1
+ import { Block } from "../../block/block";
2
+ export interface RecordOverflowAlertOptions {
3
+ hidedRecordsAmount: number;
4
+ text: RecordOverflowAlertText;
5
+ positionAttrs: AlertBlockPositionAttrs;
6
+ }
7
+ export interface RecordOverflowAlertText {
8
+ one: string;
9
+ twoToFour: string;
10
+ tenToTwenty: string;
11
+ other: string;
12
+ }
13
+ export interface AlertBlockPositionAttrs {
14
+ top?: string;
15
+ bottom?: string;
16
+ right?: string;
17
+ left?: string;
18
+ }
19
+ declare class RecordOverflowAlertCoreClass {
20
+ private readonly blockClass;
21
+ render(block: Block, options: RecordOverflowAlertOptions): void;
22
+ update(block: Block, options: RecordOverflowAlertOptions): void;
23
+ private getAlertText;
24
+ private getWordTextEndingByAmount;
25
+ private setAlertPosition;
26
+ }
27
+ export declare const RecordOverflowAlertCore: RecordOverflowAlertCoreClass;
28
+ export {};
@@ -0,0 +1,50 @@
1
+ class RecordOverflowAlertCoreClass {
2
+ constructor() {
3
+ this.blockClass = 'record-overflow-alert';
4
+ }
5
+ render(block, options) {
6
+ const alertBlock = block.getWrapper()
7
+ .append('div')
8
+ .attr('class', this.blockClass)
9
+ .text(this.getAlertText(options));
10
+ this.setAlertPosition(alertBlock, options.positionAttrs);
11
+ }
12
+ update(block, options) {
13
+ let alertBlock = block.getWrapper()
14
+ .select(`div.${this.blockClass}`);
15
+ if (alertBlock.empty()) {
16
+ if (options.hidedRecordsAmount === 0)
17
+ return;
18
+ else
19
+ this.render(block, options);
20
+ }
21
+ else {
22
+ if (options.hidedRecordsAmount === 0)
23
+ alertBlock.remove();
24
+ else
25
+ alertBlock.text(this.getAlertText(options));
26
+ }
27
+ }
28
+ getAlertText(options) {
29
+ return `+ ${options.hidedRecordsAmount} ${this.getWordTextEndingByAmount(options.hidedRecordsAmount, options.text)}`;
30
+ }
31
+ getWordTextEndingByAmount(hidedRecordsAmount, text) {
32
+ const lastDigit = hidedRecordsAmount % 10;
33
+ if (hidedRecordsAmount >= 10 && hidedRecordsAmount <= 20)
34
+ return text.tenToTwenty;
35
+ if (lastDigit === 1)
36
+ return text.one;
37
+ if (lastDigit >= 2 && lastDigit <= 4)
38
+ return text.twoToFour;
39
+ return text.other;
40
+ }
41
+ setAlertPosition(alertBlock, attrs) {
42
+ alertBlock
43
+ .style('position', 'absolute')
44
+ .style('left', attrs.left)
45
+ .style('right', attrs.right)
46
+ .style('top', attrs.top)
47
+ .style('bottom', attrs.bottom);
48
+ }
49
+ }
50
+ export const RecordOverflowAlertCore = new RecordOverflowAlertCoreClass();
@@ -1,6 +1,8 @@
1
1
  import { DomHelper } from '../../helpers/domHelper';
2
2
  export class Title {
3
3
  static render(block, text, titleBlockModel, blockSize) {
4
+ if (!text)
5
+ return;
4
6
  const titleBlock = block.getSvg()
5
7
  .append('text')
6
8
  .attr('class', 'chart-title');
@@ -19,7 +19,7 @@ export class Tooltip {
19
19
  this.renderTooltipFor2DCharts(block, data, model.blockCanvas.size, model.chartBlock.margin, scales, model.options, tooltipOptions);
20
20
  }
21
21
  else if (model.options.type === 'polar') {
22
- this.renderTooltipForPolar(block, model.options, data, model.blockCanvas.size, model.chartBlock.margin, DonutHelper.getThickness(model.chartSettings.donut, model.blockCanvas.size, model.chartBlock.margin), model.otherComponents.tooltipBlock);
22
+ this.renderTooltipForPolar(block, model.options, data, model.blockCanvas.size, model.chartBlock.margin, DonutHelper.getThickness(model.options.chartCanvas, model.blockCanvas.size, model.chartBlock.margin), model.otherComponents.tooltipBlock);
23
23
  }
24
24
  else if (model.options.type === 'interval') {
25
25
  this.renderTooltipForIntervalCharts(block, data, model.blockCanvas.size, model.chartBlock.margin, scales, model.options, tooltipOptions);
@@ -1,6 +1,6 @@
1
1
  import { AxisScale } from "d3-axis";
2
2
  import { MdtChartsDataRow, Size } from "../../config/config";
3
- import { BlockMargin, TwoDimensionalOptionsModel, PolarOptionsModel, DonutChartSettings } from "../../model/model";
3
+ import { BlockMargin, TwoDimensionalOptionsModel, PolarOptionsModel } from "../../model/model";
4
4
  import { Block } from "../block/block";
5
5
  export declare type FilterCallback = (rows: MdtChartsDataRow[]) => void;
6
6
  export interface SelectDetails {
@@ -19,12 +19,12 @@ export declare class FilterEventManager {
19
19
  updateData(newDataset: MdtChartsDataRow[]): void;
20
20
  isSelected(keyValue: string): boolean;
21
21
  clearKeysFor2D(options: TwoDimensionalOptionsModel): void;
22
- clearKeysForPolar(margin: BlockMargin, blockSize: Size, options: PolarOptionsModel, donutSettings: DonutChartSettings): void;
22
+ clearKeysForPolar(margin: BlockMargin, blockSize: Size, options: PolarOptionsModel): void;
23
23
  private setKey;
24
24
  private addId;
25
25
  private removeId;
26
26
  private processKey;
27
- setListenerPolar(margin: BlockMargin, blockSize: Size, options: PolarOptionsModel, donutSettings: DonutChartSettings): void;
27
+ setListenerPolar(margin: BlockMargin, blockSize: Size, options: PolarOptionsModel): void;
28
28
  event2DUpdate(options: TwoDimensionalOptionsModel): void;
29
29
  registerEventFor2D(scaleKey: AxisScale<any>, margin: BlockMargin, blockSize: Size, options: TwoDimensionalOptionsModel): void;
30
30
  private registerEventToDonut;
@@ -29,11 +29,11 @@ export class FilterEventManager {
29
29
  this.callback([]);
30
30
  SelectHighlighter.clear2D(this.block, options);
31
31
  }
32
- clearKeysForPolar(margin, blockSize, options, donutSettings) {
32
+ clearKeysForPolar(margin, blockSize, options) {
33
33
  this.selectedKeys = [];
34
34
  if (this.callback)
35
35
  this.callback([]);
36
- SelectHighlighter.clearPolar(margin, blockSize, this.block, options, Donut.getAllArcGroups(this.block), donutSettings);
36
+ SelectHighlighter.clearPolar(margin, blockSize, this.block, options, Donut.getAllArcGroups(this.block), options.chartCanvas);
37
37
  }
38
38
  setKey(key) {
39
39
  this.selectedKeys = [key];
@@ -66,9 +66,9 @@ export class FilterEventManager {
66
66
  }
67
67
  }
68
68
  }
69
- setListenerPolar(margin, blockSize, options, donutSettings) {
69
+ setListenerPolar(margin, blockSize, options) {
70
70
  if (this.filterable) {
71
- this.registerEventToDonut(margin, blockSize, options, donutSettings);
71
+ this.registerEventToDonut(margin, blockSize, options, options.chartCanvas);
72
72
  const selectedElems = Donut.getAllArcGroups(this.block).filter(d => this.selectedKeys.findIndex(sid => sid === d.data[options.data.keyField.name]) !== -1);
73
73
  this.selectedKeys = [];
74
74
  selectedElems.dispatch('click', { bubbles: false, cancelable: true, detail: { multySelect: true } });
@@ -1,7 +1,6 @@
1
1
  import { Axis } from "../features/axis/axis";
2
2
  import { GridLine } from "../features/gridLine/gridLine";
3
3
  import { Legend } from "../features/legend/legend";
4
- import { RecordOverflowAlert } from "../features/recordOverflowAlert/recordOverflowAlert";
5
4
  import { Scale } from "../features/scale/scale";
6
5
  import { Title } from "../features/title/title";
7
6
  import { Tooltip } from "../features/tolltip/tooltip";
@@ -10,15 +9,13 @@ export class IntervalManager {
10
9
  static render(block, model, data) {
11
10
  const options = model.options;
12
11
  block.renderSvg(model.blockCanvas.size);
13
- const scales = Scale.getScales(options.scale.key, options.scale.value, model.chartSettings.bar);
12
+ const scales = Scale.getScales(options.scale.key, options.scale.value, options.chartSettings.bar);
14
13
  Axis.render(block, scales, options.scale, options.axis, model.blockCanvas.size);
15
14
  GridLine.render(block, options.additionalElements.gridLine.flag, options.axis, model.blockCanvas.size, model.chartBlock.margin, options.scale.key);
16
- this.renderCharts(block, options.charts, scales, data, options.data, model.chartBlock.margin, options.axis.key.orient, model.chartSettings);
15
+ this.renderCharts(block, options.charts, scales, data, options.data, model.chartBlock.margin, options.axis.key.orient, options.chartSettings);
17
16
  Title.render(block, options.title, model.otherComponents.titleBlock, model.blockCanvas.size);
18
17
  Legend.render(block, data, options, model);
19
18
  Tooltip.render(block, model, data, model.otherComponents.tooltipBlock, scales);
20
- if (model.dataSettings.scope.hidedRecordsAmount !== 0)
21
- RecordOverflowAlert.render(block, model.dataSettings.scope.hidedRecordsAmount, 'top', options.orient);
22
19
  }
23
20
  static renderCharts(block, charts, scales, data, dataOptions, margin, keyAxisOrient, chartSettings) {
24
21
  block.renderChartsBlock();
@@ -12,4 +12,6 @@ export declare class DonutHelper {
12
12
  static getArcGenerator(outerRadius: number, innerRadius: number): Arc<any, PieArcDatum<MdtChartsDataRow>>;
13
13
  static getPieGenerator(valueField: string, padAngle: number): Pie<any, MdtChartsDataRow>;
14
14
  static mergeDataWithZeros(firstDataset: MdtChartsDataRow[], secondDataset: MdtChartsDataRow[], keyField: string, colorField: MdtChartsColorField): MdtChartsDataRow[];
15
+ private static getThicknessByUnit;
16
+ private static getChartBlockSize;
15
17
  }
@@ -1,10 +1,15 @@
1
1
  import { merge } from "d3-array";
2
2
  import { arc, pie } from "d3-shape";
3
+ const MIN_CHART_BLOCK_SIZE_FOR_MAX_THICKNESS = 400;
3
4
  export class DonutHelper {
4
5
  static getThickness(donutSettings, blockSize, margin) {
5
- if (Math.min(blockSize.width - margin.left - margin.right, blockSize.height - margin.bottom - margin.top) > 400)
6
- return donutSettings.maxThickness;
7
- return donutSettings.minThickness;
6
+ const thicknessOpts = donutSettings.thickness;
7
+ const chartBlockSize = this.getChartBlockSize(blockSize, margin);
8
+ if (thicknessOpts.value)
9
+ return this.getThicknessByUnit(chartBlockSize, thicknessOpts.value, thicknessOpts.unit);
10
+ if (Math.min(chartBlockSize.width, chartBlockSize.height) > MIN_CHART_BLOCK_SIZE_FOR_MAX_THICKNESS)
11
+ return this.getThicknessByUnit(chartBlockSize, thicknessOpts.max, thicknessOpts.unit);
12
+ return this.getThicknessByUnit(chartBlockSize, thicknessOpts.min, thicknessOpts.unit);
8
13
  }
9
14
  static getArcCentroid(blockSize, margin, dataItem, donutThickness) {
10
15
  const arc = this.getArcGeneratorObject(blockSize, margin, donutThickness);
@@ -57,4 +62,16 @@ export class DonutHelper {
57
62
  const sortedMerge = merge([secondDataset, onlyNew]);
58
63
  return sortedMerge;
59
64
  }
65
+ static getThicknessByUnit(chartBlockSize, valueInPx, unit) {
66
+ if (unit === "px")
67
+ return valueInPx;
68
+ const minSideSize = Math.min(chartBlockSize.width, chartBlockSize.height);
69
+ return minSideSize / 2 * (valueInPx / 100);
70
+ }
71
+ static getChartBlockSize(blockSize, margin) {
72
+ return {
73
+ height: blockSize.height - margin.top - margin.bottom,
74
+ width: blockSize.width - margin.left - margin.right
75
+ };
76
+ }
60
77
  }
@@ -11,6 +11,7 @@ export class Donut {
11
11
  const arcGenerator = DonutHelper.getArcGenerator(outerRadius, innerRadius);
12
12
  const pieGenerator = DonutHelper.getPieGenerator(chart.data.valueField.name, settings.padAngle);
13
13
  const translateAttr = DonutHelper.getTranslate(margin, blockSize);
14
+ Aggregator.render(block, data, chart.data.valueField, innerRadius, translateAttr, thickness, settings.aggregator);
14
15
  const donutBlock = block.getSvg()
15
16
  .append('g')
16
17
  .attr('class', this.donutBlockClass)
@@ -19,7 +20,6 @@ export class Donut {
19
20
  .attr('transform', `translate(${translateAttr.x}, ${translateAttr.y})`);
20
21
  this.renderNewArcItems(arcGenerator, pieGenerator, donutBlock, data, chart);
21
22
  this.renderClonesG(donutBlock);
22
- Aggregator.render(block, data, chart.data.valueField, innerRadius, translateAttr, thickness, settings.aggregatorPad);
23
23
  }
24
24
  static update(block, data, margin, chart, blockSize, donutSettings, keyField) {
25
25
  const outerRadius = DonutHelper.getOuterRadius(margin, blockSize);
@@ -0,0 +1,16 @@
1
+ import { LegendPosition } from "../../../model/model";
2
+ import { Block } from "../../block/block";
3
+ interface PolarRecordOverflowAlertOptions {
4
+ hidedRecordsAmount: number;
5
+ legendPosition: LegendPosition;
6
+ }
7
+ declare class PolarRecordOverflowAlertClass {
8
+ private readonly text;
9
+ render(block: Block, options: PolarRecordOverflowAlertOptions): void;
10
+ update(block: Block, options: PolarRecordOverflowAlertOptions): void;
11
+ private buildCoreOptions;
12
+ private getPositionAttrs;
13
+ private getLeftAttrForRightBlock;
14
+ }
15
+ export declare const PolarRecordOverflowAlert: PolarRecordOverflowAlertClass;
16
+ export {};
@@ -0,0 +1,48 @@
1
+ import { Legend } from "../../features/legend/legend";
2
+ import { RecordOverflowAlertCore } from "../../features/recordOverflowAlert/recordOverflowAlertCore";
3
+ import { DomHelper } from "../../helpers/domHelper";
4
+ class PolarRecordOverflowAlertClass {
5
+ constructor() {
6
+ this.text = {
7
+ one: 'категория',
8
+ twoToFour: 'категории',
9
+ tenToTwenty: 'категорий',
10
+ other: 'категорий'
11
+ };
12
+ }
13
+ render(block, options) {
14
+ RecordOverflowAlertCore.render(block, this.buildCoreOptions(block, options));
15
+ }
16
+ update(block, options) {
17
+ RecordOverflowAlertCore.update(block, this.buildCoreOptions(block, options));
18
+ }
19
+ buildCoreOptions(block, options) {
20
+ return {
21
+ hidedRecordsAmount: options.hidedRecordsAmount,
22
+ text: this.text,
23
+ positionAttrs: this.getPositionAttrs(block, options)
24
+ };
25
+ }
26
+ getPositionAttrs(block, options) {
27
+ const position = options.legendPosition === 'off' ? 'bottom' : options.legendPosition;
28
+ if (position === 'right') {
29
+ return {
30
+ bottom: '20px',
31
+ left: this.getLeftAttrForRightBlock(block) + 'px'
32
+ };
33
+ }
34
+ if (position === 'bottom') {
35
+ return {
36
+ bottom: '20px',
37
+ left: '20px'
38
+ };
39
+ }
40
+ }
41
+ getLeftAttrForRightBlock(block) {
42
+ const legendBlock = block.getSvg().select(`.${Legend.objectClass}`);
43
+ if (legendBlock.empty())
44
+ return 17;
45
+ return DomHelper.getSelectionNumericAttr(legendBlock, 'x');
46
+ }
47
+ }
48
+ export const PolarRecordOverflowAlert = new PolarRecordOverflowAlertClass();
@@ -1,26 +1,28 @@
1
1
  import { Legend } from "../features/legend/legend";
2
- import { RecordOverflowAlert } from "../features/recordOverflowAlert/recordOverflowAlert";
3
2
  import { Title } from "../features/title/title";
4
3
  import { ElementHighlighter } from "../elementHighlighter/elementHighlighter";
5
4
  import { Tooltip } from "../features/tolltip/tooltip";
6
5
  import { Aggregator } from "../features/aggregator/aggregator";
7
6
  import { Donut } from "./donut/donut";
7
+ import { PolarRecordOverflowAlert } from "./extenders/polarRecordOverflowAlert";
8
8
  export class PolarManager {
9
9
  static render(engine, model) {
10
10
  const options = model.options;
11
11
  engine.block.renderSvg(model.blockCanvas.size);
12
- this.renderCharts(engine.block, options.charts, engine.data, options.data.dataSource, model.chartBlock.margin, model.blockCanvas.size, model.chartSettings.donut);
12
+ this.renderCharts(engine.block, options.charts, engine.data, options.data.dataSource, model.chartBlock.margin, model.blockCanvas.size, options.chartCanvas);
13
13
  Title.render(engine.block, options.title, model.otherComponents.titleBlock, model.blockCanvas.size);
14
14
  Legend.render(engine.block, engine.data, options, model);
15
- ``;
16
15
  Tooltip.render(engine.block, model, engine.data, model.otherComponents.tooltipBlock);
17
- engine.block.filterEventManager.setListenerPolar(model.chartBlock.margin, model.blockCanvas.size, options, model.chartSettings.donut);
18
- if (model.dataSettings.scope.hidedRecordsAmount !== 0 && model.options.legend.position !== 'off')
19
- RecordOverflowAlert.render(engine.block, model.dataSettings.scope.hidedRecordsAmount, model.options.legend.position);
16
+ engine.block.filterEventManager.setListenerPolar(model.chartBlock.margin, model.blockCanvas.size, options);
17
+ if (model.dataSettings.scope.hidedRecordsAmount !== 0)
18
+ PolarRecordOverflowAlert.render(engine.block, {
19
+ hidedRecordsAmount: model.dataSettings.scope.hidedRecordsAmount,
20
+ legendPosition: model.options.legend.position
21
+ });
20
22
  engine.block.getSvg()
21
23
  .on('click', (e) => {
22
24
  if (e.target === engine.block.getSvg().node())
23
- engine.block.filterEventManager.clearKeysForPolar(model.chartBlock.margin, model.blockCanvas.size, options, model.chartSettings.donut);
25
+ engine.block.filterEventManager.clearKeysForPolar(model.chartBlock.margin, model.blockCanvas.size, options);
24
26
  });
25
27
  }
26
28
  static update(block, model, data) {
@@ -32,15 +34,17 @@ export class PolarManager {
32
34
  ElementHighlighter.toggleActivityStyle(Donut.getAllArcGroups(block), true);
33
35
  Tooltip.hide(block);
34
36
  const options = model.options;
35
- Donut.update(block, data[options.data.dataSource], model.chartBlock.margin, options.charts[0], model.blockCanvas.size, model.chartSettings.donut, options.data.keyField.name)
37
+ Donut.update(block, data[options.data.dataSource], model.chartBlock.margin, options.charts[0], model.blockCanvas.size, options.chartCanvas, options.data.keyField.name)
36
38
  .then(() => {
37
39
  Tooltip.render(block, model, data, model.otherComponents.tooltipBlock);
38
- block.filterEventManager.setListenerPolar(model.chartBlock.margin, model.blockCanvas.size, options, model.chartSettings.donut);
40
+ block.filterEventManager.setListenerPolar(model.chartBlock.margin, model.blockCanvas.size, options);
39
41
  });
40
- Aggregator.update(block, data[options.data.dataSource], options.charts[0].data.valueField, model.chartSettings.donut.aggregatorPad);
42
+ Aggregator.update(block, data[options.data.dataSource], options.charts[0].data.valueField, options.chartCanvas.aggregator);
41
43
  Legend.update(block, data, model);
42
- if (model.options.legend.position !== 'off')
43
- RecordOverflowAlert.update(block, model.dataSettings.scope.hidedRecordsAmount, model.options.legend.position);
44
+ PolarRecordOverflowAlert.update(block, {
45
+ hidedRecordsAmount: model.dataSettings.scope.hidedRecordsAmount,
46
+ legendPosition: model.options.legend.position
47
+ });
44
48
  }
45
49
  static updateColors(block, model) {
46
50
  Legend.updateColors(block, model.options);
@@ -0,0 +1,15 @@
1
+ import { ChartOrientation } from "../../../config/config";
2
+ import { Block } from "../../block/block";
3
+ interface TwoDimRecordOverflowAlertOptions {
4
+ hidedRecordsAmount: number;
5
+ chartOrientation: ChartOrientation;
6
+ }
7
+ declare class TwoDimRecordOverflowAlertClass {
8
+ render(block: Block, options: TwoDimRecordOverflowAlertOptions): void;
9
+ update(block: Block, options: TwoDimRecordOverflowAlertOptions): void;
10
+ private buildCoreOptions;
11
+ private getText;
12
+ private getPositionAttrs;
13
+ }
14
+ export declare const TwoDimRecordOverflowAlert: TwoDimRecordOverflowAlertClass;
15
+ export {};
@@ -0,0 +1,32 @@
1
+ import { RecordOverflowAlertCore } from "../../features/recordOverflowAlert/recordOverflowAlertCore";
2
+ class TwoDimRecordOverflowAlertClass {
3
+ render(block, options) {
4
+ RecordOverflowAlertCore.render(block, this.buildCoreOptions(options));
5
+ }
6
+ update(block, options) {
7
+ RecordOverflowAlertCore.update(block, this.buildCoreOptions(options));
8
+ }
9
+ buildCoreOptions(options) {
10
+ return {
11
+ hidedRecordsAmount: options.hidedRecordsAmount,
12
+ text: this.getText(options.chartOrientation),
13
+ positionAttrs: this.getPositionAttrs()
14
+ };
15
+ }
16
+ getText(chartOrientation) {
17
+ const isHorizontal = chartOrientation === 'horizontal';
18
+ return {
19
+ one: isHorizontal ? 'строка' : 'столбец',
20
+ twoToFour: isHorizontal ? 'строки' : 'столбца',
21
+ tenToTwenty: isHorizontal ? 'строк' : 'столбцов',
22
+ other: isHorizontal ? 'строк' : 'столбцов'
23
+ };
24
+ }
25
+ getPositionAttrs() {
26
+ return {
27
+ right: '17px',
28
+ top: '1rem'
29
+ };
30
+ }
31
+ }
32
+ export const TwoDimRecordOverflowAlert = new TwoDimRecordOverflowAlertClass();