mdt-charts 1.9.11 → 1.10.3
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/config/config.d.ts +148 -0
- package/lib/config/config.js +1 -0
- package/lib/designer/designerConfig.d.ts +71 -0
- package/lib/designer/designerConfig.js +1 -0
- package/lib/engine/block/block.d.ts +35 -0
- package/lib/engine/block/block.js +110 -0
- package/lib/engine/block/blockHelper.d.ts +12 -0
- package/lib/engine/block/blockHelper.js +19 -0
- package/lib/engine/colorReader/colorReader.d.ts +10 -0
- package/lib/engine/colorReader/colorReader.js +21 -0
- package/lib/engine/contentManager.d.ts +9 -0
- package/lib/engine/contentManager.js +29 -0
- package/lib/engine/elementHighlighter/elementHighlighter.d.ts +30 -0
- package/lib/engine/elementHighlighter/elementHighlighter.js +198 -0
- package/lib/engine/elementHighlighter/selectHighlighter.d.ts +11 -0
- package/lib/engine/elementHighlighter/selectHighlighter.js +95 -0
- package/lib/engine/engine.d.ts +20 -0
- package/lib/engine/engine.js +64 -0
- package/lib/engine/features/aggregator/aggregator.d.ts +22 -0
- package/lib/engine/features/aggregator/aggregator.js +95 -0
- package/lib/engine/features/axis/axis.d.ts +12 -0
- package/lib/engine/features/axis/axis.js +118 -0
- package/lib/engine/features/axis/axisDomHelper.d.ts +7 -0
- package/lib/engine/features/axis/axisDomHelper.js +24 -0
- package/lib/engine/features/axis/axisHelper.d.ts +9 -0
- package/lib/engine/features/axis/axisHelper.js +53 -0
- package/lib/engine/features/axis/axisLabelDomHelper.d.ts +17 -0
- package/lib/engine/features/axis/axisLabelDomHelper.js +143 -0
- package/lib/engine/features/axis/axisLabelsEventManager.d.ts +6 -0
- package/lib/engine/features/axis/axisLabelsEventManager.js +36 -0
- package/lib/engine/features/embeddedLabels/embeddedLabels.d.ts +23 -0
- package/lib/engine/features/embeddedLabels/embeddedLabels.js +147 -0
- package/lib/engine/features/embeddedLabels/embeddedLabelsDomHelper.d.ts +8 -0
- package/lib/engine/features/embeddedLabels/embeddedLabelsDomHelper.js +30 -0
- package/lib/engine/features/embeddedLabels/embeddedLabelsHelper.d.ts +27 -0
- package/lib/engine/features/embeddedLabels/embeddedLabelsHelper.js +65 -0
- package/lib/engine/features/gridLine/gidLineHelper.d.ts +13 -0
- package/lib/engine/features/gridLine/gidLineHelper.js +30 -0
- package/lib/engine/features/gridLine/gridLine.d.ts +11 -0
- package/lib/engine/features/gridLine/gridLine.js +67 -0
- package/lib/engine/features/legend/legend.d.ts +22 -0
- package/lib/engine/features/legend/legend.js +112 -0
- package/lib/engine/features/legend/legendDomHelper.d.ts +8 -0
- package/lib/engine/features/legend/legendDomHelper.js +48 -0
- package/lib/engine/features/legend/legendEventsManager.d.ts +12 -0
- package/lib/engine/features/legend/legendEventsManager.js +47 -0
- package/lib/engine/features/legend/legendHelper.d.ts +21 -0
- package/lib/engine/features/legend/legendHelper.js +99 -0
- package/lib/engine/features/markDots/markDot.d.ts +20 -0
- package/lib/engine/features/markDots/markDot.js +68 -0
- package/lib/engine/features/markDots/markDotsHelper.d.ts +6 -0
- package/lib/engine/features/markDots/markDotsHelper.js +16 -0
- package/lib/engine/features/recordOverflowAlert/recordOverflowAlert.d.ts +14 -0
- package/lib/engine/features/recordOverflowAlert/recordOverflowAlert.js +97 -0
- package/lib/engine/features/scale/scale.d.ts +16 -0
- package/lib/engine/features/scale/scale.js +74 -0
- package/lib/engine/features/tipBox/tipBox.d.ts +11 -0
- package/lib/engine/features/tipBox/tipBox.js +32 -0
- package/lib/engine/features/tipBox/tipBoxHelper.d.ts +16 -0
- package/lib/engine/features/tipBox/tipBoxHelper.js +48 -0
- package/lib/engine/features/title/title.d.ts +9 -0
- package/lib/engine/features/title/title.js +35 -0
- package/lib/engine/features/tolltip/newTooltip/newTooltip.d.ts +16 -0
- package/lib/engine/features/tolltip/newTooltip/newTooltip.js +26 -0
- package/lib/engine/features/tolltip/newTooltip/newTooltip.test.d.ts +1 -0
- package/lib/engine/features/tolltip/newTooltip/newTooltip.test.js +186 -0
- package/lib/engine/features/tolltip/newTooltip/newTooltipService.d.ts +17 -0
- package/lib/engine/features/tolltip/newTooltip/newTooltipService.js +26 -0
- package/lib/engine/features/tolltip/tooltip.d.ts +19 -0
- package/lib/engine/features/tolltip/tooltip.js +181 -0
- package/lib/engine/features/tolltip/tooltipComponentsManager.d.ts +17 -0
- package/lib/engine/features/tolltip/tooltipComponentsManager.js +125 -0
- package/lib/engine/features/tolltip/tooltipDomHelper.d.ts +30 -0
- package/lib/engine/features/tolltip/tooltipDomHelper.js +103 -0
- package/lib/engine/features/tolltip/tooltipHelper.d.ts +18 -0
- package/lib/engine/features/tolltip/tooltipHelper.js +93 -0
- package/lib/engine/filterManager/filterEventManager.d.ts +33 -0
- package/lib/engine/filterManager/filterEventManager.js +127 -0
- package/lib/engine/helpers/domHelper.d.ts +30 -0
- package/lib/engine/helpers/domHelper.js +68 -0
- package/lib/engine/helpers/helper.d.ts +30 -0
- package/lib/engine/helpers/helper.js +89 -0
- package/lib/engine/helpers/namesHelper.d.ts +5 -0
- package/lib/engine/helpers/namesHelper.js +9 -0
- package/lib/engine/intervalNotation/gantt.d.ts +10 -0
- package/lib/engine/intervalNotation/gantt.js +62 -0
- package/lib/engine/intervalNotation/intervalManager.d.ts +7 -0
- package/lib/engine/intervalNotation/intervalManager.js +30 -0
- package/lib/engine/polarNotation/donut/DonutHelper.d.ts +15 -0
- package/lib/engine/polarNotation/donut/DonutHelper.js +60 -0
- package/lib/engine/polarNotation/donut/donut.d.ts +32 -0
- package/lib/engine/polarNotation/donut/donut.js +125 -0
- package/lib/engine/polarNotation/polarManager.d.ts +10 -0
- package/lib/engine/polarNotation/polarManager.js +55 -0
- package/lib/engine/transitionManager.d.ts +19 -0
- package/lib/engine/transitionManager.js +64 -0
- package/lib/engine/twoDimensionalNotation/area/area.d.ts +17 -0
- package/lib/engine/twoDimensionalNotation/area/area.js +131 -0
- package/lib/engine/twoDimensionalNotation/area/areaHelper.d.ts +9 -0
- package/lib/engine/twoDimensionalNotation/area/areaHelper.js +40 -0
- package/lib/engine/twoDimensionalNotation/bar/bar.d.ts +34 -0
- package/lib/engine/twoDimensionalNotation/bar/bar.js +216 -0
- package/lib/engine/twoDimensionalNotation/bar/barHelper.d.ts +24 -0
- package/lib/engine/twoDimensionalNotation/bar/barHelper.js +103 -0
- package/lib/engine/twoDimensionalNotation/line/line.d.ts +17 -0
- package/lib/engine/twoDimensionalNotation/line/line.js +132 -0
- package/lib/engine/twoDimensionalNotation/line/lineHelper.d.ts +8 -0
- package/lib/engine/twoDimensionalNotation/line/lineHelper.js +28 -0
- package/lib/engine/twoDimensionalNotation/twoDimensionalManager.d.ts +11 -0
- package/lib/engine/twoDimensionalNotation/twoDimensionalManager.js +101 -0
- package/lib/engine/valueFormatter.d.ts +6 -0
- package/lib/engine/valueFormatter.js +8 -0
- package/lib/main.d.ts +79 -0
- package/lib/main.js +88 -0
- package/lib/model/chartStyleModel.d.ts +16 -0
- package/lib/model/chartStyleModel.js +67 -0
- package/lib/model/configsValidator/configValidator.d.ts +5 -0
- package/lib/model/configsValidator/configValidator.js +7 -0
- package/lib/model/dataManagerModel.d.ts +22 -0
- package/lib/model/dataManagerModel.js +137 -0
- package/lib/model/featuresModel/axisModel.d.ts +18 -0
- package/lib/model/featuresModel/axisModel.js +111 -0
- package/lib/model/featuresModel/legendModel/legendCanvasModel.d.ts +7 -0
- package/lib/model/featuresModel/legendModel/legendCanvasModel.js +86 -0
- package/lib/model/featuresModel/legendModel/legendModel.d.ts +13 -0
- package/lib/model/featuresModel/legendModel/legendModel.js +78 -0
- package/lib/model/featuresModel/otherComponents.d.ts +6 -0
- package/lib/model/featuresModel/otherComponents.js +12 -0
- package/lib/model/featuresModel/scaleModel.d.ts +17 -0
- package/lib/model/featuresModel/scaleModel.js +100 -0
- package/lib/model/featuresModel/titleModel.d.ts +4 -0
- package/lib/model/featuresModel/titleModel.js +14 -0
- package/lib/model/featuresModel/tooltipModel.d.ts +4 -0
- package/lib/model/featuresModel/tooltipModel.js +7 -0
- package/lib/model/marginModel.d.ts +19 -0
- package/lib/model/marginModel.js +126 -0
- package/lib/model/model.d.ts +221 -0
- package/lib/model/model.js +1 -0
- package/lib/model/modelBuilder.d.ts +16 -0
- package/lib/model/modelBuilder.js +128 -0
- package/lib/model/modelHelper.d.ts +7 -0
- package/lib/model/modelHelper.js +41 -0
- package/lib/model/notations/intervalModel.d.ts +8 -0
- package/lib/model/notations/intervalModel.js +93 -0
- package/lib/model/notations/polarModel.d.ts +7 -0
- package/lib/model/notations/polarModel.js +27 -0
- package/lib/model/notations/twoDimensionalModel.d.ts +19 -0
- package/lib/model/notations/twoDimensionalModel.js +85 -0
- package/lib/optionsServices/publicOptionsService.d.ts +6 -0
- package/lib/optionsServices/publicOptionsService.js +8 -0
- package/lib/optionsServices/validators/sizeValidator.d.ts +5 -0
- package/lib/optionsServices/validators/sizeValidator.js +13 -0
- package/lib/style/charts-main.css +243 -0
- package/lib/style/charts-main.less +243 -0
- package/package.json +1 -1
- package/dist/index.html +0 -363
- package/dist/listeners.89e1e272264c0e680de8.js +0 -278
- package/dist/main.f8b6bc6fee33cef1116c.js +0 -228
- package/dist/src_engine_engine_ts.ccee2a280374e0083541.js +0 -759
- package/dist/vendors-node_modules_chroma-js_chroma_js-node_modules_d3-array_src_max_js-node_modules_d3-arr-c3fc24.b32acc465b8557229277.js +0 -1869
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { stack } from 'd3-shape';
|
|
2
|
+
import { select } from 'd3-selection';
|
|
3
|
+
import { EmbeddedLabels } from "../../features/embeddedLabels/embeddedLabels";
|
|
4
|
+
import { EmbeddedLabelsHelper } from "../../features/embeddedLabels/embeddedLabelsHelper";
|
|
5
|
+
import { BarHelper } from "./barHelper";
|
|
6
|
+
import { sum } from "d3-array";
|
|
7
|
+
import { DomHelper } from "../../helpers/domHelper";
|
|
8
|
+
import { Helper } from "../../helpers/helper";
|
|
9
|
+
export class Bar {
|
|
10
|
+
static render(block, scales, data, keyField, margin, keyAxisOrient, chart, blockSize, barSettings, barsAmounts, isSegmented, firstBarIndex) {
|
|
11
|
+
if (isSegmented)
|
|
12
|
+
this.renderSegmented(block, scales, data, keyField, margin, keyAxisOrient, chart, barsAmounts, blockSize, firstBarIndex, barSettings);
|
|
13
|
+
else
|
|
14
|
+
this.renderGrouped(block, scales, data, keyField, margin, keyAxisOrient, chart, barsAmounts, blockSize, firstBarIndex, barSettings);
|
|
15
|
+
}
|
|
16
|
+
static update(block, newData, scales, margin, keyAxisOrient, chart, blockSize, barsAmounts, keyField, firstBarIndex, barSettings, isSegmented) {
|
|
17
|
+
let promises;
|
|
18
|
+
if (isSegmented) {
|
|
19
|
+
promises = this.updateSegmented(block, newData, scales, margin, keyAxisOrient, chart, blockSize, barsAmounts, keyField, firstBarIndex, barSettings);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
promises = this.updateGrouped(block, newData, scales, margin, keyAxisOrient, chart, blockSize, barsAmounts, keyField, firstBarIndex, barSettings);
|
|
23
|
+
}
|
|
24
|
+
return promises;
|
|
25
|
+
}
|
|
26
|
+
static updateColors(block, chart) {
|
|
27
|
+
chart.data.valueFields.forEach((_vf, index) => {
|
|
28
|
+
const bars = block.getChartGroup(chart.index)
|
|
29
|
+
.selectAll(`.${this.barItemClass}${Helper.getCssClassesLine(chart.cssClasses)}${Helper.getCssClassesLine(Helper.getCssClassesWithElementIndex(chart.cssClasses, index))}`);
|
|
30
|
+
DomHelper.setChartStyle(bars, chart.style, index, 'fill');
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
static getAllBarsForChart(block, chartCssClasses) {
|
|
34
|
+
return block.getSvg().selectAll(`rect.${this.barItemClass}${Helper.getCssClassesLine(chartCssClasses)}`);
|
|
35
|
+
}
|
|
36
|
+
static renderGrouped(block, scales, data, keyField, margin, keyAxisOrient, chart, barsAmounts, blockSize, firstBarIndex, barSettings) {
|
|
37
|
+
chart.data.valueFields.forEach((field, index) => {
|
|
38
|
+
const bars = block.getChartGroup(chart.index)
|
|
39
|
+
.selectAll(`.${this.barItemClass}${Helper.getCssClassesLine(chart.cssClasses)}${Helper.getCssClassesLine(Helper.getCssClassesWithElementIndex(chart.cssClasses, index))}`)
|
|
40
|
+
.data(data)
|
|
41
|
+
.enter()
|
|
42
|
+
.append('rect')
|
|
43
|
+
.attr('class', this.barItemClass)
|
|
44
|
+
.style('clip-path', `url(#${block.getClipPathId()})`);
|
|
45
|
+
const barAttrs = BarHelper.getGroupedBarAttrs(keyAxisOrient, scales, margin, keyField.name, field.name, blockSize, BarHelper.getBarIndex(barsAmounts, chart.index - firstBarIndex) + index, sum(barsAmounts), barSettings);
|
|
46
|
+
this.fillBarAttrs(bars, barAttrs);
|
|
47
|
+
DomHelper.setCssClasses(bars, Helper.getCssClassesWithElementIndex(chart.cssClasses, index));
|
|
48
|
+
DomHelper.setChartStyle(bars, chart.style, index, 'fill');
|
|
49
|
+
this.setInitialAttrsInfo(bars, keyAxisOrient, barSettings);
|
|
50
|
+
if (chart.embeddedLabels !== 'none')
|
|
51
|
+
EmbeddedLabels.render(block, bars, barAttrs, EmbeddedLabelsHelper.getLabelField(chart.embeddedLabels, chart.data.valueFields, keyField, index), chart.embeddedLabels, keyAxisOrient, blockSize, margin, index, chart.cssClasses);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
static renderSegmented(block, scales, data, keyField, margin, keyAxisOrient, chart, barsAmounts, blockSize, firstBarIndex, barSettings) {
|
|
55
|
+
const stackedData = stack().keys(chart.data.valueFields.map(field => field.name))(data);
|
|
56
|
+
let groups = block.getChartGroup(chart.index)
|
|
57
|
+
.selectAll(`g.${this.barSegmentGroupClass}${Helper.getCssClassesLine(chart.cssClasses)}`)
|
|
58
|
+
.data(stackedData);
|
|
59
|
+
if (groups.empty())
|
|
60
|
+
groups = groups
|
|
61
|
+
.data(stackedData)
|
|
62
|
+
.enter()
|
|
63
|
+
.append('g')
|
|
64
|
+
.attr('class', this.barSegmentGroupClass);
|
|
65
|
+
const bars = groups
|
|
66
|
+
.selectAll(`rect${Helper.getCssClassesLine(chart.cssClasses)}`)
|
|
67
|
+
.data(d => d)
|
|
68
|
+
.enter()
|
|
69
|
+
.append('rect')
|
|
70
|
+
.attr('class', this.barItemClass)
|
|
71
|
+
.style('clip-path', `url(#${block.getClipPathId()})`);
|
|
72
|
+
const barAttrs = BarHelper.getStackedBarAttr(keyAxisOrient, scales, margin, keyField.name, blockSize, BarHelper.getBarIndex(barsAmounts, chart.index) - firstBarIndex, sum(barsAmounts), barSettings);
|
|
73
|
+
this.fillBarAttrs(bars, barAttrs);
|
|
74
|
+
this.setInitialAttrsInfo(bars, keyAxisOrient, barSettings);
|
|
75
|
+
DomHelper.setCssClasses(groups, chart.cssClasses);
|
|
76
|
+
DomHelper.setCssClasses(bars, chart.cssClasses); // Для обозначения принадлежности бара к конкретному чарту
|
|
77
|
+
const thisClass = this;
|
|
78
|
+
groups.each(function (d, i) {
|
|
79
|
+
DomHelper.setCssClasses(select(this).selectAll(`rect${Helper.getCssClassesLine(chart.cssClasses)}`), Helper.getCssClassesWithElementIndex(chart.cssClasses, i)); // Для обозначения принадлежности бара к конкретной части стака
|
|
80
|
+
thisClass.setSegmentColor(select(this).selectAll(Helper.getCssClassesLine(chart.cssClasses)), chart.style.elementColors, i);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
static updateGrouped(block, newData, scales, margin, keyAxisOrient, chart, blockSize, barsAmounts, keyField, firstBarIndex, barSettings) {
|
|
84
|
+
const promises = [];
|
|
85
|
+
chart.data.valueFields.forEach((valueField, index) => {
|
|
86
|
+
const indexesOfRemoved = [];
|
|
87
|
+
block.getChartGroup(chart.index)
|
|
88
|
+
.selectAll(`.${this.barItemClass}${Helper.getCssClassesLine(chart.cssClasses)}.chart-element-${index}`)
|
|
89
|
+
.filter((d, i) => {
|
|
90
|
+
if (newData.findIndex(row => row[keyField.name] === d[keyField.name]) === -1) {
|
|
91
|
+
indexesOfRemoved.push(i); // Набор индексов для встроенных лейблов
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
return false;
|
|
95
|
+
})
|
|
96
|
+
.transition()
|
|
97
|
+
.duration(block.transitionManager.durations.elementFadeOut)
|
|
98
|
+
.style('opacity', 0)
|
|
99
|
+
.remove();
|
|
100
|
+
const bars = block.getChartGroup(chart.index)
|
|
101
|
+
.selectAll(`.${this.barItemClass}${Helper.getCssClassesLine(chart.cssClasses)}.chart-element-${index}`)
|
|
102
|
+
.filter(d => newData.findIndex(row => row[keyField.name] === d[keyField.name]) !== -1)
|
|
103
|
+
.style('opacity', 1)
|
|
104
|
+
.data(newData);
|
|
105
|
+
const newBars = bars
|
|
106
|
+
.enter()
|
|
107
|
+
.append('rect')
|
|
108
|
+
.attr('class', this.barItemClass)
|
|
109
|
+
.style('clip-path', `url(#${block.getClipPathId()})`);
|
|
110
|
+
const barAttrs = BarHelper.getGroupedBarAttrs(keyAxisOrient, scales, margin, keyField.name, valueField.name, blockSize, BarHelper.getBarIndex(barsAmounts, chart.index) + index - firstBarIndex, sum(barsAmounts), barSettings);
|
|
111
|
+
const prom = this.fillBarAttrs(bars, barAttrs, block.transitionManager.durations.chartUpdate)
|
|
112
|
+
.then(() => {
|
|
113
|
+
bars.style('opacity', null);
|
|
114
|
+
this.setInitialAttrsInfo(bars, keyAxisOrient, barSettings);
|
|
115
|
+
});
|
|
116
|
+
this.fillBarAttrs(newBars, barAttrs);
|
|
117
|
+
promises.push(prom);
|
|
118
|
+
this.setInitialAttrsInfo(newBars, keyAxisOrient, barSettings);
|
|
119
|
+
DomHelper.setCssClasses(newBars, Helper.getCssClassesWithElementIndex(chart.cssClasses, index));
|
|
120
|
+
DomHelper.setChartStyle(newBars, chart.style, index, 'fill');
|
|
121
|
+
if (chart.embeddedLabels !== 'none') {
|
|
122
|
+
EmbeddedLabels.removeUnused(block, chart.cssClasses, index, indexesOfRemoved);
|
|
123
|
+
EmbeddedLabels.update(block, bars, keyAxisOrient, barAttrs, margin, valueField, chart.embeddedLabels, blockSize, newData, index, chart.cssClasses);
|
|
124
|
+
if (!newBars.empty())
|
|
125
|
+
EmbeddedLabels.render(block, newBars, barAttrs, valueField, chart.embeddedLabels, keyAxisOrient, blockSize, margin, index, chart.cssClasses);
|
|
126
|
+
EmbeddedLabels.restoreRemoved(block, bars, barAttrs, valueField, chart.embeddedLabels, keyAxisOrient, blockSize, margin, index, chart.cssClasses, keyField.name);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
return promises;
|
|
130
|
+
}
|
|
131
|
+
static updateSegmented(block, newData, scales, margin, keyAxisOrient, chart, blockSize, barsAmounts, keyField, firstBarIndex, barSettings) {
|
|
132
|
+
const stackedData = stack().keys(chart.data.valueFields.map(field => field.name))(newData);
|
|
133
|
+
block.getChartGroup(chart.index)
|
|
134
|
+
.selectAll(`.${this.barItemClass}${Helper.getCssClassesLine(chart.cssClasses)}`)
|
|
135
|
+
.filter(d => newData.findIndex(row => row[keyField.name] === d.data[keyField.name]) === -1)
|
|
136
|
+
.transition()
|
|
137
|
+
.duration(block.transitionManager.durations.elementFadeOut)
|
|
138
|
+
.style('opacity', 0)
|
|
139
|
+
.remove();
|
|
140
|
+
const groups = block.getChartGroup(chart.index)
|
|
141
|
+
.selectAll(`g.${this.barSegmentGroupClass}${Helper.getCssClassesLine(chart.cssClasses)}`)
|
|
142
|
+
.data(stackedData);
|
|
143
|
+
const bars = groups
|
|
144
|
+
.selectAll(`.${this.barItemClass}${Helper.getCssClassesLine(chart.cssClasses)}`)
|
|
145
|
+
.filter(d => newData.findIndex(row => row[keyField.name] === d.data[keyField.name]) !== -1)
|
|
146
|
+
.style('opacity', 1)
|
|
147
|
+
.data(d => d);
|
|
148
|
+
const newBars = bars.enter()
|
|
149
|
+
.append('rect')
|
|
150
|
+
.attr('class', this.barItemClass)
|
|
151
|
+
.style('clip-path', `url(#${block.getClipPathId()})`);
|
|
152
|
+
const barAttrs = BarHelper.getStackedBarAttr(keyAxisOrient, scales, margin, keyField.name, blockSize, BarHelper.getBarIndex(barsAmounts, chart.index) - firstBarIndex, sum(barsAmounts), barSettings);
|
|
153
|
+
const prom = this.fillBarAttrs(bars, barAttrs, block.transitionManager.durations.chartUpdate)
|
|
154
|
+
.then(() => {
|
|
155
|
+
this.setInitialAttrsInfo(bars, keyAxisOrient, barSettings);
|
|
156
|
+
bars.style('opacity', null);
|
|
157
|
+
});
|
|
158
|
+
this.fillBarAttrs(newBars, barAttrs);
|
|
159
|
+
this.setInitialAttrsInfo(newBars, keyAxisOrient, barSettings);
|
|
160
|
+
DomHelper.setCssClasses(newBars, chart.cssClasses);
|
|
161
|
+
const thisClass = this;
|
|
162
|
+
groups.each(function (d, i) {
|
|
163
|
+
DomHelper.setCssClasses(select(this).selectAll(`rect${Helper.getCssClassesLine(chart.cssClasses)}`), Helper.getCssClassesWithElementIndex(chart.cssClasses, i)); // Для обозначения принадлежности бара к конкретной части стака
|
|
164
|
+
thisClass.setSegmentColor(select(this).selectAll(Helper.getCssClassesLine(chart.cssClasses)), chart.style.elementColors, i);
|
|
165
|
+
});
|
|
166
|
+
return [prom];
|
|
167
|
+
}
|
|
168
|
+
static fillBarAttrs(bars, barAttrs, transitionDuration = 0) {
|
|
169
|
+
return new Promise((resolve) => {
|
|
170
|
+
if (bars.size() === 0) {
|
|
171
|
+
resolve('');
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
let barsHander = bars;
|
|
175
|
+
if (transitionDuration > 0) {
|
|
176
|
+
barsHander = barsHander
|
|
177
|
+
.interrupt()
|
|
178
|
+
.transition()
|
|
179
|
+
.duration(transitionDuration)
|
|
180
|
+
.on('end', () => resolve(''));
|
|
181
|
+
}
|
|
182
|
+
barsHander.attr('x', d => barAttrs.x(d))
|
|
183
|
+
.attr('y', d => barAttrs.y(d))
|
|
184
|
+
.attr('height', d => barAttrs.height(d))
|
|
185
|
+
.attr('width', d => barAttrs.width(d));
|
|
186
|
+
if (transitionDuration <= 0)
|
|
187
|
+
resolve('');
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
static setSegmentColor(segments, colorPalette, segmentedIndex) {
|
|
191
|
+
segments.style('fill', colorPalette[segmentedIndex % colorPalette.length]);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Устнановка координат для удобного обновления.
|
|
195
|
+
*/
|
|
196
|
+
static setInitialAttrsInfo(bars, keyAxisOrient, barSettings) {
|
|
197
|
+
bars.each(function () {
|
|
198
|
+
const width = DomHelper.getSelectionNumericAttr(select(this), 'width');
|
|
199
|
+
const height = DomHelper.getSelectionNumericAttr(select(this), 'height');
|
|
200
|
+
const orient = keyAxisOrient === 'left' || keyAxisOrient === 'right' ? 'horizontal' : 'vertical';
|
|
201
|
+
let scaleSize = 0.06 * (orient === 'vertical' ? width : height);
|
|
202
|
+
scaleSize = scaleSize > barSettings.barDistance / 2 ? barSettings.barDistance / 2 : scaleSize;
|
|
203
|
+
this.attrs = {
|
|
204
|
+
x: DomHelper.getSelectionNumericAttr(select(this), 'x'),
|
|
205
|
+
y: DomHelper.getSelectionNumericAttr(select(this), 'y'),
|
|
206
|
+
width,
|
|
207
|
+
height,
|
|
208
|
+
orient,
|
|
209
|
+
scaleSize
|
|
210
|
+
};
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
Bar.barItemClass = 'bar-item';
|
|
215
|
+
Bar.barItemCloneClass = 'bar-item-clone';
|
|
216
|
+
Bar.barSegmentGroupClass = 'bar-segment-group';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { BarChartSettings, BlockMargin, Orient, TwoDimensionalChartModel } from "../../../model/model";
|
|
2
|
+
import { Scales } from "../../features/scale/scale";
|
|
3
|
+
import { MdtChartsDataRow, Size } from "../../../config/config";
|
|
4
|
+
export interface BarAttrsHelper {
|
|
5
|
+
x: (dataRow: MdtChartsDataRow) => number;
|
|
6
|
+
y: (dataRow: MdtChartsDataRow) => number;
|
|
7
|
+
width: (dataRow: MdtChartsDataRow) => number;
|
|
8
|
+
height: (dataRow: MdtChartsDataRow) => number;
|
|
9
|
+
}
|
|
10
|
+
export declare class BarHelper {
|
|
11
|
+
static getGroupedBarAttrs(keyAxisOrient: Orient, scales: Scales, margin: BlockMargin, keyField: string, valueFieldName: string, blockSize: Size, barIndex: number, barsAmount: number, barSettings: BarChartSettings): BarAttrsHelper;
|
|
12
|
+
static getStackedBarAttr(keyAxisOrient: Orient, scales: Scales, margin: BlockMargin, keyField: string, blockSize: Size, barIndex: number, barsAmount: number, barSettings: BarChartSettings): BarAttrsHelper;
|
|
13
|
+
static getBarsInGroupAmount(charts: TwoDimensionalChartModel[]): number[];
|
|
14
|
+
/**
|
|
15
|
+
* Получение индекса бара среди всх графиков и value-филдов. Используется для того, чтобы узнать, какой по счету в группе
|
|
16
|
+
* этот бар идет (сегментированный всегда один, группированный - количество value-филдов).
|
|
17
|
+
* @param barsAmounts
|
|
18
|
+
* @param chartIndex
|
|
19
|
+
*/
|
|
20
|
+
static getBarIndex(barsAmounts: number[], chartIndex: number): number;
|
|
21
|
+
private static setBarAttrsByKey;
|
|
22
|
+
private static setGroupedBarAttrsByValue;
|
|
23
|
+
private static setSegmentedBarAttrsByValue;
|
|
24
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { Scale } from "../../features/scale/scale";
|
|
2
|
+
import { Helper } from "../../helpers/helper";
|
|
3
|
+
export class BarHelper {
|
|
4
|
+
static getGroupedBarAttrs(keyAxisOrient, scales, margin, keyField, valueFieldName, blockSize, barIndex, barsAmount, barSettings) {
|
|
5
|
+
const attrs = {
|
|
6
|
+
x: null,
|
|
7
|
+
y: null,
|
|
8
|
+
width: null,
|
|
9
|
+
height: null
|
|
10
|
+
};
|
|
11
|
+
this.setBarAttrsByKey(attrs, keyAxisOrient, scales.key, margin, keyField, barIndex, barsAmount, barSettings, false);
|
|
12
|
+
this.setGroupedBarAttrsByValue(attrs, keyAxisOrient, margin, scales.value, valueFieldName, blockSize);
|
|
13
|
+
return attrs;
|
|
14
|
+
}
|
|
15
|
+
static getStackedBarAttr(keyAxisOrient, scales, margin, keyField, blockSize, barIndex, barsAmount, barSettings) {
|
|
16
|
+
const attrs = {
|
|
17
|
+
x: null,
|
|
18
|
+
y: null,
|
|
19
|
+
width: null,
|
|
20
|
+
height: null
|
|
21
|
+
};
|
|
22
|
+
this.setBarAttrsByKey(attrs, keyAxisOrient, scales.key, margin, keyField, barIndex, barsAmount, barSettings, true);
|
|
23
|
+
this.setSegmentedBarAttrsByValue(attrs, keyAxisOrient, scales.value, margin, blockSize);
|
|
24
|
+
return attrs;
|
|
25
|
+
}
|
|
26
|
+
static getBarsInGroupAmount(charts) {
|
|
27
|
+
let amounts = [];
|
|
28
|
+
charts.forEach((chart) => {
|
|
29
|
+
if (chart.type === 'bar' && chart.isSegmented)
|
|
30
|
+
amounts.push(1); // Сегментированный бар содержит все свои valueFields в одном баре
|
|
31
|
+
else if (chart.type === 'bar')
|
|
32
|
+
amounts.push(chart.data.valueFields.length);
|
|
33
|
+
});
|
|
34
|
+
return amounts;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Получение индекса бара среди всх графиков и value-филдов. Используется для того, чтобы узнать, какой по счету в группе
|
|
38
|
+
* этот бар идет (сегментированный всегда один, группированный - количество value-филдов).
|
|
39
|
+
* @param barsAmounts
|
|
40
|
+
* @param chartIndex
|
|
41
|
+
*/
|
|
42
|
+
static getBarIndex(barsAmounts, chartIndex) {
|
|
43
|
+
if (barsAmounts.length < 2)
|
|
44
|
+
return 0;
|
|
45
|
+
let index = 0;
|
|
46
|
+
barsAmounts.forEach((chartBars, i) => {
|
|
47
|
+
if (i < chartIndex) {
|
|
48
|
+
index += chartBars;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
return index;
|
|
52
|
+
}
|
|
53
|
+
static setBarAttrsByKey(attrs, keyAxisOrient, scaleKey, margin, keyField, barIndex, barsAmount, barSettings, isSegmented) {
|
|
54
|
+
const barStep = (Scale.getScaleBandWidth(scaleKey) - barSettings.barDistance * (barsAmount - 1)) / barsAmount; // Space for one bar
|
|
55
|
+
const barSize = barStep > barSettings.maxBarWidth ? barSettings.maxBarWidth : barStep;
|
|
56
|
+
const barDiff = (barStep - barSize) * barsAmount / 2; // if bar bigger than maxWidth, diff for x coordinate
|
|
57
|
+
const barPad = barSize * barIndex + barSettings.barDistance * barIndex + barDiff; // Отступ бара от края. Зависит от количества баров в одной группе и порядке текущего бара
|
|
58
|
+
if (keyAxisOrient === 'top' || keyAxisOrient === 'bottom') {
|
|
59
|
+
attrs.x = d => scaleKey(Helper.getKeyFieldValue(d, keyField, isSegmented)) + margin.left + barPad;
|
|
60
|
+
attrs.width = d => barSize;
|
|
61
|
+
}
|
|
62
|
+
if (keyAxisOrient === 'left' || keyAxisOrient === 'right') {
|
|
63
|
+
attrs.y = d => scaleKey(Helper.getKeyFieldValue(d, keyField, isSegmented)) + margin.top + barPad;
|
|
64
|
+
attrs.height = d => barSize;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
static setGroupedBarAttrsByValue(attrs, keyAxisOrient, margin, scaleValue, valueFieldName, blockSize) {
|
|
68
|
+
if (keyAxisOrient === 'top') {
|
|
69
|
+
attrs.y = d => margin.top;
|
|
70
|
+
attrs.height = d => Helper.getValueOrZero(scaleValue(d[valueFieldName]));
|
|
71
|
+
}
|
|
72
|
+
if (keyAxisOrient === 'bottom') {
|
|
73
|
+
attrs.y = d => scaleValue(d[valueFieldName]) + margin.top;
|
|
74
|
+
attrs.height = d => Helper.getValueOrZero(blockSize.height - margin.top - margin.bottom - scaleValue(d[valueFieldName]));
|
|
75
|
+
}
|
|
76
|
+
if (keyAxisOrient === 'left') {
|
|
77
|
+
attrs.x = d => margin.left + 1;
|
|
78
|
+
attrs.width = d => Helper.getValueOrZero(scaleValue(d[valueFieldName]));
|
|
79
|
+
}
|
|
80
|
+
if (keyAxisOrient === 'right') {
|
|
81
|
+
attrs.x = d => scaleValue(d[valueFieldName]) + margin.left;
|
|
82
|
+
attrs.width = d => Helper.getValueOrZero(blockSize.width - margin.left - margin.right - scaleValue(d[valueFieldName]));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
static setSegmentedBarAttrsByValue(attrs, keyAxisOrient, scaleValue, margin, blockSize) {
|
|
86
|
+
if (keyAxisOrient === 'top') {
|
|
87
|
+
attrs.y = d => margin.top + scaleValue(d[0]);
|
|
88
|
+
attrs.height = d => Helper.getValueOrZero(scaleValue(d[1] - d[0]));
|
|
89
|
+
}
|
|
90
|
+
if (keyAxisOrient === 'bottom') {
|
|
91
|
+
attrs.y = d => scaleValue(d[1]) + margin.top;
|
|
92
|
+
attrs.height = d => Helper.getValueOrZero(blockSize.height - margin.top - margin.bottom - scaleValue(d[1] - d[0]));
|
|
93
|
+
}
|
|
94
|
+
if (keyAxisOrient === 'left') {
|
|
95
|
+
attrs.x = d => margin.left + scaleValue(d[0]) + 1;
|
|
96
|
+
attrs.width = d => Helper.getValueOrZero(scaleValue(d[1] - d[0]));
|
|
97
|
+
}
|
|
98
|
+
if (keyAxisOrient === 'right') {
|
|
99
|
+
attrs.x = d => scaleValue(d[1]) + margin.left;
|
|
100
|
+
attrs.width = d => Helper.getValueOrZero(blockSize.width - margin.left - margin.right - scaleValue(d[1] - d[0]));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { BlockMargin, Field, Orient, TwoDimensionalChartModel } from "../../../model/model";
|
|
2
|
+
import { Scales } from "../../features/scale/scale";
|
|
3
|
+
import { Block } from "../../block/block";
|
|
4
|
+
import { MdtChartsDataRow } from '../../../config/config';
|
|
5
|
+
export declare class Line {
|
|
6
|
+
static readonly lineChartClass = "line";
|
|
7
|
+
static render(block: Block, scales: Scales, data: MdtChartsDataRow[], keyField: Field, margin: BlockMargin, keyAxisOrient: Orient, chart: TwoDimensionalChartModel): void;
|
|
8
|
+
static update(block: Block, scales: Scales, newData: MdtChartsDataRow[], keyField: Field, margin: BlockMargin, keyAxisOrient: Orient, chart: TwoDimensionalChartModel): Promise<any>[];
|
|
9
|
+
static updateColors(block: Block, chart: TwoDimensionalChartModel): void;
|
|
10
|
+
private static renderGrouped;
|
|
11
|
+
private static renderSegmented;
|
|
12
|
+
private static updateGrouped;
|
|
13
|
+
private static updateSegmeneted;
|
|
14
|
+
private static updateGroupedPath;
|
|
15
|
+
private static updateSegmentedPath;
|
|
16
|
+
private static setSegmentColor;
|
|
17
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { stack } from 'd3-shape';
|
|
2
|
+
import { select } from 'd3-selection';
|
|
3
|
+
import { MarkDot } from "../../features/markDots/markDot";
|
|
4
|
+
import { LineHelper } from './lineHelper';
|
|
5
|
+
import { DomHelper } from '../../helpers/domHelper';
|
|
6
|
+
import { Helper } from '../../helpers/helper';
|
|
7
|
+
export class Line {
|
|
8
|
+
static render(block, scales, data, keyField, margin, keyAxisOrient, chart) {
|
|
9
|
+
if (chart.isSegmented)
|
|
10
|
+
this.renderSegmented(block, scales, data, keyField, margin, keyAxisOrient, chart);
|
|
11
|
+
else
|
|
12
|
+
this.renderGrouped(block, scales, data, keyField, margin, keyAxisOrient, chart);
|
|
13
|
+
}
|
|
14
|
+
static update(block, scales, newData, keyField, margin, keyAxisOrient, chart) {
|
|
15
|
+
let promises;
|
|
16
|
+
if (chart.isSegmented) {
|
|
17
|
+
promises = this.updateSegmeneted(block, scales, newData, keyField, margin, keyAxisOrient, chart);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
promises = this.updateGrouped(block, scales, newData, keyField, margin, keyAxisOrient, chart);
|
|
21
|
+
}
|
|
22
|
+
return promises;
|
|
23
|
+
}
|
|
24
|
+
static updateColors(block, chart) {
|
|
25
|
+
chart.data.valueFields.forEach((_vf, valueIndex) => {
|
|
26
|
+
const path = block.getChartGroup(chart.index)
|
|
27
|
+
.select(`.${this.lineChartClass}${Helper.getCssClassesLine(chart.cssClasses)}.chart-element-${valueIndex}`);
|
|
28
|
+
DomHelper.setChartStyle(path, chart.style, valueIndex, 'stroke');
|
|
29
|
+
MarkDot.updateColors(block, chart, valueIndex);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
static renderGrouped(block, scales, data, keyField, margin, keyAxisOrient, chart) {
|
|
33
|
+
chart.data.valueFields.forEach((valueField, valueIndex) => {
|
|
34
|
+
const lineGenerator = LineHelper.getLineGenerator(keyAxisOrient, scales, keyField.name, valueField.name, margin);
|
|
35
|
+
const path = block.getChartGroup(chart.index)
|
|
36
|
+
.append('path')
|
|
37
|
+
.attr('d', lineGenerator(data))
|
|
38
|
+
.attr('class', this.lineChartClass)
|
|
39
|
+
.style('fill', 'none')
|
|
40
|
+
.style('clip-path', `url(#${block.getClipPathId()})`)
|
|
41
|
+
.style('pointer-events', 'none');
|
|
42
|
+
DomHelper.setCssClasses(path, Helper.getCssClassesWithElementIndex(chart.cssClasses, valueIndex));
|
|
43
|
+
DomHelper.setChartStyle(path, chart.style, valueIndex, 'stroke');
|
|
44
|
+
MarkDot.render(block, data, keyAxisOrient, scales, margin, keyField.name, valueIndex, valueField.name, chart);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
static renderSegmented(block, scales, data, keyField, margin, keyAxisOrient, chart) {
|
|
48
|
+
const stackedData = stack().keys(chart.data.valueFields.map(field => field.name))(data);
|
|
49
|
+
const lineGenerator = LineHelper.getSegmentedLineGenerator(keyAxisOrient, scales, keyField.name, margin);
|
|
50
|
+
const lines = block.getChartGroup(chart.index)
|
|
51
|
+
.selectAll(`.${this.lineChartClass}${Helper.getCssClassesLine(chart.cssClasses)}`)
|
|
52
|
+
.data(stackedData)
|
|
53
|
+
.enter()
|
|
54
|
+
.append('path')
|
|
55
|
+
.attr('d', d => lineGenerator(d))
|
|
56
|
+
.attr('class', this.lineChartClass)
|
|
57
|
+
.style('fill', 'none')
|
|
58
|
+
.style('clip-path', `url(#${block.getClipPathId()})`)
|
|
59
|
+
.style('pointer-events', 'none');
|
|
60
|
+
lines.each(function (d, i) {
|
|
61
|
+
DomHelper.setCssClasses(select(this), Helper.getCssClassesWithElementIndex(chart.cssClasses, i));
|
|
62
|
+
});
|
|
63
|
+
this.setSegmentColor(lines, chart.style.elementColors);
|
|
64
|
+
stackedData.forEach((dataset, stackIndex) => {
|
|
65
|
+
MarkDot.render(block, dataset, keyAxisOrient, scales, margin, keyField.name, stackIndex, '1', chart);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
static updateGrouped(block, scales, newData, keyField, margin, keyAxisOrient, chart) {
|
|
69
|
+
const promises = [];
|
|
70
|
+
chart.data.valueFields.forEach((valueField, valueFieldIndex) => {
|
|
71
|
+
const lineGenerator = LineHelper.getLineGenerator(keyAxisOrient, scales, keyField.name, valueField.name, margin);
|
|
72
|
+
const lineObject = block.getChartGroup(chart.index)
|
|
73
|
+
.select(`.${this.lineChartClass}${Helper.getCssClassesLine(chart.cssClasses)}.chart-element-${valueFieldIndex}`);
|
|
74
|
+
const prom = this.updateGroupedPath(block, lineObject, lineGenerator, newData);
|
|
75
|
+
promises.push(prom);
|
|
76
|
+
MarkDot.update(block, newData, keyAxisOrient, scales, margin, keyField.name, valueFieldIndex, valueField.name, chart);
|
|
77
|
+
});
|
|
78
|
+
return promises;
|
|
79
|
+
}
|
|
80
|
+
static updateSegmeneted(block, scales, newData, keyField, margin, keyAxisOrient, chart) {
|
|
81
|
+
const stackedData = stack().keys(chart.data.valueFields.map(field => field.name))(newData);
|
|
82
|
+
const lineGenerator = LineHelper.getSegmentedLineGenerator(keyAxisOrient, scales, keyField.name, margin);
|
|
83
|
+
const lines = block.getChartGroup(chart.index)
|
|
84
|
+
.selectAll(`path.${this.lineChartClass}${Helper.getCssClassesLine(chart.cssClasses)}`)
|
|
85
|
+
.data(stackedData);
|
|
86
|
+
const prom = this.updateSegmentedPath(block, lines, lineGenerator);
|
|
87
|
+
lines.each((dataset, index) => {
|
|
88
|
+
MarkDot.update(block, dataset, keyAxisOrient, scales, margin, keyField.name, index, '1', chart);
|
|
89
|
+
});
|
|
90
|
+
return [prom];
|
|
91
|
+
}
|
|
92
|
+
static updateGroupedPath(block, lineObject, lineGenerator, newData) {
|
|
93
|
+
return new Promise(resolve => {
|
|
94
|
+
if (lineObject.size() === 0) {
|
|
95
|
+
resolve('');
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
let lineHandler = lineObject;
|
|
99
|
+
if (block.transitionManager.durations.chartUpdate > 0)
|
|
100
|
+
lineHandler = lineHandler.interrupt()
|
|
101
|
+
.transition()
|
|
102
|
+
.duration(block.transitionManager.durations.chartUpdate)
|
|
103
|
+
.on('end', () => resolve(''));
|
|
104
|
+
lineHandler
|
|
105
|
+
.attr('d', lineGenerator(newData));
|
|
106
|
+
if (block.transitionManager.durations.chartUpdate <= 0)
|
|
107
|
+
resolve('');
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
static updateSegmentedPath(block, linesObjects, lineGenerator) {
|
|
111
|
+
return new Promise(resolve => {
|
|
112
|
+
if (linesObjects.size() === 0) {
|
|
113
|
+
resolve('');
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
let linesHandler = linesObjects;
|
|
117
|
+
if (block.transitionManager.durations.chartUpdate > 0)
|
|
118
|
+
linesHandler = linesHandler.interrupt()
|
|
119
|
+
.transition()
|
|
120
|
+
.duration(block.transitionManager.durations.chartUpdate)
|
|
121
|
+
.on('end', () => resolve(''));
|
|
122
|
+
linesHandler
|
|
123
|
+
.attr('d', d => lineGenerator(d));
|
|
124
|
+
if (block.transitionManager.durations.chartUpdate <= 0)
|
|
125
|
+
resolve('');
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
static setSegmentColor(segments, colorPalette) {
|
|
129
|
+
segments.style('stroke', (d, i) => colorPalette[i % colorPalette.length]);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
Line.lineChartClass = 'line';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Line as ILine } from 'd3-shape';
|
|
2
|
+
import { MdtChartsDataRow } from '../../../config/config';
|
|
3
|
+
import { Orient, BlockMargin } from "../../../model/model";
|
|
4
|
+
import { Scales } from "../../features/scale/scale";
|
|
5
|
+
export declare class LineHelper {
|
|
6
|
+
static getLineGenerator(keyAxisOrient: Orient, scales: Scales, keyFieldName: string, valueFieldName: string, margin: BlockMargin): ILine<MdtChartsDataRow>;
|
|
7
|
+
static getSegmentedLineGenerator(keyAxisOrient: Orient, scales: Scales, keyFieldName: string, margin: BlockMargin): ILine<MdtChartsDataRow>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { line } from 'd3-shape';
|
|
2
|
+
import { Scale } from "../../features/scale/scale";
|
|
3
|
+
export class LineHelper {
|
|
4
|
+
static getLineGenerator(keyAxisOrient, scales, keyFieldName, valueFieldName, margin) {
|
|
5
|
+
if (keyAxisOrient === 'bottom' || keyAxisOrient === 'top') {
|
|
6
|
+
return line()
|
|
7
|
+
.x(d => Scale.getScaledValue(scales.key, d[keyFieldName]) + margin.left)
|
|
8
|
+
.y(d => scales.value(d[valueFieldName]) + margin.top);
|
|
9
|
+
}
|
|
10
|
+
if (keyAxisOrient === 'left' || keyAxisOrient === 'right') {
|
|
11
|
+
return line()
|
|
12
|
+
.x(d => scales.value(d[valueFieldName]) + margin.left)
|
|
13
|
+
.y(d => Scale.getScaledValue(scales.key, d[keyFieldName]) + margin.top);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
static getSegmentedLineGenerator(keyAxisOrient, scales, keyFieldName, margin) {
|
|
17
|
+
if (keyAxisOrient === 'bottom' || keyAxisOrient === 'top') {
|
|
18
|
+
return line()
|
|
19
|
+
.x(d => Scale.getScaledValue(scales.key, d.data[keyFieldName]) + margin.left)
|
|
20
|
+
.y(d => scales.value(d[1]) + margin.top);
|
|
21
|
+
}
|
|
22
|
+
if (keyAxisOrient === 'left' || keyAxisOrient === 'right') {
|
|
23
|
+
return line()
|
|
24
|
+
.x(d => scales.value(d[1]) + margin.left)
|
|
25
|
+
.y(d => Scale.getScaledValue(scales.key, d.data[keyFieldName]) + margin.top);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { MdtChartsDataSource } from "../../config/config";
|
|
2
|
+
import { Model } from "../../model/model";
|
|
3
|
+
import { Block } from "../block/block";
|
|
4
|
+
import Engine from "../engine";
|
|
5
|
+
export declare class TwoDimensionalManager {
|
|
6
|
+
static render(engine: Engine, model: Model): void;
|
|
7
|
+
static updateData(block: Block, model: Model, data: MdtChartsDataSource): void;
|
|
8
|
+
static updateColors(block: Block, model: Model): void;
|
|
9
|
+
private static renderCharts;
|
|
10
|
+
private static updateCharts;
|
|
11
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { ElementHighlighter } from "../elementHighlighter/elementHighlighter";
|
|
2
|
+
import { Axis } from "../features/axis/axis";
|
|
3
|
+
import { EmbeddedLabels } from "../features/embeddedLabels/embeddedLabels";
|
|
4
|
+
import { GridLine } from "../features/gridLine/gridLine";
|
|
5
|
+
import { Legend } from "../features/legend/legend";
|
|
6
|
+
import { RecordOverflowAlert } from "../features/recordOverflowAlert/recordOverflowAlert";
|
|
7
|
+
import { Scale } from "../features/scale/scale";
|
|
8
|
+
import { TipBox } from "../features/tipBox/tipBox";
|
|
9
|
+
import { Title } from "../features/title/title";
|
|
10
|
+
import { Tooltip } from "../features/tolltip/tooltip";
|
|
11
|
+
import { Helper } from "../helpers/helper";
|
|
12
|
+
import { Area } from "./area/area";
|
|
13
|
+
import { Bar } from "./bar/bar";
|
|
14
|
+
import { BarHelper } from "./bar/barHelper";
|
|
15
|
+
import { Line } from "./line/line";
|
|
16
|
+
export class TwoDimensionalManager {
|
|
17
|
+
static render(engine, model) {
|
|
18
|
+
const options = model.options;
|
|
19
|
+
const scales = Scale.getScales(options.scale.key, options.scale.value, model.chartSettings.bar);
|
|
20
|
+
engine.block.scales = scales;
|
|
21
|
+
engine.block.renderSvg(model.blockCanvas.size);
|
|
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, options.scale.key);
|
|
24
|
+
this.renderCharts(engine.block, options.charts, scales, engine.data, options.data, model.chartBlock.margin, options.axis.key.orient, model.chartSettings.bar, model.blockCanvas.size);
|
|
25
|
+
engine.block.filterEventManager.registerEventFor2D(scales.key, model.chartBlock.margin, model.blockCanvas.size, options);
|
|
26
|
+
engine.block.filterEventManager.event2DUpdate(options);
|
|
27
|
+
Title.render(engine.block, options.title, model.otherComponents.titleBlock, model.blockCanvas.size);
|
|
28
|
+
Legend.render(engine.block, engine.data, options, model);
|
|
29
|
+
Tooltip.render(engine.block, model, engine.data, model.otherComponents.tooltipBlock, scales);
|
|
30
|
+
if (model.dataSettings.scope.hidedRecordsAmount !== 0)
|
|
31
|
+
RecordOverflowAlert.render(engine.block, model.dataSettings.scope.hidedRecordsAmount, 'top', options.orient);
|
|
32
|
+
engine.block.getSvg()
|
|
33
|
+
.on('click', (e) => {
|
|
34
|
+
if (e.target === engine.block.getSvg().node())
|
|
35
|
+
engine.block.filterEventManager.clearKeysFor2D(options);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
static updateData(block, model, data) {
|
|
39
|
+
block.transitionManager.interruptTransitions();
|
|
40
|
+
block.filterEventManager.updateData(data[model.options.data.dataSource]);
|
|
41
|
+
TipBox.clearEvents(block);
|
|
42
|
+
Tooltip.hide(block);
|
|
43
|
+
const options = model.options;
|
|
44
|
+
ElementHighlighter.remove2DChartsFullHighlighting(block, options.charts);
|
|
45
|
+
const scales = Scale.getScales(options.scale.key, options.scale.value, model.chartSettings.bar);
|
|
46
|
+
const keyDomainEquality = Helper.checkDomainsEquality(block.scales.key.domain(), scales.key.domain());
|
|
47
|
+
block.scales = scales;
|
|
48
|
+
Axis.update(block, scales, options.scale, options.axis, model.blockCanvas.size, keyDomainEquality);
|
|
49
|
+
GridLine.update(block, options.additionalElements.gridLine.flag, options.axis, model.blockCanvas.size, model.chartBlock.margin, options.scale.key);
|
|
50
|
+
const promises = this.updateCharts(block, options.charts, scales, data, model.options.data, model.chartBlock.margin, options.axis.key.orient, model.blockCanvas.size, model.chartSettings.bar);
|
|
51
|
+
Promise.all(promises)
|
|
52
|
+
.then(() => {
|
|
53
|
+
block.filterEventManager.event2DUpdate(options);
|
|
54
|
+
block.filterEventManager.registerEventFor2D(scales.key, model.chartBlock.margin, model.blockCanvas.size, options);
|
|
55
|
+
Tooltip.render(block, model, data, model.otherComponents.tooltipBlock, scales);
|
|
56
|
+
});
|
|
57
|
+
RecordOverflowAlert.update(block, model.dataSettings.scope.hidedRecordsAmount, 'top', options.orient);
|
|
58
|
+
}
|
|
59
|
+
static updateColors(block, model) {
|
|
60
|
+
Legend.updateColors(block, model.options);
|
|
61
|
+
model.options.charts.forEach(chart => {
|
|
62
|
+
if (chart.type === 'bar')
|
|
63
|
+
Bar.updateColors(block, chart);
|
|
64
|
+
else if (chart.type === 'line')
|
|
65
|
+
Line.updateColors(block, chart);
|
|
66
|
+
else if (chart.type === 'area')
|
|
67
|
+
Area.updateColors(block, chart);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
static renderCharts(block, charts, scales, data, dataOptions, margin, keyAxisOrient, barSettings, blockSize) {
|
|
71
|
+
block.renderChartClipPath(margin, blockSize);
|
|
72
|
+
block.renderChartsBlock();
|
|
73
|
+
charts.forEach((chart) => {
|
|
74
|
+
if (chart.type === 'bar')
|
|
75
|
+
Bar.render(block, scales, data[dataOptions.dataSource], dataOptions.keyField, margin, keyAxisOrient, chart, blockSize, barSettings, BarHelper.getBarsInGroupAmount(charts), chart.isSegmented, charts.findIndex(ch => ch.type === 'bar'));
|
|
76
|
+
else if (chart.type === 'line')
|
|
77
|
+
Line.render(block, scales, data[dataOptions.dataSource], dataOptions.keyField, margin, keyAxisOrient, chart);
|
|
78
|
+
else if (chart.type === 'area')
|
|
79
|
+
Area.render(block, scales, data[dataOptions.dataSource], dataOptions.keyField, margin, keyAxisOrient, chart, blockSize);
|
|
80
|
+
});
|
|
81
|
+
EmbeddedLabels.raiseGroups(block);
|
|
82
|
+
}
|
|
83
|
+
static updateCharts(block, charts, scales, data, dataOptions, margin, keyAxisOrient, blockSize, barSettings) {
|
|
84
|
+
block.updateChartClipPath(margin, blockSize);
|
|
85
|
+
let promises = [];
|
|
86
|
+
charts.forEach((chart) => {
|
|
87
|
+
let proms;
|
|
88
|
+
if (chart.type === 'bar') {
|
|
89
|
+
proms = Bar.update(block, data[dataOptions.dataSource], scales, margin, keyAxisOrient, chart, blockSize, BarHelper.getBarsInGroupAmount(charts), dataOptions.keyField, charts.findIndex(ch => ch.type === 'bar'), barSettings, chart.isSegmented);
|
|
90
|
+
}
|
|
91
|
+
else if (chart.type === 'line') {
|
|
92
|
+
proms = Line.update(block, scales, data[dataOptions.dataSource], dataOptions.keyField, margin, keyAxisOrient, chart);
|
|
93
|
+
}
|
|
94
|
+
else if (chart.type === 'area') {
|
|
95
|
+
proms = Area.update(block, scales, data[dataOptions.dataSource], dataOptions.keyField, margin, chart, keyAxisOrient, blockSize);
|
|
96
|
+
}
|
|
97
|
+
promises.push(...proms);
|
|
98
|
+
});
|
|
99
|
+
return promises;
|
|
100
|
+
}
|
|
101
|
+
}
|