bezel-charts 1.2.0 → 1.4.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 +57 -8
- package/dist/bezel-charts.iife.js +11 -9
- package/dist/bezel-charts.js +1133 -924
- package/dist/bezel-charts.min.js +11 -9
- package/dist/charts/area.js +4 -0
- package/dist/charts/bars.js +4 -0
- package/dist/charts/donut.js +2 -0
- package/dist/charts/gauge.js +3 -0
- package/dist/charts/heatmap.js +2 -0
- package/dist/charts/line.js +3 -0
- package/dist/charts/progress.js +2 -0
- package/dist/charts/ring.js +2 -0
- package/dist/charts/scatter.js +5 -0
- package/dist/charts/shared-4QPUIMAU.js +2 -0
- package/dist/charts/shared-APAAEWNX.js +2 -0
- package/dist/charts/shared-XBZ5QGIC.js +2 -0
- package/dist/charts/spark.js +2 -0
- package/package.json +12 -2
- package/src/charts/area.js +97 -0
- package/src/charts/bars.js +2 -1
- package/src/charts/line.js +18 -58
- package/src/charts/scatter.js +2 -1
- package/src/core/series.js +85 -0
- package/src/core/util.js +0 -83
- package/src/core/xy.js +81 -0
- package/src/element.js +13 -0
- package/src/entries/area.js +10 -0
- package/src/entries/bars.js +10 -0
- package/src/entries/donut.js +10 -0
- package/src/entries/gauge.js +10 -0
- package/src/entries/heatmap.js +10 -0
- package/src/entries/line.js +10 -0
- package/src/entries/progress.js +10 -0
- package/src/entries/ring.js +10 -0
- package/src/entries/scatter.js +10 -0
- package/src/entries/spark.js +10 -0
- package/src/index.js +14 -17
- package/src/render.js +13 -12
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { newId, r2, num, list, series, bool, fmt, pathOf, text, small, palette, emptyState, parseNotes, statOf } from '../core/util.js';
|
|
2
|
+
import { seriesTable, styleOf, pattern, DASHES, SHAPES, PATTERNS } from '../core/series.js';
|
|
3
|
+
import { xyFrame, xyFinish, lineKey, seriesLine, pointMarks } from '../core/xy.js';
|
|
4
|
+
import { tile } from '../core/tile.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Areas over time. Several series overlap as see-through fills; `stacked` piles them so the top edge is the total,
|
|
8
|
+
* and stacked="percent" scales each column to 100% to show shares. The axis always includes zero, since an area's
|
|
9
|
+
* height reads as an amount.
|
|
10
|
+
*/
|
|
11
|
+
export default function area(o, th) {
|
|
12
|
+
var S = series(o.values), names = list(o.series), labels = list(o.labels), pal = palette(o, th);
|
|
13
|
+
var h = num(o.height, 170), k = S.length, n = Math.max.apply(null, [0].concat(S.map(function (s) { return s.length; })));
|
|
14
|
+
var mode = k > 1 ? (o.stacked === 'percent' ? 'percent' : bool(o.stacked) ? 'stack' : '') : '';
|
|
15
|
+
var notes = parseNotes(o, labels), multi = k > 1 || names.length > 0;
|
|
16
|
+
var nameOf = function (j) { return names[j] || 'Series ' + (j + 1); };
|
|
17
|
+
var val = function (j, i) { return i < S[j].length ? S[j][i] : 0; };
|
|
18
|
+
|
|
19
|
+
// Where each band starts and ends in every column. In a stack, positive parts pile up from zero and negative parts
|
|
20
|
+
// down from it, as stacked bars do. In a percent stack, each column's positive parts are scaled to add up to 100.
|
|
21
|
+
var lows = S.map(function () { return []; }), highs = S.map(function () { return []; }), totals = [], pos = [];
|
|
22
|
+
for (var i = 0; i < n; i++) {
|
|
23
|
+
var up = 0, down = 0, t = 0, p = 0;
|
|
24
|
+
for (var j = 0; j < k; j++) { t += val(j, i); p += Math.max(0, val(j, i)); }
|
|
25
|
+
totals.push(t); pos.push(p);
|
|
26
|
+
for (j = 0; j < k; j++) {
|
|
27
|
+
var v = mode === 'percent' ? (p ? Math.max(0, val(j, i)) / p * 100 : 0) : val(j, i);
|
|
28
|
+
if (!mode) { lows[j].push(0); highs[j].push(v); }
|
|
29
|
+
else if (v >= 0) { lows[j].push(up); up += v; highs[j].push(up); }
|
|
30
|
+
else { lows[j].push(down); down += v; highs[j].push(down); }
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
var edges = [].concat.apply([], lows.concat(highs));
|
|
34
|
+
|
|
35
|
+
var dashOf = styleOf(o.dash, Object.keys(DASHES), 'solid'), markOf = styleOf(o.markers, SHAPES, 'none');
|
|
36
|
+
var patOf = k > 1 ? styleOf(o.patterns, PATTERNS, 'solid') : null, bg = o.background || th.tile, defs = '', fills = [];
|
|
37
|
+
for (var q = 0; patOf && q < k; q++) {
|
|
38
|
+
if (patOf(q) === 'solid') continue;
|
|
39
|
+
var pid = newId('g');
|
|
40
|
+
defs += pattern(pid, patOf(q), pal[q % pal.length], bg);
|
|
41
|
+
fills[q] = 'url(#' + pid + ')';
|
|
42
|
+
}
|
|
43
|
+
// The legend shows each band's pattern, or a sample of its edge when lines have dashes or markers.
|
|
44
|
+
var key = patOf
|
|
45
|
+
? function (j, x, y) { return '<rect x="' + r2(x) + '" y="' + r2(y + 1) + '" width="10" height="10" rx="2" fill="' + (fills[j] || pal[j % pal.length]) + '"/>'; }
|
|
46
|
+
: (dashOf || markOf) && lineKey(pal, dashOf, markOf, bg);
|
|
47
|
+
var share = function (j, i) { return pos[i] ? Math.round(Math.max(0, val(j, i)) / pos[i] * 100) : 0; };
|
|
48
|
+
|
|
49
|
+
return tile(o, th, h, function (x0, y0, w, h) {
|
|
50
|
+
if (!n) return emptyState(th, x0, y0, w, h);
|
|
51
|
+
var f = xyFrame(o, th, {
|
|
52
|
+
n: n, names: multi ? S.map(function (_, j) { return nameOf(j); }) : null, pal: pal, key: key, kw: key && (patOf ? 15 : 24),
|
|
53
|
+
lo: Math.min.apply(null, edges), hi: Math.max.apply(null, edges), zero: true, labels: labels, notes: notes,
|
|
54
|
+
tick: mode === 'percent' ? function (t) { return fmt(t, { lang: o.lang }, true) + '%'; } : function (t) { return fmt(t, o, true); },
|
|
55
|
+
}, x0, y0, w, h);
|
|
56
|
+
var s = (defs ? '<defs>' + defs + '</defs>' : '') + f.svg, X = f.X, Y = f.Y;
|
|
57
|
+
// One value stretches across the chart, like a line chart does.
|
|
58
|
+
var pts = function (ys) {
|
|
59
|
+
var P = ys.map(function (y, i) { return [X(i), Y(y)]; });
|
|
60
|
+
return P.length === 1 ? [[f.px, P[0][1]], [f.px + f.pw, P[0][1]]] : P;
|
|
61
|
+
};
|
|
62
|
+
var straight = bool(o.straight), alpha = mode ? '.8' : '.22';
|
|
63
|
+
var shown = function (j) { return mode ? highs[j] : S[j]; };
|
|
64
|
+
// Fills first, so no band covers another's edge.
|
|
65
|
+
S.forEach(function (_, j) {
|
|
66
|
+
var top = pts(shown(j)), base = pts(mode ? lows[j] : shown(j).map(function () { return 0; })).reverse();
|
|
67
|
+
s += '<path d="' + pathOf(top, straight) + pathOf(base, straight).replace(/^M/, 'L') + 'Z" fill="' + (fills[j] || pal[j % pal.length]) +
|
|
68
|
+
'" fill-opacity="' + alpha + '"' + (o.animate ? ' class="bzc-a" style="animation-delay:' + r2(j * 0.1) + 's"' : '') + '/>';
|
|
69
|
+
});
|
|
70
|
+
S.forEach(function (_, j) {
|
|
71
|
+
var c = pal[j % pal.length], ys = shown(j), P = pts(ys), mk = markOf ? markOf(j) : 'none';
|
|
72
|
+
s += seriesLine(o, pathOf(P, straight), c, j, dashOf ? DASHES[dashOf(j)] : '');
|
|
73
|
+
if (mk !== 'none') s += pointMarks(o, mk, ys, X, Y, c, bg, j);
|
|
74
|
+
else if (!mode) s += '<circle cx="' + r2(P[P.length - 1][0]) + '" cy="' + r2(P[P.length - 1][1]) + '" r="4" fill="' + c + '" stroke="' + bg + '" stroke-width="2"/>';
|
|
75
|
+
if (bool(o.showValues) && !mode) ys.forEach(function (y, i) { s += text(X(i), Y(y) - 8, fmt(y, o, true), small(th, 9, 'text-anchor="middle"')); });
|
|
76
|
+
});
|
|
77
|
+
// A stack writes its total above each column. Every column of a percent stack is 100%, so it writes nothing.
|
|
78
|
+
if (bool(o.showValues) && mode === 'stack') {
|
|
79
|
+
totals.forEach(function (t, i) {
|
|
80
|
+
var top = Math.max.apply(null, highs.map(function (hs) { return hs[i]; }).concat([0]));
|
|
81
|
+
s += text(X(i), Y(top) - 8, fmt(t, o, true), small(th, 9, 'text-anchor="middle"'));
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return s + xyFinish(o, th, f, n, function (i) {
|
|
85
|
+
var tip = labels[i] || '#' + (i + 1);
|
|
86
|
+
S.forEach(function (ser, j) {
|
|
87
|
+
if (i < ser.length) tip += '\n' + (multi ? nameOf(j) + ': ' : '') + fmt(ser[i], o) + (mode === 'percent' ? ' (' + share(j, i) + '%)' : '');
|
|
88
|
+
});
|
|
89
|
+
return tip + (mode ? '\nTotal: ' + fmt(totals[i], o) : '');
|
|
90
|
+
});
|
|
91
|
+
}, {
|
|
92
|
+
stat: statOf(mode ? totals : S[0] || [], o, ''),
|
|
93
|
+
summary: k + ' series ' + (mode === 'percent' ? 'as shares of each total' : mode ? 'stacked' : 'filled') + ' over ' + n + ' points',
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
area.table = function (o) { var S = series(o.values); return seriesTable(o, S.length > 1 && (o.stacked === 'percent' || bool(o.stacked))); };
|
package/src/charts/bars.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { newId, r2, num, has, list, series, tw, trunc, bool, fmt, text, small, hit, anim, palette, emptyState, goalLine, statOf,
|
|
1
|
+
import { newId, r2, num, has, list, series, tw, trunc, bool, fmt, text, small, hit, anim, palette, emptyState, goalLine, statOf, SANS, MONO } from '../core/util.js';
|
|
2
|
+
import { legend, seriesTable, styleOf, pattern, PATTERNS } from '../core/series.js';
|
|
2
3
|
import { tile, dims } from '../core/tile.js';
|
|
3
4
|
|
|
4
5
|
/** How far angled labels lean, and the longest label they show before shortening it. */
|
package/src/charts/line.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { newId, r2,
|
|
1
|
+
import { newId, r2, num, list, series, bool, fmt, pathOf, text, small, anim, palette, emptyState, parseNotes, statOf } from '../core/util.js';
|
|
2
|
+
import { seriesTable, styleOf, DASHES, SHAPES } from '../core/series.js';
|
|
3
|
+
import { xyFrame, xyFinish, lineKey, seriesLine, pointMarks } from '../core/xy.js';
|
|
2
4
|
import { tile } from '../core/tile.js';
|
|
3
5
|
|
|
4
6
|
export default function line(o, th) {
|
|
@@ -9,49 +11,17 @@ export default function line(o, th) {
|
|
|
9
11
|
var dashOf = styleOf(o.dash, Object.keys(DASHES), 'solid'), markOf = styleOf(o.markers, SHAPES, 'none');
|
|
10
12
|
var bg = o.background || th.tile;
|
|
11
13
|
// With dashes or markers, the legend shows a short sample of each line instead of a dot.
|
|
12
|
-
var key = (dashOf || markOf) &&
|
|
13
|
-
|
|
14
|
-
return '<line x1="' + r2(x) + '" x2="' + r2(x + 18) + '" y1="' + r2(y + 6) + '" y2="' + r2(y + 6) + '" stroke="' + c + '" stroke-width="2.5" stroke-linecap="round"' +
|
|
15
|
-
(dk ? ' stroke-dasharray="' + dk + '"' : '') + '/>' + (mk !== 'none' ? marker(mk, x + 9, y + 6, 3.5, ' fill="' + c + '" stroke="' + bg + '" stroke-width="1.5"') : '');
|
|
16
|
-
};
|
|
14
|
+
var key = (dashOf || markOf) && lineKey(pal, dashOf, markOf, bg);
|
|
15
|
+
var nameOf = function (k) { return names[k] || 'Series ' + (k + 1); };
|
|
17
16
|
return tile(o, th, h, function (x0, y0, w, h) {
|
|
18
17
|
if (!n) return emptyState(th, x0, y0, w, h);
|
|
19
|
-
var s = '', top = y0;
|
|
20
|
-
if (multi) {
|
|
21
|
-
var lg = legend(S.map(function (_, k) { return names[k] || 'Series ' + (k + 1); }), pal, th, x0, top, w, key, key && 24);
|
|
22
|
-
s += lg.svg;
|
|
23
|
-
top += lg.height;
|
|
24
|
-
}
|
|
25
18
|
var all = [].concat.apply([], S);
|
|
26
|
-
var
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
var
|
|
32
|
-
var bottom = labels.length ? 20 : 4;
|
|
33
|
-
var px = x0 + axisW, pw = w - axisW, ph = h - (top - y0) - bottom;
|
|
34
|
-
var X = function (i) { return n === 1 ? px + pw / 2 : px + i * pw / (n - 1); };
|
|
35
|
-
var Y = function (v) { return top + ph - (v - sc.lo) / (sc.hi - sc.lo) * ph; };
|
|
36
|
-
sc.ticks.forEach(function (t, i) {
|
|
37
|
-
var y = Y(t);
|
|
38
|
-
s += '<line x1="' + r2(px) + '" x2="' + r2(px + pw) + '" y1="' + r2(y) + '" y2="' + r2(y) + '" stroke="' + th.grid + '"' + (t === 0 ? '' : ' stroke-dasharray="2 4"') + '/>' +
|
|
39
|
-
text(px - 8, y + 3.5, tl[i], small(th, 10, 'text-anchor="end"'));
|
|
40
|
-
});
|
|
41
|
-
if (labels.length) {
|
|
42
|
-
var every = Math.max(1, Math.ceil(n * (Math.max.apply(null, labels.map(function (l) { return tw(l, 10, true); })) + 10) / pw));
|
|
43
|
-
for (var i = 0; i < n; i += every) {
|
|
44
|
-
if (labels[i] == null) continue;
|
|
45
|
-
var anchor = n > 1 && i === 0 ? 'start' : n > 1 && i === n - 1 ? 'end' : 'middle';
|
|
46
|
-
s += text(X(i), top + ph + 15, labels[i], small(th, 10, 'text-anchor="' + anchor + '"'));
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
notes.forEach(function (nt) {
|
|
50
|
-
if (nt.i >= n) return;
|
|
51
|
-
var x = X(nt.i);
|
|
52
|
-
s += '<line x1="' + r2(x) + '" x2="' + r2(x) + '" y1="' + r2(top + 12) + '" y2="' + r2(top + ph) + '" stroke="' + th.fg + '" stroke-opacity=".4" stroke-dasharray="3 3"/>' +
|
|
53
|
-
text(clamp(x, px + 30, px + pw - 30), top + 8, nt.text, small(th, 10, 'text-anchor="middle"', th.fg));
|
|
54
|
-
});
|
|
19
|
+
var f = xyFrame(o, th, {
|
|
20
|
+
n: n, names: multi ? S.map(function (_, k) { return nameOf(k); }) : null, pal: pal, key: key, kw: key && 24,
|
|
21
|
+
lo: Math.min.apply(null, all), hi: Math.max.apply(null, all), zero: bool(o.zero), labels: labels, notes: notes,
|
|
22
|
+
tick: function (t) { return fmt(t, o, true); },
|
|
23
|
+
}, x0, y0, w, h);
|
|
24
|
+
var s = f.svg, X = f.X, Y = f.Y, px = f.px, pw = f.pw, top = f.top, ph = f.ph;
|
|
55
25
|
S.forEach(function (v, k) {
|
|
56
26
|
var c = pal[k % pal.length];
|
|
57
27
|
var P = v.map(function (y, i) { return [X(i), Y(y)]; });
|
|
@@ -62,31 +32,21 @@ export default function line(o, th) {
|
|
|
62
32
|
s += '<defs><linearGradient id="' + g + '" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="' + c + '" stop-opacity=".26"/><stop offset="1" stop-color="' + c + '" stop-opacity="0"/></linearGradient></defs>' +
|
|
63
33
|
'<path d="' + d + 'L' + r2(last[0]) + ',' + r2(top + ph) + 'L' + r2(P[0][0]) + ',' + r2(top + ph) + 'Z" fill="url(#' + g + ')"' + anim(o, 'bzc-a') + '/>';
|
|
64
34
|
}
|
|
65
|
-
var
|
|
66
|
-
|
|
67
|
-
s += dk
|
|
68
|
-
? '<path d="' + d + '" fill="none" stroke="' + c + '" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="' + dk + '"' + anim(o, 'bzc-a', k * 0.15) + '/>'
|
|
69
|
-
: '<path d="' + d + '" fill="none" stroke="' + c + '" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" pathLength="1" style="stroke-dasharray:1' + (o.animate ? ';animation-delay:' + k * 0.15 + 's' : '') + '"' + (o.animate ? ' class="bzc-d"' : '') + '/>';
|
|
35
|
+
var mk = markOf ? markOf(k) : 'none';
|
|
36
|
+
s += seriesLine(o, d, c, k, dashOf ? DASHES[dashOf(k)] : '');
|
|
70
37
|
if (mk !== 'none') {
|
|
71
|
-
|
|
72
|
-
var every = Math.ceil(v.length / 40);
|
|
73
|
-
v.forEach(function (y, i) {
|
|
74
|
-
if (i % every === 0 || i === v.length - 1) s += marker(mk, X(i), Y(y), 3.5, ' fill="' + c + '" stroke="' + bg + '" stroke-width="1.5"' + anim(o, 'bzc-a', 0.6 + k * 0.15));
|
|
75
|
-
});
|
|
38
|
+
s += pointMarks(o, mk, v, X, Y, c, bg, k);
|
|
76
39
|
} else {
|
|
77
40
|
var e = P[P.length - 1];
|
|
78
41
|
s += '<circle cx="' + r2(e[0]) + '" cy="' + r2(e[1]) + '" r="4" fill="' + c + '" stroke="' + bg + '" stroke-width="2"/>';
|
|
79
42
|
}
|
|
80
43
|
if (bool(o.showValues)) v.forEach(function (y, i) { s += text(X(i), Y(y) - 8, fmt(y, o, true), small(th, 9, 'text-anchor="middle"')); });
|
|
81
44
|
});
|
|
82
|
-
|
|
83
|
-
var step = n > 1 ? pw / (n - 1) : pw;
|
|
84
|
-
for (var j = 0; j < n; j++) {
|
|
45
|
+
return s + xyFinish(o, th, f, n, function (j) {
|
|
85
46
|
var tip = labels[j] || '#' + (j + 1);
|
|
86
|
-
S.forEach(function (v, k) { if (j < v.length) tip += '\n' + (multi ? (
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
return s;
|
|
47
|
+
S.forEach(function (v, k) { if (j < v.length) tip += '\n' + (multi ? nameOf(k) + ': ' : '') + fmt(v[j], o); });
|
|
48
|
+
return tip;
|
|
49
|
+
});
|
|
90
50
|
}, { stat: st, summary: S.length + ' series over ' + n + ' points' });
|
|
91
51
|
}
|
|
92
52
|
|
package/src/charts/scatter.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { r2, clamp, num, has, list, series, bool, fmt,
|
|
1
|
+
import { r2, clamp, num, has, list, series, bool, fmt, text, small, hit, palette, emptyState, parseNotes, goalLine } from '../core/util.js';
|
|
2
|
+
import { niceScale, legend, axisWidth, styleOf, marker, SHAPES } from '../core/series.js';
|
|
2
3
|
import { tile } from '../core/tile.js';
|
|
3
4
|
|
|
4
5
|
/** Least-squares fit. Returns slope, intercept and Pearson's r, or null when x has no spread. */
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/** Helpers for the charts with axes and several series: line, bars and scatter. Kept apart from util.js so the other charts don't load them. */
|
|
2
|
+
import { r2, list, series, fmt, tw, text, SANS } from './util.js';
|
|
3
|
+
|
|
4
|
+
export function niceScale(min, max, count) {
|
|
5
|
+
if (min === max) {
|
|
6
|
+
if (min === 0) max = 1;
|
|
7
|
+
else { var p = Math.abs(min) * 0.1; min -= p; max += p; }
|
|
8
|
+
}
|
|
9
|
+
var step0 = (max - min) / (count || 4);
|
|
10
|
+
var mag = Math.pow(10, Math.floor(Math.log10(step0)));
|
|
11
|
+
var err = step0 / mag;
|
|
12
|
+
var step = (err <= 1 ? 1 : err <= 2 ? 2 : err <= 5 ? 5 : 10) * mag;
|
|
13
|
+
var lo = Math.floor(min / step) * step, hi = Math.ceil(max / step) * step, ticks = [];
|
|
14
|
+
for (var t = lo; t <= hi + step / 2; t += step) ticks.push(+t.toFixed(10));
|
|
15
|
+
return { lo: lo, hi: hi, ticks: ticks };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* A wrapping row of coloured dots and series names. Returns the SVG and the height it used.
|
|
20
|
+
* key(k, x, y) draws a different swatch, such as a dashed line, and kw is the room it takes before the name.
|
|
21
|
+
*/
|
|
22
|
+
export function legend(names, pal, th, x0, y0, w, key, kw) {
|
|
23
|
+
var x = x0, y = y0, s = '', off = kw || 13;
|
|
24
|
+
names.forEach(function (nm, k) {
|
|
25
|
+
var wd = off + tw(nm, 12) + 16;
|
|
26
|
+
if (x > x0 && x + wd - 16 > x0 + w) { x = x0; y += 20; }
|
|
27
|
+
s += (key ? key(k, x, y) : '<circle cx="' + r2(x + 4) + '" cy="' + r2(y + 6) + '" r="4" fill="' + pal[k % pal.length] + '"/>') +
|
|
28
|
+
text(x + off, y + 10, nm, 'fill="' + th.fg + '" font-family="' + SANS + '" font-size="12"');
|
|
29
|
+
x += wd;
|
|
30
|
+
});
|
|
31
|
+
return { svg: s, height: y - y0 + 24 };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Line dashes, marker shapes and bar patterns, so series differ by more than colour. "auto" hands them out in this order. */
|
|
35
|
+
export var DASHES = { solid: '', dashed: '7 5', dotted: '1 5', dashdot: '9 4 1 4' };
|
|
36
|
+
export var SHAPES = ['circle', 'square', 'triangle', 'diamond'];
|
|
37
|
+
export var PATTERNS = ['solid', 'stripes', 'dots', 'grid'];
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Reads dash, markers or patterns. The bare attribute or "auto" hands out every style in turn; a list sets one per series,
|
|
41
|
+
* repeating like colours do. Returns a function from series index to style name, or null when the option is off.
|
|
42
|
+
*/
|
|
43
|
+
export function styleOf(v, names, off) {
|
|
44
|
+
if (v == null || v === false || v === 'none' || v === 'false') return null;
|
|
45
|
+
var l = v === true || v === '' || v === 'auto' ? names : list(v).map(function (s) { return names.indexOf(s) < 0 ? off : s; });
|
|
46
|
+
if (!l.length) return null;
|
|
47
|
+
return function (k) { return l[k % l.length]; };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** A point marker centred on x, y. attrs carries the fill and stroke. */
|
|
51
|
+
export function marker(kind, x, y, r, attrs) {
|
|
52
|
+
var a = r * 1.15, b = r * 0.85;
|
|
53
|
+
if (kind === 'square') return '<rect x="' + r2(x - b) + '" y="' + r2(y - b) + '" width="' + r2(2 * b) + '" height="' + r2(2 * b) + '" rx="1"' + attrs + '/>';
|
|
54
|
+
if (kind === 'triangle') return '<path d="M' + r2(x) + ',' + r2(y - a) + 'L' + r2(x + a) + ',' + r2(y + b) + 'L' + r2(x - a) + ',' + r2(y + b) + 'Z"' + attrs + '/>';
|
|
55
|
+
if (kind === 'diamond') return '<path d="M' + r2(x) + ',' + r2(y - a * 1.1) + 'L' + r2(x + a) + ',' + r2(y) + 'L' + r2(x) + ',' + r2(y + a * 1.1) + 'L' + r2(x - a) + ',' + r2(y) + 'Z"' + attrs + '/>';
|
|
56
|
+
return '<circle cx="' + r2(x) + '" cy="' + r2(y) + '" r="' + r2(r) + '"' + attrs + '/>';
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** A fill pattern in colour c, with stripes, dots or a grid drawn in the tile colour so they show on any colour. */
|
|
60
|
+
export function pattern(id, kind, c, bg) {
|
|
61
|
+
var ink = ' stroke="' + bg + '" stroke-opacity=".55" stroke-width="1.5"';
|
|
62
|
+
return '<pattern id="' + id + '" width="6" height="6" patternUnits="userSpaceOnUse"' + (kind === 'dots' ? '' : ' patternTransform="rotate(45)"') +
|
|
63
|
+
'><rect width="6" height="6" fill="' + c + '"/>' +
|
|
64
|
+
(kind === 'dots' ? '<circle cx="3" cy="3" r="1.3" fill="' + bg + '" fill-opacity=".55"/>' : '<path d="M3,0V6' + (kind === 'grid' ? 'M0,3H6' : '') + '"' + ink + '/>') +
|
|
65
|
+
'</pattern>';
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Value axis: gridlines plus tick labels on the left. Returns the axis width it reserved. */
|
|
69
|
+
export function axisWidth(ticks) {
|
|
70
|
+
return Math.max.apply(null, ticks.map(function (t) { return tw(t, 10, true); })) + 10;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** The data table for charts with labels and one or more series. total adds a column adding each row up. */
|
|
74
|
+
export function seriesTable(o, total) {
|
|
75
|
+
var S = series(o.values), names = list(o.series), labels = list(o.labels), rows = [];
|
|
76
|
+
var n = Math.max.apply(null, [0].concat(S.map(function (s) { return s.length; })));
|
|
77
|
+
for (var i = 0; i < n; i++) {
|
|
78
|
+
var row = [labels[i] || '#' + (i + 1)], t = 0;
|
|
79
|
+
S.forEach(function (s) { row.push(i < s.length ? fmt(s[i], o) : ''); t += i < s.length ? s[i] : 0; });
|
|
80
|
+
if (total) row.push(fmt(t, o));
|
|
81
|
+
rows.push(row);
|
|
82
|
+
}
|
|
83
|
+
var head = S.length > 1 || names.length ? S.map(function (_, k) { return names[k] || 'Series ' + (k + 1); }) : ['Value'];
|
|
84
|
+
return { head: ['Label'].concat(head, total ? ['Total'] : []), rows: rows };
|
|
85
|
+
}
|
package/src/core/util.js
CHANGED
|
@@ -46,20 +46,6 @@ export function fmt(n, o, short) {
|
|
|
46
46
|
return (n < 0 ? '−' : '') + (o.prefix || '') + s + (o.suffix || '');
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
export function niceScale(min, max, count) {
|
|
50
|
-
if (min === max) {
|
|
51
|
-
if (min === 0) max = 1;
|
|
52
|
-
else { var p = Math.abs(min) * 0.1; min -= p; max += p; }
|
|
53
|
-
}
|
|
54
|
-
var step0 = (max - min) / (count || 4);
|
|
55
|
-
var mag = Math.pow(10, Math.floor(Math.log10(step0)));
|
|
56
|
-
var err = step0 / mag;
|
|
57
|
-
var step = (err <= 1 ? 1 : err <= 2 ? 2 : err <= 5 ? 5 : 10) * mag;
|
|
58
|
-
var lo = Math.floor(min / step) * step, hi = Math.ceil(max / step) * step, ticks = [];
|
|
59
|
-
for (var t = lo; t <= hi + step / 2; t += step) ticks.push(+t.toFixed(10));
|
|
60
|
-
return { lo: lo, hi: hi, ticks: ticks };
|
|
61
|
-
}
|
|
62
|
-
|
|
63
49
|
export function pathOf(pts, straight) {
|
|
64
50
|
if (!pts.length) return '';
|
|
65
51
|
var d = 'M' + r2(pts[0][0]) + ',' + r2(pts[0][1]);
|
|
@@ -122,72 +108,3 @@ export function statOf(v, o, fallback) {
|
|
|
122
108
|
if (k === 'last' && v.length > 1 && o.delta !== 'none') delta = v[v.length - 1] - v[0];
|
|
123
109
|
return { val: map[k], delta: delta };
|
|
124
110
|
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* A wrapping row of coloured dots and series names. Returns the SVG and the height it used.
|
|
128
|
-
* key(k, x, y) draws a different swatch, such as a dashed line, and kw is the room it takes before the name.
|
|
129
|
-
*/
|
|
130
|
-
export function legend(names, pal, th, x0, y0, w, key, kw) {
|
|
131
|
-
var x = x0, y = y0, s = '', off = kw || 13;
|
|
132
|
-
names.forEach(function (nm, k) {
|
|
133
|
-
var wd = off + tw(nm, 12) + 16;
|
|
134
|
-
if (x > x0 && x + wd - 16 > x0 + w) { x = x0; y += 20; }
|
|
135
|
-
s += (key ? key(k, x, y) : '<circle cx="' + r2(x + 4) + '" cy="' + r2(y + 6) + '" r="4" fill="' + pal[k % pal.length] + '"/>') +
|
|
136
|
-
text(x + off, y + 10, nm, 'fill="' + th.fg + '" font-family="' + SANS + '" font-size="12"');
|
|
137
|
-
x += wd;
|
|
138
|
-
});
|
|
139
|
-
return { svg: s, height: y - y0 + 24 };
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/** Line dashes, marker shapes and bar patterns, so series differ by more than colour. "auto" hands them out in this order. */
|
|
143
|
-
export var DASHES = { solid: '', dashed: '7 5', dotted: '1 5', dashdot: '9 4 1 4' };
|
|
144
|
-
export var SHAPES = ['circle', 'square', 'triangle', 'diamond'];
|
|
145
|
-
export var PATTERNS = ['solid', 'stripes', 'dots', 'grid'];
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Reads dash, markers or patterns. The bare attribute or "auto" hands out every style in turn; a list sets one per series,
|
|
149
|
-
* repeating like colours do. Returns a function from series index to style name, or null when the option is off.
|
|
150
|
-
*/
|
|
151
|
-
export function styleOf(v, names, off) {
|
|
152
|
-
if (v == null || v === false || v === 'none' || v === 'false') return null;
|
|
153
|
-
var l = v === true || v === '' || v === 'auto' ? names : list(v).map(function (s) { return names.indexOf(s) < 0 ? off : s; });
|
|
154
|
-
if (!l.length) return null;
|
|
155
|
-
return function (k) { return l[k % l.length]; };
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/** A point marker centred on x, y. attrs carries the fill and stroke. */
|
|
159
|
-
export function marker(kind, x, y, r, attrs) {
|
|
160
|
-
var a = r * 1.15, b = r * 0.85;
|
|
161
|
-
if (kind === 'square') return '<rect x="' + r2(x - b) + '" y="' + r2(y - b) + '" width="' + r2(2 * b) + '" height="' + r2(2 * b) + '" rx="1"' + attrs + '/>';
|
|
162
|
-
if (kind === 'triangle') return '<path d="M' + r2(x) + ',' + r2(y - a) + 'L' + r2(x + a) + ',' + r2(y + b) + 'L' + r2(x - a) + ',' + r2(y + b) + 'Z"' + attrs + '/>';
|
|
163
|
-
if (kind === 'diamond') return '<path d="M' + r2(x) + ',' + r2(y - a * 1.1) + 'L' + r2(x + a) + ',' + r2(y) + 'L' + r2(x) + ',' + r2(y + a * 1.1) + 'L' + r2(x - a) + ',' + r2(y) + 'Z"' + attrs + '/>';
|
|
164
|
-
return '<circle cx="' + r2(x) + '" cy="' + r2(y) + '" r="' + r2(r) + '"' + attrs + '/>';
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/** A fill pattern in colour c, with stripes, dots or a grid drawn in the tile colour so they show on any colour. */
|
|
168
|
-
export function pattern(id, kind, c, bg) {
|
|
169
|
-
var ink = ' stroke="' + bg + '" stroke-opacity=".55" stroke-width="1.5"';
|
|
170
|
-
return '<pattern id="' + id + '" width="6" height="6" patternUnits="userSpaceOnUse"' + (kind === 'dots' ? '' : ' patternTransform="rotate(45)"') +
|
|
171
|
-
'><rect width="6" height="6" fill="' + c + '"/>' +
|
|
172
|
-
(kind === 'dots' ? '<circle cx="3" cy="3" r="1.3" fill="' + bg + '" fill-opacity=".55"/>' : '<path d="M3,0V6' + (kind === 'grid' ? 'M0,3H6' : '') + '"' + ink + '/>') +
|
|
173
|
-
'</pattern>';
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/** Value axis: gridlines plus tick labels on the left. Returns the axis width it reserved. */
|
|
177
|
-
export function axisWidth(ticks) {
|
|
178
|
-
return Math.max.apply(null, ticks.map(function (t) { return tw(t, 10, true); })) + 10;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/** The data table for charts with labels and one or more series. total adds a column adding each row up. */
|
|
182
|
-
export function seriesTable(o, total) {
|
|
183
|
-
var S = series(o.values), names = list(o.series), labels = list(o.labels), rows = [];
|
|
184
|
-
var n = Math.max.apply(null, [0].concat(S.map(function (s) { return s.length; })));
|
|
185
|
-
for (var i = 0; i < n; i++) {
|
|
186
|
-
var row = [labels[i] || '#' + (i + 1)], t = 0;
|
|
187
|
-
S.forEach(function (s) { row.push(i < s.length ? fmt(s[i], o) : ''); t += i < s.length ? s[i] : 0; });
|
|
188
|
-
if (total) row.push(fmt(t, o));
|
|
189
|
-
rows.push(row);
|
|
190
|
-
}
|
|
191
|
-
var head = S.length > 1 || names.length ? S.map(function (_, k) { return names[k] || 'Series ' + (k + 1); }) : ['Value'];
|
|
192
|
-
return { head: ['Label'].concat(head, total ? ['Total'] : []), rows: rows };
|
|
193
|
-
}
|
package/src/core/xy.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/** The axis frame and series lines line and area charts share. Kept apart so other charts don't load them. */
|
|
2
|
+
import { r2, clamp, has, tw, text, small, hit, anim, goalLine } from './util.js';
|
|
3
|
+
import { niceScale, legend, marker, DASHES } from './series.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The frame line and area charts share: the legend, the value axis with its gridlines, labels along the bottom and notes.
|
|
7
|
+
* c holds n (points), names (legend names, or null for no legend), pal, key and kw (legend swatches), lo and hi (the data
|
|
8
|
+
* range), zero (keep zero on the axis), labels, notes and tick (formats an axis number).
|
|
9
|
+
* Returns the SVG so far, the scales X(i) and Y(v), and the plot box: px, pw, top, ph.
|
|
10
|
+
*/
|
|
11
|
+
export function xyFrame(o, th, c, x0, y0, w, h) {
|
|
12
|
+
var s = '', top = y0, n = c.n, labels = c.labels;
|
|
13
|
+
if (c.names) {
|
|
14
|
+
var lg = legend(c.names, c.pal, th, x0, top, w, c.key, c.kw);
|
|
15
|
+
s += lg.svg;
|
|
16
|
+
top += lg.height;
|
|
17
|
+
}
|
|
18
|
+
var mn = c.lo, mx = c.hi;
|
|
19
|
+
if (has(o.goal)) { mn = Math.min(mn, +o.goal); mx = Math.max(mx, +o.goal); }
|
|
20
|
+
if (c.zero) { mn = Math.min(0, mn); mx = Math.max(0, mx); }
|
|
21
|
+
var sc = niceScale(mn, mx, 4);
|
|
22
|
+
var tl = sc.ticks.map(c.tick);
|
|
23
|
+
var axisW = Math.max.apply(null, tl.map(function (t) { return tw(t, 10, true); })) + 10;
|
|
24
|
+
var bottom = labels.length ? 20 : 4;
|
|
25
|
+
var px = x0 + axisW, pw = w - axisW, ph = h - (top - y0) - bottom;
|
|
26
|
+
var X = function (i) { return n === 1 ? px + pw / 2 : px + i * pw / (n - 1); };
|
|
27
|
+
var Y = function (v) { return top + ph - (v - sc.lo) / (sc.hi - sc.lo) * ph; };
|
|
28
|
+
sc.ticks.forEach(function (t, i) {
|
|
29
|
+
var y = Y(t);
|
|
30
|
+
s += '<line x1="' + r2(px) + '" x2="' + r2(px + pw) + '" y1="' + r2(y) + '" y2="' + r2(y) + '" stroke="' + th.grid + '"' + (t === 0 ? '' : ' stroke-dasharray="2 4"') + '/>' +
|
|
31
|
+
text(px - 8, y + 3.5, tl[i], small(th, 10, 'text-anchor="end"'));
|
|
32
|
+
});
|
|
33
|
+
if (labels.length) {
|
|
34
|
+
var every = Math.max(1, Math.ceil(n * (Math.max.apply(null, labels.map(function (l) { return tw(l, 10, true); })) + 10) / pw));
|
|
35
|
+
for (var i = 0; i < n; i += every) {
|
|
36
|
+
if (labels[i] == null) continue;
|
|
37
|
+
var anchor = n > 1 && i === 0 ? 'start' : n > 1 && i === n - 1 ? 'end' : 'middle';
|
|
38
|
+
s += text(X(i), top + ph + 15, labels[i], small(th, 10, 'text-anchor="' + anchor + '"'));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
c.notes.forEach(function (nt) {
|
|
42
|
+
if (nt.i >= n) return;
|
|
43
|
+
var x = X(nt.i);
|
|
44
|
+
s += '<line x1="' + r2(x) + '" x2="' + r2(x) + '" y1="' + r2(top + 12) + '" y2="' + r2(top + ph) + '" stroke="' + th.fg + '" stroke-opacity=".4" stroke-dasharray="3 3"/>' +
|
|
45
|
+
text(clamp(x, px + 30, px + pw - 30), top + 8, nt.text, small(th, 10, 'text-anchor="middle"', th.fg));
|
|
46
|
+
});
|
|
47
|
+
return { svg: s, X: X, Y: Y, px: px, pw: pw, top: top, ph: ph };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** The goal line, then one hover column per point, centred on it. tip(j) gives each column's tooltip. */
|
|
51
|
+
export function xyFinish(o, th, f, n, tip) {
|
|
52
|
+
var s = has(o.goal) ? goalLine(o, th, f.px, f.px + f.pw, f.Y(+o.goal)) : '';
|
|
53
|
+
var step = n > 1 ? f.pw / (n - 1) : f.pw;
|
|
54
|
+
for (var j = 0; j < n; j++) s += hit(f.X(j) - step / 2, f.top, step, f.ph, tip(j));
|
|
55
|
+
return s;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** A legend swatch for a line: a short sample with its dash and marker. */
|
|
59
|
+
export function lineKey(pal, dashOf, markOf, bg) {
|
|
60
|
+
return function (k, x, y) {
|
|
61
|
+
var c = pal[k % pal.length], dk = dashOf ? DASHES[dashOf(k)] : '', mk = markOf ? markOf(k) : 'none';
|
|
62
|
+
return '<line x1="' + r2(x) + '" x2="' + r2(x + 18) + '" y1="' + r2(y + 6) + '" y2="' + r2(y + 6) + '" stroke="' + c + '" stroke-width="2.5" stroke-linecap="round"' +
|
|
63
|
+
(dk ? ' stroke-dasharray="' + dk + '"' : '') + '/>' + (mk !== 'none' ? marker(mk, x + 9, y + 6, 3.5, ' fill="' + c + '" stroke="' + bg + '" stroke-width="1.5"') : '');
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** A series line along path d. The draw-in animation is itself a dash, so dashed lines fade in instead. */
|
|
68
|
+
export function seriesLine(o, d, c, k, dk) {
|
|
69
|
+
return dk
|
|
70
|
+
? '<path d="' + d + '" fill="none" stroke="' + c + '" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="' + dk + '"' + anim(o, 'bzc-a', k * 0.15) + '/>'
|
|
71
|
+
: '<path d="' + d + '" fill="none" stroke="' + c + '" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" pathLength="1" style="stroke-dasharray:1' + (o.animate ? ';animation-delay:' + k * 0.15 + 's' : '') + '"' + (o.animate ? ' class="bzc-d"' : '') + '/>';
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Markers on a series' points. Long series get one on every few points, and always on the last. */
|
|
75
|
+
export function pointMarks(o, mk, ys, X, Y, c, bg, k) {
|
|
76
|
+
var s = '', every = Math.ceil(ys.length / 40);
|
|
77
|
+
ys.forEach(function (y, i) {
|
|
78
|
+
if (i % every === 0 || i === ys.length - 1) s += marker(mk, X(i), Y(y), 3.5, ' fill="' + c + '" stroke="' + bg + '" stroke-width="1.5"' + anim(o, 'bzc-a', 0.6 + k * 0.15));
|
|
79
|
+
});
|
|
80
|
+
return s;
|
|
81
|
+
}
|
package/src/element.js
CHANGED
|
@@ -265,3 +265,16 @@ function tableHTML(caption, { head, rows }) {
|
|
|
265
265
|
return `<table><caption>${esc(caption || 'Chart data')}</caption><thead><tr>${head.map((h) => `<th scope="col">${esc(h)}</th>`).join('')}</tr></thead>` +
|
|
266
266
|
`<tbody>${rows.map((r) => `<tr>${cells(r)}</tr>`).join('')}</tbody></table>`;
|
|
267
267
|
}
|
|
268
|
+
|
|
269
|
+
/** Defines <bezel-type>, plus <bezel-chart> if no chart has yet. Safe to call twice, and does nothing outside a browser. */
|
|
270
|
+
export function define(type) {
|
|
271
|
+
if (typeof customElements === 'undefined' || typeof HTMLElement === 'undefined') return;
|
|
272
|
+
if (!customElements.get(`bezel-${type}`)) {
|
|
273
|
+
customElements.define(`bezel-${type}`, class extends BezelChart {
|
|
274
|
+
get chartType() {
|
|
275
|
+
return type;
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
if (!customElements.get('bezel-chart')) customElements.define('bezel-chart', class extends BezelChart {});
|
|
280
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** <bezel-area> on its own: import 'bezel-charts/area', or load dist/charts/area.js. */
|
|
2
|
+
import area from '../charts/area.js';
|
|
3
|
+
import { register } from '../render.js';
|
|
4
|
+
import { define } from '../element.js';
|
|
5
|
+
|
|
6
|
+
register('area', area);
|
|
7
|
+
define('area');
|
|
8
|
+
|
|
9
|
+
export { render, toSVG } from '../render.js';
|
|
10
|
+
export { BezelChart } from '../element.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** <bezel-bars> on its own: import 'bezel-charts/bars', or load dist/charts/bars.js. */
|
|
2
|
+
import bars from '../charts/bars.js';
|
|
3
|
+
import { register } from '../render.js';
|
|
4
|
+
import { define } from '../element.js';
|
|
5
|
+
|
|
6
|
+
register('bars', bars);
|
|
7
|
+
define('bars');
|
|
8
|
+
|
|
9
|
+
export { render, toSVG } from '../render.js';
|
|
10
|
+
export { BezelChart } from '../element.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** <bezel-donut> on its own: import 'bezel-charts/donut', or load dist/charts/donut.js. */
|
|
2
|
+
import donut from '../charts/donut.js';
|
|
3
|
+
import { register } from '../render.js';
|
|
4
|
+
import { define } from '../element.js';
|
|
5
|
+
|
|
6
|
+
register('donut', donut);
|
|
7
|
+
define('donut');
|
|
8
|
+
|
|
9
|
+
export { render, toSVG } from '../render.js';
|
|
10
|
+
export { BezelChart } from '../element.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** <bezel-gauge> on its own: import 'bezel-charts/gauge', or load dist/charts/gauge.js. */
|
|
2
|
+
import gauge from '../charts/gauge.js';
|
|
3
|
+
import { register } from '../render.js';
|
|
4
|
+
import { define } from '../element.js';
|
|
5
|
+
|
|
6
|
+
register('gauge', gauge);
|
|
7
|
+
define('gauge');
|
|
8
|
+
|
|
9
|
+
export { render, toSVG } from '../render.js';
|
|
10
|
+
export { BezelChart } from '../element.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** <bezel-heatmap> on its own: import 'bezel-charts/heatmap', or load dist/charts/heatmap.js. */
|
|
2
|
+
import heatmap from '../charts/heatmap.js';
|
|
3
|
+
import { register } from '../render.js';
|
|
4
|
+
import { define } from '../element.js';
|
|
5
|
+
|
|
6
|
+
register('heatmap', heatmap);
|
|
7
|
+
define('heatmap');
|
|
8
|
+
|
|
9
|
+
export { render, toSVG } from '../render.js';
|
|
10
|
+
export { BezelChart } from '../element.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** <bezel-line> on its own: import 'bezel-charts/line', or load dist/charts/line.js. */
|
|
2
|
+
import line from '../charts/line.js';
|
|
3
|
+
import { register } from '../render.js';
|
|
4
|
+
import { define } from '../element.js';
|
|
5
|
+
|
|
6
|
+
register('line', line);
|
|
7
|
+
define('line');
|
|
8
|
+
|
|
9
|
+
export { render, toSVG } from '../render.js';
|
|
10
|
+
export { BezelChart } from '../element.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** <bezel-progress> on its own: import 'bezel-charts/progress', or load dist/charts/progress.js. */
|
|
2
|
+
import progress from '../charts/progress.js';
|
|
3
|
+
import { register } from '../render.js';
|
|
4
|
+
import { define } from '../element.js';
|
|
5
|
+
|
|
6
|
+
register('progress', progress);
|
|
7
|
+
define('progress');
|
|
8
|
+
|
|
9
|
+
export { render, toSVG } from '../render.js';
|
|
10
|
+
export { BezelChart } from '../element.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** <bezel-ring> on its own: import 'bezel-charts/ring', or load dist/charts/ring.js. */
|
|
2
|
+
import ring from '../charts/ring.js';
|
|
3
|
+
import { register } from '../render.js';
|
|
4
|
+
import { define } from '../element.js';
|
|
5
|
+
|
|
6
|
+
register('ring', ring);
|
|
7
|
+
define('ring');
|
|
8
|
+
|
|
9
|
+
export { render, toSVG } from '../render.js';
|
|
10
|
+
export { BezelChart } from '../element.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** <bezel-scatter> on its own: import 'bezel-charts/scatter', or load dist/charts/scatter.js. */
|
|
2
|
+
import scatter from '../charts/scatter.js';
|
|
3
|
+
import { register } from '../render.js';
|
|
4
|
+
import { define } from '../element.js';
|
|
5
|
+
|
|
6
|
+
register('scatter', scatter);
|
|
7
|
+
define('scatter');
|
|
8
|
+
|
|
9
|
+
export { render, toSVG } from '../render.js';
|
|
10
|
+
export { BezelChart } from '../element.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** <bezel-spark> on its own: import 'bezel-charts/spark', or load dist/charts/spark.js. */
|
|
2
|
+
import spark from '../charts/spark.js';
|
|
3
|
+
import { register } from '../render.js';
|
|
4
|
+
import { define } from '../element.js';
|
|
5
|
+
|
|
6
|
+
register('spark', spark);
|
|
7
|
+
define('spark');
|
|
8
|
+
|
|
9
|
+
export { render, toSVG } from '../render.js';
|
|
10
|
+
export { BezelChart } from '../element.js';
|