mdt-charts 1.19.0 → 1.20.1

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 (64) hide show
  1. package/lib/config/config.d.ts +16 -0
  2. package/lib/engine/block/blockSvg.d.ts +1 -1
  3. package/lib/engine/block/blockSvg.js +1 -1
  4. package/lib/engine/elementHighlighter/elementHighlighter.d.ts +0 -1
  5. package/lib/engine/elementHighlighter/elementHighlighter.js +5 -8
  6. package/lib/engine/elementHighlighter/selectHighlighter.js +11 -10
  7. package/lib/engine/features/axis/axis.d.ts +3 -3
  8. package/lib/engine/features/axis/axis.js +6 -0
  9. package/lib/engine/features/legend/legendMarkerCreator.js +1 -1
  10. package/lib/engine/features/markDots/markDot.d.ts +11 -3
  11. package/lib/engine/features/markDots/markDot.js +21 -10
  12. package/lib/engine/features/scale/scale.js +1 -1
  13. package/lib/engine/features/tolltip/tooltip.js +5 -4
  14. package/lib/engine/features/valueLabels/valueLabels.d.ts +45 -0
  15. package/lib/engine/features/valueLabels/valueLabels.js +139 -0
  16. package/lib/engine/features/valueLabels/valueLabelsHelper.d.ts +6 -0
  17. package/lib/engine/features/valueLabels/valueLabelsHelper.js +21 -0
  18. package/lib/engine/features/valueLabelsCollision/valueLabelsCollision.d.ts +23 -0
  19. package/lib/engine/features/valueLabelsCollision/valueLabelsCollision.js +24 -0
  20. package/lib/engine/features/valueLabelsCollision/valueLabelsCollisionHelper.d.ts +5 -0
  21. package/lib/engine/features/valueLabelsCollision/valueLabelsCollisionHelper.js +47 -0
  22. package/lib/engine/twoDimensionalNotation/area/area.d.ts +18 -11
  23. package/lib/engine/twoDimensionalNotation/area/area.js +32 -22
  24. package/lib/engine/twoDimensionalNotation/area/areaGenerator.d.ts +14 -0
  25. package/lib/engine/twoDimensionalNotation/area/areaGenerator.js +22 -0
  26. package/lib/engine/twoDimensionalNotation/area/areaHelper.d.ts +7 -7
  27. package/lib/engine/twoDimensionalNotation/area/areaHelper.js +30 -31
  28. package/lib/engine/twoDimensionalNotation/bar/barHelper.js +1 -1
  29. package/lib/engine/twoDimensionalNotation/bar/stackedData/dataStacker.d.ts +4 -2
  30. package/lib/engine/twoDimensionalNotation/bar/stackedData/dataStacker.js +2 -5
  31. package/lib/engine/twoDimensionalNotation/line/line.d.ts +0 -6
  32. package/lib/engine/twoDimensionalNotation/line/line.js +4 -4
  33. package/lib/engine/twoDimensionalNotation/line/lineGenerator.d.ts +4 -7
  34. package/lib/engine/twoDimensionalNotation/line/lineGenerator.js +2 -16
  35. package/lib/engine/twoDimensionalNotation/line/lineHelper.d.ts +4 -13
  36. package/lib/engine/twoDimensionalNotation/line/lineHelper.js +22 -10
  37. package/lib/engine/twoDimensionalNotation/lineLike/generatorFactory/lineLikeGeneratorFactory.d.ts +12 -0
  38. package/lib/engine/twoDimensionalNotation/lineLike/generatorFactory/lineLikeGeneratorFactory.js +1 -0
  39. package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorCurveMiddleware.d.ts +14 -0
  40. package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorCurveMiddleware.js +21 -0
  41. package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorDefineMiddleware.d.ts +20 -0
  42. package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorDefineMiddleware.js +9 -0
  43. package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorMiddleware.d.ts +5 -0
  44. package/lib/engine/twoDimensionalNotation/lineLike/generatorMiddleware/lineLikeGeneratorMiddleware.js +1 -0
  45. package/lib/engine/twoDimensionalNotation/twoDimensionalManager.d.ts +1 -0
  46. package/lib/engine/twoDimensionalNotation/twoDimensionalManager.js +19 -3
  47. package/lib/model/featuresModel/axisModel.d.ts +4 -2
  48. package/lib/model/featuresModel/axisModel.js +14 -6
  49. package/lib/model/featuresModel/scaleModel/scaleModel.js +1 -1
  50. package/lib/model/featuresModel/valueLabelsModel/valueLabelsModel.d.ts +9 -0
  51. package/lib/model/featuresModel/valueLabelsModel/valueLabelsModel.js +33 -0
  52. package/lib/model/helpers/modelHelper.d.ts +1 -0
  53. package/lib/model/helpers/modelHelper.js +3 -2
  54. package/lib/model/helpers/twoDimensionalModelHelper.d.ts +5 -0
  55. package/lib/model/helpers/twoDimensionalModelHelper.js +16 -0
  56. package/lib/model/margin/twoDim/twoDimMarginModel.d.ts +2 -0
  57. package/lib/model/margin/twoDim/twoDimMarginModel.js +34 -1
  58. package/lib/model/model.d.ts +29 -5
  59. package/lib/model/modelInstance/configReader.d.ts +9 -3
  60. package/lib/model/modelInstance/configReader.js +46 -15
  61. package/lib/model/notations/twoDimensionalModel.js +31 -35
  62. package/package.json +1 -1
  63. /package/lib/engine/block/{defs.d.ts → defs/hatchPattern.d.ts} +0 -0
  64. /package/lib/engine/block/{defs.js → defs/hatchPattern.js} +0 -0
