@rfprodz/client-d3-charts 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +88 -0
- package/esm2020/index.mjs +5 -0
- package/esm2020/lib/client-d3-charts.module.mjs +47 -0
- package/esm2020/lib/components/bar-chart/bar-chart.component.mjs +87 -0
- package/esm2020/lib/components/chart-examples/chart-examples.component.mjs +181 -0
- package/esm2020/lib/components/force-directed-chart/force-directed-chart.component.mjs +92 -0
- package/esm2020/lib/components/index.mjs +7 -0
- package/esm2020/lib/components/line-chart/line-chart.component.mjs +91 -0
- package/esm2020/lib/components/pie-chart/pie-chart.component.mjs +90 -0
- package/esm2020/lib/components/radar-chart/radar-chart.component.mjs +102 -0
- package/esm2020/lib/interfaces/bar-chart.interface.mjs +2 -0
- package/esm2020/lib/interfaces/force-directed-chart.interface.mjs +2 -0
- package/esm2020/lib/interfaces/index.mjs +6 -0
- package/esm2020/lib/interfaces/line-chart.interface.mjs +2 -0
- package/esm2020/lib/interfaces/pie-chart.interface.mjs +2 -0
- package/esm2020/lib/interfaces/radar-chart.interface.mjs +2 -0
- package/esm2020/lib/providers/d3-chart-factory.provider.mjs +18 -0
- package/esm2020/lib/util/bar-chart.util.mjs +255 -0
- package/esm2020/lib/util/configuration.util.mjs +31 -0
- package/esm2020/lib/util/force-directed-chart.util.mjs +255 -0
- package/esm2020/lib/util/index.mjs +6 -0
- package/esm2020/lib/util/line-chart.util.mjs +266 -0
- package/esm2020/lib/util/pie-chart.util.mjs +89 -0
- package/esm2020/lib/util/radar-chart.util.mjs +295 -0
- package/esm2020/rfprodz-client-d3-charts.mjs +5 -0
- package/fesm2015/rfprodz-client-d3-charts.mjs +1868 -0
- package/fesm2015/rfprodz-client-d3-charts.mjs.map +1 -0
- package/fesm2020/rfprodz-client-d3-charts.mjs +1855 -0
- package/fesm2020/rfprodz-client-d3-charts.mjs.map +1 -0
- package/index.d.ts +4 -0
- package/lib/client-d3-charts.module.d.ts +13 -0
- package/lib/components/bar-chart/bar-chart.component.d.ts +49 -0
- package/lib/components/chart-examples/chart-examples.component.d.ts +60 -0
- package/lib/components/force-directed-chart/force-directed-chart.component.d.ts +49 -0
- package/lib/components/index.d.ts +6 -0
- package/lib/components/line-chart/line-chart.component.d.ts +49 -0
- package/lib/components/pie-chart/pie-chart.component.d.ts +49 -0
- package/lib/components/radar-chart/radar-chart.component.d.ts +49 -0
- package/lib/interfaces/bar-chart.interface.d.ts +25 -0
- package/lib/interfaces/force-directed-chart.interface.d.ts +50 -0
- package/lib/interfaces/index.d.ts +5 -0
- package/lib/interfaces/line-chart.interface.d.ts +28 -0
- package/lib/interfaces/pie-chart.interface.d.ts +19 -0
- package/lib/interfaces/radar-chart.interface.d.ts +30 -0
- package/lib/providers/d3-chart-factory.provider.d.ts +15 -0
- package/lib/util/bar-chart.util.d.ts +14 -0
- package/lib/util/configuration.util.d.ts +7 -0
- package/lib/util/force-directed-chart.util.d.ts +14 -0
- package/lib/util/index.d.ts +5 -0
- package/lib/util/line-chart.util.d.ts +14 -0
- package/lib/util/pie-chart.util.d.ts +14 -0
- package/lib/util/radar-chart.util.d.ts +14 -0
- package/package.json +53 -0
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import * as d3 from 'd3';
|
|
2
|
+
import { generateConfiguration } from './configuration.util';
|
|
3
|
+
/**
|
|
4
|
+
* The line chart default configuration.
|
|
5
|
+
*/
|
|
6
|
+
export const defaultLineChartConfig = Object.freeze({
|
|
7
|
+
chartTitle: '',
|
|
8
|
+
width: 350,
|
|
9
|
+
height: 350,
|
|
10
|
+
margin: {
|
|
11
|
+
top: 70,
|
|
12
|
+
right: 50,
|
|
13
|
+
bottom: 50,
|
|
14
|
+
left: 50,
|
|
15
|
+
},
|
|
16
|
+
transitionDuration: 400,
|
|
17
|
+
dotRadius: 3.5,
|
|
18
|
+
xAxisTitle: '',
|
|
19
|
+
yAxisTitle: '',
|
|
20
|
+
ticks: {
|
|
21
|
+
x: 5,
|
|
22
|
+
y: 10,
|
|
23
|
+
},
|
|
24
|
+
displayAxisLabels: true,
|
|
25
|
+
labelTextWrapWidth: 20,
|
|
26
|
+
color: d3.scaleOrdinal(d3.schemeCategory10),
|
|
27
|
+
});
|
|
28
|
+
/**
|
|
29
|
+
* Creates a container for the line chart.
|
|
30
|
+
* @param container the chart container
|
|
31
|
+
* @param config the chart configuration
|
|
32
|
+
* @returns the object with the svg element and the g element
|
|
33
|
+
*/
|
|
34
|
+
const createContainer = (container, config) => {
|
|
35
|
+
const id = container.nativeElement.id ?? 'line-0';
|
|
36
|
+
d3.select(`#${id}`).select('svg').remove();
|
|
37
|
+
const svg = d3
|
|
38
|
+
.select(`#${id}`)
|
|
39
|
+
.append('svg')
|
|
40
|
+
.attr('width', config.width + config.margin.left + config.margin.right)
|
|
41
|
+
.attr('height', config.height + config.margin.top + config.margin.bottom)
|
|
42
|
+
.attr('class', id);
|
|
43
|
+
const g = svg.append('g').attr('transform', `translate(${config.margin.left},${config.margin.top / 2})`);
|
|
44
|
+
return { svg, g };
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Wraps the line chart axis labels text.
|
|
48
|
+
* @param svgText the svg text elements
|
|
49
|
+
* @param width the chart axis label width
|
|
50
|
+
*/
|
|
51
|
+
const wrapSvgText = (svgText, width) => {
|
|
52
|
+
svgText.each(function () {
|
|
53
|
+
const text = d3.select(this);
|
|
54
|
+
const words = text.text().split(/\s+/).reverse();
|
|
55
|
+
let line = [];
|
|
56
|
+
let lineNumber = 0;
|
|
57
|
+
const lineHeight = 1.4;
|
|
58
|
+
const y = text.attr('y');
|
|
59
|
+
const x = text.attr('x');
|
|
60
|
+
const dy = parseFloat(text.attr('dy') ?? 0);
|
|
61
|
+
let tspan = text.text(null).append('tspan').attr('x', x).attr('y', y).attr('dy', `${dy}em`); // axis label
|
|
62
|
+
let word = words.pop();
|
|
63
|
+
while (typeof word !== 'undefined') {
|
|
64
|
+
line.push(word ?? '');
|
|
65
|
+
tspan.text(line.join(' '));
|
|
66
|
+
if ((tspan.node()?.getComputedTextLength() ?? 0) > width) {
|
|
67
|
+
line.pop();
|
|
68
|
+
tspan.text(line.join(' '));
|
|
69
|
+
line = [word ?? ''];
|
|
70
|
+
lineNumber += 1;
|
|
71
|
+
tspan = text
|
|
72
|
+
.append('tspan')
|
|
73
|
+
.attr('x', 0)
|
|
74
|
+
.attr('y', y)
|
|
75
|
+
.attr('dy', `${lineNumber * lineHeight + dy}em`)
|
|
76
|
+
.text(word ?? '');
|
|
77
|
+
}
|
|
78
|
+
word = words.pop();
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Creates the legend.
|
|
84
|
+
* @param g the svg g element
|
|
85
|
+
* @param config the chart configuration
|
|
86
|
+
*/
|
|
87
|
+
const createLegend = (g, config) => {
|
|
88
|
+
if (config.displayAxisLabels && config.xAxisTitle !== '') {
|
|
89
|
+
g.append('g')
|
|
90
|
+
.attr('transform', `translate(0, ${config.height + config.margin.bottom})`)
|
|
91
|
+
.append('text')
|
|
92
|
+
.style('font-size', '12px')
|
|
93
|
+
.attr('class', 'legend')
|
|
94
|
+
.attr('dx', '1.5em')
|
|
95
|
+
.attr('dy', '1em')
|
|
96
|
+
.text(`x - ${config.xAxisTitle}`);
|
|
97
|
+
}
|
|
98
|
+
if (config.displayAxisLabels && config.yAxisTitle !== '') {
|
|
99
|
+
g.append('g')
|
|
100
|
+
.attr('transform', `translate(0, ${config.height + config.margin.bottom})`)
|
|
101
|
+
.append('text')
|
|
102
|
+
.style('font-size', '12px')
|
|
103
|
+
.attr('class', 'legend')
|
|
104
|
+
.attr('dx', '1.5em')
|
|
105
|
+
.attr('dy', '2.5em')
|
|
106
|
+
.text(`y - ${config.yAxisTitle}`);
|
|
107
|
+
}
|
|
108
|
+
if (config.chartTitle !== '') {
|
|
109
|
+
g.append('g')
|
|
110
|
+
.attr('transform', `translate(0, 0)`)
|
|
111
|
+
.append('text')
|
|
112
|
+
.style('font-size', '12px')
|
|
113
|
+
.attr('class', 'legend')
|
|
114
|
+
.attr('dx', '1.5em')
|
|
115
|
+
.attr('dy', '-2em')
|
|
116
|
+
.text(config.chartTitle);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Creates the x axis.
|
|
121
|
+
* @param g the svg g element
|
|
122
|
+
* @param x the x axis scale
|
|
123
|
+
* @param config the chart configuration
|
|
124
|
+
*/
|
|
125
|
+
const createAxisX = (g, x, config) => {
|
|
126
|
+
const xLabels = g
|
|
127
|
+
.append('g')
|
|
128
|
+
.attr('transform', `translate(0, ${config.height})`)
|
|
129
|
+
.call(d3
|
|
130
|
+
.axisBottom(x)
|
|
131
|
+
.ticks(config.ticks.x)
|
|
132
|
+
.tickFormat(d => {
|
|
133
|
+
const date = new Date(d.valueOf());
|
|
134
|
+
const formattingOffset = 10;
|
|
135
|
+
const day = date.getDate();
|
|
136
|
+
const dd = day < formattingOffset ? `0${day}` : day;
|
|
137
|
+
const month = date.getMonth() + 1;
|
|
138
|
+
const mm = month < formattingOffset ? `0${month}` : month;
|
|
139
|
+
const year = date.getFullYear().toString();
|
|
140
|
+
const yy = year.slice(2);
|
|
141
|
+
const hours = date.getHours();
|
|
142
|
+
const hour = hours < formattingOffset ? `0${hours}` : hours;
|
|
143
|
+
const minutes = date.getMinutes();
|
|
144
|
+
const minute = minutes < formattingOffset ? `0${minutes}` : minutes;
|
|
145
|
+
return `${dd}/${mm}/${yy} ${hour}:${minute}`;
|
|
146
|
+
}))
|
|
147
|
+
.append('text');
|
|
148
|
+
g.selectAll('text').call(wrapSvgText, config.labelTextWrapWidth);
|
|
149
|
+
if (config.displayAxisLabels) {
|
|
150
|
+
xLabels.attr('transform', `translate(${config.width}, 0)`).attr('class', 'legend').attr('dx', '1.5em').attr('dy', '0.7em').text('x');
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Creates the y axis.
|
|
155
|
+
* @param g the svg g element
|
|
156
|
+
* @param y the y axis scale
|
|
157
|
+
* @param config the chart configuration
|
|
158
|
+
*/
|
|
159
|
+
const createAxisY = (g, y, config) => {
|
|
160
|
+
const yLabels = g
|
|
161
|
+
.append('g')
|
|
162
|
+
.call(d3
|
|
163
|
+
.axisLeft(y)
|
|
164
|
+
.ticks(config.ticks.y)
|
|
165
|
+
.tickFormat(d => `${d}`))
|
|
166
|
+
.append('text');
|
|
167
|
+
if (config.displayAxisLabels) {
|
|
168
|
+
yLabels.attr('class', 'legend').attr('dy', '-1.5em').attr('class', 'legend').text('y');
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
/**
|
|
172
|
+
* The mouse over event handler.
|
|
173
|
+
* @param self an svg circle element
|
|
174
|
+
* @param d the chart data node
|
|
175
|
+
* @param g the svg g element
|
|
176
|
+
* @param config the chart configuration
|
|
177
|
+
*/
|
|
178
|
+
const onMouseOver = (self, d, g, config) => {
|
|
179
|
+
const duration = 400;
|
|
180
|
+
d3.select(self)
|
|
181
|
+
.transition()
|
|
182
|
+
.duration(duration)
|
|
183
|
+
.attr('r', config.dotRadius * 2);
|
|
184
|
+
const tooltipShift = 4;
|
|
185
|
+
const tooltipDy = -10;
|
|
186
|
+
g.append('text')
|
|
187
|
+
.attr('class', 'val')
|
|
188
|
+
.style('font-size', '11px')
|
|
189
|
+
.attr('dx', () => (config.width - config.margin.left - config.margin.right) / tooltipShift)
|
|
190
|
+
.attr('dy', () => tooltipDy)
|
|
191
|
+
.text(() => `${d.value} (${new Date(d.timestamp).toUTCString()})`);
|
|
192
|
+
};
|
|
193
|
+
/**
|
|
194
|
+
* The mouse out event handler.
|
|
195
|
+
* @param self an svg circle element
|
|
196
|
+
* @param config the chart configuration
|
|
197
|
+
*/
|
|
198
|
+
const onMouseOut = (self, config) => {
|
|
199
|
+
const duration = 400;
|
|
200
|
+
d3.select(self).attr('class', 'dot');
|
|
201
|
+
d3.select(self).transition().duration(duration).attr('r', config.dotRadius);
|
|
202
|
+
d3.selectAll('.val').remove();
|
|
203
|
+
};
|
|
204
|
+
/**
|
|
205
|
+
* Draws the chart lines, dots, and sets the mouse pointer events.
|
|
206
|
+
* @param g the svg g element
|
|
207
|
+
* @param x the x axis scale
|
|
208
|
+
* @param y the y axis scale
|
|
209
|
+
* @param config the chart configuration
|
|
210
|
+
* @param data the chart data
|
|
211
|
+
*/
|
|
212
|
+
const drawLinesDotsAndSetPointerEvents = (g, x, y, config, data) => {
|
|
213
|
+
const line = d3
|
|
214
|
+
.line()
|
|
215
|
+
.x(d => x(d.timestamp))
|
|
216
|
+
.y(d => y(d.value))
|
|
217
|
+
.curve(d3.curveMonotoneX);
|
|
218
|
+
g.append('path').attr('id', 'line').style('fill', 'none').style('stroke', 'red').style('stroke-width', '2px').attr('d', line(data));
|
|
219
|
+
g.selectAll('.dot')
|
|
220
|
+
.data(data)
|
|
221
|
+
.enter()
|
|
222
|
+
.append('circle')
|
|
223
|
+
.attr('class', 'dot')
|
|
224
|
+
.style('pointer-events', 'all')
|
|
225
|
+
.style('fill', (d, i) => config.color(i.toString()))
|
|
226
|
+
.on('mouseover', function (event, d) {
|
|
227
|
+
return onMouseOver(this, d, g, config);
|
|
228
|
+
})
|
|
229
|
+
.on('mouseout', function () {
|
|
230
|
+
return onMouseOut(this, config);
|
|
231
|
+
})
|
|
232
|
+
.attr('cx', function (d) {
|
|
233
|
+
return x(d.timestamp);
|
|
234
|
+
})
|
|
235
|
+
.attr('cy', function (d) {
|
|
236
|
+
return y(d.value);
|
|
237
|
+
})
|
|
238
|
+
.attr('r', 0)
|
|
239
|
+
.transition()
|
|
240
|
+
.ease(d3.easeLinear)
|
|
241
|
+
.duration(config.transitionDuration)
|
|
242
|
+
.delay((d, i) => {
|
|
243
|
+
const multiplier = 50;
|
|
244
|
+
return i * multiplier;
|
|
245
|
+
})
|
|
246
|
+
.attr('r', config.dotRadius);
|
|
247
|
+
};
|
|
248
|
+
/**
|
|
249
|
+
* Draws the line chart.
|
|
250
|
+
* @param container the chart container
|
|
251
|
+
* @param data the chart data
|
|
252
|
+
* @param options the chart options
|
|
253
|
+
* @returns the chart configuration
|
|
254
|
+
*/
|
|
255
|
+
export const drawLineChart = (container, data, options) => {
|
|
256
|
+
const config = generateConfiguration(defaultLineChartConfig, options, {});
|
|
257
|
+
const { g } = createContainer(container, config);
|
|
258
|
+
const x = d3.scaleTime([0, config.width]).domain([Math.min(...data.map(d => d.timestamp)), Math.max(...data.map(d => d.timestamp))]);
|
|
259
|
+
const y = d3.scaleLinear([config.height, 0]).domain([0, d3.max(data, d => d.value) ?? 1]);
|
|
260
|
+
createAxisX(g, x, config);
|
|
261
|
+
createAxisY(g, y, config);
|
|
262
|
+
createLegend(g, config);
|
|
263
|
+
drawLinesDotsAndSetPointerEvents(g, x, y, config, data);
|
|
264
|
+
return config;
|
|
265
|
+
};
|
|
266
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGluZS1jaGFydC51dGlsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9jbGllbnQtZDMtY2hhcnRzL3NyYy9saWIvdXRpbC9saW5lLWNoYXJ0LnV0aWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxLQUFLLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFHekIsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFN0Q7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBc0IsTUFBTSxDQUFDLE1BQU0sQ0FBb0I7SUFDeEYsVUFBVSxFQUFFLEVBQUU7SUFDZCxLQUFLLEVBQUUsR0FBRztJQUNWLE1BQU0sRUFBRSxHQUFHO0lBQ1gsTUFBTSxFQUFFO1FBQ04sR0FBRyxFQUFFLEVBQUU7UUFDUCxLQUFLLEVBQUUsRUFBRTtRQUNULE1BQU0sRUFBRSxFQUFFO1FBQ1YsSUFBSSxFQUFFLEVBQUU7S0FDVDtJQUNELGtCQUFrQixFQUFFLEdBQUc7SUFDdkIsU0FBUyxFQUFFLEdBQUc7SUFDZCxVQUFVLEVBQUUsRUFBRTtJQUNkLFVBQVUsRUFBRSxFQUFFO0lBQ2QsS0FBSyxFQUFFO1FBQ0wsQ0FBQyxFQUFFLENBQUM7UUFDSixDQUFDLEVBQUUsRUFBRTtLQUNOO0lBQ0QsaUJBQWlCLEVBQUUsSUFBSTtJQUN2QixrQkFBa0IsRUFBRSxFQUFFO0lBQ3RCLEtBQUssRUFBRSxFQUFFLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQztDQUM1QyxDQUFDLENBQUM7QUFFSDs7Ozs7R0FLRztBQUNILE1BQU0sZUFBZSxHQUFHLENBQUMsU0FBcUMsRUFBRSxNQUF5QixFQUFFLEVBQUU7SUFDM0YsTUFBTSxFQUFFLEdBQUcsU0FBUyxDQUFDLGFBQWEsQ0FBQyxFQUFFLElBQUksUUFBUSxDQUFDO0lBRWxELEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLEVB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LENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBRXhELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEVsZW1lbnRSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCAqIGFzIGQzIGZyb20gJ2QzJztcblxuaW1wb3J0IHsgSUxpbmVDaGFydERhdGFOb2RlLCBJTGluZUNoYXJ0T3B0aW9ucywgVExpbmVDaGFydERhdGEgfSBmcm9tICcuLi9pbnRlcmZhY2VzL2xpbmUtY2hhcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IGdlbmVyYXRlQ29uZmlndXJhdGlvbiB9IGZyb20gJy4vY29uZmlndXJhdGlvbi51dGlsJztcblxuLyoqXG4gKiBUaGUgbGluZSBjaGFydCBkZWZhdWx0IGNvbmZpZ3VyYXRpb24uXG4gKi9cbmV4cG9ydCBjb25zdCBkZWZhdWx0TGluZUNoYXJ0Q29uZmlnOiBJTGluZUNoYXJ0T3B0aW9ucyA9IE9iamVjdC5mcmVlemUoPElMaW5lQ2hhcnRPcHRpb25zPntcbiAgY2hhcnRUaXRsZTogJycsXG4gIHdpZHRoOiAzNTAsXG4gIGhlaWdodDogMzUwLFxuICBtYXJnaW46IHtcbiAgICB0b3A6IDcwLFxuICAgIHJpZ2h0OiA1MCxcbiAgICBib3R0b206IDUwLFxuICAgIGxlZnQ6IDUwLFxuICB9LFxuICB0cmFuc2l0aW9uRHVyYXRpb246IDQwMCxcbiAgZG90UmFkaXVzOiAzLjUsXG4gIHhBeGlzVGl0bGU6ICcnLFxuICB5QXhpc1RpdGxlOiAnJyxcbiAgdGlja3M6IHtcbiAgICB4OiA1LFxuICAgIHk6IDEwLFxuICB9LFxuICBkaXNwbGF5QXhpc0xhYmVsczogdHJ1ZSxcbiAgbGFiZWxUZXh0V3JhcFdpZHRoOiAyMCwgLy8gdGhlIG51bWJlciBvZiBwaXhlbHMgYWZ0ZXIgd2hpY2ggYSBsYWJlbCBuZWVkcyB0byBiZSBnaXZlbiBhIG5ldyBsaW5lXG4gIGNvbG9yOiBkMy5zY2FsZU9yZGluYWwoZDMuc2NoZW1lQ2F0ZWdvcnkxMCksXG59KTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY29udGFpbmVyIGZvciB0aGUgbGluZSBjaGFydC5cbiAqIEBwYXJhbSBjb250YWluZXIgdGhlIGNoYXJ0IGNvbnRhaW5lclxuICogQHBhcmFtIGNvbmZpZyB0aGUgY2hhcnQgY29uZmlndXJhdGlvblxuICogQHJldHVybnMgdGhlIG9iamVjdCB3aXRoIHRoZSBzdmcgZWxlbWVudCBhbmQgdGhlIGcgZWxlbWVudFxuICovXG5jb25zdCBjcmVhdGVDb250YWluZXIgPSAoY29udGFpbmVyOiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PiwgY29uZmlnOiBJTGluZUNoYXJ0T3B0aW9ucykgPT4ge1xuICBjb25zdCBpZCA9IGNvbnRhaW5lci5uYXRpdmVFbGVtZW50LmlkID8/ICdsaW5lLTAnO1xuXG4gIGQzLnNlbGVjdChgIyR7aWR9YCkuc2VsZWN0KCdzdmcnKS5yZW1vdmUoKTtcbiAgY29uc3Qgc3ZnID0gZDNcbiAgICAuc2VsZWN0KGAjJHtpZH1gKVxuICAgIC5hcHBlbmQoJ3N2ZycpXG4gICAgLmF0dHIoJ3dpZHRoJywgY29uZmlnLndpZHRoICsgY29uZmlnLm1hcmdpbi5sZWZ0ICsgY29uZmlnLm1hcmdpbi5yaWdodClcbiAgICAuYXR0cignaGVpZ2h0JywgY29uZmlnLmhlaWdodCArIGNvbmZpZy5tYXJnaW4udG9wICsgY29uZmlnLm1hcmdpbi5ib3R0b20pXG4gICAgLmF0dHIoJ2NsYXNzJywgaWQpO1xuICBjb25zdCBnID0gc3ZnLmFwcGVuZCgnZycpLmF0dHIoJ3RyYW5zZm9ybScsIGB0cmFuc2xhdGUoJHtjb25maWcubWFyZ2luLmxlZnR9LCR7Y29uZmlnLm1hcmdpbi50b3AgLyAyfSlgKTtcblxuICByZXR1cm4geyBzdmcsIGcgfTtcbn07XG5cbi8qKlxuICogV3JhcHMgdGhlIGxpbmUgY2hhcnQgYXhpcyBsYWJlbHMgdGV4dC5cbiAqIEBwYXJhbSBzdmdUZXh0IHRoZSBzdmcgdGV4dCBlbGVtZW50c1xuICogQHBhcmFtIHdpZHRoIHRoZSBjaGFydCBheGlzIGxhYmVsIHdpZHRoXG4gKi9cbmNvbnN0IHdyYXBTdmdUZXh0ID0gKHN2Z1RleHQ6IGQzLlNlbGVjdGlvbjxkMy5CYXNlVHlwZSwgdW5rbm93biwgU1ZHR0VsZW1lbnQsIHVua25vd24+LCB3aWR0aDogbnVtYmVyKSA9PiB7XG4gIHN2Z1RleHQuZWFjaChmdW5jdGlvbiAodGhpczogZDMuQmFzZVR5cGUpIHtcbiAgICBjb25zdCB0ZXh0ID0gZDMuc2VsZWN0PGQzLkJhc2VUeXBlLCBzdHJpbmc+KHRoaXMpO1xuICAgIGNvbnN0IHdvcmRzID0gdGV4dC50ZXh0KCkuc3BsaXQoL1xccysvKS5yZXZlcnNlKCk7XG4gICAgbGV0IGxpbmU6IHN0cmluZ1tdID0gW107XG4gICAgbGV0IGxpbmVOdW1iZXIgPSAwO1xuICAgIGNvbnN0IGxpbmVIZWlnaHQgPSAxLjQ7XG4gICAgY29uc3QgeSA9IHRleHQuYXR0cigneScpO1xuICAgIGNvbnN0IHggPSB0ZXh0LmF0dHIoJ3gnKTtcbiAgICBjb25zdCBkeSA9IHBhcnNlRmxvYXQodGV4dC5hdHRyKCdkeScpID8/IDApO1xuICAgIGxldCB0c3BhbiA9IHRleHQudGV4dChudWxsKS5hcHBlbmQoJ3RzcGFuJykuYXR0cigneCcsIHgpLmF0dHIoJ3knLCB5KS5hdHRyKCdkeScsIGAke2R5fWVtYCk7IC8vIGF4aXMgbGFiZWxcblxuICAgIGxldCB3b3JkID0gd29yZHMucG9wKCk7XG5cbiAgICB3aGlsZSAodHlwZW9mIHdvcmQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBsaW5lLnB1c2god29yZCA/PyAnJyk7XG4gICAgICB0c3Bhbi50ZXh0KGxpbmUuam9pbignICcpKTtcbiAgICAgIGlmICgodHNwYW4ubm9kZSgpPy5nZXRDb21wdXRlZFRleHRMZW5ndGgoKSA/PyAwKSA+IHdpZHRoKSB7XG4gICAgICAgIGxpbmUucG9wKCk7XG4gICAgICAgIHRzcGFuLnRleHQobGluZS5qb2luKCcgJykpO1xuICAgICAgICBsaW5lID0gW3dvcmQgPz8gJyddO1xuICAgICAgICBsaW5lTnVtYmVyICs9IDE7XG4gICAgICAgIHRzcGFuID0gdGV4dFxuICAgICAgICAgIC5hcHBlbmQoJ3RzcGFuJylcbiAgICAgICAgICAuYXR0cigneCcsIDApXG4gICAgICAgICAgLmF0dHIoJ3knLCB5KVxuICAgICAgICAgIC5hdHRyKCdkeScsIGAke2xpbmVOdW1iZXIgKiBsaW5lSGVpZ2h0ICsgZHl9ZW1gKVxuICAgICAgICAgIC50ZXh0KHdvcmQgPz8gJycpO1xuICAgICAgfVxuICAgICAgd29yZCA9IHdvcmRzLnBvcCgpO1xuICAgIH1cbiAgfSk7XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgdGhlIGxlZ2VuZC5cbiAqIEBwYXJhbSBnIHRoZSBzdmcgZyBlbGVtZW50XG4gKiBAcGFyYW0gY29uZmlnIHRoZSBjaGFydCBjb25maWd1cmF0aW9uXG4gKi9cbmNvbnN0IGNyZWF0ZUxlZ2VuZCA9IChnOiBkMy5TZWxlY3Rpb248U1ZHR0VsZW1lbnQsIHVua25vd24sIEhUTUxFbGVtZW50LCB1bmtub3duPiwgY29uZmlnOiBJTGluZUNoYXJ0T3B0aW9ucykgPT4ge1xuICBpZiAoY29uZmlnLmRpc3BsYXlBeGlzTGFiZWxzICYmIGNvbmZpZy54QXhpc1RpdGxlICE9PSAnJykge1xuICAgIGcuYXBwZW5kKCdnJylcbiAgICAgIC5hdHRyKCd0cmFuc2Zvcm0nLCBgdHJhbnNsYXRlKDAsICR7Y29uZmlnLmhlaWdodCArIGNvbmZpZy5tYXJnaW4uYm90dG9tfSlgKVxuICAgICAgLmFwcGVuZCgndGV4dCcpXG4gICAgICAuc3R5bGUoJ2ZvbnQtc2l6ZScsICcxMnB4JylcbiAgICAgIC5hdHRyKCdjbGFzcycsICdsZWdlbmQnKVxuICAgICAgLmF0dHIoJ2R4JywgJzEuNWVtJylcbiAgICAgIC5hdHRyKCdkeScsICcxZW0nKVxuICAgICAgLnRleHQoYHggLSAke2NvbmZpZy54QXhpc1RpdGxlfWApO1xuICB9XG5cbiAgaWYgKGNvbmZpZy5kaXNwbGF5QXhpc0xhYmVscyAmJiBjb25maWcueUF4aXNUaXRsZSAhPT0gJycpIHtcbiAgICBnLmFwcGVuZCgnZycpXG4gICAgICAuYXR0cigndHJhbnNmb3JtJywgYHRyYW5zbGF0ZSgwLCAke2NvbmZpZy5oZWlnaHQgKyBjb25maWcubWFyZ2luLmJvdHRvbX0pYClcbiAgICAgIC5hcHBlbmQoJ3RleHQnKVxuICAgICAgLnN0eWxlKCdmb250LXNpemUnLCAnMTJweCcpXG4gICAgICAuYXR0cignY2xhc3MnLCAnbGVnZW5kJylcbiAgICAgIC5hdHRyKCdkeCcsICcxLjVlbScpXG4gICAgICAuYXR0cignZHknLCAnMi41ZW0nKVxuICAgICAgLnRleHQoYHkgLSAke2NvbmZpZy55QXhpc1RpdGxlfWApO1xuICB9XG5cbiAgaWYgKGNvbmZpZy5jaGFydFRpdGxlICE9PSAnJykge1xuICAgIGcuYXBwZW5kKCdnJylcbiAgICAgIC5hdHRyKCd0cmFuc2Zvcm0nLCBgdHJhbnNsYXRlKDAsIDApYClcbiAgICAgIC5hcHBlbmQoJ3RleHQnKVxuICAgICAgLnN0eWxlKCdmb250LXNpemUnLCAnMTJweCcpXG4gICAgICAuYXR0cignY2xhc3MnLCAnbGVnZW5kJylcbiAgICAgIC5hdHRyKCdkeCcsICcxLjVlbScpXG4gICAgICAuYXR0cignZHknLCAnLTJlbScpXG4gICAgICAudGV4dChjb25maWcuY2hhcnRUaXRsZSk7XG4gIH1cbn07XG5cbi8qKlxuICogQ3JlYXRlcyB0aGUgeCBheGlzLlxuICogQHBhcmFtIGcgdGhlIHN2ZyBnIGVsZW1lbnRcbiAqIEBwYXJhbSB4IHRoZSB4IGF4aXMgc2NhbGVcbiAqIEBwYXJhbSBjb25maWcgdGhlIGNoYXJ0IGNvbmZpZ3VyYXRpb25cbiAqL1xuY29uc3QgY3JlYXRlQXhpc1ggPSAoXG4gIGc6IGQzLlNlbGVjdGlvbjxTVkdHRWxlbWVudCwgdW5rbm93biwgSFRNTEVsZW1lbnQsIHVua25vd24+LFxuICB4OiBkMy5TY2FsZVRpbWU8bnVtYmVyLCBudW1iZXI+LFxuICBjb25maWc6IElMaW5lQ2hhcnRPcHRpb25zLFxuKSA9PiB7XG4gIGNvbnN0IHhMYWJlbHMgPSBnXG4gICAgLmFwcGVuZCgnZycpXG4gICAgLmF0dHIoJ3RyYW5zZm9ybScsIGB0cmFuc2xhdGUoMCwgJHtjb25maWcuaGVpZ2h0fSlgKVxuICAgIC5jYWxsKFxuICAgICAgZDNcbiAgICAgICAgLmF4aXNCb3R0b20oeClcbiAgICAgICAgLnRpY2tzKGNvbmZpZy50aWNrcy54KVxuICAgICAgICAudGlja0Zvcm1hdChkID0+IHtcbiAgICAgICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoZC52YWx1ZU9mKCkpO1xuICAgICAgICAgIGNvbnN0IGZvcm1hdHRpbmdPZmZzZXQgPSAxMDtcbiAgICAgICAgICBjb25zdCBkYXkgPSBkYXRlLmdldERhdGUoKTtcbiAgICAgICAgICBjb25zdCBkZCA9IGRheSA8IGZvcm1hdHRpbmdPZmZzZXQgPyBgMCR7ZGF5fWAgOiBkYXk7XG4gICAgICAgICAgY29uc3QgbW9udGggPSBkYXRlLmdldE1vbnRoKCkgKyAxO1xuICAgICAgICAgIGNvbnN0IG1tID0gbW9udGggPCBmb3JtYXR0aW5nT2Zmc2V0ID8gYDAke21vbnRofWAgOiBtb250aDtcbiAgICAgICAgICBjb25zdCB5ZWFyID0gZGF0ZS5nZXRGdWxsWWVhcigpLnRvU3RyaW5nKCk7XG4gICAgICAgICAgY29uc3QgeXkgPSB5ZWFyLnNsaWNlKDIpO1xuICAgICAgICAgIGNvbnN0IGhvdXJzID0gZGF0ZS5nZXRIb3VycygpO1xuICAgICAgICAgIGNvbnN0IGhvdXIgPSBob3VycyA8IGZvcm1hdHRpbmdPZmZzZXQgPyBgMCR7aG91cnN9YCA6IGhvdXJzO1xuICAgICAgICAgIGNvbnN0IG1pbnV0ZXMgPSBkYXRlLmdldE1pbnV0ZXMoKTtcbiAgICAgICAgICBjb25zdCBtaW51dGUgPSBtaW51dGVzIDwgZm9ybWF0dGluZ09mZnNldCA/IGAwJHttaW51dGVzfWAgOiBtaW51dGVzO1xuICAgICAgICAgIHJldHVybiBgJHtkZH0vJHttbX0vJHt5eX0gJHtob3VyfToke21pbnV0ZX1gO1xuICAgICAgICB9KSxcbiAgICApXG4gICAgLmFwcGVuZCgndGV4dCcpO1xuXG4gIGcuc2VsZWN0QWxsKCd0ZXh0JykuY2FsbCh3cmFwU3ZnVGV4dCwgY29uZmlnLmxhYmVsVGV4dFdyYXBXaWR0aCk7XG5cbiAgaWYgKGNvbmZpZy5kaXNwbGF5QXhpc0xhYmVscykge1xuICAgIHhMYWJlbHMuYXR0cigndHJhbnNmb3JtJywgYHRyYW5zbGF0ZSgke2NvbmZpZy53aWR0aH0sIDApYCkuYXR0cignY2xhc3MnLCAnbGVnZW5kJykuYXR0cignZHgnLCAnMS41ZW0nKS5hdHRyKCdkeScsICcwLjdlbScpLnRleHQoJ3gnKTtcbiAgfVxufTtcblxuLyoqXG4gKiBDcmVhdGVzIHRoZSB5IGF4aXMuXG4gKiBAcGFyYW0gZyB0aGUgc3ZnIGcgZWxlbWVudFxuICogQHBhcmFtIHkgdGhlIHkgYXhpcyBzY2FsZVxuICogQHBhcmFtIGNvbmZpZyB0aGUgY2hhcnQgY29uZmlndXJhdGlvblxuICovXG5jb25zdCBjcmVhdGVBeGlzWSA9IChcbiAgZzogZDMuU2VsZWN0aW9uPFNWR0dFbGVtZW50LCB1bmtub3duLCBIVE1MRWxlbWVudCwgdW5rbm93bj4sXG4gIHk6IGQzLlNjYWxlTGluZWFyPG51bWJlciwgbnVtYmVyPixcbiAgY29uZmlnOiBJTGluZUNoYXJ0T3B0aW9ucyxcbikgPT4ge1xuICBjb25zdCB5TGFiZWxzID0gZ1xuICAgIC5hcHBlbmQoJ2cnKVxuICAgIC5jYWxsKFxuICAgICAgZDNcbiAgICAgICAgLmF4aXNMZWZ0KHkpXG4gICAgICAgIC50aWNrcyhjb25maWcudGlja3MueSlcbiAgICAgICAgLnRpY2tGb3JtYXQoZCA9PiBgJHtkfWApLFxuICAgIClcbiAgICAuYXBwZW5kKCd0ZXh0Jyk7XG5cbiAgaWYgKGNvbmZpZy5kaXNwbGF5QXhpc0xhYmVscykge1xuICAgIHlMYWJlbHMuYXR0cignY2xhc3MnLCAnbGVnZW5kJykuYXR0cignZHknLCAnLTEuNWVtJykuYXR0cignY2xhc3MnLCAnbGVnZW5kJykudGV4dCgneScpO1xuICB9XG59O1xuXG4vKipcbiAqIFRoZSBtb3VzZSBvdmVyIGV2ZW50IGhhbmRsZXIuXG4gKiBAcGFyYW0gc2VsZiBhbiBzdmcgY2lyY2xlIGVsZW1lbnRcbiAqIEBwYXJhbSBkIHRoZSBjaGFydCBkYXRhIG5vZGVcbiAqIEBwYXJhbSBnIHRoZSBzdmcgZyBlbGVtZW50XG4gKiBAcGFyYW0gY29uZmlnIHRoZSBjaGFydCBjb25maWd1cmF0aW9uXG4gKi9cbmNvbnN0IG9uTW91c2VPdmVyID0gKFxuICBzZWxmOiBTVkdDaXJjbGVFbGVtZW50LFxuICBkOiBJTGluZUNoYXJ0RGF0YU5vZGUsXG4gIGc6IGQzLlNlbGVjdGlvbjxTVkdHRWxlbWVudCwgdW5rbm93biwgSFRNTEVsZW1lbnQsIHVua25vd24+LFxuICBjb25maWc6IElMaW5lQ2hhcnRPcHRpb25zLFxuKSA9PiB7XG4gIGNvbnN0IGR1cmF0aW9uID0gNDAwO1xuICBkMy5zZWxlY3Qoc2VsZilcbiAgICAudHJhbnNpdGlvbigpXG4gICAgLmR1cmF0aW9uKGR1cmF0aW9uKVxuICAgIC5hdHRyKCdyJywgY29uZmlnLmRvdFJhZGl1cyAqIDIpO1xuXG4gIGNvbnN0IHRvb2x0aXBTaGlmdCA9IDQ7XG4gIGNvbnN0IHRvb2x0aXBEeSA9IC0xMDtcbiAgZy5hcHBlbmQoJ3RleHQnKVxuICAgIC5hdHRyKCdjbGFzcycsICd2YWwnKVxuICAgIC5zdHlsZSgnZm9udC1zaXplJywgJzExcHgnKVxuICAgIC5hdHRyKCdkeCcsICgpID0+IChjb25maWcud2lkdGggLSBjb25maWcubWFyZ2luLmxlZnQgLSBjb25maWcubWFyZ2luLnJpZ2h0KSAvIHRvb2x0aXBTaGlmdClcbiAgICAuYXR0cignZHknLCAoKSA9PiB0b29sdGlwRHkpXG4gICAgLnRleHQoKCkgPT4gYCR7ZC52YWx1ZX0gKCR7bmV3IERhdGUoZC50aW1lc3RhbXApLnRvVVRDU3RyaW5nKCl9KWApO1xufTtcblxuLyoqXG4gKiBUaGUgbW91c2Ugb3V0IGV2ZW50IGhhbmRsZXIuXG4gKiBAcGFyYW0gc2VsZiBhbiBzdmcgY2lyY2xlIGVsZW1lbnRcbiAqIEBwYXJhbSBjb25maWcgdGhlIGNoYXJ0IGNvbmZpZ3VyYXRpb25cbiAqL1xuY29uc3Qgb25Nb3VzZU91dCA9IChzZWxmOiBTVkdDaXJjbGVFbGVtZW50LCBjb25maWc6IElMaW5lQ2hhcnRPcHRpb25zKSA9PiB7XG4gIGNvbnN0IGR1cmF0aW9uID0gNDAwO1xuICBkMy5zZWxlY3Qoc2VsZikuYXR0cignY2xhc3MnLCAnZG90Jyk7XG4gIGQzLnNlbGVjdChzZWxmKS50cmFuc2l0aW9uKCkuZHVyYXRpb24oZHVyYXRpb24pLmF0dHIoJ3InLCBjb25maWcuZG90UmFkaXVzKTtcblxuICBkMy5zZWxlY3RBbGwoJy52YWwnKS5yZW1vdmUoKTtcbn07XG5cbi8qKlxuICogRHJhd3MgdGhlIGNoYXJ0IGxpbmVzLCBkb3RzLCBhbmQgc2V0cyB0aGUgbW91c2UgcG9pbnRlciBldmVudHMuXG4gKiBAcGFyYW0gZyB0aGUgc3ZnIGcgZWxlbWVudFxuICogQHBhcmFtIHggdGhlIHggYXhpcyBzY2FsZVxuICogQHBhcmFtIHkgdGhlIHkgYXhpcyBzY2FsZVxuICogQHBhcmFtIGNvbmZpZyB0aGUgY2hhcnQgY29uZmlndXJhdGlvblxuICogQHBhcmFtIGRhdGEgdGhlIGNoYXJ0IGRhdGFcbiAqL1xuY29uc3QgZHJhd0xpbmVzRG90c0FuZFNldFBvaW50ZXJFdmVudHMgPSAoXG4gIGc6IGQzLlNlbGVjdGlvbjxTVkdHRWxlbWVudCwgdW5rbm93biwgSFRNTEVsZW1lbnQsIHVua25vd24+LFxuICB4OiBkMy5TY2FsZVRpbWU8bnVtYmVyLCBudW1iZXI+LFxuICB5OiBkMy5TY2FsZUxpbmVhcjxudW1iZXIsIG51bWJlcj4sXG4gIGNvbmZpZzogSUxpbmVDaGFydE9wdGlvbnMsXG4gIGRhdGE6IFRMaW5lQ2hhcnREYXRhLFxuKSA9PiB7XG4gIGNvbnN0IGxpbmUgPSBkM1xuICAgIC5saW5lPElMaW5lQ2hhcnREYXRhTm9kZT4oKVxuICAgIC54KGQgPT4geChkLnRpbWVzdGFtcCkpXG4gICAgLnkoZCA9PiB5KGQudmFsdWUpKVxuICAgIC5jdXJ2ZShkMy5jdXJ2ZU1vbm90b25lWCk7XG5cbiAgZy5hcHBlbmQoJ3BhdGgnKS5hdHRyKCdpZCcsICdsaW5lJykuc3R5bGUoJ2ZpbGwnLCAnbm9uZScpLnN0eWxlKCdzdHJva2UnLCAncmVkJykuc3R5bGUoJ3N0cm9rZS13aWR0aCcsICcycHgnKS5hdHRyKCdkJywgbGluZShkYXRhKSk7XG5cbiAgZy5zZWxlY3RBbGwoJy5kb3QnKVxuICAgIC5kYXRhKGRhdGEpXG4gICAgLmVudGVyKClcbiAgICAuYXBwZW5kKCdjaXJjbGUnKVxuICAgIC5hdHRyKCdjbGFzcycsICdkb3QnKVxuICAgIC5zdHlsZSgncG9pbnRlci1ldmVudHMnLCAnYWxsJylcbiAgICAuc3R5bGUoJ2ZpbGwnLCAoZCwgaSkgPT4gY29uZmlnLmNvbG9yKGkudG9TdHJpbmcoKSkpXG4gICAgLm9uKCdtb3VzZW92ZXInLCBmdW5jdGlvbiAodGhpcywgZXZlbnQsIGQpIHtcbiAgICAgIHJldHVybiBvbk1vdXNlT3Zlcih0aGlzLCBkLCBnLCBjb25maWcpO1xuICAgIH0pXG4gICAgLm9uKCdtb3VzZW91dCcsIGZ1bmN0aW9uICh0aGlzKSB7XG4gICAgICByZXR1cm4gb25Nb3VzZU91dCh0aGlzLCBjb25maWcpO1xuICAgIH0pXG4gICAgLmF0dHIoJ2N4JywgZnVuY3Rpb24gKHRoaXMsIGQpIHtcbiAgICAgIHJldHVybiB4KGQudGltZXN0YW1wKTtcbiAgICB9KVxuICAgIC5hdHRyKCdjeScsIGZ1bmN0aW9uICh0aGlzLCBkKSB7XG4gICAgICByZXR1cm4geShkLnZhbHVlKTtcbiAgICB9KVxuICAgIC5hdHRyKCdyJywgMClcbiAgICAudHJhbnNpdGlvbigpXG4gICAgLmVhc2UoZDMuZWFzZUxpbmVhcilcbiAgICAuZHVyYXRpb24oY29uZmlnLnRyYW5zaXRpb25EdXJhdGlvbilcbiAgICAuZGVsYXkoKGQsIGkpID0+IHtcbiAgICAgIGNvbnN0IG11bHRpcGxpZXIgPSA1MDtcbiAgICAgIHJldHVybiBpICogbXVsdGlwbGllcjtcbiAgICB9KVxuICAgIC5hdHRyKCdyJywgY29uZmlnLmRvdFJhZGl1cyk7XG59O1xuXG4vKipcbiAqIERyYXdzIHRoZSBsaW5lIGNoYXJ0LlxuICogQHBhcmFtIGNvbnRhaW5lciB0aGUgY2hhcnQgY29udGFpbmVyXG4gKiBAcGFyYW0gZGF0YSB0aGUgY2hhcnQgZGF0YVxuICogQHBhcmFtIG9wdGlvbnMgdGhlIGNoYXJ0IG9wdGlvbnNcbiAqIEByZXR1cm5zIHRoZSBjaGFydCBjb25maWd1cmF0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBkcmF3TGluZUNoYXJ0ID0gKGNvbnRhaW5lcjogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD4sIGRhdGE6IFRMaW5lQ2hhcnREYXRhLCBvcHRpb25zPzogUGFydGlhbDxJTGluZUNoYXJ0T3B0aW9ucz4pID0+IHtcbiAgY29uc3QgY29uZmlnOiBJTGluZUNoYXJ0T3B0aW9ucyA9IGdlbmVyYXRlQ29uZmlndXJhdGlvbjxJTGluZUNoYXJ0T3B0aW9ucz4oZGVmYXVsdExpbmVDaGFydENvbmZpZywgb3B0aW9ucywge30pO1xuXG4gIGNvbnN0IHsgZyB9ID0gY3JlYXRlQ29udGFpbmVyKGNvbnRhaW5lciwgY29uZmlnKTtcblxuICBjb25zdCB4ID0gZDMuc2NhbGVUaW1lKFswLCBjb25maWcud2lkdGhdKS5kb21haW4oW01hdGgubWluKC4uLmRhdGEubWFwKGQgPT4gZC50aW1lc3RhbXApKSwgTWF0aC5tYXgoLi4uZGF0YS5tYXAoZCA9PiBkLnRpbWVzdGFtcCkpXSk7XG4gIGNvbnN0IHkgPSBkMy5zY2FsZUxpbmVhcihbY29uZmlnLmhlaWdodCwgMF0pLmRvbWFpbihbMCwgZDMubWF4KGRhdGEsIGQgPT4gZC52YWx1ZSkgPz8gMV0pO1xuXG4gIGNyZWF0ZUF4aXNYKGcsIHgsIGNvbmZpZyk7XG5cbiAgY3JlYXRlQXhpc1koZywgeSwgY29uZmlnKTtcblxuICBjcmVhdGVMZWdlbmQoZywgY29uZmlnKTtcblxuICBkcmF3TGluZXNEb3RzQW5kU2V0UG9pbnRlckV2ZW50cyhnLCB4LCB5LCBjb25maWcsIGRhdGEpO1xuXG4gIHJldHVybiBjb25maWc7XG59O1xuIl19
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import * as d3 from 'd3';
|
|
2
|
+
import { generateConfiguration } from './configuration.util';
|
|
3
|
+
/**
|
|
4
|
+
* The pie chart default configuration.
|
|
5
|
+
*/
|
|
6
|
+
export const defaultPieChartConfig = Object.freeze({
|
|
7
|
+
chartTitle: '',
|
|
8
|
+
width: 600,
|
|
9
|
+
height: 600,
|
|
10
|
+
margin: {
|
|
11
|
+
top: 20,
|
|
12
|
+
right: 20,
|
|
13
|
+
bottom: 20,
|
|
14
|
+
left: 20,
|
|
15
|
+
},
|
|
16
|
+
innerRadius: 0,
|
|
17
|
+
labelRadiusModifier: 50,
|
|
18
|
+
labelTextWrapWidth: 60,
|
|
19
|
+
color: d3.scaleOrdinal(d3.schemeCategory10),
|
|
20
|
+
});
|
|
21
|
+
/**
|
|
22
|
+
* Creates a container for the pie chart.
|
|
23
|
+
* @param container the chart container
|
|
24
|
+
* @param config the chart configuration
|
|
25
|
+
* @returns the object with the svg element and the g element
|
|
26
|
+
*/
|
|
27
|
+
const createContainer = (container, config) => {
|
|
28
|
+
const id = container.nativeElement.id ?? 'pie-0';
|
|
29
|
+
d3.select(`#${id}`).select('svg').remove();
|
|
30
|
+
const svg = d3
|
|
31
|
+
.select(`#${id}`)
|
|
32
|
+
.append('svg')
|
|
33
|
+
.attr('width', config.width + config.margin.left + config.margin.right)
|
|
34
|
+
.attr('height', config.height + config.margin.top + config.margin.bottom)
|
|
35
|
+
.attr('class', id);
|
|
36
|
+
const g = svg
|
|
37
|
+
.append('g')
|
|
38
|
+
.attr('transform', `translate(${config.width / 2 + config.margin.left},${config.height / 2 + config.margin.top})`);
|
|
39
|
+
return { svg, g };
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Draws the pie chart.
|
|
43
|
+
* @param container the chart container
|
|
44
|
+
* @param data the chart data
|
|
45
|
+
* @param options the chart options
|
|
46
|
+
* @returns the chart configuration
|
|
47
|
+
*/
|
|
48
|
+
export const drawPieChart = (container, data, options) => {
|
|
49
|
+
const config = generateConfiguration(defaultPieChartConfig, options, {});
|
|
50
|
+
const { g } = createContainer(container, config);
|
|
51
|
+
const pie = d3.pie().value(datum => datum.y);
|
|
52
|
+
const radius = Math.min(config.width, config.height) / 2;
|
|
53
|
+
const arc = d3.arc().innerRadius(config.innerRadius).outerRadius(radius);
|
|
54
|
+
const arcs = g
|
|
55
|
+
.selectAll('arc')
|
|
56
|
+
.data(pie(data))
|
|
57
|
+
.enter()
|
|
58
|
+
.append('g')
|
|
59
|
+
.attr('class', 'arc')
|
|
60
|
+
.on('mouseover', function (event, d) {
|
|
61
|
+
d3.select('#tooltip')
|
|
62
|
+
.style('left', `${event.pageX}px`)
|
|
63
|
+
.style('top', `${event.pageY}px`)
|
|
64
|
+
.style('opacity', 1)
|
|
65
|
+
.select('#value')
|
|
66
|
+
.text(d.value);
|
|
67
|
+
})
|
|
68
|
+
.on('mouseout', function (event, d) {
|
|
69
|
+
d3.select('#tooltip').style('opacity', 0);
|
|
70
|
+
});
|
|
71
|
+
const label = d3
|
|
72
|
+
.arc()
|
|
73
|
+
.innerRadius(radius)
|
|
74
|
+
.outerRadius(radius + config.labelRadiusModifier);
|
|
75
|
+
arcs
|
|
76
|
+
.append('path')
|
|
77
|
+
.attr('fill', (d, i) => config.color(i.toString()))
|
|
78
|
+
.attr('d', arc);
|
|
79
|
+
const textDy = 5;
|
|
80
|
+
arcs
|
|
81
|
+
.append('text')
|
|
82
|
+
.attr('class', 'legend')
|
|
83
|
+
.attr('text-anchor', 'middle')
|
|
84
|
+
.attr('dy', textDy)
|
|
85
|
+
.attr('transform', d => `translate(${label.centroid(d)})`)
|
|
86
|
+
.text(d => d.data.y);
|
|
87
|
+
return config;
|
|
88
|
+
};
|
|
89
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGllLWNoYXJ0LnV0aWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL2NsaWVudC1kMy1jaGFydHMvc3JjL2xpYi91dGlsL3BpZS1jaGFydC51dGlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBR3pCLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRTdEOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQXFCLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDbkUsVUFBVSxFQUFFLEVBQUU7SUFDZCxLQUFLLEVBQUUsR0FBRztJQUNWLE1BQU0sRUFBRSxHQUFHO0lBQ1gsTUFBTSxFQUFFO1FBQ04sR0FBRyxFQUFFLEVBQUU7UUFDUCxLQUFLLEVBQUUsRUFBRTtRQUNULE1BQU0sRUFBRSxFQUFFO1FBQ1YsSUFBSSxFQUFFLEVBQUU7S0FDVDtJQUNELFdBQVcsRUFBRSxDQUFDO0lBQ2QsbUJBQW1CLEVBQUUsRUFBRTtJQUN2QixrQkFBa0IsRUFBRSxFQUFFO0lBQ3RCLEtBQUssRUFBRSxFQUFFLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQztDQUM1QyxDQUFDLENBQUM7QUFFSDs7Ozs7R0FLRztBQUNILE1BQU0sZUFBZSxHQUFHLENBQUMsU0FBcUMsRUFBRSxNQUF3QixFQUFFLEVBQUU7SUFDMUYsTUFBTSxFQUFFLEdBQUcsU0FBUyxDQUFDLGFBQWEsQ0FBQyxFQUFFLElBQUksT0FBTyxDQUFDO0lBRWpELEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUMzQyxNQUFNLEdBQUcsR0FBRyxFQUFFO1NBQ1gsTUFBTSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7U0FDaEIsTUFBTSxD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Q0FBQyxDQUFDO0lBRXBELElBQUk7U0FDRCxNQUFNLENBQUMsTUFBTSxDQUFDO1NBQ2QsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7U0FDbEQsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUVsQixNQUFNLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDakIsSUFBSTtTQUNELE1BQU0sQ0FBQyxNQUFNLENBQUM7U0FDZCxJQUFJLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQztTQUN2QixJQUFJLENBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQztTQUM3QixJQUFJLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQztTQUNsQixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsYUFBYSxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7U0FDekQsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUV2QixPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBFbGVtZW50UmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgKiBhcyBkMyBmcm9tICdkMyc7XG5cbmltcG9ydCB7IElQaWVDaGFydERhdGFOb2RlLCBJUGllQ2hhcnRPcHRpb25zIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9waWUtY2hhcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IGdlbmVyYXRlQ29uZmlndXJhdGlvbiB9IGZyb20gJy4vY29uZmlndXJhdGlvbi51dGlsJztcblxuLyoqXG4gKiBUaGUgcGllIGNoYXJ0IGRlZmF1bHQgY29uZmlndXJhdGlvbi5cbiAqL1xuZXhwb3J0IGNvbnN0IGRlZmF1bHRQaWVDaGFydENvbmZpZzogSVBpZUNoYXJ0T3B0aW9ucyA9IE9iamVjdC5mcmVlemUoe1xuICBjaGFydFRpdGxlOiAnJyxcbiAgd2lkdGg6IDYwMCxcbiAgaGVpZ2h0OiA2MDAsXG4gIG1hcmdpbjoge1xuICAgIHRvcDogMjAsXG4gICAgcmlnaHQ6IDIwLFxuICAgIGJvdHRvbTogMjAsXG4gICAgbGVmdDogMjAsXG4gIH0sXG4gIGlubmVyUmFkaXVzOiAwLCAvLyBpbmNyZWFzZSBpbm5lciByYWRpdXMgdG8gcmVuZGVyIGEgZG9udXQgY2hhcnRcbiAgbGFiZWxSYWRpdXNNb2RpZmllcjogNTAsXG4gIGxhYmVsVGV4dFdyYXBXaWR0aDogNjAsXG4gIGNvbG9yOiBkMy5zY2FsZU9yZGluYWwoZDMuc2NoZW1lQ2F0ZWdvcnkxMCksXG59KTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY29udGFpbmVyIGZvciB0aGUgcGllIGNoYXJ0LlxuICogQHBhcmFtIGNvbnRhaW5lciB0aGUgY2hhcnQgY29udGFpbmVyXG4gKiBAcGFyYW0gY29uZmlnIHRoZSBjaGFydCBjb25maWd1cmF0aW9uXG4gKiBAcmV0dXJucyB0aGUgb2JqZWN0IHdpdGggdGhlIHN2ZyBlbGVtZW50IGFuZCB0aGUgZyBlbGVtZW50XG4gKi9cbmNvbnN0IGNyZWF0ZUNvbnRhaW5lciA9IChjb250YWluZXI6IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+LCBjb25maWc6IElQaWVDaGFydE9wdGlvbnMpID0+IHtcbiAgY29uc3QgaWQgPSBjb250YWluZXIubmF0aXZlRWxlbWVudC5pZCA/PyAncGllLTAnO1xuXG4gIGQzLnNlbGVjdChgIyR7aWR9YCkuc2VsZWN0KCdzdmcnKS5yZW1vdmUoKTtcbiAgY29uc3Qgc3ZnID0gZDNcbiAgICAuc2VsZWN0KGAjJHtpZH1gKVxuICAgIC5hcHBlbmQoJ3N2ZycpXG4gICAgLmF0dHIoJ3dpZHRoJywgY29uZmlnLndpZHRoICsgY29uZmlnLm1hcmdpbi5sZWZ0ICsgY29uZmlnLm1hcmdpbi5yaWdodClcbiAgICAuYXR0cignaGVpZ2h0JywgY29uZmlnLmhlaWdodCArIGNvbmZpZy5tYXJnaW4udG9wICsgY29uZmlnLm1hcmdpbi5ib3R0b20pXG4gICAgLmF0dHIoJ2NsYXNzJywgaWQpO1xuICBjb25zdCBnID0gc3ZnXG4gICAgLmFwcGVuZCgnZycpXG4gICAgLmF0dHIoJ3RyYW5zZm9ybScsIGB0cmFuc2xhdGUoJHtjb25maWcud2lkdGggLyAyICsgY29uZmlnLm1hcmdpbi5sZWZ0fSwke2NvbmZpZy5oZWlnaHQgLyAyICsgY29uZmlnLm1hcmdpbi50b3B9KWApO1xuXG4gIHJldHVybiB7IHN2ZywgZyB9O1xufTtcblxuLyoqXG4gKiBEcmF3cyB0aGUgcGllIGNoYXJ0LlxuICogQHBhcmFtIGNvbnRhaW5lciB0aGUgY2hhcnQgY29udGFpbmVyXG4gKiBAcGFyYW0gZGF0YSB0aGUgY2hhcnQgZGF0YVxuICogQHBhcmFtIG9wdGlvbnMgdGhlIGNoYXJ0IG9wdGlvbnNcbiAqIEByZXR1cm5zIHRoZSBjaGFydCBjb25maWd1cmF0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBkcmF3UGllQ2hhcnQgPSAoY29udGFpbmVyOiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PiwgZGF0YTogSVBpZUNoYXJ0RGF0YU5vZGVbXSwgb3B0aW9ucz86IFBhcnRpYWw8SVBpZUNoYXJ0T3B0aW9ucz4pID0+IHtcbiAgY29uc3QgY29uZmlnOiBJUGllQ2hhcnRPcHRpb25zID0gZ2VuZXJhdGVDb25maWd1cmF0aW9uPElQaWVDaGFydE9wdGlvbnM+KGRlZmF1bHRQaWVDaGFydENvbmZpZywgb3B0aW9ucywge30pO1xuXG4gIGNvbnN0IHsgZyB9ID0gY3JlYXRlQ29udGFpbmVyKGNvbnRhaW5lciwgY29uZmlnKTtcblxuICBjb25zdCBwaWUgPSBkMy5waWU8SVBpZUNoYXJ0RGF0YU5vZGU+KCkudmFsdWUoZGF0dW0gPT4gZGF0dW0ueSk7XG5cbiAgY29uc3QgcmFkaXVzID0gTWF0aC5taW4oY29uZmlnLndpZHRoLCBjb25maWcuaGVpZ2h0KSAvIDI7XG5cbiAgY29uc3QgYXJjID0gZDMuYXJjPGQzLlBpZUFyY0RhdHVtPElQaWVDaGFydERhdGFOb2RlPj4oKS5pbm5lclJhZGl1cyhjb25maWcuaW5uZXJSYWRpdXMpLm91dGVyUmFkaXVzKHJhZGl1cyk7XG5cbiAgY29uc3QgYXJjcyA9IGdcbiAgICAuc2VsZWN0QWxsKCdhcmMnKVxuICAgIC5kYXRhKHBpZShkYXRhKSlcbiAgICAuZW50ZXIoKVxuICAgIC5hcHBlbmQoJ2cnKVxuICAgIC5hdHRyKCdjbGFzcycsICdhcmMnKVxuICAgIC5vbignbW91c2VvdmVyJywgZnVuY3Rpb24gKHRoaXMsIGV2ZW50OiBNb3VzZUV2ZW50LCBkKSB7XG4gICAgICBkMy5zZWxlY3QoJyN0b29sdGlwJylcbiAgICAgICAgLnN0eWxlKCdsZWZ0JywgYCR7ZXZlbnQucGFnZVh9cHhgKVxuICAgICAgICAuc3R5bGUoJ3RvcCcsIGAke2V2ZW50LnBhZ2VZfXB4YClcbiAgICAgICAgLnN0eWxlKCdvcGFjaXR5JywgMSlcbiAgICAgICAgLnNlbGVjdCgnI3ZhbHVlJylcbiAgICAgICAgLnRleHQoZC52YWx1ZSk7XG4gICAgfSlcbiAgICAub24oJ21vdXNlb3V0JywgZnVuY3Rpb24gKHRoaXMsIGV2ZW50LCBkKSB7XG4gICAgICBkMy5zZWxlY3QoJyN0b29sdGlwJykuc3R5bGUoJ29wYWNpdHknLCAwKTtcbiAgICB9KTtcblxuICBjb25zdCBsYWJlbCA9IGQzXG4gICAgLmFyYzxkMy5QaWVBcmNEYXR1bTxJUGllQ2hhcnREYXRhTm9kZT4+KClcbiAgICAuaW5uZXJSYWRpdXMocmFkaXVzKVxuICAgIC5vdXRlclJhZGl1cyhyYWRpdXMgKyBjb25maWcubGFiZWxSYWRpdXNNb2RpZmllcik7XG5cbiAgYXJjc1xuICAgIC5hcHBlbmQoJ3BhdGgnKVxuICAgIC5hdHRyKCdmaWxsJywgKGQsIGkpID0+IGNvbmZpZy5jb2xvcihpLnRvU3RyaW5nKCkpKVxuICAgIC5hdHRyKCdkJywgYXJjKTtcblxuICBjb25zdCB0ZXh0RHkgPSA1O1xuICBhcmNzXG4gICAgLmFwcGVuZCgndGV4dCcpXG4gICAgLmF0dHIoJ2NsYXNzJywgJ2xlZ2VuZCcpXG4gICAgLmF0dHIoJ3RleHQtYW5jaG9yJywgJ21pZGRsZScpXG4gICAgLmF0dHIoJ2R5JywgdGV4dER5KVxuICAgIC5hdHRyKCd0cmFuc2Zvcm0nLCBkID0+IGB0cmFuc2xhdGUoJHtsYWJlbC5jZW50cm9pZChkKX0pYClcbiAgICAudGV4dChkID0+IGQuZGF0YS55KTtcblxuICByZXR1cm4gY29uZmlnO1xufTtcbiJdfQ==
|