bezel-charts 1.3.0 → 1.5.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 +53 -9
- package/dist/bezel-charts.iife.js +12 -9
- package/dist/bezel-charts.js +457 -90
- package/dist/bezel-charts.min.js +12 -9
- package/dist/charts/area.js +4 -0
- package/dist/charts/bars.js +2 -2
- package/dist/charts/donut.js +2 -2
- package/dist/charts/gauge.js +2 -2
- package/dist/charts/heatmap.js +2 -2
- package/dist/charts/histogram.js +3 -0
- package/dist/charts/line.js +3 -3
- package/dist/charts/progress.js +2 -2
- package/dist/charts/ring.js +2 -2
- package/dist/charts/scatter.js +2 -2
- package/dist/charts/shared-5J5X5F2N.js +2 -0
- package/dist/charts/{shared-PCFIMFLL.js → shared-I437GKHE.js} +2 -2
- package/dist/charts/shared-WQEE2V6C.js +2 -0
- package/dist/charts/spark.js +2 -2
- package/package.json +6 -3
- package/src/charts/area.js +97 -0
- package/src/charts/histogram.js +182 -0
- package/src/charts/line.js +18 -59
- package/src/core/xy.js +81 -0
- package/src/element.js +1 -1
- package/src/entries/area.js +10 -0
- package/src/entries/histogram.js +10 -0
- package/src/index.js +3 -1
- package/src/render.js +1 -1
- package/dist/charts/shared-L67BQ555.js +0 -2
package/dist/bezel-charts.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Bezel Charts v1.
|
|
1
|
+
/*! Bezel Charts v1.5.0 | MIT | github.com/ShazMoghaddam/bezel-charts */
|
|
2
2
|
|
|
3
3
|
// src/core/util.js
|
|
4
4
|
var SANS = "ui-sans-serif,system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif";
|
|
@@ -268,7 +268,7 @@ var THEMES = {
|
|
|
268
268
|
};
|
|
269
269
|
|
|
270
270
|
// src/render.js
|
|
271
|
-
var NAMES = ["spark", "line", "bars", "scatter", "ring", "donut", "gauge", "progress", "heatmap"];
|
|
271
|
+
var NAMES = ["spark", "line", "area", "bars", "histogram", "scatter", "ring", "donut", "gauge", "progress", "heatmap"];
|
|
272
272
|
var TYPES = {};
|
|
273
273
|
function register(type, fn) {
|
|
274
274
|
TYPES[type] = fn;
|
|
@@ -346,7 +346,11 @@ var ATTRIBUTES = [
|
|
|
346
346
|
"angle-labels",
|
|
347
347
|
"dash",
|
|
348
348
|
"markers",
|
|
349
|
-
"patterns"
|
|
349
|
+
"patterns",
|
|
350
|
+
"bins",
|
|
351
|
+
"bin-width",
|
|
352
|
+
"mark",
|
|
353
|
+
"percent"
|
|
350
354
|
];
|
|
351
355
|
var HOST_CSS = `:host{display:block;position:relative;max-width:100%}:host([hidden]){display:none}svg{display:block;max-width:100%;height:auto;overflow:visible}.tip{position:absolute;left:0;top:0;pointer-events:none;background:#0b0b10;color:#f2f1f7;font:600 12px/1.5 ${MONO};padding:7px 10px;border-radius:10px;white-space:pre;opacity:0;transform:translate(-50%,calc(-100% - 12px));transition:opacity .12s;z-index:3;border:1px solid #2a2935;box-shadow:0 8px 24px rgba(0,0,0,.35)}.tip.on{opacity:1}.c{outline:none}.c:focus-visible{outline:2px solid #fff;outline-offset:3px;box-shadow:0 0 0 7px #000}.k{stroke:currentColor;stroke-width:2;stroke-opacity:1}.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}@media (forced-colors:active){.c:focus-visible{outline-color:Highlight}}`;
|
|
352
356
|
var STEPS = { ArrowLeft: -1, ArrowUp: -1, ArrowRight: 1, ArrowDown: 1 };
|
|
@@ -635,7 +639,7 @@ function axisWidth(ticks) {
|
|
|
635
639
|
return tw(t, 10, true);
|
|
636
640
|
})) + 10;
|
|
637
641
|
}
|
|
638
|
-
function seriesTable(o,
|
|
642
|
+
function seriesTable(o, total2) {
|
|
639
643
|
var S = series(o.values), names = list(o.series), labels = list(o.labels), rows = [];
|
|
640
644
|
var n = Math.max.apply(null, [0].concat(S.map(function(s) {
|
|
641
645
|
return s.length;
|
|
@@ -646,13 +650,87 @@ function seriesTable(o, total) {
|
|
|
646
650
|
row.push(i < s.length ? fmt(s[i], o) : "");
|
|
647
651
|
t += i < s.length ? s[i] : 0;
|
|
648
652
|
});
|
|
649
|
-
if (
|
|
653
|
+
if (total2) row.push(fmt(t, o));
|
|
650
654
|
rows.push(row);
|
|
651
655
|
}
|
|
652
656
|
var head = S.length > 1 || names.length ? S.map(function(_, k) {
|
|
653
657
|
return names[k] || "Series " + (k + 1);
|
|
654
658
|
}) : ["Value"];
|
|
655
|
-
return { head: ["Label"].concat(head,
|
|
659
|
+
return { head: ["Label"].concat(head, total2 ? ["Total"] : []), rows };
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
// src/core/xy.js
|
|
663
|
+
function xyFrame(o, th, c, x0, y0, w, h) {
|
|
664
|
+
var s = "", top = y0, n = c.n, labels = c.labels;
|
|
665
|
+
if (c.names) {
|
|
666
|
+
var lg = legend(c.names, c.pal, th, x0, top, w, c.key, c.kw);
|
|
667
|
+
s += lg.svg;
|
|
668
|
+
top += lg.height;
|
|
669
|
+
}
|
|
670
|
+
var mn = c.lo, mx = c.hi;
|
|
671
|
+
if (has(o.goal)) {
|
|
672
|
+
mn = Math.min(mn, +o.goal);
|
|
673
|
+
mx = Math.max(mx, +o.goal);
|
|
674
|
+
}
|
|
675
|
+
if (c.zero) {
|
|
676
|
+
mn = Math.min(0, mn);
|
|
677
|
+
mx = Math.max(0, mx);
|
|
678
|
+
}
|
|
679
|
+
var sc = niceScale(mn, mx, 4);
|
|
680
|
+
var tl = sc.ticks.map(c.tick);
|
|
681
|
+
var axisW = Math.max.apply(null, tl.map(function(t) {
|
|
682
|
+
return tw(t, 10, true);
|
|
683
|
+
})) + 10;
|
|
684
|
+
var bottom = labels.length ? 20 : 4;
|
|
685
|
+
var px = x0 + axisW, pw = w - axisW, ph = h - (top - y0) - bottom;
|
|
686
|
+
var X = function(i2) {
|
|
687
|
+
return n === 1 ? px + pw / 2 : px + i2 * pw / (n - 1);
|
|
688
|
+
};
|
|
689
|
+
var Y = function(v) {
|
|
690
|
+
return top + ph - (v - sc.lo) / (sc.hi - sc.lo) * ph;
|
|
691
|
+
};
|
|
692
|
+
sc.ticks.forEach(function(t, i2) {
|
|
693
|
+
var y = Y(t);
|
|
694
|
+
s += '<line x1="' + r2(px) + '" x2="' + r2(px + pw) + '" y1="' + r2(y) + '" y2="' + r2(y) + '" stroke="' + th.grid + '"' + (t === 0 ? "" : ' stroke-dasharray="2 4"') + "/>" + text(px - 8, y + 3.5, tl[i2], small(th, 10, 'text-anchor="end"'));
|
|
695
|
+
});
|
|
696
|
+
if (labels.length) {
|
|
697
|
+
var every = Math.max(1, Math.ceil(n * (Math.max.apply(null, labels.map(function(l) {
|
|
698
|
+
return tw(l, 10, true);
|
|
699
|
+
})) + 10) / pw));
|
|
700
|
+
for (var i = 0; i < n; i += every) {
|
|
701
|
+
if (labels[i] == null) continue;
|
|
702
|
+
var anchor = n > 1 && i === 0 ? "start" : n > 1 && i === n - 1 ? "end" : "middle";
|
|
703
|
+
s += text(X(i), top + ph + 15, labels[i], small(th, 10, 'text-anchor="' + anchor + '"'));
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
c.notes.forEach(function(nt) {
|
|
707
|
+
if (nt.i >= n) return;
|
|
708
|
+
var x = X(nt.i);
|
|
709
|
+
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"/>' + text(clamp(x, px + 30, px + pw - 30), top + 8, nt.text, small(th, 10, 'text-anchor="middle"', th.fg));
|
|
710
|
+
});
|
|
711
|
+
return { svg: s, X, Y, px, pw, top, ph };
|
|
712
|
+
}
|
|
713
|
+
function xyFinish(o, th, f, n, tip) {
|
|
714
|
+
var s = has(o.goal) ? goalLine(o, th, f.px, f.px + f.pw, f.Y(+o.goal)) : "";
|
|
715
|
+
var step = n > 1 ? f.pw / (n - 1) : f.pw;
|
|
716
|
+
for (var j = 0; j < n; j++) s += hit(f.X(j) - step / 2, f.top, step, f.ph, tip(j));
|
|
717
|
+
return s;
|
|
718
|
+
}
|
|
719
|
+
function lineKey(pal, dashOf, markOf, bg) {
|
|
720
|
+
return function(k, x, y) {
|
|
721
|
+
var c = pal[k % pal.length], dk = dashOf ? DASHES[dashOf(k)] : "", mk = markOf ? markOf(k) : "none";
|
|
722
|
+
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"' + (dk ? ' stroke-dasharray="' + dk + '"' : "") + "/>" + (mk !== "none" ? marker(mk, x + 9, y + 6, 3.5, ' fill="' + c + '" stroke="' + bg + '" stroke-width="1.5"') : "");
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
function seriesLine(o, d, c, k, dk) {
|
|
726
|
+
return dk ? '<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) + "/>" : '<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"' : "") + "/>";
|
|
727
|
+
}
|
|
728
|
+
function pointMarks(o, mk, ys, X, Y, c, bg, k) {
|
|
729
|
+
var s = "", every = Math.ceil(ys.length / 40);
|
|
730
|
+
ys.forEach(function(y, i) {
|
|
731
|
+
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));
|
|
732
|
+
});
|
|
733
|
+
return s;
|
|
656
734
|
}
|
|
657
735
|
|
|
658
736
|
// src/charts/line.js
|
|
@@ -665,68 +743,35 @@ function line(o, th) {
|
|
|
665
743
|
var st = statOf(S[0] || [], o, "");
|
|
666
744
|
var dashOf = styleOf(o.dash, Object.keys(DASHES), "solid"), markOf = styleOf(o.markers, SHAPES, "none");
|
|
667
745
|
var bg = o.background || th.tile;
|
|
668
|
-
var key = (dashOf || markOf) &&
|
|
669
|
-
|
|
670
|
-
return
|
|
746
|
+
var key = (dashOf || markOf) && lineKey(pal, dashOf, markOf, bg);
|
|
747
|
+
var nameOf = function(k) {
|
|
748
|
+
return names[k] || "Series " + (k + 1);
|
|
671
749
|
};
|
|
672
750
|
return tile(o, th, h, function(x0, y0, w, h2) {
|
|
673
751
|
if (!n) return emptyState(th, x0, y0, w, h2);
|
|
674
|
-
var s = "", top = y0;
|
|
675
|
-
if (multi) {
|
|
676
|
-
var lg = legend(S.map(function(_, k) {
|
|
677
|
-
return names[k] || "Series " + (k + 1);
|
|
678
|
-
}), pal, th, x0, top, w, key, key && 24);
|
|
679
|
-
s += lg.svg;
|
|
680
|
-
top += lg.height;
|
|
681
|
-
}
|
|
682
752
|
var all = [].concat.apply([], S);
|
|
683
|
-
var
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
})) + 10;
|
|
699
|
-
var bottom = labels.length ? 20 : 4;
|
|
700
|
-
var px = x0 + axisW, pw = w - axisW, ph = h2 - (top - y0) - bottom;
|
|
701
|
-
var X = function(i2) {
|
|
702
|
-
return n === 1 ? px + pw / 2 : px + i2 * pw / (n - 1);
|
|
703
|
-
};
|
|
704
|
-
var Y = function(v) {
|
|
705
|
-
return top + ph - (v - sc.lo) / (sc.hi - sc.lo) * ph;
|
|
706
|
-
};
|
|
707
|
-
sc.ticks.forEach(function(t, i2) {
|
|
708
|
-
var y = Y(t);
|
|
709
|
-
s += '<line x1="' + r2(px) + '" x2="' + r2(px + pw) + '" y1="' + r2(y) + '" y2="' + r2(y) + '" stroke="' + th.grid + '"' + (t === 0 ? "" : ' stroke-dasharray="2 4"') + "/>" + text(px - 8, y + 3.5, tl[i2], small(th, 10, 'text-anchor="end"'));
|
|
710
|
-
});
|
|
711
|
-
if (labels.length) {
|
|
712
|
-
var every = Math.max(1, Math.ceil(n * (Math.max.apply(null, labels.map(function(l) {
|
|
713
|
-
return tw(l, 10, true);
|
|
714
|
-
})) + 10) / pw));
|
|
715
|
-
for (var i = 0; i < n; i += every) {
|
|
716
|
-
if (labels[i] == null) continue;
|
|
717
|
-
var anchor = n > 1 && i === 0 ? "start" : n > 1 && i === n - 1 ? "end" : "middle";
|
|
718
|
-
s += text(X(i), top + ph + 15, labels[i], small(th, 10, 'text-anchor="' + anchor + '"'));
|
|
753
|
+
var f = xyFrame(o, th, {
|
|
754
|
+
n,
|
|
755
|
+
names: multi ? S.map(function(_, k) {
|
|
756
|
+
return nameOf(k);
|
|
757
|
+
}) : null,
|
|
758
|
+
pal,
|
|
759
|
+
key,
|
|
760
|
+
kw: key && 24,
|
|
761
|
+
lo: Math.min.apply(null, all),
|
|
762
|
+
hi: Math.max.apply(null, all),
|
|
763
|
+
zero: bool(o.zero),
|
|
764
|
+
labels,
|
|
765
|
+
notes,
|
|
766
|
+
tick: function(t) {
|
|
767
|
+
return fmt(t, o, true);
|
|
719
768
|
}
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
if (nt.i >= n) return;
|
|
723
|
-
var x = X(nt.i);
|
|
724
|
-
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"/>' + text(clamp(x, px + 30, px + pw - 30), top + 8, nt.text, small(th, 10, 'text-anchor="middle"', th.fg));
|
|
725
|
-
});
|
|
769
|
+
}, x0, y0, w, h2);
|
|
770
|
+
var s = f.svg, X = f.X, Y = f.Y, px = f.px, pw = f.pw, top = f.top, ph = f.ph;
|
|
726
771
|
S.forEach(function(v, k) {
|
|
727
772
|
var c = pal[k % pal.length];
|
|
728
|
-
var P = v.map(function(y,
|
|
729
|
-
return [X(
|
|
773
|
+
var P = v.map(function(y, i) {
|
|
774
|
+
return [X(i), Y(y)];
|
|
730
775
|
});
|
|
731
776
|
if (P.length === 1) P = [[px, P[0][1]], [px + pw, P[0][1]]];
|
|
732
777
|
var d = pathOf(P, bool(o.straight));
|
|
@@ -734,31 +779,25 @@ function line(o, th) {
|
|
|
734
779
|
var g = newId("g"), last = P[P.length - 1];
|
|
735
780
|
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><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") + "/>";
|
|
736
781
|
}
|
|
737
|
-
var
|
|
738
|
-
s +=
|
|
782
|
+
var mk = markOf ? markOf(k) : "none";
|
|
783
|
+
s += seriesLine(o, d, c, k, dashOf ? DASHES[dashOf(k)] : "");
|
|
739
784
|
if (mk !== "none") {
|
|
740
|
-
|
|
741
|
-
v.forEach(function(y, i2) {
|
|
742
|
-
if (i2 % every2 === 0 || i2 === v.length - 1) s += marker(mk, X(i2), Y(y), 3.5, ' fill="' + c + '" stroke="' + bg + '" stroke-width="1.5"' + anim(o, "bzc-a", 0.6 + k * 0.15));
|
|
743
|
-
});
|
|
785
|
+
s += pointMarks(o, mk, v, X, Y, c, bg, k);
|
|
744
786
|
} else {
|
|
745
787
|
var e = P[P.length - 1];
|
|
746
788
|
s += '<circle cx="' + r2(e[0]) + '" cy="' + r2(e[1]) + '" r="4" fill="' + c + '" stroke="' + bg + '" stroke-width="2"/>';
|
|
747
789
|
}
|
|
748
|
-
if (bool(o.showValues)) v.forEach(function(y,
|
|
749
|
-
s += text(X(
|
|
790
|
+
if (bool(o.showValues)) v.forEach(function(y, i) {
|
|
791
|
+
s += text(X(i), Y(y) - 8, fmt(y, o, true), small(th, 9, 'text-anchor="middle"'));
|
|
750
792
|
});
|
|
751
793
|
});
|
|
752
|
-
|
|
753
|
-
var step = n > 1 ? pw / (n - 1) : pw;
|
|
754
|
-
for (var j = 0; j < n; j++) {
|
|
794
|
+
return s + xyFinish(o, th, f, n, function(j) {
|
|
755
795
|
var tip = labels[j] || "#" + (j + 1);
|
|
756
796
|
S.forEach(function(v, k) {
|
|
757
|
-
if (j < v.length) tip += "\n" + (multi ? (
|
|
797
|
+
if (j < v.length) tip += "\n" + (multi ? nameOf(k) + ": " : "") + fmt(v[j], o);
|
|
758
798
|
});
|
|
759
|
-
|
|
760
|
-
}
|
|
761
|
-
return s;
|
|
799
|
+
return tip;
|
|
800
|
+
});
|
|
762
801
|
}, { stat: st, summary: S.length + " series over " + n + " points" });
|
|
763
802
|
}
|
|
764
803
|
line.table = function(o) {
|
|
@@ -769,6 +808,140 @@ line.table = function(o) {
|
|
|
769
808
|
register("line", line);
|
|
770
809
|
define("line");
|
|
771
810
|
|
|
811
|
+
// src/charts/area.js
|
|
812
|
+
function area(o, th) {
|
|
813
|
+
var S = series(o.values), names = list(o.series), labels = list(o.labels), pal = palette(o, th);
|
|
814
|
+
var h = num(o.height, 170), k = S.length, n = Math.max.apply(null, [0].concat(S.map(function(s) {
|
|
815
|
+
return s.length;
|
|
816
|
+
})));
|
|
817
|
+
var mode = k > 1 ? o.stacked === "percent" ? "percent" : bool(o.stacked) ? "stack" : "" : "";
|
|
818
|
+
var notes = parseNotes(o, labels), multi = k > 1 || names.length > 0;
|
|
819
|
+
var nameOf = function(j2) {
|
|
820
|
+
return names[j2] || "Series " + (j2 + 1);
|
|
821
|
+
};
|
|
822
|
+
var val = function(j2, i2) {
|
|
823
|
+
return i2 < S[j2].length ? S[j2][i2] : 0;
|
|
824
|
+
};
|
|
825
|
+
var lows = S.map(function() {
|
|
826
|
+
return [];
|
|
827
|
+
}), highs = S.map(function() {
|
|
828
|
+
return [];
|
|
829
|
+
}), totals = [], pos = [];
|
|
830
|
+
for (var i = 0; i < n; i++) {
|
|
831
|
+
var up = 0, down = 0, t = 0, p = 0;
|
|
832
|
+
for (var j = 0; j < k; j++) {
|
|
833
|
+
t += val(j, i);
|
|
834
|
+
p += Math.max(0, val(j, i));
|
|
835
|
+
}
|
|
836
|
+
totals.push(t);
|
|
837
|
+
pos.push(p);
|
|
838
|
+
for (j = 0; j < k; j++) {
|
|
839
|
+
var v = mode === "percent" ? p ? Math.max(0, val(j, i)) / p * 100 : 0 : val(j, i);
|
|
840
|
+
if (!mode) {
|
|
841
|
+
lows[j].push(0);
|
|
842
|
+
highs[j].push(v);
|
|
843
|
+
} else if (v >= 0) {
|
|
844
|
+
lows[j].push(up);
|
|
845
|
+
up += v;
|
|
846
|
+
highs[j].push(up);
|
|
847
|
+
} else {
|
|
848
|
+
lows[j].push(down);
|
|
849
|
+
down += v;
|
|
850
|
+
highs[j].push(down);
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
var edges = [].concat.apply([], lows.concat(highs));
|
|
855
|
+
var dashOf = styleOf(o.dash, Object.keys(DASHES), "solid"), markOf = styleOf(o.markers, SHAPES, "none");
|
|
856
|
+
var patOf = k > 1 ? styleOf(o.patterns, PATTERNS, "solid") : null, bg = o.background || th.tile, defs = "", fills = [];
|
|
857
|
+
for (var q = 0; patOf && q < k; q++) {
|
|
858
|
+
if (patOf(q) === "solid") continue;
|
|
859
|
+
var pid = newId("g");
|
|
860
|
+
defs += pattern(pid, patOf(q), pal[q % pal.length], bg);
|
|
861
|
+
fills[q] = "url(#" + pid + ")";
|
|
862
|
+
}
|
|
863
|
+
var key = patOf ? function(j2, x, y) {
|
|
864
|
+
return '<rect x="' + r2(x) + '" y="' + r2(y + 1) + '" width="10" height="10" rx="2" fill="' + (fills[j2] || pal[j2 % pal.length]) + '"/>';
|
|
865
|
+
} : (dashOf || markOf) && lineKey(pal, dashOf, markOf, bg);
|
|
866
|
+
var share = function(j2, i2) {
|
|
867
|
+
return pos[i2] ? Math.round(Math.max(0, val(j2, i2)) / pos[i2] * 100) : 0;
|
|
868
|
+
};
|
|
869
|
+
return tile(o, th, h, function(x0, y0, w, h2) {
|
|
870
|
+
if (!n) return emptyState(th, x0, y0, w, h2);
|
|
871
|
+
var f = xyFrame(o, th, {
|
|
872
|
+
n,
|
|
873
|
+
names: multi ? S.map(function(_, j2) {
|
|
874
|
+
return nameOf(j2);
|
|
875
|
+
}) : null,
|
|
876
|
+
pal,
|
|
877
|
+
key,
|
|
878
|
+
kw: key && (patOf ? 15 : 24),
|
|
879
|
+
lo: Math.min.apply(null, edges),
|
|
880
|
+
hi: Math.max.apply(null, edges),
|
|
881
|
+
zero: true,
|
|
882
|
+
labels,
|
|
883
|
+
notes,
|
|
884
|
+
tick: mode === "percent" ? function(t2) {
|
|
885
|
+
return fmt(t2, { lang: o.lang }, true) + "%";
|
|
886
|
+
} : function(t2) {
|
|
887
|
+
return fmt(t2, o, true);
|
|
888
|
+
}
|
|
889
|
+
}, x0, y0, w, h2);
|
|
890
|
+
var s = (defs ? "<defs>" + defs + "</defs>" : "") + f.svg, X = f.X, Y = f.Y;
|
|
891
|
+
var pts = function(ys) {
|
|
892
|
+
var P = ys.map(function(y, i2) {
|
|
893
|
+
return [X(i2), Y(y)];
|
|
894
|
+
});
|
|
895
|
+
return P.length === 1 ? [[f.px, P[0][1]], [f.px + f.pw, P[0][1]]] : P;
|
|
896
|
+
};
|
|
897
|
+
var straight = bool(o.straight), alpha = mode ? ".8" : ".22";
|
|
898
|
+
var shown = function(j2) {
|
|
899
|
+
return mode ? highs[j2] : S[j2];
|
|
900
|
+
};
|
|
901
|
+
S.forEach(function(_, j2) {
|
|
902
|
+
var top = pts(shown(j2)), base = pts(mode ? lows[j2] : shown(j2).map(function() {
|
|
903
|
+
return 0;
|
|
904
|
+
})).reverse();
|
|
905
|
+
s += '<path d="' + pathOf(top, straight) + pathOf(base, straight).replace(/^M/, "L") + 'Z" fill="' + (fills[j2] || pal[j2 % pal.length]) + '" fill-opacity="' + alpha + '"' + (o.animate ? ' class="bzc-a" style="animation-delay:' + r2(j2 * 0.1) + 's"' : "") + "/>";
|
|
906
|
+
});
|
|
907
|
+
S.forEach(function(_, j2) {
|
|
908
|
+
var c = pal[j2 % pal.length], ys = shown(j2), P = pts(ys), mk = markOf ? markOf(j2) : "none";
|
|
909
|
+
s += seriesLine(o, pathOf(P, straight), c, j2, dashOf ? DASHES[dashOf(j2)] : "");
|
|
910
|
+
if (mk !== "none") s += pointMarks(o, mk, ys, X, Y, c, bg, j2);
|
|
911
|
+
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"/>';
|
|
912
|
+
if (bool(o.showValues) && !mode) ys.forEach(function(y, i2) {
|
|
913
|
+
s += text(X(i2), Y(y) - 8, fmt(y, o, true), small(th, 9, 'text-anchor="middle"'));
|
|
914
|
+
});
|
|
915
|
+
});
|
|
916
|
+
if (bool(o.showValues) && mode === "stack") {
|
|
917
|
+
totals.forEach(function(t2, i2) {
|
|
918
|
+
var top = Math.max.apply(null, highs.map(function(hs) {
|
|
919
|
+
return hs[i2];
|
|
920
|
+
}).concat([0]));
|
|
921
|
+
s += text(X(i2), Y(top) - 8, fmt(t2, o, true), small(th, 9, 'text-anchor="middle"'));
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
return s + xyFinish(o, th, f, n, function(i2) {
|
|
925
|
+
var tip = labels[i2] || "#" + (i2 + 1);
|
|
926
|
+
S.forEach(function(ser, j2) {
|
|
927
|
+
if (i2 < ser.length) tip += "\n" + (multi ? nameOf(j2) + ": " : "") + fmt(ser[i2], o) + (mode === "percent" ? " (" + share(j2, i2) + "%)" : "");
|
|
928
|
+
});
|
|
929
|
+
return tip + (mode ? "\nTotal: " + fmt(totals[i2], o) : "");
|
|
930
|
+
});
|
|
931
|
+
}, {
|
|
932
|
+
stat: statOf(mode ? totals : S[0] || [], o, ""),
|
|
933
|
+
summary: k + " series " + (mode === "percent" ? "as shares of each total" : mode ? "stacked" : "filled") + " over " + n + " points"
|
|
934
|
+
});
|
|
935
|
+
}
|
|
936
|
+
area.table = function(o) {
|
|
937
|
+
var S = series(o.values);
|
|
938
|
+
return seriesTable(o, S.length > 1 && (o.stacked === "percent" || bool(o.stacked)));
|
|
939
|
+
};
|
|
940
|
+
|
|
941
|
+
// src/entries/area.js
|
|
942
|
+
register("area", area);
|
|
943
|
+
define("area");
|
|
944
|
+
|
|
772
945
|
// src/charts/bars.js
|
|
773
946
|
var ANGLE = 40;
|
|
774
947
|
var ANGLE_MAX_CHARS = 24;
|
|
@@ -995,6 +1168,200 @@ bars.table = function(o) {
|
|
|
995
1168
|
register("bars", bars);
|
|
996
1169
|
define("bars");
|
|
997
1170
|
|
|
1171
|
+
// src/charts/histogram.js
|
|
1172
|
+
function histogram(o, th) {
|
|
1173
|
+
var b = binned(o), names = list(o.series), pal = palette(o, th), h = num(o.height, 190);
|
|
1174
|
+
var S = b ? b.S : [], k = S.length, multi = k > 1 || names.length > 0, pct = bool(o.percent);
|
|
1175
|
+
var nameOf = function(j) {
|
|
1176
|
+
return names[j] || "Series " + (j + 1);
|
|
1177
|
+
};
|
|
1178
|
+
var eo = Object.assign({}, o, { decimals: has(o.decimals) ? o.decimals : b ? b.dp : 0 });
|
|
1179
|
+
var range = function(i2) {
|
|
1180
|
+
return fmt(b.edge(i2), eo) + " to " + fmt(b.edge(i2 + 1), eo);
|
|
1181
|
+
};
|
|
1182
|
+
var share = function(j, i2) {
|
|
1183
|
+
return Math.round(b.counts[j][i2] / S[j].length * 100);
|
|
1184
|
+
};
|
|
1185
|
+
var height = function(j, i2) {
|
|
1186
|
+
return pct ? b.counts[j][i2] / S[j].length * 100 : b.counts[j][i2];
|
|
1187
|
+
};
|
|
1188
|
+
var marks = list(o.mark).filter(function(m) {
|
|
1189
|
+
return m === "mean" || m === "median";
|
|
1190
|
+
});
|
|
1191
|
+
var patOf = k > 1 ? styleOf(o.patterns, PATTERNS, "solid") : null, defs = "", fills = [];
|
|
1192
|
+
for (var q = 0; patOf && q < k; q++) {
|
|
1193
|
+
if (patOf(q) === "solid") continue;
|
|
1194
|
+
var pid = newId("g");
|
|
1195
|
+
defs += pattern(pid, patOf(q), pal[q % pal.length], o.background || th.tile);
|
|
1196
|
+
fills[q] = "url(#" + pid + ")";
|
|
1197
|
+
}
|
|
1198
|
+
var key = patOf && function(j, x, y) {
|
|
1199
|
+
return '<rect x="' + r2(x) + '" y="' + r2(y + 1) + '" width="10" height="10" rx="2" fill="' + (fills[j] || pal[j % pal.length]) + '"/>';
|
|
1200
|
+
};
|
|
1201
|
+
var peak = 0, n = 0;
|
|
1202
|
+
if (b) {
|
|
1203
|
+
for (var i = 0; i < b.count; i++) if (total(b, i) > total(b, peak)) peak = i;
|
|
1204
|
+
S.forEach(function(s) {
|
|
1205
|
+
n += s.length;
|
|
1206
|
+
});
|
|
1207
|
+
}
|
|
1208
|
+
return tile(o, th, h, function(x0, y0, w, h2) {
|
|
1209
|
+
if (!b) return emptyState(th, x0, y0, w, h2);
|
|
1210
|
+
var s = defs ? "<defs>" + defs + "</defs>" : "", top = y0;
|
|
1211
|
+
if (multi) {
|
|
1212
|
+
var lg = legend(S.map(function(_, j) {
|
|
1213
|
+
return nameOf(j);
|
|
1214
|
+
}), pal, th, x0, top, w, key, key && 15);
|
|
1215
|
+
s += lg.svg;
|
|
1216
|
+
top += lg.height;
|
|
1217
|
+
}
|
|
1218
|
+
var most = 0;
|
|
1219
|
+
S.forEach(function(_, j) {
|
|
1220
|
+
for (var i2 = 0; i2 < b.count; i2++) most = Math.max(most, height(j, i2));
|
|
1221
|
+
});
|
|
1222
|
+
var sc = niceScale(0, most || 1, 4);
|
|
1223
|
+
var tl = sc.ticks.map(function(t) {
|
|
1224
|
+
return fmt(t, { lang: o.lang }, true) + (pct ? "%" : "");
|
|
1225
|
+
});
|
|
1226
|
+
var axisW = Math.max.apply(null, tl.map(function(t) {
|
|
1227
|
+
return tw(t, 10, true);
|
|
1228
|
+
})) + 10;
|
|
1229
|
+
var px = x0 + axisW, pw = w - axisW, ph = h2 - (top - y0) - 20, cw = pw / b.count;
|
|
1230
|
+
var X = function(i2) {
|
|
1231
|
+
return px + i2 * cw;
|
|
1232
|
+
};
|
|
1233
|
+
var Y = function(v) {
|
|
1234
|
+
return top + ph - (v - sc.lo) / (sc.hi - sc.lo) * ph;
|
|
1235
|
+
};
|
|
1236
|
+
sc.ticks.forEach(function(t, i2) {
|
|
1237
|
+
var y = Y(t);
|
|
1238
|
+
s += '<line x1="' + r2(px) + '" x2="' + r2(px + pw) + '" y1="' + r2(y) + '" y2="' + r2(y) + '" stroke="' + th.grid + '"' + (t === 0 ? "" : ' stroke-dasharray="2 4"') + "/>" + text(px - 8, y + 3.5, tl[i2], small(th, 10, 'text-anchor="end"'));
|
|
1239
|
+
});
|
|
1240
|
+
var el = [];
|
|
1241
|
+
for (var e = 0; e <= b.count; e++) el.push(fmt(b.edge(e), eo, true));
|
|
1242
|
+
var every = Math.max(1, Math.ceil((Math.max.apply(null, el.map(function(l) {
|
|
1243
|
+
return tw(l, 10, true);
|
|
1244
|
+
})) * 1.5 + 8) / cw));
|
|
1245
|
+
for (e = 0; e <= b.count; e += every) {
|
|
1246
|
+
s += text(X(e), top + ph + 15, el[e], small(th, 10, 'text-anchor="' + (e === 0 ? "start" : e === b.count ? "end" : "middle") + '"'));
|
|
1247
|
+
}
|
|
1248
|
+
S.forEach(function(_, j) {
|
|
1249
|
+
for (var i2 = 0; i2 < b.count; i2++) {
|
|
1250
|
+
var v = height(j, i2);
|
|
1251
|
+
if (!v) continue;
|
|
1252
|
+
var y = Y(v);
|
|
1253
|
+
s += '<rect x="' + r2(X(i2) + 0.5) + '" y="' + r2(y) + '" width="' + r2(Math.max(1, cw - 1)) + '" height="' + r2(top + ph - y) + '" fill="' + (fills[j] || pal[j % pal.length]) + '"' + (multi ? ' fill-opacity=".55"' : "") + anim(o, "bzc-g", Math.min(0.6, i2 * 0.03)) + "/>";
|
|
1254
|
+
}
|
|
1255
|
+
});
|
|
1256
|
+
var lo = b.edge(0), span = b.edge(b.count) - lo, lines = [];
|
|
1257
|
+
S.forEach(function(ser, j) {
|
|
1258
|
+
marks.forEach(function(m) {
|
|
1259
|
+
var v = m === "mean" ? mean(ser) : median(ser);
|
|
1260
|
+
lines.push({ x: px + (v - lo) / span * pw, c: multi ? pal[j % pal.length] : th.fg, t: (multi ? nameOf(j) + " " : "") + m + " " + fmt(v, o) });
|
|
1261
|
+
});
|
|
1262
|
+
});
|
|
1263
|
+
if (lines.length) {
|
|
1264
|
+
var xs = lines.map(function(l) {
|
|
1265
|
+
return l.x;
|
|
1266
|
+
}), left = (Math.min.apply(null, xs) + Math.max.apply(null, xs)) / 2 > px + pw / 2;
|
|
1267
|
+
var lx = left ? Math.min.apply(null, xs) - 5 : Math.max.apply(null, xs) + 5;
|
|
1268
|
+
lines.forEach(function(l, r) {
|
|
1269
|
+
s += '<line x1="' + r2(l.x) + '" x2="' + r2(l.x) + '" y1="' + r2(top) + '" y2="' + r2(top + ph) + '" stroke="' + l.c + '" stroke-width="1.5" stroke-dasharray="4 3"/>' + text(lx, top + 9 + r * 12, l.t, small(th, 10, 'text-anchor="' + (left ? "end" : "start") + '"', multi ? l.c : th.fg));
|
|
1270
|
+
});
|
|
1271
|
+
}
|
|
1272
|
+
for (i = 0; i < b.count; i++) {
|
|
1273
|
+
var tip = range(i);
|
|
1274
|
+
S.forEach(function(_, j) {
|
|
1275
|
+
tip += "\n" + (multi ? nameOf(j) + ": " : "") + b.counts[j][i] + " (" + share(j, i) + "%)";
|
|
1276
|
+
});
|
|
1277
|
+
s += hit(X(i), top, cw, ph, tip);
|
|
1278
|
+
}
|
|
1279
|
+
return s;
|
|
1280
|
+
}, {
|
|
1281
|
+
summary: b ? (multi ? k + " series, " : "") + n + " values in " + b.count + " ranges from " + fmt(b.edge(0), eo) + " to " + fmt(b.edge(b.count), eo) + ", most in " + range(peak) : "no data"
|
|
1282
|
+
});
|
|
1283
|
+
}
|
|
1284
|
+
histogram.table = function(o) {
|
|
1285
|
+
var b = binned(o), names = list(o.series);
|
|
1286
|
+
if (!b) return { head: ["Range", "Count"], rows: [] };
|
|
1287
|
+
var multi = b.S.length > 1 || names.length > 0, eo = Object.assign({}, o, { decimals: has(o.decimals) ? o.decimals : b.dp }), rows = [];
|
|
1288
|
+
for (var i = 0; i < b.count; i++) {
|
|
1289
|
+
var row = [fmt(b.edge(i), eo) + " to " + fmt(b.edge(i + 1), eo)];
|
|
1290
|
+
if (multi) b.S.forEach(function(_, j) {
|
|
1291
|
+
row.push(String(b.counts[j][i]));
|
|
1292
|
+
});
|
|
1293
|
+
else row.push(String(b.counts[0][i]), Math.round(b.counts[0][i] / b.S[0].length * 100) + "%");
|
|
1294
|
+
rows.push(row);
|
|
1295
|
+
}
|
|
1296
|
+
return { head: ["Range"].concat(multi ? b.S.map(function(_, j) {
|
|
1297
|
+
return names[j] || "Series " + (j + 1);
|
|
1298
|
+
}) : ["Count", "Share"]), rows };
|
|
1299
|
+
};
|
|
1300
|
+
function niceWidth(raw) {
|
|
1301
|
+
var e = Math.floor(Math.log10(raw)), p = Number("1e" + e), f = raw / p;
|
|
1302
|
+
var m = f < 1.4142 ? 1 : f < 2.2361 ? 2 : f < 3.5355 ? 2.5 : f < 7.0711 ? 5 : 10;
|
|
1303
|
+
return { w: m * p, dp: Math.max(0, m === 10 ? -e - 1 : -e) + (m === 2.5 ? 1 : 0) };
|
|
1304
|
+
}
|
|
1305
|
+
function binned(o) {
|
|
1306
|
+
var S = series(o.values), all = [].concat.apply([], S);
|
|
1307
|
+
if (!all.length) return null;
|
|
1308
|
+
var lo = Math.min.apply(null, all), hi = Math.max.apply(null, all), w = num(o.binWidth, 0), dp, nice;
|
|
1309
|
+
if (w > 0 && (hi - lo) / w <= 200) {
|
|
1310
|
+
var str = String(o.binWidth), dot = str.indexOf(".");
|
|
1311
|
+
dp = dot < 0 ? 0 : Math.min(6, str.length - dot - 1);
|
|
1312
|
+
} else {
|
|
1313
|
+
var k = num(o.bins, 0) > 0 ? Math.round(num(o.bins, 0)) : Math.ceil(Math.log2(all.length) + 1);
|
|
1314
|
+
k = Math.min(Math.max(k, 1), 50);
|
|
1315
|
+
nice = niceWidth(hi > lo ? (hi - lo) / k : Math.abs(lo) || 1);
|
|
1316
|
+
w = nice.w;
|
|
1317
|
+
dp = nice.dp;
|
|
1318
|
+
}
|
|
1319
|
+
var s0 = Math.floor(lo / w);
|
|
1320
|
+
var edge = function(i) {
|
|
1321
|
+
return Number(((s0 + i) * w).toFixed(dp + 3));
|
|
1322
|
+
};
|
|
1323
|
+
while (edge(0) > lo) s0--;
|
|
1324
|
+
var count = Math.max(1, Math.ceil((hi - edge(0)) / w));
|
|
1325
|
+
while (count > 1 && edge(count - 1) >= hi) count--;
|
|
1326
|
+
while (edge(count) < hi) count++;
|
|
1327
|
+
var counts = S.map(function(ser) {
|
|
1328
|
+
var c = [];
|
|
1329
|
+
for (var i = 0; i < count; i++) c.push(0);
|
|
1330
|
+
ser.forEach(function(x) {
|
|
1331
|
+
var i2 = Math.min(count - 1, Math.max(0, Math.floor((x - edge(0)) / w)));
|
|
1332
|
+
while (i2 > 0 && x < edge(i2)) i2--;
|
|
1333
|
+
while (i2 < count - 1 && x >= edge(i2 + 1)) i2++;
|
|
1334
|
+
c[i2]++;
|
|
1335
|
+
});
|
|
1336
|
+
return c;
|
|
1337
|
+
});
|
|
1338
|
+
return { S, edge, count, counts, dp };
|
|
1339
|
+
}
|
|
1340
|
+
function total(b, i) {
|
|
1341
|
+
var t = 0;
|
|
1342
|
+
b.counts.forEach(function(c) {
|
|
1343
|
+
t += c[i];
|
|
1344
|
+
});
|
|
1345
|
+
return t;
|
|
1346
|
+
}
|
|
1347
|
+
function mean(v) {
|
|
1348
|
+
var t = 0;
|
|
1349
|
+
v.forEach(function(x) {
|
|
1350
|
+
t += x;
|
|
1351
|
+
});
|
|
1352
|
+
return t / v.length;
|
|
1353
|
+
}
|
|
1354
|
+
function median(v) {
|
|
1355
|
+
var s = v.slice().sort(function(a, b) {
|
|
1356
|
+
return a - b;
|
|
1357
|
+
}), m = Math.floor(s.length / 2);
|
|
1358
|
+
return s.length % 2 ? s[m] : (s[m - 1] + s[m]) / 2;
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
// src/entries/histogram.js
|
|
1362
|
+
register("histogram", histogram);
|
|
1363
|
+
define("histogram");
|
|
1364
|
+
|
|
998
1365
|
// src/charts/scatter.js
|
|
999
1366
|
function fit(xs, ys) {
|
|
1000
1367
|
var n = Math.min(xs.length, ys.length);
|
|
@@ -1226,43 +1593,43 @@ function donut(o, th) {
|
|
|
1226
1593
|
})));
|
|
1227
1594
|
labels.push("Other");
|
|
1228
1595
|
}
|
|
1229
|
-
var
|
|
1596
|
+
var total2 = sum(v), h = num(o.height, 150);
|
|
1230
1597
|
var st = statOf(v, o, "");
|
|
1231
1598
|
return tile(o, th, h, function(x0, y0, w, h2) {
|
|
1232
|
-
if (!
|
|
1599
|
+
if (!total2) return emptyState(th, x0, y0, w, h2);
|
|
1233
1600
|
var s = "", size = Math.min(h2, w * 0.5), cx = x0 + size / 2, cy = y0 + h2 / 2;
|
|
1234
1601
|
var sw = size * 0.16, r = (size - sw) / 2, start = 0, gap = v.filter(Boolean).length > 1 ? 0.9 : 0;
|
|
1235
1602
|
v.forEach(function(n, i) {
|
|
1236
|
-
var len = n /
|
|
1603
|
+
var len = n / total2 * 100;
|
|
1237
1604
|
if (len <= 0) return;
|
|
1238
1605
|
var seg = Math.max(0.01, len - gap);
|
|
1239
1606
|
s += '<circle cx="' + r2(cx) + '" cy="' + r2(cy) + '" r="' + r2(r) + '" fill="none" stroke="' + pal[i % pal.length] + '" stroke-width="' + r2(sw) + '" pathLength="100" stroke-dasharray="' + r2(seg) + " " + r2(100 - seg) + '" stroke-dashoffset="' + r2(-start) + '" transform="rotate(-90 ' + r2(cx) + " " + r2(cy) + ')"' + anim(o, "bzc-a", i * 0.08) + "/>";
|
|
1240
1607
|
start += len;
|
|
1241
1608
|
});
|
|
1242
|
-
s += text(cx, cy + 2, fmt(
|
|
1609
|
+
s += text(cx, cy + 2, fmt(total2, o, true), 'text-anchor="middle" fill="' + th.fg + '" font-family="' + SANS + '" font-size="' + r2(size * 0.17) + '" font-weight="800"');
|
|
1243
1610
|
s += text(cx, cy + 2 + 14, (has(o.centerLabel) ? o.centerLabel : "Total").toUpperCase(), small(th, 9, 'text-anchor="middle" letter-spacing="1"'));
|
|
1244
1611
|
var lx = x0 + size + 22, rowH = Math.min(24, h2 / v.length), ly = cy - rowH * v.length / 2;
|
|
1245
1612
|
v.forEach(function(n, i) {
|
|
1246
|
-
var y = ly + i * rowH + rowH / 2, pct = Math.round(n /
|
|
1613
|
+
var y = ly + i * rowH + rowH / 2, pct = Math.round(n / total2 * 100);
|
|
1247
1614
|
var tip = (labels[i] || "#" + (i + 1)) + ": " + fmt(n, o) + " (" + pct + "%)";
|
|
1248
1615
|
s += '<circle cx="' + r2(lx + 4) + '" cy="' + r2(y) + '" r="4" fill="' + pal[i % pal.length] + '"/>' + text(lx + 14, y + 4, trunc(labels[i] || "#" + (i + 1), Math.floor((x0 + w - lx - 50) / 6.7)), 'fill="' + th.fg + '" font-family="' + SANS + '" font-size="12"') + text(x0 + w, y + 4, pct + "%", 'text-anchor="end" fill="' + th.muted + '" font-family="' + MONO + '" font-size="11" font-weight="600"') + hit(lx, y - rowH / 2, x0 + w - lx, rowH, tip);
|
|
1249
1616
|
});
|
|
1250
1617
|
start = 0;
|
|
1251
1618
|
v.forEach(function(n, i) {
|
|
1252
|
-
var len = n /
|
|
1619
|
+
var len = n / total2 * 100;
|
|
1253
1620
|
if (len <= 0) return;
|
|
1254
1621
|
s += '<circle cx="' + r2(cx) + '" cy="' + r2(cy) + '" r="' + r2(r) + '" fill="none" stroke="#000" stroke-opacity="0" stroke-width="' + r2(sw) + '" pathLength="100" stroke-dasharray="' + r2(len) + " " + r2(100 - len) + '" stroke-dashoffset="' + r2(-start) + '" transform="rotate(-90 ' + r2(cx) + " " + r2(cy) + ')" class="bzc-hit" data-skip="" data-tip="' + esc((labels[i] || "#" + (i + 1)) + ": " + fmt(n, o) + " (" + Math.round(len) + "%)") + '"/>';
|
|
1255
1622
|
start += len;
|
|
1256
1623
|
});
|
|
1257
1624
|
return s;
|
|
1258
|
-
}, { stat: st, summary: "total " + fmt(
|
|
1625
|
+
}, { stat: st, summary: "total " + fmt(total2, o) + " across " + v.length + " parts" });
|
|
1259
1626
|
}
|
|
1260
1627
|
donut.table = function(o) {
|
|
1261
1628
|
var v = nums(o.values).map(function(n) {
|
|
1262
1629
|
return Math.max(0, n);
|
|
1263
|
-
}), labels = list(o.labels),
|
|
1630
|
+
}), labels = list(o.labels), total2 = sum(v);
|
|
1264
1631
|
return { head: ["Label", "Value", "Share"], rows: v.map(function(n, i) {
|
|
1265
|
-
return [labels[i] || "#" + (i + 1), fmt(n, o), (
|
|
1632
|
+
return [labels[i] || "#" + (i + 1), fmt(n, o), (total2 ? Math.round(n / total2 * 100) : 0) + "%"];
|
|
1266
1633
|
}) };
|
|
1267
1634
|
};
|
|
1268
1635
|
|
|
@@ -1331,8 +1698,8 @@ function progress(o, th) {
|
|
|
1331
1698
|
var v = nums(o.values).map(function(n) {
|
|
1332
1699
|
return Math.max(0, n);
|
|
1333
1700
|
}), labels = list(o.labels), pal = palette(o, th);
|
|
1334
|
-
var single = v.length === 1,
|
|
1335
|
-
var max = has(o.max) ? num(o.max, 100) : single ? 100 :
|
|
1701
|
+
var single = v.length === 1, total2 = sum(v);
|
|
1702
|
+
var max = has(o.max) ? num(o.max, 100) : single ? 100 : total2;
|
|
1336
1703
|
if (!(max > 0)) max = 1;
|
|
1337
1704
|
var auto = !has(o.prefix) && !has(o.suffix) && max === 100 && single;
|
|
1338
1705
|
var show = function(n) {
|
|
@@ -1357,7 +1724,7 @@ function progress(o, th) {
|
|
|
1357
1724
|
return tile(o, th, h, function(x0, y0, w, h2) {
|
|
1358
1725
|
if (!v.length) return emptyState(th, x0, y0, w, h2);
|
|
1359
1726
|
var s = "", by = y0 + 22, cid = newId("c");
|
|
1360
|
-
var head = single ? show(v[0]) + (auto ? "" : " of " + fmt(max, o)) : fmt(
|
|
1727
|
+
var head = single ? show(v[0]) + (auto ? "" : " of " + fmt(max, o)) : fmt(total2, o) + " of " + fmt(max, o);
|
|
1361
1728
|
if (single && labels[0]) s += text(x0, y0 + 11, labels[0], 'fill="' + th.fg + '" font-family="' + SANS + '" font-size="12"');
|
|
1362
1729
|
s += text(x0 + w, y0 + 11, head, 'text-anchor="end" fill="' + th.fg + '" font-family="' + MONO + '" font-size="11" font-weight="600"');
|
|
1363
1730
|
s += '<rect x="' + x0 + '" y="' + by + '" width="' + w + '" height="14" rx="7" fill="' + th.grid + '" fill-opacity=".7"/>';
|
|
@@ -1385,7 +1752,7 @@ function progress(o, th) {
|
|
|
1385
1752
|
s += '<circle cx="' + r2(lx + 4) + '" cy="' + r2(ly) + '" r="4" fill="' + pal[i % pal.length] + '"/><text x="' + r2(lx + 14) + '" y="' + r2(ly + 4) + '" fill="' + th.fg + '" font-family="' + SANS + '" font-size="12">' + esc(it.l) + '<tspan dx="6" fill="' + th.muted + '" font-family="' + MONO + '" font-size="11">' + esc(fmt(v[i], o)) + "</tspan></text>";
|
|
1386
1753
|
});
|
|
1387
1754
|
return s;
|
|
1388
|
-
}, { stat: st, summary: single ? show(v[0]) + (auto ? "" : " of " + fmt(max, o)) : fmt(
|
|
1755
|
+
}, { stat: st, summary: single ? show(v[0]) + (auto ? "" : " of " + fmt(max, o)) : fmt(total2, o) + " of " + fmt(max, o) });
|
|
1389
1756
|
}
|
|
1390
1757
|
progress.table = function(o) {
|
|
1391
1758
|
var v = nums(o.values).map(function(n) {
|
|
@@ -1478,7 +1845,7 @@ register("heatmap", heatmap);
|
|
|
1478
1845
|
define("heatmap");
|
|
1479
1846
|
|
|
1480
1847
|
// src/index.js
|
|
1481
|
-
var version = "1.
|
|
1848
|
+
var version = "1.5.0";
|
|
1482
1849
|
var types = NAMES.slice();
|
|
1483
1850
|
export {
|
|
1484
1851
|
BezelChart,
|