@@ -0,0 +1,21 @@
1
+ import { curveBasis, curveMonotoneX, curveMonotoneY } from "d3-shape";
2
+ import { LineCurveType } from "../../../../model/model";
3
+ export class LineLikeGeneratorCurveMiddleware {
4
+ constructor(options) {
5
+ this.options = options;
6
+ this.curvies = {
7
+ [LineCurveType.monotoneX]: curveMonotoneX,
8
+ [LineCurveType.monotoneY]: curveMonotoneY,
9
+ [LineCurveType.basis]: curveBasis,
10
+ [LineCurveType.none]: undefined
11
+ };
12
+ }
13
+ handle(generator) {
14
+ if (this.options.curve != null) {
15
+ const curve = this.curvies[this.options.curve];
16
+ if (curve)
17
+ generator.curve(curve);
18
+ }
19
+ return generator;
20
+ }
21
+ }
@@ -0,0 +1,20 @@
1
+ import { Area, Line, SeriesPoint } from "d3-shape";
2
+ import { LineLikeGeneratorMiddleware } from "./lineLikeGeneratorMiddleware";
3
+ import { MdtChartsDataRow } from "../../../../config/config";
4
+ import { LineLikeChartRenderFn } from "../../../../model/model";
5
+ import { SegmentWithFieldName } from "../../bar/stackedData/dataStacker";
6
+ interface LineLikeGeneratorDefinedMiddlewareOptions {
7
+ definedFn: LineLikeChartRenderFn;
8
+ valueFieldNameGetter: (d: MdtChartsDataRow | Segment) => string;
9
+ dataRowGetter: (d: MdtChartsDataRow | Segment) => MdtChartsDataRow;
10
+ }
11
+ export interface Segment extends SeriesPoint<{
12
+ [p: string]: number;
13
+ }>, SegmentWithFieldName {
14
+ }
15
+ export declare class LineLikeGeneratorDefinedMiddleware implements LineLikeGeneratorMiddleware {
16
+ private readonly options;
17
+ constructor(options: LineLikeGeneratorDefinedMiddlewareOptions);
18
+ handle(generator: Line<MdtChartsDataRow> | Area<MdtChartsDataRow>): Line<MdtChartsDataRow> | Area<MdtChartsDataRow>;
19
+ }
20
+ export {};
@@ -0,0 +1,9 @@
1
+ export class LineLikeGeneratorDefinedMiddleware {
2
+ constructor(options) {
3
+ this.options = options;
4
+ }
5
+ handle(generator) {
6
+ generator.defined(d => this.options.definedFn(this.options.dataRowGetter(d), this.options.valueFieldNameGetter(d)));
7
+ return generator;
8
+ }
9
+ }
@@ -0,0 +1,5 @@
1
+ import { Line as ILine, Area as IArea } from "d3-shape";
2
+ import { MdtChartsDataRow } from "../../../../config/config";
3
+ export interface LineLikeGeneratorMiddleware {
4
+ handle(generator: ILine<MdtChartsDataRow> | IArea<MdtChartsDataRow>): ILine<MdtChartsDataRow> | IArea<MdtChartsDataRow>;
5
+ }
@@ -4,6 +4,7 @@ import { Block } from "../block/block";
4
4
  import { ChartContentManager } from "../contentManager/contentManagerFactory";
5
5
  import { Engine } from "../engine";
6
6
  export declare class TwoDimensionalManager implements ChartContentManager {
7
+ private canvasValueLabels?;
7
8
  render(engine: Engine, model: Model<TwoDimensionalOptionsModel>): void;
8
9
  updateData(block: Block, model: Model<TwoDimensionalOptionsModel>, data: MdtChartsDataSource): void;
9
10
  updateColors(block: Block, model: Model<TwoDimensionalOptionsModel>): void;
@@ -13,6 +13,7 @@ import { Bar } from "./bar/bar";
13
13
  import { BarHelper } from "./bar/barHelper";
14
14
  import { TwoDimRecordOverflowAlert } from "./extenders/twoDimRecordOverflowAlert";
15
15
  import { Line } from "./line/line";
16
+ import { CanvasValueLabels } from "../../engine/features/valueLabels/valueLabels";
16
17
  export class TwoDimensionalManager {
17
18
  render(engine, model) {
18
19
  const options = model.options;
@@ -38,6 +39,19 @@ export class TwoDimensionalManager {
38
39
  if (e.target === engine.block.getSvg().node())
39
40
  engine.block.filterEventManager.clearKeysFor2D(options);
40
41
  });
42
+ this.canvasValueLabels = new CanvasValueLabels({
43
+ elementAccessors: {
44
+ getBlock: () => engine.block,
45
+ },
46
+ data: {
47
+ keyFieldName: options.data.keyField.name
48
+ },
49
+ canvas: {
50
+ keyAxisOrient: options.axis.key.orient,
51
+ valueLabels: options.valueLabels,
52
+ }
53
+ });
54
+ this.canvasValueLabels.render(scales, options.charts, engine.data, options.data);
41
55
  }
42
56
  updateData(block, model, data) {
43
57
  block.transitionManager.interruptTransitions();
@@ -63,6 +77,8 @@ export class TwoDimensionalManager {
63
77
  hidedRecordsAmount: model.dataSettings.scope.hidedRecordsAmount,
64
78
  chartOrientation: options.orient
65
79
  });
80
+ if (this.canvasValueLabels)
81
+ this.canvasValueLabels.update(scales, options.charts, data, model.options.data);
66
82
  }
