mdt-charts 1.12.3 → 1.12.7
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.
- package/lib/engine/features/aggregator/aggregator.d.ts +1 -1
- package/lib/engine/features/aggregator/aggregator.js +16 -15
- package/lib/engine/features/axis/axis.d.ts +3 -1
- package/lib/engine/features/axis/axis.js +8 -0
- package/lib/engine/features/gridLine/gidLineHelper.d.ts +2 -0
- package/lib/engine/features/gridLine/gidLineHelper.js +22 -0
- package/lib/engine/features/gridLine/gridLine.d.ts +5 -3
- package/lib/engine/features/gridLine/gridLine.js +16 -17
- package/lib/engine/features/scale/scale.d.ts +2 -0
- package/lib/engine/features/scale/scale.js +6 -3
- package/lib/engine/intervalNotation/intervalManager.js +1 -1
- package/lib/engine/twoDimensionalNotation/area/areaHelper.js +2 -2
- package/lib/engine/twoDimensionalNotation/bar/bar.js +3 -3
- package/lib/engine/twoDimensionalNotation/bar/barHelper.js +8 -8
- package/lib/engine/twoDimensionalNotation/twoDimensionalManager.js +3 -2
- package/lib/model/featuresModel/axisModel.d.ts +2 -1
- package/lib/model/featuresModel/axisModel.js +19 -5
- package/lib/model/featuresModel/legendModel/legendModel.js +2 -2
- package/lib/model/featuresModel/scaleModel/scaleAxisRecalcer.d.ts +20 -0
- package/lib/model/featuresModel/scaleModel/scaleAxisRecalcer.js +31 -0
- package/lib/model/featuresModel/scaleModel/scaleModel.d.ts +19 -0
- package/lib/model/featuresModel/scaleModel/scaleModel.js +115 -0
- package/lib/model/featuresModel/scaleModel.d.ts +3 -2
- package/lib/model/featuresModel/scaleModel.js +19 -4
- package/lib/model/featuresModel/titleModel.js +1 -1
- package/lib/model/marginModel.d.ts +1 -3
- package/lib/model/marginModel.js +7 -29
- package/lib/model/modelBuilder.js +7 -8
- package/lib/model/modelInstance/canvasModel/canvasModel.d.ts +5 -4
- package/lib/model/modelInstance/canvasModel/canvasModel.js +6 -2
- package/lib/model/modelInstance/canvasModel/marginModelService.d.ts +11 -0
- package/lib/model/modelInstance/canvasModel/marginModelService.js +26 -0
- package/lib/model/modelInstance/dataModel/dataModel.d.ts +14 -0
- package/lib/model/modelInstance/dataModel/dataModel.js +26 -0
- package/lib/model/modelInstance/dataModel/dataRepository.d.ts +12 -0
- package/lib/model/modelInstance/dataModel/dataRepository.js +20 -0
- package/lib/model/modelInstance/modelInstance.d.ts +3 -3
- package/lib/model/modelInstance/modelInstance.js +6 -4
- package/lib/model/notations/intervalModel.js +1 -1
- package/lib/model/notations/polar/donut/donutAggregatorService.js +2 -2
- package/lib/model/notations/polar/donut/donutModel.d.ts +1 -1
- package/lib/model/notations/polar/donut/donutModel.js +4 -4
- package/lib/model/notations/polar/polarModel.d.ts +2 -3
- package/lib/model/notations/polar/polarModel.js +3 -5
- package/lib/model/notations/twoDimensionalModel.d.ts +2 -2
- package/lib/model/notations/twoDimensionalModel.js +9 -5
- package/lib/style/charts-main.css +1 -0
- package/lib/style/charts-main.less +1 -0
- package/package.json +1 -1
|
@@ -15,26 +15,28 @@ export class Aggregator {
|
|
|
15
15
|
name: settings.content.title,
|
|
16
16
|
value: settings.content.value,
|
|
17
17
|
format: valueField.format,
|
|
18
|
-
|
|
18
|
+
marginInPercent: settings.margin
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
static renderText(block, innerRadius, aggregatorInfo, fontSize, translate) {
|
|
22
|
-
if (innerRadius >
|
|
22
|
+
if (innerRadius > 30) {
|
|
23
23
|
const aggregatorObject = this.renderAggregatorObject(block, innerRadius, translate);
|
|
24
24
|
const wrapper = this.renderWrapper(aggregatorObject);
|
|
25
25
|
wrapper
|
|
26
26
|
.append('div')
|
|
27
27
|
.attr('class', this.aggregatorValueClass)
|
|
28
|
+
.attr('title', this.formatValue(aggregatorInfo.format, aggregatorInfo.value))
|
|
28
29
|
.style('text-align', 'center')
|
|
29
30
|
.style('font-size', `${fontSize}px`)
|
|
30
31
|
.text(this.formatValue(aggregatorInfo.format, aggregatorInfo.value));
|
|
31
|
-
wrapper
|
|
32
|
+
const titleBlock = wrapper
|
|
32
33
|
.append('div')
|
|
33
34
|
.attr('class', this.aggregatorTitleClass)
|
|
34
35
|
.attr('title', aggregatorInfo.name)
|
|
35
36
|
.style('text-align', 'center')
|
|
36
37
|
.text(aggregatorInfo.name);
|
|
37
|
-
this.
|
|
38
|
+
this.setTitleFontSize(titleBlock, innerRadius);
|
|
39
|
+
this.reCalculateAggregatorFontSize(aggregatorObject.node().getBoundingClientRect().width, block, aggregatorInfo.marginInPercent);
|
|
38
40
|
}
|
|
39
41
|
}
|
|
40
42
|
static formatValue(format, value) {
|
|
@@ -63,26 +65,25 @@ export class Aggregator {
|
|
|
63
65
|
const interpolateFunc = interpolateNumber(oldValue, newValue);
|
|
64
66
|
return t => {
|
|
65
67
|
this.textContent = thisClass.formatValue(newAggregator.format, parseFloat((interpolateFunc(t)).toFixed(precision)));
|
|
66
|
-
thisClass.reCalculateAggregatorFontSize(aggregatorObject.node().getBoundingClientRect().width, block, newAggregator.
|
|
68
|
+
thisClass.reCalculateAggregatorFontSize(aggregatorObject.node().getBoundingClientRect().width, block, newAggregator.marginInPercent);
|
|
67
69
|
};
|
|
68
70
|
});
|
|
69
71
|
}
|
|
70
72
|
static reCalculateAggregatorFontSize(wrapperSize, block, pad) {
|
|
71
73
|
const aggregatorValue = block.getSvg()
|
|
72
74
|
.select(`.${this.aggregatorValueClass}`);
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
const sizeCoefficient = 0.25;
|
|
76
|
+
let fontSize = wrapperSize * sizeCoefficient;
|
|
77
|
+
aggregatorValue.style('font-size', `${fontSize}px`);
|
|
78
|
+
const margin = pad / 100 * wrapperSize;
|
|
79
|
+
while (aggregatorValue.node().getBoundingClientRect().width > wrapperSize - margin * 2 && fontSize > 12) {
|
|
77
80
|
aggregatorValue.style('font-size', `${fontSize -= 2}px`);
|
|
78
81
|
}
|
|
79
|
-
while (aggregatorValue.node().getBoundingClientRect().width < wrapperSize - pad * 2 && fontSize < 60) {
|
|
80
|
-
aggregatorValue.style('font-size', `${fontSize += 2}px`);
|
|
81
|
-
}
|
|
82
|
-
this.setTitleFontSize(aggregatorTitle, fontSize);
|
|
83
82
|
}
|
|
84
|
-
static setTitleFontSize(aggregatorTitle,
|
|
85
|
-
|
|
83
|
+
static setTitleFontSize(aggregatorTitle, innerRadius) {
|
|
84
|
+
const sizeCoefficient = 0.15;
|
|
85
|
+
aggregatorTitle.style('font-size', `${Math.round(innerRadius * sizeCoefficient)}px`);
|
|
86
|
+
aggregatorTitle.style('max-height', `${sizeCoefficient * 100}%`);
|
|
86
87
|
}
|
|
87
88
|
static renderAggregatorObject(block, innerRadius, translate) {
|
|
88
89
|
return block.getSvg()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IAxisModel, IScaleModel } from "../../../model/model";
|
|
1
|
+
import { AxisModelOptions, IAxisModel, IScaleModel } from "../../../model/model";
|
|
2
2
|
import { Block } from "../../block/block";
|
|
3
3
|
import { Scales } from "../scale/scale";
|
|
4
4
|
import { Size } from '../../../config/config';
|
|
@@ -6,6 +6,8 @@ export declare class Axis {
|
|
|
6
6
|
static axesClass: string;
|
|
7
7
|
static render(block: Block, scales: Scales, scaleModel: IScaleModel, axisModel: IAxisModel, blockSize: Size): void;
|
|
8
8
|
static update(block: Block, scales: Scales, scalesOptions: IScaleModel, axisModel: IAxisModel, blockSize: Size, keyDomainsEquality: boolean): void;
|
|
9
|
+
static raiseKeyAxis(block: Block, axisOptions: AxisModelOptions): void;
|
|
10
|
+
private static findAxis;
|
|
9
11
|
private static renderAxis;
|
|
10
12
|
private static updateValueAxis;
|
|
11
13
|
private static updateKeyAxis;
|
|
@@ -20,6 +20,14 @@ export class Axis {
|
|
|
20
20
|
if (axisModel.key.visibility)
|
|
21
21
|
this.updateKeyAxis(block, scales.key, scalesOptions.key, axisModel.key, blockSize, keyDomainsEquality);
|
|
22
22
|
}
|
|
23
|
+
static raiseKeyAxis(block, axisOptions) {
|
|
24
|
+
const axisElement = this.findAxis(block, axisOptions.cssClass);
|
|
25
|
+
axisElement.raise();
|
|
26
|
+
}
|
|
27
|
+
static findAxis(block, axisCssClass) {
|
|
28
|
+
return block.getSvg()
|
|
29
|
+
.select(`g.${axisCssClass}`);
|
|
30
|
+
}
|
|
23
31
|
static renderAxis(block, scale, scaleOptions, axisOptions, blockSize) {
|
|
24
32
|
const axisGenerator = AxisHelper.getBaseAxisGenerator(axisOptions, scale, scaleOptions);
|
|
25
33
|
if (axisOptions.type === 'value' && (scaleOptions.type === 'linear' || scaleOptions.type === 'datetime'))
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AxisScale } from "d3-axis";
|
|
1
2
|
import { Size } from "../../../config/config";
|
|
2
3
|
import { AxisModelOptions, BlockMargin } from "../../../model/model";
|
|
3
4
|
export declare type GridLineType = 'key' | 'value';
|
|
@@ -10,4 +11,5 @@ export interface GridLineAttributes {
|
|
|
10
11
|
export declare class GridLineHelper {
|
|
11
12
|
static getGridLineLength(gridLineType: GridLineType, keyAxis: AxisModelOptions, valueAxis: AxisModelOptions, blockSize: Size, margin: BlockMargin): number;
|
|
12
13
|
static getLineAttributes(axis: AxisModelOptions, lineLength: number): GridLineAttributes;
|
|
14
|
+
static getKeyLineAttributes(axis: AxisModelOptions, scaleValue: AxisScale<any>): GridLineAttributes;
|
|
13
15
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { max, min } from "d3-array";
|
|
1
2
|
export class GridLineHelper {
|
|
2
3
|
static getGridLineLength(gridLineType, keyAxis, valueAxis, blockSize, margin) {
|
|
3
4
|
let axis;
|
|
@@ -27,4 +28,25 @@ export class GridLineHelper {
|
|
|
27
28
|
attributes.y2 = lineLength;
|
|
28
29
|
return attributes;
|
|
29
30
|
}
|
|
31
|
+
static getKeyLineAttributes(axis, scaleValue) {
|
|
32
|
+
const attributes = {
|
|
33
|
+
x1: 0,
|
|
34
|
+
y1: 0,
|
|
35
|
+
x2: 0,
|
|
36
|
+
y2: 0
|
|
37
|
+
};
|
|
38
|
+
const scaledStart = scaleValue(scaleValue.domain()[0]);
|
|
39
|
+
const scaledEnd = scaleValue(scaleValue.domain()[1]);
|
|
40
|
+
const minCoord = min([scaledStart, scaledEnd]) - scaleValue(0);
|
|
41
|
+
const maxCoord = max([scaledStart, scaledEnd]) - scaleValue(0);
|
|
42
|
+
if (axis.orient === 'left' || axis.orient === 'right') {
|
|
43
|
+
attributes.x1 = minCoord;
|
|
44
|
+
attributes.x2 = maxCoord;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
attributes.y1 = minCoord;
|
|
48
|
+
attributes.y2 = maxCoord;
|
|
49
|
+
}
|
|
50
|
+
return attributes;
|
|
51
|
+
}
|
|
30
52
|
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { Size } from "../../../config/config";
|
|
2
|
-
import { BlockMargin, GridLineFlag, IAxisModel
|
|
2
|
+
import { BlockMargin, GridLineFlag, IAxisModel } from "../../../model/model";
|
|
3
3
|
import { Block } from "../../block/block";
|
|
4
|
+
import { Scales } from "../scale/scale";
|
|
4
5
|
export declare class GridLine {
|
|
5
6
|
private static readonly gridLineClass;
|
|
6
|
-
static render(block: Block, gridLineFlag: GridLineFlag, axes: IAxisModel, blockSize: Size, margin: BlockMargin,
|
|
7
|
-
static update(block: Block, gridLineFlag: GridLineFlag, axes: IAxisModel, blockSize: Size, margin: BlockMargin,
|
|
7
|
+
static render(block: Block, gridLineFlag: GridLineFlag, axes: IAxisModel, blockSize: Size, margin: BlockMargin, scales: Scales): void;
|
|
8
|
+
static update(block: Block, gridLineFlag: GridLineFlag, axes: IAxisModel, blockSize: Size, margin: BlockMargin, scales: Scales): void;
|
|
8
9
|
private static renderLine;
|
|
9
10
|
private static clear;
|
|
10
11
|
private static removeGridLinesOnAxes;
|
|
12
|
+
private static rmGridLineOnTick;
|
|
11
13
|
}
|
|
@@ -1,24 +1,20 @@
|
|
|
1
1
|
import { GridLineHelper } from "./gidLineHelper";
|
|
2
2
|
export class GridLine {
|
|
3
|
-
static render(block, gridLineFlag, axes, blockSize, margin,
|
|
3
|
+
static render(block, gridLineFlag, axes, blockSize, margin, scales) {
|
|
4
4
|
if (gridLineFlag.value) {
|
|
5
5
|
const lineLength = GridLineHelper.getGridLineLength('value', axes.key, axes.value, blockSize, margin);
|
|
6
6
|
const lineAttributes = GridLineHelper.getLineAttributes(axes.value, lineLength);
|
|
7
7
|
this.renderLine(block, axes.value, lineAttributes);
|
|
8
8
|
}
|
|
9
9
|
if (gridLineFlag.key) {
|
|
10
|
-
const
|
|
11
|
-
const lineAttributes = GridLineHelper.getLineAttributes(axes.key, lineLength);
|
|
10
|
+
const lineAttributes = GridLineHelper.getKeyLineAttributes(axes.key, scales.value);
|
|
12
11
|
this.renderLine(block, axes.key, lineAttributes);
|
|
13
12
|
}
|
|
14
|
-
|
|
15
|
-
this.removeGridLinesOnAxes(block, axes.key, axes.value, false);
|
|
16
|
-
else if (gridLineFlag.key || gridLineFlag.value)
|
|
17
|
-
this.removeGridLinesOnAxes(block, axes.key, axes.value, true);
|
|
13
|
+
this.removeGridLinesOnAxes(block, axes.key, axes.value, true);
|
|
18
14
|
}
|
|
19
|
-
static update(block, gridLineFlag, axes, blockSize, margin,
|
|
15
|
+
static update(block, gridLineFlag, axes, blockSize, margin, scales) {
|
|
20
16
|
this.clear(block, axes.key.cssClass, axes.value.cssClass);
|
|
21
|
-
this.render(block, gridLineFlag, axes, blockSize, margin,
|
|
17
|
+
this.render(block, gridLineFlag, axes, blockSize, margin, scales);
|
|
22
18
|
}
|
|
23
19
|
static renderLine(block, axis, lineAttributes) {
|
|
24
20
|
block
|
|
@@ -51,17 +47,20 @@ export class GridLine {
|
|
|
51
47
|
tickOnValueAxisSelector = ':last-of-type';
|
|
52
48
|
if (keyAxis.orient === 'bottom' || keyAxis.orient === 'right')
|
|
53
49
|
tickOnKeyAxisSelector = ':last-of-type';
|
|
54
|
-
block.getSvg()
|
|
50
|
+
const tickOnKey = block.getSvg()
|
|
55
51
|
.select(`.${valueAxis.cssClass}`)
|
|
56
|
-
.select(`g.tick${tickOnKeyAxisSelector}`)
|
|
52
|
+
.select(`g.tick${tickOnKeyAxisSelector}`);
|
|
53
|
+
const tickOnValue = block.getSvg()
|
|
54
|
+
.select(`.${keyAxis.cssClass}`)
|
|
55
|
+
.select(`g.tick${tickOnValueAxisSelector}`);
|
|
56
|
+
// this.rmGridLineOnTick(tickOnKey);
|
|
57
|
+
// if (!excludeKey)
|
|
58
|
+
// this.rmGridLineOnTick(tickOnValue);
|
|
59
|
+
}
|
|
60
|
+
static rmGridLineOnTick(tick) {
|
|
61
|
+
tick
|
|
57
62
|
.select(`.${this.gridLineClass}`)
|
|
58
63
|
.remove();
|
|
59
|
-
if (!excludeKey)
|
|
60
|
-
block.getSvg()
|
|
61
|
-
.select(`.${keyAxis.cssClass}`)
|
|
62
|
-
.select(`g.tick${tickOnValueAxisSelector}`)
|
|
63
|
-
.select(`.${this.gridLineClass}`)
|
|
64
|
-
.remove();
|
|
65
64
|
}
|
|
66
65
|
}
|
|
67
66
|
GridLine.gridLineClass = 'grid-line';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ScaleLinear, ScaleTime } from 'd3-scale';
|
|
1
2
|
import { AxisScale } from 'd3-axis';
|
|
2
3
|
import { BarChartSettings, ScaleKeyModel, ScaleValueModel } from '../../../model/model';
|
|
3
4
|
export interface Scales {
|
|
@@ -6,6 +7,7 @@ export interface Scales {
|
|
|
6
7
|
}
|
|
7
8
|
export declare class Scale {
|
|
8
9
|
static getScales(scaleKey: ScaleKeyModel, scaleValue: ScaleValueModel, bandSettings: BarChartSettings): Scales;
|
|
10
|
+
static getScaleValue(scaleValue: ScaleValueModel): ScaleLinear<number, number, never> | ScaleTime<number, number, never>;
|
|
9
11
|
static getScaleBandWidth(scale: AxisScale<any>): number;
|
|
10
12
|
static getScaleStep(scale: AxisScale<any>): number;
|
|
11
13
|
static getScaledValue(scale: AxisScale<any>, value: any): number;
|
|
@@ -9,11 +9,14 @@ export class Scale {
|
|
|
9
9
|
scales.key = this.getScaleBand(scaleKey.domain, scaleKey.range, bandSettings, scaleKey.elementsAmount);
|
|
10
10
|
else if (scaleKey.type === 'point')
|
|
11
11
|
scales.key = this.getScalePoint(scaleKey.domain, scaleKey.range);
|
|
12
|
+
scales.value = this.getScaleValue(scaleValue);
|
|
13
|
+
return scales;
|
|
14
|
+
}
|
|
15
|
+
static getScaleValue(scaleValue) {
|
|
12
16
|
if (scaleValue.type === 'linear')
|
|
13
|
-
|
|
17
|
+
return this.getScaleLinear(scaleValue.domain, scaleValue.range);
|
|
14
18
|
else if (scaleValue.type === 'datetime')
|
|
15
|
-
|
|
16
|
-
return scales;
|
|
19
|
+
return this.getScaleTime(scaleValue.domain, scaleValue.range);
|
|
17
20
|
}
|
|
18
21
|
static getScaleBandWidth(scale) {
|
|
19
22
|
if (scale.bandwidth && scale.bandwidth() !== 0) {
|
|
@@ -11,7 +11,7 @@ export class IntervalManager {
|
|
|
11
11
|
block.renderSvg(model.blockCanvas.size);
|
|
12
12
|
const scales = Scale.getScales(options.scale.key, options.scale.value, options.chartSettings.bar);
|
|
13
13
|
Axis.render(block, scales, options.scale, options.axis, model.blockCanvas.size);
|
|
14
|
-
GridLine.render(block, options.additionalElements.gridLine.flag, options.axis, model.blockCanvas.size, model.chartBlock.margin,
|
|
14
|
+
GridLine.render(block, options.additionalElements.gridLine.flag, options.axis, model.blockCanvas.size, model.chartBlock.margin, scales);
|
|
15
15
|
this.renderCharts(block, options.charts, scales, data, options.data, model.chartBlock.margin, options.axis.key.orient, options.chartSettings);
|
|
16
16
|
Title.render(block, options.title, model.otherComponents.titleBlock, model.blockCanvas.size);
|
|
17
17
|
Legend.render(block, data, options, model);
|
|
@@ -5,11 +5,11 @@ export class AreaHelper {
|
|
|
5
5
|
if (keyAxisOrient === 'bottom' || keyAxisOrient === 'top')
|
|
6
6
|
return area()
|
|
7
7
|
.x(d => Scale.getScaledValue(scales.key, d[keyFieldName]) + margin.left)
|
|
8
|
-
.y0(d =>
|
|
8
|
+
.y0(d => scales.value(0) + margin.top)
|
|
9
9
|
.y1(d => scales.value(d[valueFieldName]) + margin.top);
|
|
10
10
|
if (keyAxisOrient === 'left' || keyAxisOrient === 'right')
|
|
11
11
|
return area()
|
|
12
|
-
.x0(d =>
|
|
12
|
+
.x0(d => scales.value(0) + margin.left)
|
|
13
13
|
.x1(d => scales.value(d[valueFieldName]) + margin.left)
|
|
14
14
|
.y(d => Scale.getScaledValue(scales.key, d[keyFieldName]) + margin.top);
|
|
15
15
|
}
|
|
@@ -171,15 +171,15 @@ export class Bar {
|
|
|
171
171
|
resolve('');
|
|
172
172
|
return;
|
|
173
173
|
}
|
|
174
|
-
let
|
|
174
|
+
let barsHandler = bars;
|
|
175
175
|
if (transitionDuration > 0) {
|
|
176
|
-
|
|
176
|
+
barsHandler = barsHandler
|
|
177
177
|
.interrupt()
|
|
178
178
|
.transition()
|
|
179
179
|
.duration(transitionDuration)
|
|
180
180
|
.on('end', () => resolve(''));
|
|
181
181
|
}
|
|
182
|
-
|
|
182
|
+
barsHandler.attr('x', d => barAttrs.x(d))
|
|
183
183
|
.attr('y', d => barAttrs.y(d))
|
|
184
184
|
.attr('height', d => barAttrs.height(d))
|
|
185
185
|
.attr('width', d => barAttrs.width(d));
|
|
@@ -66,20 +66,20 @@ export class BarHelper {
|
|
|
66
66
|
}
|
|
67
67
|
static setGroupedBarAttrsByValue(attrs, keyAxisOrient, margin, scaleValue, valueFieldName, blockSize) {
|
|
68
68
|
if (keyAxisOrient === 'top') {
|
|
69
|
-
attrs.y = d => margin.top;
|
|
70
|
-
attrs.height = d =>
|
|
69
|
+
attrs.y = d => scaleValue(Math.min(d[valueFieldName], 0)) + margin.top;
|
|
70
|
+
attrs.height = d => Math.abs(scaleValue(d[valueFieldName]) - scaleValue(0));
|
|
71
71
|
}
|
|
72
72
|
if (keyAxisOrient === 'bottom') {
|
|
73
|
-
attrs.y = d => scaleValue(d[valueFieldName]) + margin.top;
|
|
74
|
-
attrs.height = d =>
|
|
73
|
+
attrs.y = d => scaleValue(Math.max(d[valueFieldName], 0)) + margin.top;
|
|
74
|
+
attrs.height = d => Math.abs(scaleValue(d[valueFieldName]) - scaleValue(0));
|
|
75
75
|
}
|
|
76
76
|
if (keyAxisOrient === 'left') {
|
|
77
|
-
attrs.x = d =>
|
|
78
|
-
attrs.width = d =>
|
|
77
|
+
attrs.x = d => scaleValue(Math.min(d[valueFieldName], 0)) + margin.left;
|
|
78
|
+
attrs.width = d => Math.abs(scaleValue(d[valueFieldName]) - scaleValue(0));
|
|
79
79
|
}
|
|
80
80
|
if (keyAxisOrient === 'right') {
|
|
81
|
-
attrs.x = d => scaleValue(d[valueFieldName]) + margin.left;
|
|
82
|
-
attrs.width = d =>
|
|
81
|
+
attrs.x = d => scaleValue(Math.max(d[valueFieldName], 0)) + margin.left;
|
|
82
|
+
attrs.width = d => Math.abs(scaleValue(d[valueFieldName]) - scaleValue(0));
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
static setSegmentedBarAttrsByValue(attrs, keyAxisOrient, scaleValue, margin, blockSize) {
|
|
@@ -20,8 +20,9 @@ export class TwoDimensionalManager {
|
|
|
20
20
|
engine.block.scales = scales;
|
|
21
21
|
engine.block.renderSvg(model.blockCanvas.size);
|
|
22
22
|
Axis.render(engine.block, scales, options.scale, options.axis, model.blockCanvas.size);
|
|
23
|
-
GridLine.render(engine.block, options.additionalElements.gridLine.flag, options.axis, model.blockCanvas.size, model.chartBlock.margin,
|
|
23
|
+
GridLine.render(engine.block, options.additionalElements.gridLine.flag, options.axis, model.blockCanvas.size, model.chartBlock.margin, scales);
|
|
24
24
|
this.renderCharts(engine.block, options.charts, scales, engine.data, options.data, model.chartBlock.margin, options.axis.key.orient, options.chartSettings.bar, model.blockCanvas.size);
|
|
25
|
+
Axis.raiseKeyAxis(engine.block, options.axis.key);
|
|
25
26
|
engine.block.filterEventManager.registerEventFor2D(scales.key, model.chartBlock.margin, model.blockCanvas.size, options);
|
|
26
27
|
engine.block.filterEventManager.event2DUpdate(options);
|
|
27
28
|
Title.render(engine.block, options.title, model.otherComponents.titleBlock, model.blockCanvas.size);
|
|
@@ -49,7 +50,7 @@ export class TwoDimensionalManager {
|
|
|
49
50
|
const keyDomainEquality = Helper.checkDomainsEquality(block.scales.key.domain(), scales.key.domain());
|
|
50
51
|
block.scales = scales;
|
|
51
52
|
Axis.update(block, scales, options.scale, options.axis, model.blockCanvas.size, keyDomainEquality);
|
|
52
|
-
GridLine.update(block, options.additionalElements.gridLine.flag, options.axis, model.blockCanvas.size, model.chartBlock.margin,
|
|
53
|
+
GridLine.update(block, options.additionalElements.gridLine.flag, options.axis, model.blockCanvas.size, model.chartBlock.margin, scales);
|
|
53
54
|
const promises = this.updateCharts(block, options.charts, scales, data, model.options.data, model.chartBlock.margin, options.axis.key.orient, model.blockCanvas.size, options.chartSettings.bar);
|
|
54
55
|
Promise.all(promises)
|
|
55
56
|
.then(() => {
|
|
@@ -9,7 +9,7 @@ export interface LabelSize {
|
|
|
9
9
|
}
|
|
10
10
|
export declare class AxisModel {
|
|
11
11
|
private static service;
|
|
12
|
-
static getKeyAxis(options: MdtChartsTwoDimensionalOptions, data: MdtChartsDataSource, labelConfig: AxisLabelCanvas, canvasModel: CanvasModel, tooltipSettings: TooltipSettings): AxisModelOptions;
|
|
12
|
+
static getKeyAxis(options: MdtChartsTwoDimensionalOptions, data: MdtChartsDataSource, labelConfig: AxisLabelCanvas, canvasModel: CanvasModel, tooltipSettings: TooltipSettings, getZeroCoordinate?: () => number): AxisModelOptions;
|
|
13
13
|
static getValueAxis(orient: ChartOrientation, axisConfig: NumberAxisOptions, labelConfig: AxisLabelCanvas, canvasModel: CanvasModel): AxisModelOptions;
|
|
14
14
|
static getAxisLength(chartOrientation: ChartOrientation, canvasModel: CanvasModel): number;
|
|
15
15
|
static getAxisOrient(axisType: AxisType, chartOrientation: ChartOrientation, axisPosition: AxisPosition): Orient;
|
|
@@ -17,4 +17,5 @@ export declare class AxisModel {
|
|
|
17
17
|
static getAxisTranslateY(axisType: AxisType, chartOrientation: ChartOrientation, axisPosition: AxisPosition, canvasModel: CanvasModel): number;
|
|
18
18
|
static getKeyAxisLabelPosition(canvasModel: CanvasModel, scopedDataLength: number, axisConfig?: DiscreteAxisOptions): AxisLabelPosition;
|
|
19
19
|
static getLabelSize(labelMaxWidth: number, labelTexts: any[]): LabelSize;
|
|
20
|
+
private static getKeyAxisTranslateModel;
|
|
20
21
|
}
|
|
@@ -4,16 +4,14 @@ import { DataManagerModel } from "../dataManagerModel/dataManagerModel";
|
|
|
4
4
|
import { TwoDimensionalModel } from "../notations/twoDimensionalModel";
|
|
5
5
|
import { AxisModelService } from "./axisModelService";
|
|
6
6
|
export class AxisModel {
|
|
7
|
-
static getKeyAxis(options, data, labelConfig, canvasModel, tooltipSettings) {
|
|
7
|
+
static getKeyAxis(options, data, labelConfig, canvasModel, tooltipSettings, getZeroCoordinate) {
|
|
8
8
|
const { charts, orientation, data: dataOptions } = options;
|
|
9
9
|
const axisConfig = options.axis.key;
|
|
10
|
+
const translate = this.getKeyAxisTranslateModel(orientation, axisConfig.position, canvasModel, getZeroCoordinate);
|
|
10
11
|
return {
|
|
11
12
|
type: 'key',
|
|
12
13
|
orient: AxisModel.getAxisOrient(AxisType.Key, orientation, axisConfig.position),
|
|
13
|
-
translate
|
|
14
|
-
translateX: AxisModel.getAxisTranslateX(AxisType.Key, orientation, axisConfig.position, canvasModel),
|
|
15
|
-
translateY: AxisModel.getAxisTranslateY(AxisType.Key, orientation, axisConfig.position, canvasModel)
|
|
16
|
-
},
|
|
14
|
+
translate,
|
|
17
15
|
cssClass: 'key-axis',
|
|
18
16
|
ticks: axisConfig.ticks,
|
|
19
17
|
labels: {
|
|
@@ -109,5 +107,21 @@ export class AxisModel {
|
|
|
109
107
|
textBlock.remove();
|
|
110
108
|
return labelSize;
|
|
111
109
|
}
|
|
110
|
+
static getKeyAxisTranslateModel(chartOrientation, axisPosition, canvasModel, getZeroCoordinate) {
|
|
111
|
+
let translateY;
|
|
112
|
+
let translateX;
|
|
113
|
+
if (chartOrientation === "vertical") {
|
|
114
|
+
translateY = getZeroCoordinate() + canvasModel.getMarginSide("top");
|
|
115
|
+
translateX = AxisModel.getAxisTranslateX(AxisType.Key, chartOrientation, axisPosition, canvasModel);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
translateX = getZeroCoordinate() + canvasModel.getMarginSide("left");
|
|
119
|
+
translateY = AxisModel.getAxisTranslateY(AxisType.Key, chartOrientation, axisPosition, canvasModel);
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
translateX,
|
|
123
|
+
translateY
|
|
124
|
+
};
|
|
125
|
+
}
|
|
112
126
|
}
|
|
113
127
|
AxisModel.service = new AxisModelService();
|
|
@@ -30,12 +30,12 @@ export class LegendModel {
|
|
|
30
30
|
},
|
|
31
31
|
right: {
|
|
32
32
|
size: 0,
|
|
33
|
-
margin: { top: canvasModel.titleCanvas.getAllNeededSpace(), bottom: mb, left:
|
|
33
|
+
margin: { top: canvasModel.titleCanvas.getAllNeededSpace(), bottom: mb, left: 5, right: 0 },
|
|
34
34
|
pad: 0
|
|
35
35
|
},
|
|
36
36
|
top: {
|
|
37
37
|
size: 0,
|
|
38
|
-
margin: { top:
|
|
38
|
+
margin: { top: 5, bottom: 10, left: 0, right: 0 },
|
|
39
39
|
pad: canvasModel.titleCanvas.getAllNeededSpace()
|
|
40
40
|
}
|
|
41
41
|
},
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ScaleLinear, ScaleTime } from "d3-scale";
|
|
2
|
+
import { ChartOrientation, DiscreteAxisOptions } from "../../../config/config";
|
|
3
|
+
import { ScaleValueModel } from "../../model";
|
|
4
|
+
import { CanvasModel } from "../../modelInstance/canvasModel/canvasModel";
|
|
5
|
+
export declare const keyAxisLabelVerticalLog = "keyAxisLabel_vertical_margin_log";
|
|
6
|
+
export declare const keyAxisLabelHorizontalLog = "keyAxisLabel_horizontal_margin_log";
|
|
7
|
+
interface ScaleInfo {
|
|
8
|
+
scale: ScaleValueModel;
|
|
9
|
+
scaleFn: ScaleLinear<number, number, never> | ScaleTime<number, number, never>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Предназначен для получения нового scaleValue и уменьшения globalMargin, если ось ключей находится где-то внутри chartBlock, а не на его границе
|
|
13
|
+
*/
|
|
14
|
+
export declare class ScaleAxisRecalcer {
|
|
15
|
+
private generateScaleLinear;
|
|
16
|
+
constructor(generateScaleLinear: () => ScaleValueModel);
|
|
17
|
+
recalculateMargin(canvasModel: CanvasModel, chartOrientation: ChartOrientation, keyAxis: DiscreteAxisOptions): void;
|
|
18
|
+
getScaleValue(): ScaleInfo;
|
|
19
|
+
}
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Scale } from "../../../engine/features/scale/scale";
|
|
2
|
+
export const keyAxisLabelVerticalLog = "keyAxisLabel_vertical_margin_log";
|
|
3
|
+
export const keyAxisLabelHorizontalLog = "keyAxisLabel_horizontal_margin_log";
|
|
4
|
+
/**
|
|
5
|
+
* Предназначен для получения нового scaleValue и уменьшения globalMargin, если ось ключей находится где-то внутри chartBlock, а не на его границе
|
|
6
|
+
*/
|
|
7
|
+
export class ScaleAxisRecalcer {
|
|
8
|
+
constructor(generateScaleLinear) {
|
|
9
|
+
this.generateScaleLinear = generateScaleLinear;
|
|
10
|
+
}
|
|
11
|
+
recalculateMargin(canvasModel, chartOrientation, keyAxis) {
|
|
12
|
+
const scaleValue = this.generateScaleLinear();
|
|
13
|
+
//TODO: rm import from engine
|
|
14
|
+
const scaleValueFn = Scale.getScaleValue(scaleValue);
|
|
15
|
+
const coordinateOnChartBlock = (keyAxis.position === "start"
|
|
16
|
+
? scaleValueFn(0)
|
|
17
|
+
: (chartOrientation === "vertical"
|
|
18
|
+
? canvasModel.getChartBlockHeight()
|
|
19
|
+
: canvasModel.getChartBlockWidth()) - scaleValueFn(0));
|
|
20
|
+
const key = chartOrientation === "vertical" ? keyAxisLabelVerticalLog : keyAxisLabelHorizontalLog;
|
|
21
|
+
const logInfo = canvasModel.marginService.getDataByKey(key);
|
|
22
|
+
canvasModel.decreaseMarginSide(logInfo.side, logInfo.byValue - coordinateOnChartBlock < 0 ? logInfo.byValue : coordinateOnChartBlock);
|
|
23
|
+
}
|
|
24
|
+
getScaleValue() {
|
|
25
|
+
const scale = this.generateScaleLinear();
|
|
26
|
+
return {
|
|
27
|
+
scale,
|
|
28
|
+
scaleFn: Scale.getScaleValue(scale)
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ScaleKeyModel, ScaleKeyType, ScaleValueModel, ScaleValueType } from "../../model";
|
|
2
|
+
import { AxisPosition, NumberDomain, IntervalChart, MdtChartsTwoDimensionalChart, MdtChartsTwoDimensionalOptions, ChartOrientation, MdtChartsDataSource, MdtChartsDataRow } from "../../../config/config";
|
|
3
|
+
import { CanvasModel } from "../../modelInstance/canvasModel/canvasModel";
|
|
4
|
+
export declare enum ScaleType {
|
|
5
|
+
Key = 0,
|
|
6
|
+
Value = 1
|
|
7
|
+
}
|
|
8
|
+
export declare class ScaleModel {
|
|
9
|
+
static getScaleKey(allowableKeys: string[], orient: ChartOrientation, canvasModel: CanvasModel, charts: MdtChartsTwoDimensionalChart[], barCharts: MdtChartsTwoDimensionalChart[]): ScaleKeyModel;
|
|
10
|
+
static getScaleLinear(options: MdtChartsTwoDimensionalOptions, data: MdtChartsDataSource, canvasModel: CanvasModel): ScaleValueModel;
|
|
11
|
+
static getRangePeek(scaleType: ScaleType, chartOrientation: string, canvasModel: CanvasModel): number;
|
|
12
|
+
static getDateValueDomain(data: MdtChartsDataSource, chart: IntervalChart, keyAxisPosition: AxisPosition, dataSource: string): [Date, Date];
|
|
13
|
+
static getLinearDomain(configDomain: NumberDomain, data: MdtChartsDataSource, configOptions: MdtChartsTwoDimensionalOptions): [number, number];
|
|
14
|
+
static getScaleKeyType(charts: MdtChartsTwoDimensionalChart[]): ScaleKeyType;
|
|
15
|
+
static getScaleValueType(charts: MdtChartsTwoDimensionalChart[] | IntervalChart[]): ScaleValueType;
|
|
16
|
+
static getElementsAmount(barCharts: MdtChartsTwoDimensionalChart[]): number;
|
|
17
|
+
static getScaleMaxValue(charts: MdtChartsTwoDimensionalChart[], dataRows: MdtChartsDataRow[]): number;
|
|
18
|
+
static getScaleMinValue(charts: MdtChartsTwoDimensionalChart[], dataRows: MdtChartsDataRow[]): number;
|
|
19
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { ModelHelper } from "../../modelHelper";
|
|
2
|
+
export var ScaleType;
|
|
3
|
+
(function (ScaleType) {
|
|
4
|
+
ScaleType[ScaleType["Key"] = 0] = "Key";
|
|
5
|
+
ScaleType[ScaleType["Value"] = 1] = "Value";
|
|
6
|
+
})(ScaleType || (ScaleType = {}));
|
|
7
|
+
export class ScaleModel {
|
|
8
|
+
static getScaleKey(allowableKeys, orient, canvasModel, charts, barCharts) {
|
|
9
|
+
return {
|
|
10
|
+
domain: allowableKeys,
|
|
11
|
+
range: {
|
|
12
|
+
start: 0,
|
|
13
|
+
end: ScaleModel.getRangePeek(ScaleType.Key, orient, canvasModel)
|
|
14
|
+
},
|
|
15
|
+
type: ScaleModel.getScaleKeyType(charts),
|
|
16
|
+
elementsAmount: this.getElementsAmount(barCharts)
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
static getScaleLinear(options, data, canvasModel) {
|
|
20
|
+
return {
|
|
21
|
+
domain: ScaleModel.getLinearDomain(options.axis.value.domain, data, options),
|
|
22
|
+
range: {
|
|
23
|
+
start: 0,
|
|
24
|
+
end: ScaleModel.getRangePeek(ScaleType.Value, options.orientation, canvasModel)
|
|
25
|
+
},
|
|
26
|
+
type: ScaleModel.getScaleValueType(options.charts)
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
static getRangePeek(scaleType, chartOrientation, canvasModel) {
|
|
30
|
+
if (chartOrientation === 'vertical')
|
|
31
|
+
return scaleType === ScaleType.Key
|
|
32
|
+
? canvasModel.getChartBlockWidth()
|
|
33
|
+
: canvasModel.getChartBlockHeight();
|
|
34
|
+
return scaleType === ScaleType.Key
|
|
35
|
+
? canvasModel.getChartBlockHeight()
|
|
36
|
+
: canvasModel.getChartBlockWidth();
|
|
37
|
+
}
|
|
38
|
+
static getDateValueDomain(data, chart, keyAxisPosition, dataSource) {
|
|
39
|
+
const minMax = ModelHelper.getMinAndMaxOfIntervalData(data, dataSource, chart);
|
|
40
|
+
let domainPeekMin = minMax[0];
|
|
41
|
+
let domainPeekMax = minMax[1];
|
|
42
|
+
if (keyAxisPosition === 'start')
|
|
43
|
+
return [domainPeekMin, domainPeekMax];
|
|
44
|
+
return [domainPeekMax, domainPeekMin];
|
|
45
|
+
}
|
|
46
|
+
static getLinearDomain(configDomain, data, configOptions) {
|
|
47
|
+
let domainPeekMin;
|
|
48
|
+
let domainPeekMax;
|
|
49
|
+
if (configDomain.start === -1)
|
|
50
|
+
domainPeekMin = this.getScaleMinValue(configOptions.charts, data[configOptions.data.dataSource]);
|
|
51
|
+
else
|
|
52
|
+
domainPeekMin = configDomain.start;
|
|
53
|
+
if (configDomain.end === -1)
|
|
54
|
+
domainPeekMax = this.getScaleMaxValue(configOptions.charts, data[configOptions.data.dataSource]);
|
|
55
|
+
else
|
|
56
|
+
domainPeekMax = configDomain.end;
|
|
57
|
+
if (configOptions.axis.key.position === 'start')
|
|
58
|
+
return [domainPeekMin, domainPeekMax];
|
|
59
|
+
return [domainPeekMax, domainPeekMin];
|
|
60
|
+
}
|
|
61
|
+
static getScaleKeyType(charts) {
|
|
62
|
+
if (charts.findIndex((chart) => chart.type === 'bar') === -1)
|
|
63
|
+
return 'point';
|
|
64
|
+
return 'band';
|
|
65
|
+
}
|
|
66
|
+
static getScaleValueType(charts) {
|
|
67
|
+
if (charts.findIndex((chart) => chart.type === 'gantt') !== -1)
|
|
68
|
+
return 'datetime';
|
|
69
|
+
return 'linear';
|
|
70
|
+
}
|
|
71
|
+
static getElementsAmount(barCharts) {
|
|
72
|
+
if (barCharts.length === 0)
|
|
73
|
+
return 1;
|
|
74
|
+
let barsAmount = 0;
|
|
75
|
+
barCharts.forEach(chart => {
|
|
76
|
+
if (chart.isSegmented)
|
|
77
|
+
barsAmount += 1; // Если бар сегментированный, то все valueFields являются частями одного бара
|
|
78
|
+
else
|
|
79
|
+
barsAmount += chart.data.valueFields.length;
|
|
80
|
+
});
|
|
81
|
+
return barsAmount;
|
|
82
|
+
}
|
|
83
|
+
static getScaleMaxValue(charts, dataRows) {
|
|
84
|
+
let max = 0;
|
|
85
|
+
charts.forEach(chart => {
|
|
86
|
+
dataRows.forEach(dataRow => {
|
|
87
|
+
let sumInRow = 0;
|
|
88
|
+
chart.data.valueFields.forEach(field => {
|
|
89
|
+
if (chart.isSegmented)
|
|
90
|
+
sumInRow += dataRow[field.name];
|
|
91
|
+
else if (dataRow[field.name] > sumInRow)
|
|
92
|
+
sumInRow = dataRow[field.name];
|
|
93
|
+
});
|
|
94
|
+
if (max < sumInRow)
|
|
95
|
+
max = sumInRow;
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
return max;
|
|
99
|
+
}
|
|
100
|
+
static getScaleMinValue(charts, dataRows) {
|
|
101
|
+
let min = 0;
|
|
102
|
+
charts.forEach(chart => {
|
|
103
|
+
dataRows.forEach(dataRow => {
|
|
104
|
+
let sumInRow = 0;
|
|
105
|
+
chart.data.valueFields.forEach(field => {
|
|
106
|
+
if (dataRow[field.name] < sumInRow)
|
|
107
|
+
sumInRow = dataRow[field.name];
|
|
108
|
+
});
|
|
109
|
+
if (min > sumInRow)
|
|
110
|
+
min = sumInRow;
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
return min;
|
|
114
|
+
}
|
|
115
|
+
}
|