ngx-trend 6.1.0 → 8.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/README.md +8 -6
- package/esm2020/helpers/DOM.helpers.mjs +33 -0
- package/esm2020/helpers/math.helpers.mjs +68 -0
- package/esm2020/helpers/misc.helpers.mjs +2 -0
- package/{esm2015/ngx-trend.js → esm2020/ngx-trend.mjs} +1 -1
- package/{esm2015/public_api.js → esm2020/public_api.mjs} +1 -1
- package/esm2020/trend/trend.component.mjs +255 -0
- package/esm2020/trend/trend.helpers.mjs +28 -0
- package/esm2020/trend/trend.module.mjs +18 -0
- package/fesm2015/{ngx-trend.js → ngx-trend.mjs} +148 -60
- package/fesm2015/ngx-trend.mjs.map +1 -0
- package/fesm2020/ngx-trend.mjs +402 -0
- package/fesm2020/ngx-trend.mjs.map +1 -0
- package/ngx-trend.d.ts +1 -0
- package/package.json +23 -11
- package/trend/trend.component.d.ts +3 -0
- package/trend/trend.module.d.ts +6 -0
- package/bundles/ngx-trend.umd.js +0 -593
- package/bundles/ngx-trend.umd.js.map +0 -1
- package/bundles/ngx-trend.umd.min.js +0 -16
- package/bundles/ngx-trend.umd.min.js.map +0 -1
- package/esm2015/helpers/DOM.helpers.js +0 -33
- package/esm2015/helpers/math.helpers.js +0 -68
- package/esm2015/helpers/misc.helpers.js +0 -2
- package/esm2015/trend/trend.component.js +0 -171
- package/esm2015/trend/trend.helpers.js +0 -28
- package/esm2015/trend/trend.module.js +0 -13
- package/fesm2015/ngx-trend.js.map +0 -1
- package/ngx-trend.metadata.json +0 -1
package/README.md
CHANGED
@@ -40,12 +40,14 @@ npm install ngx-trend
|
|
40
40
|
|
41
41
|
Latest version available for each version of Angular
|
42
42
|
|
43
|
-
| ngx-trend | Angular
|
44
|
-
| --------- |
|
45
|
-
| 3.4.3 | 6.x 7.x
|
46
|
-
| 4.0.2 | 8.x
|
47
|
-
| 5.0.1 | 9.x
|
48
|
-
|
|
43
|
+
| ngx-trend | Angular |
|
44
|
+
| --------- | --------- |
|
45
|
+
| 3.4.3 | 6.x 7.x |
|
46
|
+
| 4.0.2 | 8.x |
|
47
|
+
| 5.0.1 | 9.x |
|
48
|
+
| 6.1.1 | 10.x 11.x |
|
49
|
+
| 7.0.0 | 12.x |
|
50
|
+
| current | >= 13.x |
|
49
51
|
|
50
52
|
### Quickstart
|
51
53
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import { checkForCollinearPoints, getDistanceBetween, moveTo, } from './math.helpers';
|
2
|
+
export const buildLinearPath = (data) => data.reduce((path, point, index) => {
|
3
|
+
// The very first instruction needs to be a "move".
|
4
|
+
// The rest will be a "line".
|
5
|
+
const isFirstInstruction = index === 0;
|
6
|
+
const instruction = isFirstInstruction ? 'M' : 'L';
|
7
|
+
return `${path}${instruction} ${point.x},${point.y}\n`;
|
8
|
+
}, '');
|
9
|
+
export function buildSmoothPath(data, radius) {
|
10
|
+
const [firstPoint, ...otherPoints] = data;
|
11
|
+
return otherPoints.reduce((path, point, index) => {
|
12
|
+
const next = otherPoints[index + 1];
|
13
|
+
const prev = otherPoints[index - 1] || firstPoint;
|
14
|
+
const isCollinear = next && checkForCollinearPoints(prev, point, next);
|
15
|
+
if (!next || isCollinear) {
|
16
|
+
// The very last line in the sequence can just be a regular line.
|
17
|
+
return `${path}\nL ${point.x},${point.y}`;
|
18
|
+
}
|
19
|
+
const distanceFromPrev = getDistanceBetween(prev, point);
|
20
|
+
const distanceFromNext = getDistanceBetween(next, point);
|
21
|
+
const threshold = Math.min(distanceFromPrev, distanceFromNext);
|
22
|
+
const isTooCloseForRadius = threshold / 2 < radius;
|
23
|
+
const radiusForPoint = isTooCloseForRadius ? threshold / 2 : radius;
|
24
|
+
const before = moveTo(prev, point, radiusForPoint);
|
25
|
+
const after = moveTo(next, point, radiusForPoint);
|
26
|
+
return [
|
27
|
+
path,
|
28
|
+
`L ${before.x},${before.y}`,
|
29
|
+
`S ${point.x},${point.y} ${after.x},${after.y}`,
|
30
|
+
].join('\n');
|
31
|
+
}, `M ${firstPoint.x},${firstPoint.y}`);
|
32
|
+
}
|
33
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRE9NLmhlbHBlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL2hlbHBlcnMvRE9NLmhlbHBlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixrQkFBa0IsRUFDbEIsTUFBTSxHQUVQLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEIsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUFHLENBQUMsSUFBYSxFQUFFLEVBQUUsQ0FDL0MsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUU7SUFDakMsbURBQW1EO0lBQ25ELDZCQUE2QjtJQUM3QixNQUFNLGtCQUFrQixHQUFHLEtBQUssS0FBSyxDQUFDLENBQUM7SUFDdkMsTUFBTSxXQUFXLEdBQUcsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO0lBRW5ELE9BQU8sR0FBRyxJQUFJLEdBQUcsV0FBVyxJQUFJLEtBQUssQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDO0FBQ3pELENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUVULE1BQU0sVUFBVSxlQUFlLENBQUMsSUFBYSxFQUFFLE1BQWM7SUFDM0QsTUFBTSxDQUFDLFVBQVUsRUFBRSxHQUFHLFdBQVcsQ0FBQyxHQUFHLElBQUksQ0FBQztJQUUxQyxPQUFPLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFO1FBQy9DLE1BQU0sSUFBSSxHQUFHLFdBQVcsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDcEMsTUFBTSxJQUFJLEdBQUcsV0FBVyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsSUFBSSxVQUFVLENBQUM7UUFFbEQsTUFBTSxXQUFXLEdBQUcsSUFBSSxJQUFJLHVCQUF1QixDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFdkUsSUFBSSxDQUFDLElBQUksSUFBSSxXQUFXLEVBQUU7WUFDeEIsaUVBQWlFO1lBQ2pFLE9BQU8sR0FBRyxJQUFJLE9BQU8sS0FBSyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7U0FDM0M7UUFFRCxNQUFNLGdCQUFnQixHQUFHLGtCQUFrQixDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN6RCxNQUFNLGdCQUFnQixHQUFHLGtCQUFrQixDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN6RCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLGdCQUFnQixFQUFFLGdCQUFnQixDQUFDLENBQUM7UUFFL0QsTUFBTSxtQkFBbUIsR0FBRyxTQUFTLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQztRQUVuRCxNQUFNLGNBQWMsR0FBRyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO1FBRXBFLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBQ25ELE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBRWxELE9BQU87WUFDTCxJQUFJO1lBQ0osS0FBSyxNQUFNLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxDQUFDLEVBQUU7WUFDM0IsS0FBSyxLQUFLLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUMsQ0FBQyxFQUFFO1NBQ2hELENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2YsQ0FBQyxFQUFFLEtBQUssVUFBVSxDQUFDLENBQUMsSUFBSSxVQUFVLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUMxQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgY2hlY2tGb3JDb2xsaW5lYXJQb2ludHMsXG4gIGdldERpc3RhbmNlQmV0d2VlbixcbiAgbW92ZVRvLFxuICBQb2ludCxcbn0gZnJvbSAnLi9tYXRoLmhlbHBlcnMnO1xuXG5leHBvcnQgY29uc3QgYnVpbGRMaW5lYXJQYXRoID0gKGRhdGE6IFBvaW50W10pID0+XG4gIGRhdGEucmVkdWNlKChwYXRoLCBwb2ludCwgaW5kZXgpID0+IHtcbiAgICAvLyBUaGUgdmVyeSBmaXJzdCBpbnN0cnVjdGlvbiBuZWVkcyB0byBiZSBhIFwibW92ZVwiLlxuICAgIC8vIFRoZSByZXN0IHdpbGwgYmUgYSBcImxpbmVcIi5cbiAgICBjb25zdCBpc0ZpcnN0SW5zdHJ1Y3Rpb24gPSBpbmRleCA9PT0gMDtcbiAgICBjb25zdCBpbnN0cnVjdGlvbiA9IGlzRmlyc3RJbnN0cnVjdGlvbiA/ICdNJyA6ICdMJztcblxuICAgIHJldHVybiBgJHtwYXRofSR7aW5zdHJ1Y3Rpb259ICR7cG9pbnQueH0sJHtwb2ludC55fVxcbmA7XG4gIH0sICcnKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkU21vb3RoUGF0aChkYXRhOiBQb2ludFtdLCByYWRpdXM6IG51bWJlcik6IHN0cmluZyB7XG4gIGNvbnN0IFtmaXJzdFBvaW50LCAuLi5vdGhlclBvaW50c10gPSBkYXRhO1xuXG4gIHJldHVybiBvdGhlclBvaW50cy5yZWR1Y2UoKHBhdGgsIHBvaW50LCBpbmRleCkgPT4ge1xuICAgIGNvbnN0IG5leHQgPSBvdGhlclBvaW50c1tpbmRleCArIDFdO1xuICAgIGNvbnN0IHByZXYgPSBvdGhlclBvaW50c1tpbmRleCAtIDFdIHx8IGZpcnN0UG9pbnQ7XG5cbiAgICBjb25zdCBpc0NvbGxpbmVhciA9IG5leHQgJiYgY2hlY2tGb3JDb2xsaW5lYXJQb2ludHMocHJldiwgcG9pbnQsIG5leHQpO1xuXG4gICAgaWYgKCFuZXh0IHx8IGlzQ29sbGluZWFyKSB7XG4gICAgICAvLyBUaGUgdmVyeSBsYXN0IGxpbmUgaW4gdGhlIHNlcXVlbmNlIGNhbiBqdXN0IGJlIGEgcmVndWxhciBsaW5lLlxuICAgICAgcmV0dXJuIGAke3BhdGh9XFxuTCAke3BvaW50Lnh9LCR7cG9pbnQueX1gO1xuICAgIH1cblxuICAgIGNvbnN0IGRpc3RhbmNlRnJvbVByZXYgPSBnZXREaXN0YW5jZUJldHdlZW4ocHJldiwgcG9pbnQpO1xuICAgIGNvbnN0IGRpc3RhbmNlRnJvbU5leHQgPSBnZXREaXN0YW5jZUJldHdlZW4obmV4dCwgcG9pbnQpO1xuICAgIGNvbnN0IHRocmVzaG9sZCA9IE1hdGgubWluKGRpc3RhbmNlRnJvbVByZXYsIGRpc3RhbmNlRnJvbU5leHQpO1xuXG4gICAgY29uc3QgaXNUb29DbG9zZUZvclJhZGl1cyA9IHRocmVzaG9sZCAvIDIgPCByYWRpdXM7XG5cbiAgICBjb25zdCByYWRpdXNGb3JQb2ludCA9IGlzVG9vQ2xvc2VGb3JSYWRpdXMgPyB0aHJlc2hvbGQgLyAyIDogcmFkaXVzO1xuXG4gICAgY29uc3QgYmVmb3JlID0gbW92ZVRvKHByZXYsIHBvaW50LCByYWRpdXNGb3JQb2ludCk7XG4gICAgY29uc3QgYWZ0ZXIgPSBtb3ZlVG8obmV4dCwgcG9pbnQsIHJhZGl1c0ZvclBvaW50KTtcblxuICAgIHJldHVybiBbXG4gICAgICBwYXRoLFxuICAgICAgYEwgJHtiZWZvcmUueH0sJHtiZWZvcmUueX1gLFxuICAgICAgYFMgJHtwb2ludC54fSwke3BvaW50Lnl9ICR7YWZ0ZXIueH0sJHthZnRlci55fWAsXG4gICAgXS5qb2luKCdcXG4nKTtcbiAgfSwgYE0gJHtmaXJzdFBvaW50Lnh9LCR7Zmlyc3RQb2ludC55fWApO1xufVxuIl19
|
@@ -0,0 +1,68 @@
|
|
1
|
+
/* eslint-disable no-restricted-properties */
|
2
|
+
/** normalize
|
3
|
+
* This lets us translate a value from one scale to another.
|
4
|
+
*
|
5
|
+
* @param value - Our initial value to translate
|
6
|
+
* @param min - the current minimum value possible
|
7
|
+
* @param max - the current maximum value possible
|
8
|
+
* @param scaleMin - the min value of the scale we're translating to
|
9
|
+
* @param scaleMax - the max value of the scale we're translating to
|
10
|
+
* @returns the value on its new scale
|
11
|
+
*/
|
12
|
+
export function normalize(value, min, max, scaleMin = 0, scaleMax = 1) {
|
13
|
+
// If the `min` and `max` are the same value, it means our dataset is flat.
|
14
|
+
// For now, let's assume that flat data should be aligned to the bottom.
|
15
|
+
if (min === max) {
|
16
|
+
return scaleMin;
|
17
|
+
}
|
18
|
+
return scaleMin + (value - min) * (scaleMax - scaleMin) / (max - min);
|
19
|
+
}
|
20
|
+
/** moveTo
|
21
|
+
* the coordinate that lies at a midpoint between 2 lines, based on the radius
|
22
|
+
*
|
23
|
+
* @param to - Our initial point
|
24
|
+
* @param to.x - The x value of our initial point
|
25
|
+
* @param to.y - The y value of our initial point
|
26
|
+
* @param from - Our final point
|
27
|
+
* @param from.x - The x value of our final point
|
28
|
+
* @param from.y - The y value of our final point
|
29
|
+
* @param radius - The distance away from the final point
|
30
|
+
* @returns an object holding the x/y coordinates of the midpoint.
|
31
|
+
*/
|
32
|
+
export function moveTo(to, from, radius) {
|
33
|
+
const length = Math.sqrt((to.x - from.x) * (to.x - from.x) + (to.y - from.y) * (to.y - from.y));
|
34
|
+
const unitVector = { x: (to.x - from.x) / length, y: (to.y - from.y) / length };
|
35
|
+
return {
|
36
|
+
x: from.x + unitVector.x * radius,
|
37
|
+
y: from.y + unitVector.y * radius,
|
38
|
+
};
|
39
|
+
}
|
40
|
+
/** getDistanceBetween
|
41
|
+
* Simple formula derived from pythagoras to calculate the distance between
|
42
|
+
* 2 points on a plane.
|
43
|
+
*
|
44
|
+
* @param p1 - Our initial point
|
45
|
+
* @param p1.x - The x value of our initial point
|
46
|
+
* @param p1.y - The y value of our initial point
|
47
|
+
* @param p2 - Our final point
|
48
|
+
* @param p2.x - The x value of our final point
|
49
|
+
* @param p2.y - The y value of our final point
|
50
|
+
* @returns the distance between the points.
|
51
|
+
*/
|
52
|
+
export const getDistanceBetween = (p1, p2) => Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
|
53
|
+
/** checkForCollinearPoints
|
54
|
+
* Figure out if the midpoint fits perfectly on a line between the two others.
|
55
|
+
*
|
56
|
+
* @param p1 - Our initial point
|
57
|
+
* @param p1.x - The x value of our initial point
|
58
|
+
* @param p1.y - The y value of our initial point
|
59
|
+
* @param p2 - Our mid-point
|
60
|
+
* @param p2.x - The x value of our mid-point
|
61
|
+
* @param p2.y - The y value of our mid-point
|
62
|
+
* @param p3 - Our final point
|
63
|
+
* @param p3.x - The x value of our final point
|
64
|
+
* @param p3.y - The y value of our final point
|
65
|
+
* @returns whether or not p2 sits on the line between p1 and p3.
|
66
|
+
*/
|
67
|
+
export const checkForCollinearPoints = (p1, p2, p3) => (p1.y - p2.y) * (p1.x - p3.x) === (p1.y - p3.y) * (p1.x - p2.x);
|
68
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0aC5oZWxwZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9oZWxwZXJzL21hdGguaGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw2Q0FBNkM7QUFFN0M7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxVQUFVLFNBQVMsQ0FDdkIsS0FBYSxFQUNiLEdBQVcsRUFDWCxHQUFXLEVBQ1gsUUFBUSxHQUFHLENBQUMsRUFDWixRQUFRLEdBQUcsQ0FBQztJQUVaLDJFQUEyRTtJQUMzRSx3RUFBd0U7SUFDeEUsSUFBSSxHQUFHLEtBQUssR0FBRyxFQUFFO1FBQ2YsT0FBTyxRQUFRLENBQUM7S0FDakI7SUFFRCxPQUFPLFFBQVEsR0FBRyxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUN4RSxDQUFDO0FBT0Q7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxNQUFNLFVBQVUsTUFBTSxDQUFDLEVBQVMsRUFBRSxJQUFXLEVBQUUsTUFBYztJQUMzRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNoRyxNQUFNLFVBQVUsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLEVBQUUsQ0FBQztJQUVoRixPQUFPO1FBQ0wsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLENBQUMsR0FBRyxNQUFNO1FBQ2pDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxDQUFDLEdBQUcsTUFBTTtLQUNsQyxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxFQUFTLEVBQUUsRUFBUyxFQUFVLEVBQUUsQ0FDakUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBRWpFOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFDSCxNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBRyxDQUFDLEVBQVMsRUFBRSxFQUFTLEVBQUUsRUFBUyxFQUFXLEVBQUUsQ0FDbEYsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIG5vLXJlc3RyaWN0ZWQtcHJvcGVydGllcyAqL1xuXG4vKiogbm9ybWFsaXplXG4gKiBUaGlzIGxldHMgdXMgdHJhbnNsYXRlIGEgdmFsdWUgZnJvbSBvbmUgc2NhbGUgdG8gYW5vdGhlci5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBPdXIgaW5pdGlhbCB2YWx1ZSB0byB0cmFuc2xhdGVcbiAqIEBwYXJhbSBtaW4gLSB0aGUgY3VycmVudCBtaW5pbXVtIHZhbHVlIHBvc3NpYmxlXG4gKiBAcGFyYW0gbWF4IC0gdGhlIGN1cnJlbnQgbWF4aW11bSB2YWx1ZSBwb3NzaWJsZVxuICogQHBhcmFtIHNjYWxlTWluIC0gdGhlIG1pbiB2YWx1ZSBvZiB0aGUgc2NhbGUgd2UncmUgdHJhbnNsYXRpbmcgdG9cbiAqIEBwYXJhbSBzY2FsZU1heCAtIHRoZSBtYXggdmFsdWUgb2YgdGhlIHNjYWxlIHdlJ3JlIHRyYW5zbGF0aW5nIHRvXG4gKiBAcmV0dXJucyB0aGUgdmFsdWUgb24gaXRzIG5ldyBzY2FsZVxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplKFxuICB2YWx1ZTogbnVtYmVyLFxuICBtaW46IG51bWJlcixcbiAgbWF4OiBudW1iZXIsXG4gIHNjYWxlTWluID0gMCxcbiAgc2NhbGVNYXggPSAxLFxuKTogbnVtYmVyIHtcbiAgLy8gSWYgdGhlIGBtaW5gIGFuZCBgbWF4YCBhcmUgdGhlIHNhbWUgdmFsdWUsIGl0IG1lYW5zIG91ciBkYXRhc2V0IGlzIGZsYXQuXG4gIC8vIEZvciBub3csIGxldCdzIGFzc3VtZSB0aGF0IGZsYXQgZGF0YSBzaG91bGQgYmUgYWxpZ25lZCB0byB0aGUgYm90dG9tLlxuICBpZiAobWluID09PSBtYXgpIHtcbiAgICByZXR1cm4gc2NhbGVNaW47XG4gIH1cblxuICByZXR1cm4gc2NhbGVNaW4gKyAodmFsdWUgLSBtaW4pICogKHNjYWxlTWF4IC0gc2NhbGVNaW4pIC8gKG1heCAtIG1pbik7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUG9pbnQge1xuICB4OiBudW1iZXI7XG4gIHk6IG51bWJlcjtcbn1cblxuLyoqIG1vdmVUb1xuICogdGhlIGNvb3JkaW5hdGUgdGhhdCBsaWVzIGF0IGEgbWlkcG9pbnQgYmV0d2VlbiAyIGxpbmVzLCBiYXNlZCBvbiB0aGUgcmFkaXVzXG4gKlxuICogQHBhcmFtIHRvIC0gT3VyIGluaXRpYWwgcG9pbnRcbiAqIEBwYXJhbSB0by54IC0gVGhlIHggdmFsdWUgb2Ygb3VyIGluaXRpYWwgcG9pbnRcbiAqIEBwYXJhbSB0by55IC0gVGhlIHkgdmFsdWUgb2Ygb3VyIGluaXRpYWwgcG9pbnRcbiAqIEBwYXJhbSBmcm9tIC0gT3VyIGZpbmFsIHBvaW50XG4gKiBAcGFyYW0gZnJvbS54IC0gVGhlIHggdmFsdWUgb2Ygb3VyIGZpbmFsIHBvaW50XG4gKiBAcGFyYW0gZnJvbS55IC0gVGhlIHkgdmFsdWUgb2Ygb3VyIGZpbmFsIHBvaW50XG4gKiBAcGFyYW0gcmFkaXVzIC0gVGhlIGRpc3RhbmNlIGF3YXkgZnJvbSB0aGUgZmluYWwgcG9pbnRcbiAqIEByZXR1cm5zIGFuIG9iamVjdCBob2xkaW5nIHRoZSB4L3kgY29vcmRpbmF0ZXMgb2YgdGhlIG1pZHBvaW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gbW92ZVRvKHRvOiBQb2ludCwgZnJvbTogUG9pbnQsIHJhZGl1czogbnVtYmVyKTogUG9pbnQge1xuICBjb25zdCBsZW5ndGggPSBNYXRoLnNxcnQoKHRvLnggLSBmcm9tLngpICogKHRvLnggLSBmcm9tLngpICsgKHRvLnkgLSBmcm9tLnkpICogKHRvLnkgLSBmcm9tLnkpKTtcbiAgY29uc3QgdW5pdFZlY3RvciA9IHsgeDogKHRvLnggLSBmcm9tLngpIC8gbGVuZ3RoLCB5OiAodG8ueSAtIGZyb20ueSkgLyBsZW5ndGggfTtcblxuICByZXR1cm4ge1xuICAgIHg6IGZyb20ueCArIHVuaXRWZWN0b3IueCAqIHJhZGl1cyxcbiAgICB5OiBmcm9tLnkgKyB1bml0VmVjdG9yLnkgKiByYWRpdXMsXG4gIH07XG59XG5cbi8qKiBnZXREaXN0YW5jZUJldHdlZW5cbiAqIFNpbXBsZSBmb3JtdWxhIGRlcml2ZWQgZnJvbSBweXRoYWdvcmFzIHRvIGNhbGN1bGF0ZSB0aGUgZGlzdGFuY2UgYmV0d2VlblxuICogMiBwb2ludHMgb24gYSBwbGFuZS5cbiAqXG4gKiBAcGFyYW0gcDEgLSBPdXIgaW5pdGlhbCBwb2ludFxuICogQHBhcmFtIHAxLnggLSBUaGUgeCB2YWx1ZSBvZiBvdXIgaW5pdGlhbCBwb2ludFxuICogQHBhcmFtIHAxLnkgLSBUaGUgeSB2YWx1ZSBvZiBvdXIgaW5pdGlhbCBwb2ludFxuICogQHBhcmFtIHAyIC0gT3VyIGZpbmFsIHBvaW50XG4gKiBAcGFyYW0gcDIueCAtIFRoZSB4IHZhbHVlIG9mIG91ciBmaW5hbCBwb2ludFxuICogQHBhcmFtIHAyLnkgLSBUaGUgeSB2YWx1ZSBvZiBvdXIgZmluYWwgcG9pbnRcbiAqIEByZXR1cm5zIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHRoZSBwb2ludHMuXG4gKi9cbmV4cG9ydCBjb25zdCBnZXREaXN0YW5jZUJldHdlZW4gPSAocDE6IFBvaW50LCBwMjogUG9pbnQpOiBudW1iZXIgPT5cbiAgTWF0aC5zcXJ0KE1hdGgucG93KHAyLnggLSBwMS54LCAyKSArIE1hdGgucG93KHAyLnkgLSBwMS55LCAyKSk7XG5cbi8qKiBjaGVja0ZvckNvbGxpbmVhclBvaW50c1xuICogRmlndXJlIG91dCBpZiB0aGUgbWlkcG9pbnQgZml0cyBwZXJmZWN0bHkgb24gYSBsaW5lIGJldHdlZW4gdGhlIHR3byBvdGhlcnMuXG4gKlxuICogQHBhcmFtIHAxIC0gT3VyIGluaXRpYWwgcG9pbnRcbiAqIEBwYXJhbSBwMS54IC0gVGhlIHggdmFsdWUgb2Ygb3VyIGluaXRpYWwgcG9pbnRcbiAqIEBwYXJhbSBwMS55IC0gVGhlIHkgdmFsdWUgb2Ygb3VyIGluaXRpYWwgcG9pbnRcbiAqIEBwYXJhbSBwMiAtIE91ciBtaWQtcG9pbnRcbiAqIEBwYXJhbSBwMi54IC0gVGhlIHggdmFsdWUgb2Ygb3VyIG1pZC1wb2ludFxuICogQHBhcmFtIHAyLnkgLSBUaGUgeSB2YWx1ZSBvZiBvdXIgbWlkLXBvaW50XG4gKiBAcGFyYW0gcDMgLSBPdXIgZmluYWwgcG9pbnRcbiAqIEBwYXJhbSBwMy54IC0gVGhlIHggdmFsdWUgb2Ygb3VyIGZpbmFsIHBvaW50XG4gKiBAcGFyYW0gcDMueSAtIFRoZSB5IHZhbHVlIG9mIG91ciBmaW5hbCBwb2ludFxuICogQHJldHVybnMgd2hldGhlciBvciBub3QgcDIgc2l0cyBvbiB0aGUgbGluZSBiZXR3ZWVuIHAxIGFuZCBwMy5cbiAqL1xuZXhwb3J0IGNvbnN0IGNoZWNrRm9yQ29sbGluZWFyUG9pbnRzID0gKHAxOiBQb2ludCwgcDI6IFBvaW50LCBwMzogUG9pbnQpOiBib29sZWFuID0+XG4gIChwMS55IC0gcDIueSkgKiAocDEueCAtIHAzLngpID09PSAocDEueSAtIHAzLnkpICogKHAxLnggLSBwMi54KTtcbiJdfQ==
|
@@ -0,0 +1,2 @@
|
|
1
|
+
export const generateId = () => Math.round(Math.random() * Math.pow(10, 16));
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlzYy5oZWxwZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9oZWxwZXJzL21pc2MuaGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQUcsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjb25zdCBnZW5lcmF0ZUlkID0gKCkgPT4gTWF0aC5yb3VuZChNYXRoLnJhbmRvbSgpICogTWF0aC5wb3coMTAsIDE2KSk7XG4iXX0=
|
@@ -2,4 +2,4 @@
|
|
2
2
|
* Generated bundle index. Do not edit.
|
3
3
|
*/
|
4
4
|
export * from './public_api';
|
5
|
-
//# sourceMappingURL=data:application/json;base64,
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXRyZW5kLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xpYi9uZ3gtdHJlbmQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLGNBQWMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2VuZXJhdGVkIGJ1bmRsZSBpbmRleC4gRG8gbm90IGVkaXQuXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9wdWJsaWNfYXBpJztcbiJdfQ==
|
@@ -1,3 +1,3 @@
|
|
1
1
|
export * from './trend/trend.component';
|
2
2
|
export * from './trend/trend.module';
|
3
|
-
//# sourceMappingURL=data:application/json;base64,
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljX2FwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvcHVibGljX2FwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLHlCQUF5QixDQUFDO0FBQ3hDLGNBQWMsc0JBQXNCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL3RyZW5kL3RyZW5kLmNvbXBvbmVudCc7XG5leHBvcnQgKiBmcm9tICcuL3RyZW5kL3RyZW5kLm1vZHVsZSc7XG4iXX0=
|
@@ -0,0 +1,255 @@
|
|
1
|
+
import { animate, keyframes, state, style, transition, trigger } from '@angular/animations';
|
2
|
+
import { Component, Input, ViewChild } from '@angular/core';
|
3
|
+
import { buildLinearPath, buildSmoothPath } from '../helpers/DOM.helpers';
|
4
|
+
import { normalize } from '../helpers/math.helpers';
|
5
|
+
import { generateId } from '../helpers/misc.helpers';
|
6
|
+
import { normalizeDataset } from './trend.helpers';
|
7
|
+
import * as i0 from "@angular/core";
|
8
|
+
import * as i1 from "@angular/common";
|
9
|
+
export class TrendComponent {
|
10
|
+
constructor() {
|
11
|
+
this.autoDraw = false;
|
12
|
+
this.autoDrawDuration = 2000;
|
13
|
+
this.autoDrawEasing = 'ease';
|
14
|
+
this.padding = 8;
|
15
|
+
this.radius = 10;
|
16
|
+
this.stroke = 'black';
|
17
|
+
this.strokeLinecap = '';
|
18
|
+
this.strokeWidth = 1;
|
19
|
+
this.gradient = [];
|
20
|
+
this.svgHeight = '25%';
|
21
|
+
this.svgWidth = '100%';
|
22
|
+
this.animationState = '';
|
23
|
+
this.id = generateId();
|
24
|
+
this.gradientId = `ngx-trend-vertical-gradient-${this.id}`;
|
25
|
+
}
|
26
|
+
ngOnChanges() {
|
27
|
+
// We need at least 2 points to draw a graph.
|
28
|
+
if (!this.data || this.data.length < 2) {
|
29
|
+
return;
|
30
|
+
}
|
31
|
+
// `data` can either be an array of numbers:
|
32
|
+
// [1, 2, 3]
|
33
|
+
// or, an array of objects containing a value:
|
34
|
+
// [{ value: 1 }, { value: 2 }, { value: 3 }]
|
35
|
+
//
|
36
|
+
// For now, we're just going to convert the second form to the first.
|
37
|
+
// Later on, if/when we support tooltips, we may adjust.
|
38
|
+
const plainValues = this.data.map(point => {
|
39
|
+
if (typeof point === 'number') {
|
40
|
+
return point;
|
41
|
+
}
|
42
|
+
return point.value;
|
43
|
+
});
|
44
|
+
// Our viewbox needs to be in absolute units, so we'll default to 300x75
|
45
|
+
// Our SVG can be a %, though; this is what makes it scalable.
|
46
|
+
// By defaulting to percentages, the SVG will grow to fill its parent
|
47
|
+
// container, preserving a 1/4 aspect ratio.
|
48
|
+
const viewBoxWidth = this.width || 300;
|
49
|
+
const viewBoxHeight = this.height || 75;
|
50
|
+
this.svgWidth = this.width || '100%';
|
51
|
+
this.svgHeight = this.height || '25%';
|
52
|
+
this.viewBox = `0 0 ${viewBoxWidth} ${viewBoxHeight}`;
|
53
|
+
const root = location.href.split(location.hash || '#')[0];
|
54
|
+
this.pathStroke =
|
55
|
+
this.gradient && this.gradient.length ? `url('${root}#${this.gradientId}')` : undefined;
|
56
|
+
this.gradientTrimmed = this.gradient
|
57
|
+
.slice()
|
58
|
+
.reverse()
|
59
|
+
.map((val, idx) => {
|
60
|
+
return {
|
61
|
+
idx,
|
62
|
+
stopColor: val,
|
63
|
+
offset: normalize(idx, 0, this.gradient.length - 1 || 1),
|
64
|
+
};
|
65
|
+
});
|
66
|
+
const normalizedValues = normalizeDataset(plainValues, this.padding, viewBoxWidth - this.padding,
|
67
|
+
// NOTE: Because SVGs are indexed from the top left, but most data is
|
68
|
+
// indexed from the bottom left, we're inverting the Y min/max.
|
69
|
+
viewBoxHeight - this.padding, this.padding);
|
70
|
+
if (this.autoDraw && this.animationState !== 'active') {
|
71
|
+
this.animationState = 'inactive';
|
72
|
+
setTimeout(() => {
|
73
|
+
this.lineLength = this.pathEl.nativeElement.getTotalLength();
|
74
|
+
this.animationState = 'active';
|
75
|
+
});
|
76
|
+
}
|
77
|
+
this.d = this.smooth
|
78
|
+
? buildSmoothPath(normalizedValues, this.radius)
|
79
|
+
: buildLinearPath(normalizedValues);
|
80
|
+
}
|
81
|
+
}
|
82
|
+
TrendComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.1", ngImport: i0, type: TrendComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
83
|
+
TrendComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.1", type: TrendComponent, selector: "ngx-trend", inputs: { data: "data", smooth: "smooth", autoDraw: "autoDraw", autoDrawDuration: "autoDrawDuration", autoDrawEasing: "autoDrawEasing", width: "width", height: "height", padding: "padding", radius: "radius", stroke: "stroke", strokeLinecap: "strokeLinecap", strokeWidth: "strokeWidth", gradient: "gradient", preserveAspectRatio: "preserveAspectRatio", svgHeight: "svgHeight", svgWidth: "svgWidth" }, viewQueries: [{ propertyName: "pathEl", first: true, predicate: ["pathEl"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
|
84
|
+
<svg
|
85
|
+
*ngIf="data && data.length >= 2"
|
86
|
+
[attr.width]="svgWidth"
|
87
|
+
[attr.height]="svgHeight"
|
88
|
+
[attr.stroke]="stroke"
|
89
|
+
[attr.stroke-width]="strokeWidth"
|
90
|
+
[attr.stroke-linecap]="strokeLinecap"
|
91
|
+
[attr.viewBox]="viewBox"
|
92
|
+
[attr.preserveAspectRatio]="preserveAspectRatio"
|
93
|
+
>
|
94
|
+
<defs *ngIf="gradient && gradient.length">
|
95
|
+
<linearGradient [attr.id]="gradientId" x1="0%" y1="0%" x2="0%" y2="100%">
|
96
|
+
<stop
|
97
|
+
*ngFor="let g of gradientTrimmed"
|
98
|
+
[attr.key]="g.idx"
|
99
|
+
[attr.offset]="g.offset"
|
100
|
+
[attr.stop-color]="g.stopColor"
|
101
|
+
/>
|
102
|
+
</linearGradient>
|
103
|
+
</defs>
|
104
|
+
<path
|
105
|
+
fill="none"
|
106
|
+
#pathEl
|
107
|
+
[attr.stroke]="pathStroke"
|
108
|
+
[attr.d]="d"
|
109
|
+
[@pathAnimaiton]="{
|
110
|
+
value: animationState,
|
111
|
+
params: {
|
112
|
+
autoDrawDuration: autoDrawDuration,
|
113
|
+
autoDrawEasing: autoDrawEasing,
|
114
|
+
lineLength: lineLength
|
115
|
+
}
|
116
|
+
}"
|
117
|
+
/>
|
118
|
+
</svg>
|
119
|
+
`, isInline: true, directives: [{ type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], animations: [
|
120
|
+
trigger('pathAnimaiton', [
|
121
|
+
state('inactive', style({ display: 'none' })),
|
122
|
+
transition('* => active', [
|
123
|
+
style({ display: 'initial' }),
|
124
|
+
// We do the animation using the dash array/offset trick
|
125
|
+
// https://css-tricks.com/svg-line-animation-works/
|
126
|
+
animate('{{ autoDrawDuration }}ms {{ autoDrawEasing }}', keyframes([
|
127
|
+
style({
|
128
|
+
'stroke-dasharray': '{{ lineLength }}px',
|
129
|
+
'stroke-dashoffset': '{{ lineLength }}px',
|
130
|
+
}),
|
131
|
+
style({
|
132
|
+
'stroke-dasharray': '{{ lineLength }}px',
|
133
|
+
'stroke-dashoffset': 0,
|
134
|
+
}),
|
135
|
+
])),
|
136
|
+
// One unfortunate side-effect of the auto-draw is that the line is
|
137
|
+
// actually 1 big dash, the same length as the line itself. If the
|
138
|
+
// line length changes (eg. radius change, new data), that dash won't
|
139
|
+
// be the same length anymore. We can fix that by removing those
|
140
|
+
// properties once the auto-draw is completed.
|
141
|
+
style({
|
142
|
+
'stroke-dashoffset': '',
|
143
|
+
'stroke-dasharray': '',
|
144
|
+
}),
|
145
|
+
]),
|
146
|
+
]),
|
147
|
+
] });
|
148
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.1", ngImport: i0, type: TrendComponent, decorators: [{
|
149
|
+
type: Component,
|
150
|
+
args: [{
|
151
|
+
selector: 'ngx-trend',
|
152
|
+
template: `
|
153
|
+
<svg
|
154
|
+
*ngIf="data && data.length >= 2"
|
155
|
+
[attr.width]="svgWidth"
|
156
|
+
[attr.height]="svgHeight"
|
157
|
+
[attr.stroke]="stroke"
|
158
|
+
[attr.stroke-width]="strokeWidth"
|
159
|
+
[attr.stroke-linecap]="strokeLinecap"
|
160
|
+
[attr.viewBox]="viewBox"
|
161
|
+
[attr.preserveAspectRatio]="preserveAspectRatio"
|
162
|
+
>
|
163
|
+
<defs *ngIf="gradient && gradient.length">
|
164
|
+
<linearGradient [attr.id]="gradientId" x1="0%" y1="0%" x2="0%" y2="100%">
|
165
|
+
<stop
|
166
|
+
*ngFor="let g of gradientTrimmed"
|
167
|
+
[attr.key]="g.idx"
|
168
|
+
[attr.offset]="g.offset"
|
169
|
+
[attr.stop-color]="g.stopColor"
|
170
|
+
/>
|
171
|
+
</linearGradient>
|
172
|
+
</defs>
|
173
|
+
<path
|
174
|
+
fill="none"
|
175
|
+
#pathEl
|
176
|
+
[attr.stroke]="pathStroke"
|
177
|
+
[attr.d]="d"
|
178
|
+
[@pathAnimaiton]="{
|
179
|
+
value: animationState,
|
180
|
+
params: {
|
181
|
+
autoDrawDuration: autoDrawDuration,
|
182
|
+
autoDrawEasing: autoDrawEasing,
|
183
|
+
lineLength: lineLength
|
184
|
+
}
|
185
|
+
}"
|
186
|
+
/>
|
187
|
+
</svg>
|
188
|
+
`,
|
189
|
+
animations: [
|
190
|
+
trigger('pathAnimaiton', [
|
191
|
+
state('inactive', style({ display: 'none' })),
|
192
|
+
transition('* => active', [
|
193
|
+
style({ display: 'initial' }),
|
194
|
+
// We do the animation using the dash array/offset trick
|
195
|
+
// https://css-tricks.com/svg-line-animation-works/
|
196
|
+
animate('{{ autoDrawDuration }}ms {{ autoDrawEasing }}', keyframes([
|
197
|
+
style({
|
198
|
+
'stroke-dasharray': '{{ lineLength }}px',
|
199
|
+
'stroke-dashoffset': '{{ lineLength }}px',
|
200
|
+
}),
|
201
|
+
style({
|
202
|
+
'stroke-dasharray': '{{ lineLength }}px',
|
203
|
+
'stroke-dashoffset': 0,
|
204
|
+
}),
|
205
|
+
])),
|
206
|
+
// One unfortunate side-effect of the auto-draw is that the line is
|
207
|
+
// actually 1 big dash, the same length as the line itself. If the
|
208
|
+
// line length changes (eg. radius change, new data), that dash won't
|
209
|
+
// be the same length anymore. We can fix that by removing those
|
210
|
+
// properties once the auto-draw is completed.
|
211
|
+
style({
|
212
|
+
'stroke-dashoffset': '',
|
213
|
+
'stroke-dasharray': '',
|
214
|
+
}),
|
215
|
+
]),
|
216
|
+
]),
|
217
|
+
],
|
218
|
+
}]
|
219
|
+
}], ctorParameters: function () { return []; }, propDecorators: { data: [{
|
220
|
+
type: Input
|
221
|
+
}], smooth: [{
|
222
|
+
type: Input
|
223
|
+
}], autoDraw: [{
|
224
|
+
type: Input
|
225
|
+
}], autoDrawDuration: [{
|
226
|
+
type: Input
|
227
|
+
}], autoDrawEasing: [{
|
228
|
+
type: Input
|
229
|
+
}], width: [{
|
230
|
+
type: Input
|
231
|
+
}], height: [{
|
232
|
+
type: Input
|
233
|
+
}], padding: [{
|
234
|
+
type: Input
|
235
|
+
}], radius: [{
|
236
|
+
type: Input
|
237
|
+
}], stroke: [{
|
238
|
+
type: Input
|
239
|
+
}], strokeLinecap: [{
|
240
|
+
type: Input
|
241
|
+
}], strokeWidth: [{
|
242
|
+
type: Input
|
243
|
+
}], gradient: [{
|
244
|
+
type: Input
|
245
|
+
}], preserveAspectRatio: [{
|
246
|
+
type: Input
|
247
|
+
}], svgHeight: [{
|
248
|
+
type: Input
|
249
|
+
}], svgWidth: [{
|
250
|
+
type: Input
|
251
|
+
}], pathEl: [{
|
252
|
+
type: ViewChild,
|
253
|
+
args: ['pathEl']
|
254
|
+
}] } });
|
255
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlbmQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi90cmVuZC90cmVuZC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDNUYsT0FBTyxFQUFFLFNBQVMsRUFBYyxLQUFLLEVBQWEsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRW5GLE9BQU8sRUFBRSxlQUFlLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDMUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3BELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7O0FBMEVuRCxNQUFNLE9BQU8sY0FBYztJQTJCekI7UUF2QlMsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixxQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFDeEIsbUJBQWMsR0FBRyxNQUFNLENBQUM7UUFHeEIsWUFBTyxHQUFHLENBQUMsQ0FBQztRQUNaLFdBQU0sR0FBRyxFQUFFLENBQUM7UUFDWixXQUFNLEdBQUcsT0FBTyxDQUFDO1FBQ2pCLGtCQUFhLEdBQUcsRUFBRSxDQUFDO1FBQ25CLGdCQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ2hCLGFBQVEsR0FBYSxFQUFFLENBQUM7UUFFeEIsY0FBUyxHQUFvQixLQUFLLENBQUM7UUFDbkMsYUFBUSxHQUFvQixNQUFNLENBQUM7UUFRNUMsbUJBQWMsR0FBRyxFQUFFLENBQUM7UUFHbEIsSUFBSSxDQUFDLEVBQUUsR0FBRyxVQUFVLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsVUFBVSxHQUFHLCtCQUErQixJQUFJ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O3NCQUExQixTQUFTO3VCQUFDLFFBQVEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBhbmltYXRlLCBrZXlmcmFtZXMsIHN0YXRlLCBzdHlsZSwgdHJhbnNpdGlvbiwgdHJpZ2dlciB9IGZyb20gJ0Bhbmd1bGFyL2FuaW1hdGlvbnMnO1xuaW1wb3J0IHsgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBJbnB1dCwgT25DaGFuZ2VzLCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgYnVpbGRMaW5lYXJQYXRoLCBidWlsZFNtb290aFBhdGggfSBmcm9tICcuLi9oZWxwZXJzL0RPTS5oZWxwZXJzJztcbmltcG9ydCB7IG5vcm1hbGl6ZSB9IGZyb20gJy4uL2hlbHBlcnMvbWF0aC5oZWxwZXJzJztcbmltcG9ydCB7IGdlbmVyYXRlSWQgfSBmcm9tICcuLi9oZWxwZXJzL21pc2MuaGVscGVycyc7XG5pbXBvcnQgeyBub3JtYWxpemVEYXRhc2V0IH0gZnJvbSAnLi90cmVuZC5oZWxwZXJzJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LXRyZW5kJyxcbiAgdGVtcGxhdGU6IGBcbiAgICA8c3ZnXG4gICAgICAqbmdJZj1cImRhdGEgJiYgZGF0YS5sZW5ndGggPj0gMlwiXG4gICAgICBbYXR0ci53aWR0aF09XCJzdmdXaWR0aFwiXG4gICAgICBbYXR0ci5oZWlnaHRdPVwic3ZnSGVpZ2h0XCJcbiAgICAgIFthdHRyLnN0cm9rZV09XCJzdHJva2VcIlxuICAgICAgW2F0dHIuc3Ryb2tlLXdpZHRoXT1cInN0cm9rZVdpZHRoXCJcbiAgICAgIFthdHRyLnN0cm9rZS1saW5lY2FwXT1cInN0cm9rZUxpbmVjYXBcIlxuICAgICAgW2F0dHIudmlld0JveF09XCJ2aWV3Qm94XCJcbiAgICAgIFthdHRyLnByZXNlcnZlQXNwZWN0UmF0aW9dPVwicHJlc2VydmVBc3BlY3RSYXRpb1wiXG4gICAgPlxuICAgICAgPGRlZnMgKm5nSWY9XCJncmFkaWVudCAmJiBncmFkaWVudC5sZW5ndGhcIj5cbiAgICAgICAgPGxpbmVhckdyYWRpZW50IFthdHRyLmlkXT1cImdyYWRpZW50SWRcIiB4MT1cIjAlXCIgeTE9XCIwJVwiIHgyPVwiMCVcIiB5Mj1cIjEwMCVcIj5cbiAgICAgICAgICA8c3RvcFxuICAgICAgICAgICAgKm5nRm9yPVwibGV0IGcgb2YgZ3JhZGllbnRUcmltbWVkXCJcbiAgICAgICAgICAgIFthdHRyLmtleV09XCJnLmlkeFwiXG4gICAgICAgICAgICBbYXR0ci5vZmZzZXRdPVwiZy5vZmZzZXRcIlxuICAgICAgICAgICAgW2F0dHIuc3RvcC1jb2xvcl09XCJnLnN0b3BDb2xvclwiXG4gICAgICAgICAgLz5cbiAgICAgICAgPC9saW5lYXJHcmFkaWVudD5cbiAgICAgIDwvZGVmcz5cbiAgICAgIDxwYXRoXG4gICAgICAgIGZpbGw9XCJub25lXCJcbiAgICAgICAgI3BhdGhFbFxuICAgICAgICBbYXR0ci5zdHJva2VdPVwicGF0aFN0cm9rZVwiXG4gICAgICAgIFthdHRyLmRdPVwiZFwiXG4gICAgICAgIFtAcGF0aEFuaW1haXRvbl09XCJ7XG4gICAgICAgICAgdmFsdWU6IGFuaW1hdGlvblN0YXRlLFxuICAgICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgYXV0b0RyYXdEdXJhdGlvbjogYXV0b0RyYXdEdXJhdGlvbixcbiAgICAgICAgICAgIGF1dG9EcmF3RWFzaW5nOiBhdXRvRHJhd0Vhc2luZyxcbiAgICAgICAgICAgIGxpbmVMZW5ndGg6IGxpbmVMZW5ndGhcbiAgICAgICAgICB9XG4gICAgICAgIH1cIlxuICAgICAgLz5cbiAgICA8L3N2Zz5cbiAgYCxcbiAgYW5pbWF0aW9uczogW1xuICAgIHRyaWdnZXIoJ3BhdGhBbmltYWl0b24nLCBbXG4gICAgICBzdGF0ZSgnaW5hY3RpdmUnLCBzdHlsZSh7IGRpc3BsYXk6ICdub25lJyB9KSksXG4gICAgICB0cmFuc2l0aW9uKCcqID0+IGFjdGl2ZScsIFtcbiAgICAgICAgc3R5bGUoeyBkaXNwbGF5OiAnaW5pdGlhbCcgfSksXG4gICAgICAgIC8vIFdlIGRvIHRoZSBhbmltYXRpb24gdXNpbmcgdGhlIGRhc2ggYXJyYXkvb2Zmc2V0IHRyaWNrXG4gICAgICAgIC8vIGh0dHBzOi8vY3NzLXRyaWNrcy5jb20vc3ZnLWxpbmUtYW5pbWF0aW9uLXdvcmtzL1xuICAgICAgICBhbmltYXRlKFxuICAgICAgICAgICd7eyBhdXRvRHJhd0R1cmF0aW9uIH19bXMge3sgYXV0b0RyYXdFYXNpbmcgfX0nLFxuICAgICAgICAgIGtleWZyYW1lcyhbXG4gICAgICAgICAgICBzdHlsZSh7XG4gICAgICAgICAgICAgICdzdHJva2UtZGFzaGFycmF5JzogJ3t7IGxpbmVMZW5ndGggfX1weCcsXG4gICAgICAgICAgICAgICdzdHJva2UtZGFzaG9mZnNldCc6ICd7eyBsaW5lTGVuZ3RoIH19cHgnLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBzdHlsZSh7XG4gICAgICAgICAgICAgICdzdHJva2UtZGFzaGFycmF5JzogJ3t7IGxpbmVMZW5ndGggfX1weCcsXG4gICAgICAgICAgICAgICdzdHJva2UtZGFzaG9mZnNldCc6IDAsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICBdKSxcbiAgICAgICAgKSxcbiAgICAgICAgLy8gT25lIHVuZm9ydHVuYXRlIHNpZGUtZWZmZWN0IG9mIHRoZSBhdXRvLWRyYXcgaXMgdGhhdCB0aGUgbGluZSBpc1xuICAgICAgICAvLyBhY3R1YWxseSAxIGJpZyBkYXNoLCB0aGUgc2FtZSBsZW5ndGggYXMgdGhlIGxpbmUgaXRzZWxmLiBJZiB0aGVcbiAgICAgICAgLy8gbGluZSBsZW5ndGggY2hhbmdlcyAoZWcuIHJhZGl1cyBjaGFuZ2UsIG5ldyBkYXRhKSwgdGhhdCBkYXNoIHdvbid0XG4gICAgICAgIC8vIGJlIHRoZSBzYW1lIGxlbmd0aCBhbnltb3JlLiBXZSBjYW4gZml4IHRoYXQgYnkgcmVtb3ZpbmcgdGhvc2VcbiAgICAgICAgLy8gcHJvcGVydGllcyBvbmNlIHRoZSBhdXRvLWRyYXcgaXMgY29tcGxldGVkLlxuICAgICAgICBzdHlsZSh7XG4gICAgICAgICAgJ3N0cm9rZS1kYXNob2Zmc2V0JzogJycsXG4gICAgICAgICAgJ3N0cm9rZS1kYXNoYXJyYXknOiAnJyxcbiAgICAgICAgfSksXG4gICAgICBdKSxcbiAgICBdKSxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgVHJlbmRDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICBpZDogbnVtYmVyO1xuICBASW5wdXQoKSBkYXRhPzogQXJyYXk8KG51bWJlciB8IHsgdmFsdWU6IG51bWJlciB9KT47XG4gIEBJbnB1dCgpIHNtb290aD86IGJvb2xlYW47XG4gIEBJbnB1dCgpIGF1dG9EcmF3ID0gZmFsc2U7XG4gIEBJbnB1dCgpIGF1dG9EcmF3RHVyYXRpb24gPSAyMDAwO1xuICBASW5wdXQoKSBhdXRvRHJhd0Vhc2luZyA9ICdlYXNlJztcbiAgQElucHV0KCkgd2lkdGg/OiBudW1iZXI7XG4gIEBJbnB1dCgpIGhlaWdodD86IG51bWJlcjtcbiAgQElucHV0KCkgcGFkZGluZyA9IDg7XG4gIEBJbnB1dCgpIHJhZGl1cyA9IDEwO1xuICBASW5wdXQoKSBzdHJva2UgPSAnYmxhY2snO1xuICBASW5wdXQoKSBzdHJva2VMaW5lY2FwID0gJyc7XG4gIEBJbnB1dCgpIHN0cm9rZVdpZHRoID0gMTtcbiAgQElucHV0KCkgZ3JhZGllbnQ6IHN0cmluZ1tdID0gW107XG4gIEBJbnB1dCgpIHByZXNlcnZlQXNwZWN0UmF0aW8/OiBzdHJpbmc7XG4gIEBJbnB1dCgpIHN2Z0hlaWdodDogc3RyaW5nIHwgbnVtYmVyID0gJzI1JSc7XG4gIEBJbnB1dCgpIHN2Z1dpZHRoOiBzdHJpbmcgfCBudW1iZXIgPSAnMTAwJSc7XG4gIEBWaWV3Q2hpbGQoJ3BhdGhFbCcpIHBhdGhFbCE6IEVsZW1lbnRSZWY7XG4gIGdyYWRpZW50VHJpbW1lZCE6IEFycmF5PHsgaWR4OiBudW1iZXI7IHN0b3BDb2xvcjogc3RyaW5nOyBvZmZzZXQ6IG51bWJlciB9PjtcbiAgZDogYW55O1xuICB2aWV3Qm94ITogc3RyaW5nO1xuICBwYXRoU3Ryb2tlOiBhbnk7XG4gIGdyYWRpZW50SWQ6IHN0cmluZztcbiAgbGluZUxlbmd0aCE6IG51bWJlcjtcbiAgYW5pbWF0aW9uU3RhdGUgPSAnJztcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmlkID0gZ2VuZXJhdGVJZCgpO1xuICAgIHRoaXMuZ3JhZGllbnRJZCA9IGBuZ3gtdHJlbmQtdmVydGljYWwtZ3JhZGllbnQtJHt0aGlzLmlkfWA7XG4gIH1cbiAgbmdPbkNoYW5nZXMoKTogdm9pZCB7XG4gICAgLy8gV2UgbmVlZCBhdCBsZWFzdCAyIHBvaW50cyB0byBkcmF3IGEgZ3JhcGguXG4gICAgaWYgKCF0aGlzLmRhdGEgfHwgdGhpcy5kYXRhLmxlbmd0aCA8IDIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBgZGF0YWAgY2FuIGVpdGhlciBiZSBhbiBhcnJheSBvZiBudW1iZXJzOlxuICAgIC8vIFsxLCAyLCAzXVxuICAgIC8vIG9yLCBhbiBhcnJheSBvZiBvYmplY3RzIGNvbnRhaW5pbmcgYSB2YWx1ZTpcbiAgICAvLyBbeyB2YWx1ZTogMSB9LCB7IHZhbHVlOiAyIH0sIHsgdmFsdWU6IDMgfV1cbiAgICAvL1xuICAgIC8vIEZvciBub3csIHdlJ3JlIGp1c3QgZ29pbmcgdG8gY29udmVydCB0aGUgc2Vjb25kIGZvcm0gdG8gdGhlIGZpcnN0LlxuICAgIC8vIExhdGVyIG9uLCBpZi93aGVuIHdlIHN1cHBvcnQgdG9vbHRpcHMsIHdlIG1heSBhZGp1c3QuXG4gICAgY29uc3QgcGxhaW5WYWx1ZXMgPSB0aGlzLmRhdGEubWFwKHBvaW50ID0+IHtcbiAgICAgIGlmICh0eXBlb2YgcG9pbnQgPT09ICdudW1iZXInKSB7XG4gICAgICAgIHJldHVybiBwb2ludDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBwb2ludC52YWx1ZTtcbiAgICB9KTtcblxuICAgIC8vIE91ciB2aWV3Ym94IG5lZWRzIHRvIGJlIGluIGFic29sdXRlIHVuaXRzLCBzbyB3ZSdsbCBkZWZhdWx0IHRvIDMwMHg3NVxuICAgIC8vIE91ciBTVkcgY2FuIGJlIGEgJSwgdGhvdWdoOyB0aGlzIGlzIHdoYXQgbWFrZXMgaXQgc2NhbGFibGUuXG4gICAgLy8gQnkgZGVmYXVsdGluZyB0byBwZXJjZW50YWdlcywgdGhlIFNWRyB3aWxsIGdyb3cgdG8gZmlsbCBpdHMgcGFyZW50XG4gICAgLy8gY29udGFpbmVyLCBwcmVzZXJ2aW5nIGEgMS80IGFzcGVjdCByYXRpby5cbiAgICBjb25zdCB2aWV3Qm94V2lkdGggPSB0aGlzLndpZHRoIHx8IDMwMDtcbiAgICBjb25zdCB2aWV3Qm94SGVpZ2h0ID0gdGhpcy5oZWlnaHQgfHwgNzU7XG4gICAgdGhpcy5zdmdXaWR0aCA9IHRoaXMud2lkdGggfHwgJzEwMCUnO1xuICAgIHRoaXMuc3ZnSGVpZ2h0ID0gdGhpcy5oZWlnaHQgfHwgJzI1JSc7XG4gICAgdGhpcy52aWV3Qm94ID0gYDAgMCAke3ZpZXdCb3hXaWR0aH0gJHt2aWV3Qm94SGVpZ2h0fWA7XG4gICAgY29uc3Qgcm9vdCA9IGxvY2F0aW9uLmhyZWYuc3BsaXQobG9jYXRpb24uaGFzaCB8fCAnIycpWzBdO1xuICAgIHRoaXMucGF0aFN0cm9rZSA9XG4gICAgICB0aGlzLmdyYWRpZW50ICYmIHRoaXMuZ3JhZGllbnQubGVuZ3RoID8gYHVybCgnJHtyb290fSMke3RoaXMuZ3JhZGllbnRJZH0nKWAgOiB1bmRlZmluZWQ7XG5cbiAgICB0aGlzLmdyYWRpZW50VHJpbW1lZCA9IHRoaXMuZ3JhZGllbnRcbiAgICAgIC5zbGljZSgpXG4gICAgICAucmV2ZXJzZSgpXG4gICAgICAubWFwKCh2YWwsIGlkeCkgPT4ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGlkeCxcbiAgICAgICAgICBzdG9wQ29sb3I6IHZhbCxcbiAgICAgICAgICBvZmZzZXQ6IG5vcm1hbGl6ZShpZHgsIDAsIHRoaXMuZ3JhZGllbnQubGVuZ3RoIC0gMSB8fCAxKSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuXG4gICAgY29uc3Qgbm9ybWFsaXplZFZhbHVlcyA9IG5vcm1hbGl6ZURhdGFzZXQoXG4gICAgICBwbGFpblZhbHVlcyxcbiAgICAgIHRoaXMucGFkZGluZyxcbiAgICAgIHZpZXdCb3hXaWR0aCAtIHRoaXMucGFkZGluZyxcbiAgICAgIC8vIE5PVEU6IEJlY2F1c2UgU1ZHcyBhcmUgaW5kZXhlZCBmcm9tIHRoZSB0b3AgbGVmdCwgYnV0IG1vc3QgZGF0YSBpc1xuICAgICAgLy8gaW5kZXhlZCBmcm9tIHRoZSBib3R0b20gbGVmdCwgd2UncmUgaW52ZXJ0aW5nIHRoZSBZIG1pbi9tYXguXG4gICAgICB2aWV3Qm94SGVpZ2h0IC0gdGhpcy5wYWRkaW5nLFxuICAgICAgdGhpcy5wYWRkaW5nLFxuICAgICk7XG5cbiAgICBpZiAodGhpcy5hdXRvRHJhdyAmJiB0aGlzLmFuaW1hdGlvblN0YXRlICE9PSAnYWN0aXZlJykge1xuICAgICAgdGhpcy5hbmltYXRpb25TdGF0ZSA9ICdpbmFjdGl2ZSc7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5saW5lTGVuZ3RoID0gdGhpcy5wYXRoRWwubmF0aXZlRWxlbWVudC5nZXRUb3RhbExlbmd0aCgpO1xuICAgICAgICB0aGlzLmFuaW1hdGlvblN0YXRlID0gJ2FjdGl2ZSc7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLmQgPSB0aGlzLnNtb290aFxuICAgICAgPyBidWlsZFNtb290aFBhdGgobm9ybWFsaXplZFZhbHVlcywgdGhpcy5yYWRpdXMpXG4gICAgICA6IGJ1aWxkTGluZWFyUGF0aChub3JtYWxpemVkVmFsdWVzKTtcbiAgfVxufVxuIl19
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import { normalize } from '../helpers/math.helpers';
|
2
|
+
export function normalizeDataset(data, minX, maxX, minY, maxY) {
|
3
|
+
// For the X axis, we want to normalize it based on its index in the array.
|
4
|
+
// For the Y axis, we want to normalize it based on the element's value.
|
5
|
+
//
|
6
|
+
// X axis is easy: just evenly-space each item in the array.
|
7
|
+
// For the Y axis, we first need to find the min and max of our array,
|
8
|
+
// and then normalize those values between 0 and 1.
|
9
|
+
const boundariesX = { min: 0, max: data.length - 1 };
|
10
|
+
const boundariesY = { min: Math.min(...data), max: Math.max(...data) };
|
11
|
+
const normalizedData = data.map((point, index) => ({
|
12
|
+
x: normalize(index, boundariesX.min, boundariesX.max, minX, maxX),
|
13
|
+
y: normalize(point, boundariesY.min, boundariesY.max, minY, maxY),
|
14
|
+
}));
|
15
|
+
// According to the SVG spec, paths with a height/width of `0` can't have
|
16
|
+
// linear gradients applied. This means that our lines are invisible when
|
17
|
+
// the dataset is flat (eg. [0, 0, 0, 0]).
|
18
|
+
//
|
19
|
+
// The hacky solution is to apply a very slight offset to the first point of
|
20
|
+
// the dataset. As ugly as it is, it's the best solution we can find (there
|
21
|
+
// are ways within the SVG spec of changing it, but not without causing
|
22
|
+
// breaking changes).
|
23
|
+
if (boundariesY.min === boundariesY.max) {
|
24
|
+
normalizedData[0].y += 0.0001;
|
25
|
+
}
|
26
|
+
return normalizedData;
|
27
|
+
}
|
28
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlbmQuaGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvdHJlbmQvdHJlbmQuaGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFcEQsTUFBTSxVQUFVLGdCQUFnQixDQUM5QixJQUFjLEVBQ2QsSUFBWSxFQUNaLElBQVksRUFDWixJQUFZLEVBQ1osSUFBWTtJQUVaLDJFQUEyRTtJQUMzRSx3RUFBd0U7SUFDeEUsRUFBRTtJQUNGLDREQUE0RDtJQUM1RCxzRUFBc0U7SUFDdEUsbURBQW1EO0lBQ25ELE1BQU0sV0FBVyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztJQUNyRCxNQUFNLFdBQVcsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDO0lBRXZFLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ2pELENBQUMsRUFBRSxTQUFTLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxHQUFHLEVBQUUsV0FBVyxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDO1FBQ2pFLENBQUMsRUFBRSxTQUFTLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxHQUFHLEVBQUUsV0FBVyxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDO0tBQ2xFLENBQUMsQ0FBQyxDQUFDO0lBRUoseUVBQXlFO0lBQ3pFLHlFQUF5RTtJQUN6RSwwQ0FBMEM7SUFDMUMsRUFBRTtJQUNGLDRFQUE0RTtJQUM1RSwyRUFBMkU7SUFDM0UsdUVBQXVFO0lBQ3ZFLHFCQUFxQjtJQUNyQixJQUFJLFdBQVcsQ0FBQyxHQUFHLEtBQUssV0FBVyxDQUFDLEdBQUcsRUFBRTtRQUN2QyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQztLQUMvQjtJQUVELE9BQU8sY0FBYyxDQUFDO0FBQ3hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBub3JtYWxpemUgfSBmcm9tICcuLi9oZWxwZXJzL21hdGguaGVscGVycyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVEYXRhc2V0KFxuICBkYXRhOiBudW1iZXJbXSxcbiAgbWluWDogbnVtYmVyLFxuICBtYXhYOiBudW1iZXIsXG4gIG1pblk6IG51bWJlcixcbiAgbWF4WTogbnVtYmVyLFxuKTogQXJyYXk8eyB4OiBudW1iZXI7IHk6IG51bWJlciB9PiB7XG4gIC8vIEZvciB0aGUgWCBheGlzLCB3ZSB3YW50IHRvIG5vcm1hbGl6ZSBpdCBiYXNlZCBvbiBpdHMgaW5kZXggaW4gdGhlIGFycmF5LlxuICAvLyBGb3IgdGhlIFkgYXhpcywgd2Ugd2FudCB0byBub3JtYWxpemUgaXQgYmFzZWQgb24gdGhlIGVsZW1lbnQncyB2YWx1ZS5cbiAgLy9cbiAgLy8gWCBheGlzIGlzIGVhc3k6IGp1c3QgZXZlbmx5LXNwYWNlIGVhY2ggaXRlbSBpbiB0aGUgYXJyYXkuXG4gIC8vIEZvciB0aGUgWSBheGlzLCB3ZSBmaXJzdCBuZWVkIHRvIGZpbmQgdGhlIG1pbiBhbmQgbWF4IG9mIG91ciBhcnJheSxcbiAgLy8gYW5kIHRoZW4gbm9ybWFsaXplIHRob3NlIHZhbHVlcyBiZXR3ZWVuIDAgYW5kIDEuXG4gIGNvbnN0IGJvdW5kYXJpZXNYID0geyBtaW46IDAsIG1heDogZGF0YS5sZW5ndGggLSAxIH07XG4gIGNvbnN0IGJvdW5kYXJpZXNZID0geyBtaW46IE1hdGgubWluKC4uLmRhdGEpLCBtYXg6IE1hdGgubWF4KC4uLmRhdGEpIH07XG5cbiAgY29uc3Qgbm9ybWFsaXplZERhdGEgPSBkYXRhLm1hcCgocG9pbnQsIGluZGV4KSA9PiAoe1xuICAgIHg6IG5vcm1hbGl6ZShpbmRleCwgYm91bmRhcmllc1gubWluLCBib3VuZGFyaWVzWC5tYXgsIG1pblgsIG1heFgpLFxuICAgIHk6IG5vcm1hbGl6ZShwb2ludCwgYm91bmRhcmllc1kubWluLCBib3VuZGFyaWVzWS5tYXgsIG1pblksIG1heFkpLFxuICB9KSk7XG5cbiAgLy8gQWNjb3JkaW5nIHRvIHRoZSBTVkcgc3BlYywgcGF0aHMgd2l0aCBhIGhlaWdodC93aWR0aCBvZiBgMGAgY2FuJ3QgaGF2ZVxuICAvLyBsaW5lYXIgZ3JhZGllbnRzIGFwcGxpZWQuIFRoaXMgbWVhbnMgdGhhdCBvdXIgbGluZXMgYXJlIGludmlzaWJsZSB3aGVuXG4gIC8vIHRoZSBkYXRhc2V0IGlzIGZsYXQgKGVnLiBbMCwgMCwgMCwgMF0pLlxuICAvL1xuICAvLyBUaGUgaGFja3kgc29sdXRpb24gaXMgdG8gYXBwbHkgYSB2ZXJ5IHNsaWdodCBvZmZzZXQgdG8gdGhlIGZpcnN0IHBvaW50IG9mXG4gIC8vIHRoZSBkYXRhc2V0LiBBcyB1Z2x5IGFzIGl0IGlzLCBpdCdzIHRoZSBiZXN0IHNvbHV0aW9uIHdlIGNhbiBmaW5kICh0aGVyZVxuICAvLyBhcmUgd2F5cyB3aXRoaW4gdGhlIFNWRyBzcGVjIG9mIGNoYW5naW5nIGl0LCBidXQgbm90IHdpdGhvdXQgY2F1c2luZ1xuICAvLyBicmVha2luZyBjaGFuZ2VzKS5cbiAgaWYgKGJvdW5kYXJpZXNZLm1pbiA9PT0gYm91bmRhcmllc1kubWF4KSB7XG4gICAgbm9ybWFsaXplZERhdGFbMF0ueSArPSAwLjAwMDE7XG4gIH1cblxuICByZXR1cm4gbm9ybWFsaXplZERhdGE7XG59XG4iXX0=
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
2
|
+
import { NgModule } from '@angular/core';
|
3
|
+
import { TrendComponent } from './trend.component';
|
4
|
+
import * as i0 from "@angular/core";
|
5
|
+
export class TrendModule {
|
6
|
+
}
|
7
|
+
TrendModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.1", ngImport: i0, type: TrendModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
8
|
+
TrendModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.1", ngImport: i0, type: TrendModule, declarations: [TrendComponent], imports: [CommonModule], exports: [TrendComponent] });
|
9
|
+
TrendModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.1", ngImport: i0, type: TrendModule, imports: [[CommonModule]] });
|
10
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.1", ngImport: i0, type: TrendModule, decorators: [{
|
11
|
+
type: NgModule,
|
12
|
+
args: [{
|
13
|
+
imports: [CommonModule],
|
14
|
+
exports: [TrendComponent],
|
15
|
+
declarations: [TrendComponent],
|
16
|
+
}]
|
17
|
+
}] });
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlbmQubW9kdWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi90cmVuZC90cmVuZC5tb2R1bGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFekMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFDOztBQU9uRCxNQUFNLE9BQU8sV0FBVzs7d0dBQVgsV0FBVzt5R0FBWCxXQUFXLGlCQUZQLGNBQWMsYUFGbkIsWUFBWSxhQUNaLGNBQWM7eUdBR2IsV0FBVyxZQUpiLENBQUMsWUFBWSxDQUFDOzJGQUlaLFdBQVc7a0JBTHZCLFFBQVE7bUJBQUM7b0JBQ1IsT0FBTyxFQUFFLENBQUMsWUFBWSxDQUFDO29CQUN2QixPQUFPLEVBQUUsQ0FBQyxjQUFjLENBQUM7b0JBQ3pCLFlBQVksRUFBRSxDQUFDLGNBQWMsQ0FBQztpQkFDL0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgVHJlbmRDb21wb25lbnQgfSBmcm9tICcuL3RyZW5kLmNvbXBvbmVudCc7XG5cbkBOZ01vZHVsZSh7XG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGVdLFxuICBleHBvcnRzOiBbVHJlbmRDb21wb25lbnRdLFxuICBkZWNsYXJhdGlvbnM6IFtUcmVuZENvbXBvbmVudF0sXG59KVxuZXhwb3J0IGNsYXNzIFRyZW5kTW9kdWxlIHtcbn1cbiJdfQ==
|