67
83
  updateColors(block, model) {
68
84
  Legend.get().updateColors(block, model.options);
@@ -72,7 +88,7 @@ export class TwoDimensionalManager {
72
88
  else if (chart.type === 'line')
73
89
  Line.get({ staticSettings: model.options.chartSettings.lineLike }).updateColors(block, chart);
74
90
  else if (chart.type === 'area')
75
- Area.updateColors(block, chart);
91
+ Area.get({ staticSettings: model.options.chartSettings.lineLike }).updateColors(block, chart);
76
92
  });
77
93
  }
78
94
  renderCharts(block, charts, scales, data, dataOptions, margin, keyAxisOrient, chartSettings, blockSize) {
@@ -86,7 +102,7 @@ export class TwoDimensionalManager {
86
102
  else if (chart.type === 'line')
87
103
  Line.get({ staticSettings: chartSettings.lineLike }).render(block, chartScales, data[dataOptions.dataSource], dataOptions.keyField, margin, keyAxisOrient, chart);
88
104
  else if (chart.type === 'area')
89
- Area.render(block, chartScales, data[dataOptions.dataSource], dataOptions.keyField, margin, keyAxisOrient, chart, blockSize);
105
+ Area.get({ staticSettings: chartSettings.lineLike }).render(block, chartScales, data[dataOptions.dataSource], dataOptions.keyField, margin, keyAxisOrient, chart, blockSize);
90
106
  });
91
107
  EmbeddedLabels.raiseGroups(block);
92
108
  }
@@ -103,7 +119,7 @@ export class TwoDimensionalManager {
103
119
  proms = Line.get({ staticSettings: chartSettings.lineLike }).update(block, chartScales, data[dataOptions.dataSource], dataOptions.keyField, margin, keyAxisOrient, chart);
104
120
  }
105
121
  else if (chart.type === 'area') {
106
- proms = Area.update(block, chartScales, data[dataOptions.dataSource], dataOptions.keyField, margin, chart, keyAxisOrient, blockSize);
122
+ proms = Area.get({ staticSettings: chartSettings.lineLike }).update(block, chartScales, data[dataOptions.dataSource], dataOptions.keyField, margin, chart, keyAxisOrient, blockSize);
107
123
  }
108
124
  promises.push(...proms);
109
125
  });
@@ -1,4 +1,4 @@
1
- import { AxisPosition, ChartOrientation, MdtChartsDataSource, NumberAxisOptions, AxisLabelPosition, MdtChartsTwoDimensionalOptions, DiscreteAxisOptions } from "../../config/config";
1
+ import { AxisPosition, ChartOrientation, MdtChartsDataSource, NumberAxisOptions, AxisLabelPosition, MdtChartsTwoDimensionalOptions, DiscreteAxisOptions, NumberSecondaryAxisOptions } from "../../config/config";
2
2
  import { AxisModelOptions, Orient } from "../model";
3
3
  import { AxisType } from "../modelBuilder";
4
4
  import { AxisLabelCanvas, TooltipSettings } from "../../designer/designerConfig";
@@ -12,7 +12,9 @@ export declare const MINIMAL_HORIZONTAL_STEP_SIZE = 100;
12
12
  export declare class AxisModel {
13
13
  private static service;
14
14
  static getKeyAxis(options: MdtChartsTwoDimensionalOptions, data: MdtChartsDataSource, labelConfig: AxisLabelCanvas, canvasModel: CanvasModel, tooltipSettings: TooltipSettings, getZeroCoordinate?: () => number): AxisModelOptions;
15
- static getValueAxis(orient: ChartOrientation, axisConfig: NumberAxisOptions, labelConfig: AxisLabelCanvas, canvasModel: CanvasModel): AxisModelOptions;
15
+ static getMainValueAxis(orient: ChartOrientation, position: AxisPosition, axisConfig: NumberAxisOptions, labelConfig: AxisLabelCanvas, canvasModel: CanvasModel): AxisModelOptions;
16
+ static getSecondaryValueAxis(orient: ChartOrientation, mainAxisPosition: AxisPosition, axisConfig: NumberSecondaryAxisOptions, labelConfig: AxisLabelCanvas, canvasModel: CanvasModel): AxisModelOptions;
17
+ private static getValueAxis;
16
18
  static getAxisLength(chartOrientation: ChartOrientation, canvasModel: CanvasModel): number;
17
19
  static getAxisOrient(axisType: AxisType, chartOrientation: ChartOrientation, axisPosition: AxisPosition): Orient;
18
20
  static getAxisTranslateX(axisType: AxisType, chartOrientation: ChartOrientation, axisPosition: AxisPosition, canvasModel: CanvasModel): number;
@@ -19,7 +19,7 @@ export class AxisModel {
19
19
  cssClass: 'key-axis',
20
20
  ticks: axisConfig.ticks,
21
21
  labels: {
22
- maxSize: AxisModel.getLabelSizeLegacy(labelConfig.maxSize.main, data[dataOptions.dataSource].map(d => d[dataOptions.keyField.name])).width,
22
+ maxSize: AxisModel.getLabelSize(labelConfig.maxSize.main, data[dataOptions.dataSource].map(d => d[dataOptions.keyField.name])).width,
23
23
  position: AxisModel.getKeyAxisLabelPosition(canvasModel, DataManagerModel.getDataValuesByKeyField(data, dataOptions.dataSource, dataOptions.keyField.name).length, axisConfig),
24
24
  visible: !TwoDimensionalModel.getChartsEmbeddedLabelsFlag(charts, orientation),
25
25
  defaultTooltip: tooltipSettings.position === 'fixed',
@@ -29,16 +29,22 @@ export class AxisModel {
29
29
  visibility: axisConfig.visibility
30
30
  };
31
31
  }
32
- static getValueAxis(orient, axisConfig, labelConfig, canvasModel) {
32
+ static getMainValueAxis(orient, position, axisConfig, labelConfig, canvasModel) {
33
+ return this.getValueAxis(orient, position, 'value-axis', axisConfig, labelConfig, canvasModel);
34
+ }
35
+ static getSecondaryValueAxis(orient, mainAxisPosition, axisConfig, labelConfig, canvasModel) {
36
+ return this.getValueAxis(orient, mainAxisPosition === "start" ? "end" : "start", 'value-secondary-axis', axisConfig, labelConfig, canvasModel);
37
+ }
38
+ static getValueAxis(orient, position, cssClass, axisConfig, labelConfig, canvasModel) {
33
39
  var _a, _b;
34
40
  return {
35
41
  type: 'value',
36
- orient: AxisModel.getAxisOrient(AxisType.Value, orient, axisConfig.position),
42
+ orient: AxisModel.getAxisOrient(AxisType.Value, orient, position),
37
43
  translate: {
38
- translateX: AxisModel.getAxisTranslateX(AxisType.Value, orient, axisConfig.position, canvasModel),
39
- translateY: AxisModel.getAxisTranslateY(AxisType.Value, orient, axisConfig.position, canvasModel)
44
+ translateX: AxisModel.getAxisTranslateX(AxisType.Value, orient, position, canvasModel),
45
+ translateY: AxisModel.getAxisTranslateY(AxisType.Value, orient, position, canvasModel)
40
46
  },
41
- cssClass: 'value-axis',
47
+ cssClass,
42
48
  ticks: axisConfig.ticks,
43
49
  labels: {
44
50
  maxSize: labelConfig.maxSize.main,
@@ -131,6 +137,8 @@ export class AxisModel {
131
137
  const sign = Math.sign(value);
132
138
  if (absValue < 10)
133
139
  return value;
140
+ if (absValue < 100)
141
+ return sign * Math.floor(absValue / 10) * 10;
134
142
  const valueStr = absValue.toString();
135
143
  const firstTwoDigits = Math.floor(absValue / Math.pow(10, valueStr.length - 2));
136
144
  const roundedFirstTwoDigits = firstTwoDigits < 10 ? firstTwoDigits : Math.floor(firstTwoDigits / 5) * 5;
@@ -38,7 +38,7 @@ export class ScaleModel {
38
38
  end: getScaleValueRangePeek(options.orientation, canvasModel)
39
39
  },
40
40
  type: "linear",
41
- formatter: (_a = configReader === null || configReader === void 0 ? void 0 : configReader.getAxisLabelFormatter()) !== null && _a !== void 0 ? _a : null
41
+ formatter: (_a = configReader === null || configReader === void 0 ? void 0 : configReader.getSecondaryAxisLabelFormatter()) !== null && _a !== void 0 ? _a : null
42
42
  };
43
43
  }
44
44
  getScaleKeyType(charts) {
@@ -0,0 +1,9 @@
1
+ import { BlockMargin, Orient, ValueLabelAnchor, ValueLabelDominantBaseline } from "../../model";
2
+ interface ValueLabelAlignment {
3
+ dominantBaseline: ValueLabelDominantBaseline;
4
+ textAnchor: ValueLabelAnchor;
5
+ }
6
+ export declare function getValueLabelY(scaledValue: number, keyAxisOrient: Orient, margin: BlockMargin): number;
7
+ export declare function getValueLabelX(scaledValue: number, keyAxisOrient: Orient, margin: BlockMargin): number;
8
+ export declare function calculateValueLabelAlignment(keyAxisOrient: Orient): ValueLabelAlignment;
9
+ export {};
@@ -0,0 +1,33 @@
1
+ const OFFSET_SIZE_PX = 10;
2
+ export function getValueLabelY(scaledValue, keyAxisOrient, margin) {
3
+ switch (keyAxisOrient) {
4
+ case 'bottom':
5
+ return scaledValue - OFFSET_SIZE_PX + margin.top;
6
+ case 'top':
7
+ return scaledValue + OFFSET_SIZE_PX + margin.top;
8
+ default:
9
+ return scaledValue + margin.top;
10
+ }
11
+ }
12
+ export function getValueLabelX(scaledValue, keyAxisOrient, margin) {
13
+ switch (keyAxisOrient) {
14
+ case 'right':
15
+ return scaledValue - OFFSET_SIZE_PX + margin.left;
16
+ case 'left':
17
+ return scaledValue + OFFSET_SIZE_PX + margin.left;
18
+ default:
19
+ return scaledValue + margin.left;
20
+ }
21
+ }
22
+ export function calculateValueLabelAlignment(keyAxisOrient) {
23
+ switch (keyAxisOrient) {
24
+ case 'top':
25
+ return { dominantBaseline: "hanging", textAnchor: "middle" };
26
+ case "bottom":
27
+ return { dominantBaseline: "auto", textAnchor: "middle" };
28
+ case "left":
29
+ return { dominantBaseline: "middle", textAnchor: "start" };
30
+ case "right":
31
+ return { dominantBaseline: "middle", textAnchor: "end" };
32
+ }
33
+ }
@@ -1,4 +1,5 @@
1
1
  export declare class ModelHelper {
2
+ private static readonly defaultBaseFontSize;
2
3
  private static baseFontSize;
3
4
  private static getBaseFontSize;
4
5
  static getSum(items: number[]): number;
@@ -3,7 +3,7 @@ export class ModelHelper {
3
3
  static getBaseFontSize() {
4
4
  if (!this.baseFontSize)
5
5
  this.baseFontSize = parseInt(DomHelper.getCssPropertyValue(document.documentElement, '--chart-base-font-size'));
6
- return this.baseFontSize;
6
+ return (!this.baseFontSize || isNaN(this.baseFontSize)) ? this.defaultBaseFontSize : this.baseFontSize;
7
7
  }
8
8
  static getSum(items) {
9
9
  return items.reduce((acc, item) => acc + item, 0);
@@ -17,7 +17,7 @@ export class ModelHelper {
17
17
  // Number width == lower case letter width
18
18
  const fontSize = this.getBaseFontSize();
19
19
  let score = 0;
20
- const upperLetterScore = fontSize / 13;
20
+ const upperLetterScore = fontSize / 10;
21
21
  const lowerLetterScore = fontSize / 15;
22
22
  const digitScore = fontSize / 15;
23
23
  const otherSymbolScore = fontSize / 23;
@@ -37,3 +37,4 @@ export class ModelHelper {
37
37
  return score;
38
38
  }
39
39
  }
40
+ ModelHelper.defaultBaseFontSize = 13;
@@ -0,0 +1,5 @@
1
+ import { MdtChartsDataRow, MdtChartsTwoDimensionalChart } from "../../config/config";
2
+ import { MarkDotDatumItem } from "../model";
3
+ export declare class TwoDimensionalModelHelper {
4
+ static shouldMarkerShow(chart: MdtChartsTwoDimensionalChart, dataRows: MdtChartsDataRow[], valueFieldName: string, currentRow: MarkDotDatumItem, keyFieldName: string): boolean;
5
+ }
@@ -0,0 +1,16 @@
1
+ export class TwoDimensionalModelHelper {
2
+ static shouldMarkerShow(chart, dataRows, valueFieldName, currentRow, keyFieldName) {
3
+ if (chart.markers.show || dataRows.length === 1)
4
+ return true;
5
+ const rowIndex = dataRows.findIndex(row => row[keyFieldName] === currentRow[keyFieldName]);
6
+ if (rowIndex === -1)
7
+ return false;
8
+ const isFirst = rowIndex === 0;
9
+ const isLast = rowIndex === dataRows.length - 1;
10
+ const previousRow = dataRows[rowIndex - 1];
11
+ const nextRow = dataRows[rowIndex + 1];
12
+ const hasNullNeighborsRows = !isFirst && !isLast &&
13
+ (previousRow === null || previousRow === void 0 ? void 0 : previousRow[valueFieldName]) === null && (nextRow === null || nextRow === void 0 ? void 0 : nextRow[valueFieldName]) === null;
14
+ return (isFirst && (nextRow === null || nextRow === void 0 ? void 0 : nextRow[valueFieldName]) === null) || (isLast && (previousRow === null || previousRow === void 0 ? void 0 : previousRow[valueFieldName]) === null) || hasNullNeighborsRows;
15
+ }
16
+ }
@@ -12,6 +12,8 @@ export declare class TwoDimMarginModel {
12
12
  recalcMargin(otherComponents: OtherCommonComponents, modelInstance: ModelInstance): void;
13
13
  recalcMarginByVerticalAxisLabel(modelInstance: ModelInstance): void;
14
14
  private getMaxLabelSize;
15
+ private getMaxLabelSizeSecondary;
15
16
  private recalcVerticalMarginByAxisLabelHeight;
16
17
  private recalcHorizontalMarginByAxisLabelWidth;
18
+ private recalcMarginBySecondaryAxisLabelSize;
17
19
  }
@@ -23,6 +23,10 @@ export class TwoDimMarginModel {
23
23
  ? !TwoDimensionalModel.getChartsEmbeddedLabelsFlag(this.configReader.options.charts, this.configReader.options.orientation)
24
24
  : true;
25
25
  this.recalcHorizontalMarginByAxisLabelWidth(labelSize, canvasModel, showingFlag);
26
+ if (this.configReader.containsSecondaryAxis()) {
27
+ const secondaryLabelSize = this.getMaxLabelSizeSecondary(modelInstance);
28
+ this.recalcMarginBySecondaryAxisLabelSize(secondaryLabelSize, canvasModel);
29
+ }
26
30
  }
27
31
  recalcMarginByVerticalAxisLabel(modelInstance) {
28
32
  if (this.configReader.options.orientation === 'vertical') {
@@ -43,11 +47,23 @@ export class TwoDimMarginModel {
43
47
  labelsTexts = modelInstance.dataModel.repository.getValuesByKeyField();
44
48
  }
45
49
  else {
46
- labelsTexts = this.configReader.calculateBiggestValueAndDecremented(modelInstance.dataModel.repository)
50
+ labelsTexts = this.configReader.getBiggestValueAndDecremented(modelInstance.dataModel.repository)
47
51
  .map(v => this.configReader.getAxisLabelFormatter()(v).toString());
48
52
  }
49
53
  return AxisModel.getLabelSize(this.designerConfig.canvas.axisLabel.maxSize.main, labelsTexts);
50
54
  }
55
+ getMaxLabelSizeSecondary(modelInstance) {
56
+ const keyAxisOrient = AxisModel.getAxisOrient(AxisType.Key, this.configReader.options.orientation, this.configReader.options.axis.key.position);
57
+ let labelsTexts;
58
+ if (keyAxisOrient === 'left' || keyAxisOrient === 'right') {
59
+ labelsTexts = modelInstance.dataModel.repository.getValuesByKeyField();
60
+ }
61
+ else {
62
+ labelsTexts = this.configReader.getBiggestValueAndDecrementedSecondary(modelInstance.dataModel.repository)
63
+ .map(v => this.configReader.getSecondaryAxisLabelFormatter()(v).toString());
64
+ }
65
+ return AxisModel.getLabelSize(this.designerConfig.canvas.axisLabel.maxSize.main, labelsTexts);
66
+ }
51
67
  recalcVerticalMarginByAxisLabelHeight(labelSize, canvasModel) {
52
68
  const keyAxisOrient = AxisModel.getAxisOrient(AxisType.Key, this.configReader.options.orientation, this.configReader.options.axis.key.position);
53
69
  const valueAxisOrient = AxisModel.getAxisOrient(AxisType.Value, this.configReader.options.orientation, this.configReader.options.axis.value.position);
@@ -68,4 +84,21 @@ export class TwoDimMarginModel {
68
84
  canvasModel.increaseMarginSide(valueAxisOrient, labelSize.width + AXIS_VERTICAL_LABEL_PADDING);
69
85
  }
70
86
  }
87
+ recalcMarginBySecondaryAxisLabelSize(labelSize, canvasModel) {
88
+ const valueAxisOrient = AxisModel.getAxisOrient(AxisType.Value, this.configReader.options.orientation, this.configReader.options.axis.value.position);
89
+ const secondaryOrientByMain = {
90
+ bottom: "top",
91
+ left: "right",
92
+ right: "left",
93
+ top: "bottom"
94
+ };
95
+ const secondaryOrient = secondaryOrientByMain[valueAxisOrient];
96
+ const sizeMap = {
97
+ vertical: labelSize.width + AXIS_VERTICAL_LABEL_PADDING,
98
+ horizontal: labelSize.height + AXIS_HORIZONTAL_LABEL_PADDING
99
+ };
100
+ if (this.configReader.options.axis.valueSecondary.visibility) {
101
+ canvasModel.increaseMarginSide(secondaryOrient, sizeMap[this.configReader.options.orientation]);
102
+ }
103
+ }
71
104
  }
@@ -1,4 +1,4 @@
1
- import { ChartOrientation, MdtChartsColorField, IntervalChartType, PolarChartType, Size, TooltipOptions, TwoDimensionalChartType, AxisLabelPosition, ShowTickFn, MdtChartsDataRow, TwoDimensionalValueGroup } from "../config/config";
1
+ import { ChartOrientation, MdtChartsColorField, IntervalChartType, PolarChartType, Size, TooltipOptions, TwoDimensionalChartType, AxisLabelPosition, ShowTickFn, MdtChartsDataRow, TwoDimensionalValueGroup, ValueLabelsCollision } from "../config/config";
2
2
  import { DataType, DonutOptionsCanvas, Formatter, StaticLegendBlockCanvas, TooltipSettings, Transitions } from "../designer/designerConfig";
3
3
  declare type AxisType = "key" | "value";
4
4
  export declare type Orient = "top" | "bottom" | "left" | "right";
@@ -10,6 +10,8 @@ export declare type DataOptions = {
10
10
  [option: string]: any;
11
11
  };
12
12
  export declare type UnitsFromConfig = "%" | "px";
13
+ export declare type ValueLabelAnchor = "start" | "middle" | "end";
14
+ export declare type ValueLabelDominantBaseline = "hanging" | "middle" | "auto";
13
15
  export declare type OptionsModel = TwoDimensionalOptionsModel | PolarOptionsModel | IntervalOptionsModel;
14
16
  export interface Model<O = OptionsModel> {
15
17
  blockCanvas: BlockCanvas;
@@ -49,6 +51,7 @@ export interface TwoDimensionalOptionsModel extends GraphicNotationOptionsModel
49
51
  additionalElements: AdditionalElementsOptions;
50
52
  orient: ChartOrientation;
51
53
  chartSettings: TwoDimChartElementsSettings;
54
+ valueLabels: TwoDimensionalValueLabels;
52
55
  }
53
56
  export interface PolarOptionsModel extends GraphicNotationOptionsModel {
54
57
  type: "polar";
@@ -101,6 +104,7 @@ export interface RangeModel {
101
104
  export interface IAxisModel {
102
105
  key: AxisModelOptions;
103
106
  value: AxisModelOptions;
107
+ valueSecondary?: AxisModelOptions;
104
108
  }
105
109
  export interface AxisModelOptions {
106
110
  visibility: boolean;
@@ -170,6 +174,9 @@ interface LineLikeChartCurveOptions {
170
174
  interface BarLikeChartHatchOptions {
171
175
  on: boolean;
172
176
  }
177
+ export interface TwoDimensionalValueLabels {
178
+ collision: ValueLabelsCollision;
179
+ }
173
180
  export interface DonutChartSettings extends Omit<DonutOptionsCanvas, "aggregatorPad" | "thickness"> {
174
181
  aggregator: DonutAggregatorModel;
175
182
  thickness: DonutThicknessOptions;
@@ -214,14 +221,14 @@ export interface TwoDimensionalChartLegendLineModel extends Omit<TwoDimensionalL
214
221
  width: number;
215
222
  }
216
223
  interface TwoDimensionalLineLikeChartModel {
217
- lineViewOptions: TwoDimensionalLineLikeChartViewModel;
224
+ lineLikeViewOptions: TwoDimensionalLineLikeChartViewModel;
218
225
  markersOptions: MarkersOptions;
219
226
  }
220
227
  interface TwoDimensionalLineLikeChartViewModel {
221
228
  dashedStyles: LineLikeChartDashOptions;
222
- renderForKey: LineLikeChartRenderOptions;
229
+ renderForKey: LineLikeChartRenderFn;
223
230
  }
224
- export declare type LineLikeChartRenderOptions = (dataRow: MdtChartsDataRow, valueFieldName: string) => boolean;
231
+ export declare type LineLikeChartRenderFn = (dataRow: MdtChartsDataRow, valueFieldName: string) => boolean;
225
232
  interface TwoDimensionalBarLikeChartModel {
226
233
  barViewOptions: TwoDimensionalBarLikeChartViewModel;
227
234
  }
@@ -235,6 +242,7 @@ export interface TwoDimensionalChartModel extends ChartModel, TwoDimensionalLine
235
242
  embeddedLabels: EmbeddedLabelTypeModel;
236
243
  isSegmented: boolean;
237
244
  legend: ChartLegendModel;
245
+ valueLabels?: TwoDimChartValueLabelsOptions;
238
246
  }
239
247
  export interface IntervalChartModel extends Omit<ChartModel, "legend"> {
240
248
  type: IntervalChartType;
@@ -252,10 +260,26 @@ export interface TwoDimensionalChartDataModel {
252
260
  export interface ValueField extends Field {
253
261
  title: string;
254
262
  }
255
- export interface MarkersOptions {
263
+ export interface TwoDimChartValueLabelsOptions {
256
264
  show: boolean;
265
+ handleX: (scaledValue: number) => number;
266
+ handleY: (scaledValue: number) => number;
267
+ textAnchor: ValueLabelAnchor;
268
+ dominantBaseline: ValueLabelDominantBaseline;
269
+ format: ValueLabelsFormatter;
270
+ }
271
+ export declare type ValueLabelsFormatter = (value: number) => string;
272
+ export interface MarkersOptions {
273
+ show: MarkersOptionsShow;
257
274
  styles: MarkersStyleOptions;
258
275
  }
276
+ export declare type MarkDotDatumItem = MdtChartsDataRow | {
277
+ "1": any;
278
+ } & Array<number>;
279
+ export declare type MarkersOptionsShow = (options: {
280
+ row: MarkDotDatumItem;
281
+ valueFieldName: string;
282
+ }) => boolean;
259
283
  export interface MarkersStyleOptions {
260
284
  highlighted: MarkerStyle;
261
285
  normal: MarkerStyle;
@@ -1,4 +1,4 @@
1
- import { AxisLabelFormatter, MdtChartsConfig, MdtChartsField, MdtChartsFieldName, MdtChartsTwoDimensionalOptions, TwoDimensionalChartType } from "../../config/config";
1
+ import { AxisLabelFormatter, MdtChartsConfig, MdtChartsField, MdtChartsFieldName, MdtChartsTwoDimensionalOptions, TwoDimensionalChartType, TwoDimensionalValueGroup, ValueLabelsFormatter } from "../../config/config";
2
2
  import { DesignerConfig } from "../../designer/designerConfig";
3
3
  import { DataRepositoryModel } from "../../model/modelInstance/dataModel/dataRepository";
4
4
  interface BaseConfigReader {
@@ -10,13 +10,19 @@ export declare class TwoDimConfigReader implements BaseConfigReader {
10
10
  readonly options: MdtChartsTwoDimensionalOptions;
11
11
  constructor(config: MdtChartsConfig, designerConfig: DesignerConfig);
12
12
  getValueFields(): MdtChartsField[];
13
- calculateBiggestValueAndDecremented(repository: DataRepositoryModel): number[];
14
- getFieldsBySegments(): MdtChartsFieldName[][];
13
+ getBiggestValueAndDecremented(repository: DataRepositoryModel): number[];
14
+ getBiggestValueAndDecrementedSecondary(repository: DataRepositoryModel): number[];
15
+ getFieldsBySegments(valueGroup: TwoDimensionalValueGroup): MdtChartsFieldName[][];
15
16
  getAxisLabelFormatter(): AxisLabelFormatter;
17
+ getSecondaryAxisLabelFormatter(): AxisLabelFormatter;
16
18
  getLegendItemInfo(): {
17
19
  text: string;
18
20
  chartType: TwoDimensionalChartType;
19
21
  }[];
22
+ containsSecondaryAxis(): boolean;
23
+ getValueLabelFormatterForChart(chartIndex: number): ValueLabelsFormatter;
24
+ private calculateBiggestValueAndDecremented;
25
+ private calculateAxisLabelFormatter;
20
26
  }
21
27
  export declare class PolarConfigReader implements BaseConfigReader {
22
28
  private options;
@@ -18,18 +18,16 @@ export class TwoDimConfigReader {
18
18
  });
19
19
  return fields;
20
20
  }
21
- calculateBiggestValueAndDecremented(repository) {
22
- const domain = this.options.axis.value.domain;
23
- const resolvedDomain = getResolvedDomain(domain, repository.getRawRows());
24
- if (resolvedDomain && resolvedDomain.end !== -1) {
25
- return [resolvedDomain.end, resolvedDomain.end - 1];
26
- }
27
- return repository.getBiggestValueAndDecremented(this.getFieldsBySegments());
21
+ getBiggestValueAndDecremented(repository) {
22
+ return this.calculateBiggestValueAndDecremented(repository, this.options.axis.value.domain, this.getFieldsBySegments("main"));
23
+ }
24
+ getBiggestValueAndDecrementedSecondary(repository) {
25
+ return this.calculateBiggestValueAndDecremented(repository, this.options.axis.valueSecondary.domain, this.getFieldsBySegments("secondary"));
28
26
  }
29
- getFieldsBySegments() {
27
+ getFieldsBySegments(valueGroup) {
30
28
  const segments = [];
31
- const mainCharts = this.options.charts.filter(chart => chart.data.valueGroup !== 'secondary');
32
- mainCharts.forEach(chart => {
29
+ const valueGroupCharts = this.options.charts.filter(chart => { var _a; return ((_a = chart.data.valueGroup) !== null && _a !== void 0 ? _a : "main") === valueGroup; });
30
+ valueGroupCharts.forEach(chart => {
33
31
  if (!chart.isSegmented)
34
32
  segments.push(...chart.data.valueFields.map(vf => [vf.name]));
35
33
  else
@@ -38,11 +36,10 @@ export class TwoDimConfigReader {
38
36
  return segments;
39
37
  }
40
38
  getAxisLabelFormatter() {
41
- var _a, _b;
42
- if ((_a = this.options.axis.value.labels) === null || _a === void 0 ? void 0 : _a.format)
43
- return (_b = this.options.axis.value.labels) === null || _b === void 0 ? void 0 : _b.format;
44
- const valueFieldFormat = this.options.charts[0].data.valueFields[0].format;
45
- return (v) => this.designerConfig.dataFormat.formatters(v, { type: valueFieldFormat });
39
+ return this.calculateAxisLabelFormatter(this.options.axis.value);
40
+ }
41
+ getSecondaryAxisLabelFormatter() {
42
+ return this.calculateAxisLabelFormatter(this.options.axis.valueSecondary);
46
43
  }
47
44
  getLegendItemInfo() {
48
45
  const info = [];
@@ -54,6 +51,40 @@ export class TwoDimConfigReader {
54
51
  });
55
52
  return info;
56
53
  }
54
+ containsSecondaryAxis() {
55
+ return !!this.options.axis.valueSecondary && this.options.charts.some(chart => chart.data.valueGroup === 'secondary');
56
+ }
57
+ getValueLabelFormatterForChart(chartIndex) {
58
+ var _a, _b, _c;
59
+ const chart = this.options.charts[chartIndex];
60
+ const axis = this.options.axis;
61
+ if (chart.valueLabels.format)
62
+ return chart.valueLabels.format;
63
+ if (chart.data.valueGroup === "secondary") {
64
+ if ((_a = axis.valueSecondary.labels) === null || _a === void 0 ? void 0 : _a.format)
65
+ return axis.valueSecondary.labels.format;
66
+ else if ((_b = axis.value.labels) === null || _b === void 0 ? void 0 : _b.format)
67
+ return axis.value.labels.format;
68
+ }
69
+ else if ((_c = axis.value.labels) === null || _c === void 0 ? void 0 : _c.format)
70
+ return axis.value.labels.format;
71
+ const valueFieldFormat = chart.data.valueFields[0].format;
72
+ return (v) => this.designerConfig.dataFormat.formatters(v, { type: valueFieldFormat });
73
+ }
74
+ calculateBiggestValueAndDecremented(repository, domain, fields) {
75
+ const resolvedDomain = getResolvedDomain(domain, repository.getRawRows());
76
+ if (resolvedDomain && resolvedDomain.end !== -1) {
77
+ return [resolvedDomain.end, resolvedDomain.end - 1];
78
+ }
79
+ return repository.getBiggestValueAndDecremented(fields);
80
+ }
81
+ calculateAxisLabelFormatter(axisValue) {
82
+ var _a, _b;
83
+ if ((_a = axisValue.labels) === null || _a === void 0 ? void 0 : _a.format)
84
+ return (_b = axisValue.labels) === null || _b === void 0 ? void 0 : _b.format;
85
+ const valueFieldFormat = this.options.charts[0].data.valueFields[0].format;
86
+ return (v) => this.designerConfig.dataFormat.formatters(v, { type: valueFieldFormat });
87
+ }
57
88
  }
58
89
  export class PolarConfigReader {
59
90
  constructor(config) {