// https://d3js.org/d3-shape/ v3.2.0 Copyright 2010-2022 Mike Bostock (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-path')) : typeof define === 'function' && define.amd ? define(['exports', 'd3-path'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = global.d3 || {}, global.d3)); })(this, (function (exports, d3Path) { 'use strict'; function constant(x) { return function constant() { return x; }; } const abs = Math.abs; const atan2 = Math.atan2; const cos = Math.cos; const max = Math.max; const min = Math.min; const sin = Math.sin; const sqrt = Math.sqrt; const epsilon = 1e-12; const pi = Math.PI; const halfPi = pi / 2; const tau = 2 * pi; function acos(x) { return x > 1 ? 0 : x < -1 ? pi : Math.acos(x); } function asin(x) { return x >= 1 ? halfPi : x <= -1 ? -halfPi : Math.asin(x); } function withPath(shape) { let digits = 3; shape.digits = function(_) { if (!arguments.length) return digits; if (_ == null) { digits = null; } else { const d = Math.floor(_); if (!(d >= 0)) throw new RangeError(`invalid digits: ${_}`); digits = d; } return shape; }; return () => new d3Path.Path(digits); } function arcInnerRadius(d) { return d.innerRadius; } function arcOuterRadius(d) { return d.outerRadius; } function arcStartAngle(d) { return d.startAngle; } function arcEndAngle(d) { return d.endAngle; } function arcPadAngle(d) { return d && d.padAngle; // Note: optional! } function intersect(x0, y0, x1, y1, x2, y2, x3, y3) { var x10 = x1 - x0, y10 = y1 - y0, x32 = x3 - x2, y32 = y3 - y2, t = y32 * x10 - x32 * y10; if (t * t < epsilon) return; t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / t; return [x0 + t * x10, y0 + t * y10]; } // Compute perpendicular offset line of length rc. // http://mathworld.wolfram.com/Circle-LineIntersection.html function cornerTangents(x0, y0, x1, y1, r1, rc, cw) { var x01 = x0 - x1, y01 = y0 - y1, lo = (cw ? rc : -rc) / sqrt(x01 * x01 + y01 * y01), ox = lo * y01, oy = -lo * x01, x11 = x0 + ox, y11 = y0 + oy, x10 = x1 + ox, y10 = y1 + oy, x00 = (x11 + x10) / 2, y00 = (y11 + y10) / 2, dx = x10 - x11, dy = y10 - y11, d2 = dx * dx + dy * dy, r = r1 - rc, D = x11 * y10 - x10 * y11, d = (dy < 0 ? -1 : 1) * sqrt(max(0, r * r * d2 - D * D)), cx0 = (D * dy - dx * d) / d2, cy0 = (-D * dx - dy * d) / d2, cx1 = (D * dy + dx * d) / d2, cy1 = (-D * dx + dy * d) / d2, dx0 = cx0 - x00, dy0 = cy0 - y00, dx1 = cx1 - x00, dy1 = cy1 - y00; // Pick the closer of the two intersection points. // TODO Is there a faster way to determine which intersection to use? if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1; return { cx: cx0, cy: cy0, x01: -ox, y01: -oy, x11: cx0 * (r1 / r - 1), y11: cy0 * (r1 / r - 1) }; } function arc() { var innerRadius = arcInnerRadius, outerRadius = arcOuterRadius, cornerRadius = constant(0), padRadius = null, startAngle = arcStartAngle, endAngle = arcEndAngle, padAngle = arcPadAngle, context = null, path = withPath(arc); function arc() { var buffer, r, r0 = +innerRadius.apply(this, arguments), r1 = +outerRadius.apply(this, arguments), a0 = startAngle.apply(this, arguments) - halfPi, a1 = endAngle.apply(this, arguments) - halfPi, da = abs(a1 - a0), cw = a1 > a0; if (!context) context = buffer = path(); // Ensure that the outer radius is always larger than the inner radius. if (r1 < r0) r = r1, r1 = r0, r0 = r; // Is it a point? if (!(r1 > epsilon)) context.moveTo(0, 0); // Or is it a circle or annulus? else if (da > tau - epsilon) { context.moveTo(r1 * cos(a0), r1 * sin(a0)); context.arc(0, 0, r1, a0, a1, !cw); if (r0 > epsilon) { context.moveTo(r0 * cos(a1), r0 * sin(a1)); context.arc(0, 0, r0, a1, a0, cw); } } // Or is it a circular or annular sector? else { var a01 = a0, a11 = a1, a00 = a0, a10 = a1, da0 = da, da1 = da, ap = padAngle.apply(this, arguments) / 2, rp = (ap > epsilon) && (padRadius ? +padRadius.apply(this, arguments) : sqrt(r0 * r0 + r1 * r1)), rc = min(abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)), rc0 = rc, rc1 = rc, t0, t1; // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0. if (rp > epsilon) { var p0 = asin(rp / r0 * sin(ap)), p1 = asin(rp / r1 * sin(ap)); if ((da0 -= p0 * 2) > epsilon) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0; else da0 = 0, a00 = a10 = (a0 + a1) / 2; if ((da1 -= p1 * 2) > epsilon) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1; else da1 = 0, a01 = a11 = (a0 + a1) / 2; } var x01 = r1 * cos(a01), y01 = r1 * sin(a01), x10 = r0 * cos(a10), y10 = r0 * sin(a10); // Apply rounded corners? if (rc > epsilon) { var x11 = r1 * cos(a11), y11 = r1 * sin(a11), x00 = r0 * cos(a00), y00 = r0 * sin(a00), oc; // Restrict the corner radius according to the sector angle. If this // intersection fails, it’s probably because the arc is too small, so // disable the corner radius entirely. if (da < pi) { if (oc = intersect(x01, y01, x00, y00, x11, y11, x10, y10)) { var ax = x01 - oc[0], ay = y01 - oc[1], bx = x11 - oc[0], by = y11 - oc[1], kc = 1 / sin(acos((ax * bx + ay * by) / (sqrt(ax * ax + ay * ay) * sqrt(bx * bx + by * by))) / 2), lc = sqrt(oc[0] * oc[0] + oc[1] * oc[1]); rc0 = min(rc, (r0 - lc) / (kc - 1)); rc1 = min(rc, (r1 - lc) / (kc + 1)); } else { rc0 = rc1 = 0; } } } // Is the sector collapsed to a line? if (!(da1 > epsilon)) context.moveTo(x01, y01); // Does the sector’s outer ring have rounded corners? else if (rc1 > epsilon) { t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw); t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw); context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01); // Have the corners merged? if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw); // Otherwise, draw the two corners and the ring. else { context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw); context.arc(0, 0, r1, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw); context.arc(t1.cx, t1.cy, rc1, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw); } } // Or is the outer ring just a circular arc? else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw); // Is there no inner ring, and it’s a circular sector? // Or perhaps it’s an annular sector collapsed due to padding? if (!(r0 > epsilon) || !(da0 > epsilon)) context.lineTo(x10, y10); // Does the sector’s inner ring (or point) have rounded corners? else if (rc0 > epsilon) { t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw); t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw); context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01); // Have the corners merged? if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw); // Otherwise, draw the two corners and the ring. else { context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw); context.arc(0, 0, r0, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw); context.arc(t1.cx, t1.cy, rc0, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw); } } // Or is the inner ring just a circular arc? else context.arc(0, 0, r0, a10, a00, cw); } context.closePath(); if (buffer) return context = null, buffer + "" || null; } arc.centroid = function() { var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2, a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi / 2; return [cos(a) * r, sin(a) * r]; }; arc.innerRadius = function(_) { return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant(+_), arc) : innerRadius; }; arc.outerRadius = function(_) { return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant(+_), arc) : outerRadius; }; arc.cornerRadius = function(_) { return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant(+_), arc) : cornerRadius; }; arc.padRadius = function(_) { return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant(+_), arc) : padRadius; }; arc.startAngle = function(_) { return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant(+_), arc) : startAngle; }; arc.endAngle = function(_) { return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant(+_), arc) : endAngle; }; arc.padAngle = function(_) { return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant(+_), arc) : padAngle; }; arc.context = function(_) { return arguments.length ? ((context = _ == null ? null : _), arc) : context; }; return arc; } var slice = Array.prototype.slice; function array(x) { return typeof x === "object" && "length" in x ? x // Array, TypedArray, NodeList, array-like : Array.from(x); // Map, Set, iterable, string, or anything else } function Linear(context) { this._context = context; } Linear.prototype = { areaStart: function() { this._line = 0; }, areaEnd: function() { this._line = NaN; }, lineStart: function() { this._point = 0; }, lineEnd: function() { if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); this._line = 1 - this._line; }, point: function(x, y) { x = +x, y = +y; switch (this._point) { case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; case 1: this._point = 2; // falls through default: this._context.lineTo(x, y); break; } } }; function curveLinear(context) { return new Linear(context); } function x(p) { return p[0]; } function y(p) { return p[1]; } function line(x$1, y$1) { var defined = constant(true), context = null, curve = curveLinear, output = null, path = withPath(line); x$1 = typeof x$1 === "function" ? x$1 : (x$1 === undefined) ? x : constant(x$1); y$1 = typeof y$1 === "function" ? y$1 : (y$1 === undefined) ? y : constant(y$1); function line(data) { var i, n = (data = array(data)).length, d, defined0 = false, buffer; if (context == null) output = curve(buffer = path()); for (i = 0; i <= n; ++i) { if (!(i < n && defined(d = data[i], i, data)) === defined0) { if (defined0 = !defined0) output.lineStart(); else output.lineEnd(); } if (defined0) output.point(+x$1(d, i, data), +y$1(d, i, data)); } if (buffer) return output = null, buffer + "" || null; } line.x = function(_) { return arguments.length ? (x$1 = typeof _ === "function" ? _ : constant(+_), line) : x$1; }; line.y = function(_) { return arguments.length ? (y$1 = typeof _ === "function" ? _ : constant(+_), line) : y$1; }; line.defined = function(_) { return arguments.length ? (defined = typeof _ === "function" ? _ : constant(!!_), line) : defined; }; line.curve = function(_) { return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve; }; line.context = function(_) { return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context; }; return line; } function area(x0, y0, y1) { var x1 = null, defined = constant(true), context = null, curve = curveLinear, output = null, path = withPath(area); x0 = typeof x0 === "function" ? x0 : (x0 === undefined) ? x : constant(+x0); y0 = typeof y0 === "function" ? y0 : (y0 === undefined) ? constant(0) : constant(+y0); y1 = typeof y1 === "function" ? y1 : (y1 === undefined) ? y : constant(+y1); function area(data) { var i, j, k, n = (data = array(data)).length, d, defined0 = false, buffer, x0z = new Array(n), y0z = new Array(n); if (context == null) output = curve(buffer = path()); for (i = 0; i <= n; ++i) { if (!(i < n && defined(d = data[i], i, data)) === defined0) { if (defined0 = !defined0) { j = i; output.areaStart(); output.lineStart(); } else { output.lineEnd(); output.lineStart(); for (k = i - 1; k >= j; --k) { output.point(x0z[k], y0z[k]); } output.lineEnd(); output.areaEnd(); } } if (defined0) { x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data); output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]); } } if (buffer) return output = null, buffer + "" || null; } function arealine() { return line().defined(defined).curve(curve).context(context); } area.x = function(_) { return arguments.length ? (x0 = typeof _ === "function" ? _ : constant(+_), x1 = null, area) : x0; }; area.x0 = function(_) { return arguments.length ? (x0 = typeof _ === "function" ? _ : constant(+_), area) : x0; }; area.x1 = function(_) { return arguments.length ? (x1 = _ == null ? null : typeof _ === "function" ? _ : constant(+_), area) : x1; }; area.y = function(_) { return arguments.length ? (y0 = typeof _ === "function" ? _ : constant(+_), y1 = null, area) : y0; }; area.y0 = function(_) { return arguments.length ? (y0 = typeof _ === "function" ? _ : constant(+_), area) : y0; }; area.y1 = function(_) { return arguments.length ? (y1 = _ == null ? null : typeof _ === "function" ? _ : constant(+_), area) : y1; }; area.lineX0 = area.lineY0 = function() { return arealine().x(x0).y(y0); }; area.lineY1 = function() { return arealine().x(x0).y(y1); }; area.lineX1 = function() { return arealine().x(x1).y(y0); }; area.defined = function(_) { return arguments.length ? (defined = typeof _ === "function" ? _ : constant(!!_), area) : defined; }; area.curve = function(_) { return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve; }; area.context = function(_) { return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context; }; return area; } function descending$1(a, b) { return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; } function identity(d) { return d; } function pie() { var value = identity, sortValues = descending$1, sort = null, startAngle = constant(0), endAngle = constant(tau), padAngle = constant(0); function pie(data) { var i, n = (data = array(data)).length, j, k, sum = 0, index = new Array(n), arcs = new Array(n), a0 = +startAngle.apply(this, arguments), da = Math.min(tau, Math.max(-tau, endAngle.apply(this, arguments) - a0)), a1, p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)), pa = p * (da < 0 ? -1 : 1), v; for (i = 0; i < n; ++i) { if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) { sum += v; } } // Optionally sort the arcs by previously-computed values or by data. if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); }); else if (sort != null) index.sort(function(i, j) { return sort(data[i], data[j]); }); // Compute the arcs! They are stored in the original data's order. for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) { j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = { data: data[j], index: i, value: v, startAngle: a0, endAngle: a1, padAngle: p }; } return arcs; } pie.value = function(_) { return arguments.length ? (value = typeof _ === "function" ? _ : constant(+_), pie) : value; }; pie.sortValues = function(_) { return arguments.length ? (sortValues = _, sort = null, pie) : sortValues; }; pie.sort = function(_) { return arguments.length ? (sort = _, sortValues = null, pie) : sort; }; pie.startAngle = function(_) { return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant(+_), pie) : startAngle; }; pie.endAngle = function(_) { return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant(+_), pie) : endAngle; }; pie.padAngle = function(_) { return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant(+_), pie) : padAngle; }; return pie; } var curveRadialLinear = curveRadial(curveLinear); function Radial(curve) { this._curve = curve; } Radial.prototype = { areaStart: function() { this._curve.areaStart(); }, areaEnd: function() { this._curve.areaEnd(); }, lineStart: function() { this._curve.lineStart(); }, lineEnd: function() { this._curve.lineEnd(); }, point: function(a, r) { this._curve.point(r * Math.sin(a), r * -Math.cos(a)); } }; function curveRadial(curve) { function radial(context) { return new Radial(curve(context)); } radial._curve = curve; return radial; } function lineRadial(l) { var c = l.curve; l.angle = l.x, delete l.x; l.radius = l.y, delete l.y; l.curve = function(_) { return arguments.length ? c(curveRadial(_)) : c()._curve; }; return l; } function lineRadial$1() { return lineRadial(line().curve(curveRadialLinear)); } function areaRadial() { var a = area().curve(curveRadialLinear), c = a.curve, x0 = a.lineX0, x1 = a.lineX1, y0 = a.lineY0, y1 = a.lineY1; a.angle = a.x, delete a.x; a.startAngle = a.x0, delete a.x0; a.endAngle = a.x1, delete a.x1; a.radius = a.y, delete a.y; a.innerRadius = a.y0, delete a.y0; a.outerRadius = a.y1, delete a.y1; a.lineStartAngle = function() { return lineRadial(x0()); }, delete a.lineX0; a.lineEndAngle = function() { return lineRadial(x1()); }, delete a.lineX1; a.lineInnerRadius = function() { return lineRadial(y0()); }, delete a.lineY0; a.lineOuterRadius = function() { return lineRadial(y1()); }, delete a.lineY1; a.curve = function(_) { return arguments.length ? c(curveRadial(_)) : c()._curve; }; return a; } function pointRadial(x, y) { return [(y = +y) * Math.cos(x -= Math.PI / 2), y * Math.sin(x)]; } class Bump { constructor(context, x) { this._context = context; this._x = x; } areaStart() { this._line = 0; } areaEnd() { this._line = NaN; } lineStart() { this._point = 0; } lineEnd() { if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); this._line = 1 - this._line; } point(x, y) { x = +x, y = +y; switch (this._point) { case 0: { this._point = 1; if (this._line) this._context.lineTo(x, y); else this._context.moveTo(x, y); break; } case 1: this._point = 2; // falls through default: { if (this._x) this._context.bezierCurveTo(this._x0 = (this._x0 + x) / 2, this._y0, this._x0, y, x, y); else this._context.bezierCurveTo(this._x0, this._y0 = (this._y0 + y) / 2, x, this._y0, x, y); break; } } this._x0 = x, this._y0 = y; } } class BumpRadial { constructor(context) { this._context = context; } lineStart() { this._point = 0; } lineEnd() {} point(x, y) { x = +x, y = +y; if (this._point === 0) { this._point = 1; } else { const p0 = pointRadial(this._x0, this._y0); const p1 = pointRadial(this._x0, this._y0 = (this._y0 + y) / 2); const p2 = pointRadial(x, this._y0); const p3 = pointRadial(x, y); this._context.moveTo(...p0); this._context.bezierCurveTo(...p1, ...p2, ...p3); } this._x0 = x, this._y0 = y; } } function bumpX(context) { return new Bump(context, true); } function bumpY(context) { return new Bump(context, false); } function bumpRadial(context) { return new BumpRadial(context); } function linkSource(d) { return d.source; } function linkTarget(d) { return d.target; } function link(curve) { let source = linkSource, target = linkTarget, x$1 = x, y$1 = y, context = null, output = null, path = withPath(link); function link() { let buffer; const argv = slice.call(arguments); const s = source.apply(this, argv); const t = target.apply(this, argv); if (context == null) output = curve(buffer = path()); output.lineStart(); argv[0] = s, output.point(+x$1.apply(this, argv), +y$1.apply(this, argv)); argv[0] = t, output.point(+x$1.apply(this, argv), +y$1.apply(this, argv)); output.lineEnd(); if (buffer) return output = null, buffer + "" || null; } link.source = function(_) { return arguments.length ? (source = _, link) : source; }; link.target = function(_) { return arguments.length ? (target = _, link) : target; }; link.x = function(_) { return arguments.length ? (x$1 = typeof _ === "function" ? _ : constant(+_), link) : x$1; }; link.y = function(_) { return arguments.length ? (y$1 = typeof _ === "function" ? _ : constant(+_), link) : y$1; }; link.context = function(_) { return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), link) : context; }; return link; } function linkHorizontal() { return link(bumpX); } function linkVertical() { return link(bumpY); } function linkRadial() { const l = link(bumpRadial); l.angle = l.x, delete l.x; l.radius = l.y, delete l.y; return l; } const sqrt3$2 = sqrt(3); var asterisk = { draw(context, size) { const r = sqrt(size + min(size / 28, 0.75)) * 0.59436; const t = r / 2; const u = t * sqrt3$2; context.moveTo(0, r); context.lineTo(0, -r); context.moveTo(-u, -t); context.lineTo(u, t); context.moveTo(-u, t); context.lineTo(u, -t); } }; var circle = { draw(context, size) { const r = sqrt(size / pi); context.moveTo(r, 0); context.arc(0, 0, r, 0, tau); } }; var cross = { draw(context, size) { const r = sqrt(size / 5) / 2; context.moveTo(-3 * r, -r); context.lineTo(-r, -r); context.lineTo(-r, -3 * r); context.lineTo(r, -3 * r); context.lineTo(r, -r); context.lineTo(3 * r, -r); context.lineTo(3 * r, r); context.lineTo(r, r); context.lineTo(r, 3 * r); context.lineTo(-r, 3 * r); context.lineTo(-r, r); context.lineTo(-3 * r, r); context.closePath(); } }; const tan30 = sqrt(1 / 3); const tan30_2 = tan30 * 2; var diamond = { draw(context, size) { const y = sqrt(size / tan30_2); const x = y * tan30; context.moveTo(0, -y); context.lineTo(x, 0); context.lineTo(0, y); context.lineTo(-x, 0); context.closePath(); } }; var diamond2 = { draw(context, size) { const r = sqrt(size) * 0.62625; context.moveTo(0, -r); context.lineTo(r, 0); context.lineTo(0, r); context.lineTo(-r, 0); context.closePath(); } }; var plus = { draw(context, size) { const r = sqrt(size - min(size / 7, 2)) * 0.87559; context.moveTo(-r, 0); context.lineTo(r, 0); context.moveTo(0, r); context.lineTo(0, -r); } }; var square = { draw(context, size) { const w = sqrt(size); const x = -w / 2; context.rect(x, x, w, w); } }; var square2 = { draw(context, size) { const r = sqrt(size) * 0.4431; context.moveTo(r, r); context.lineTo(r, -r); context.lineTo(-r, -r); context.lineTo(-r, r); context.closePath(); } }; const ka = 0.89081309152928522810; const kr = sin(pi / 10) / sin(7 * pi / 10); const kx = sin(tau / 10) * kr; const ky = -cos(tau / 10) * kr; var star = { draw(context, size) { const r = sqrt(size * ka); const x = kx * r; const y = ky * r; context.moveTo(0, -r); context.lineTo(x, y); for (let i = 1; i < 5; ++i) { const a = tau * i / 5; const c = cos(a); const s = sin(a); context.lineTo(s * r, -c * r); context.lineTo(c * x - s * y, s * x + c * y); } context.closePath(); } }; const sqrt3$1 = sqrt(3); var triangle = { draw(context, size) { const y = -sqrt(size / (sqrt3$1 * 3)); context.moveTo(0, y * 2); context.lineTo(-sqrt3$1 * y, -y); context.lineTo(sqrt3$1 * y, -y); context.closePath(); } }; const sqrt3 = sqrt(3); var triangle2 = { draw(context, size) { const s = sqrt(size) * 0.6824; const t = s / 2; const u = (s * sqrt3) / 2; // cos(Math.PI / 6) context.moveTo(0, -s); context.lineTo(u, t); context.lineTo(-u, t); context.closePath(); } }; const c = -0.5; const s = sqrt(3) / 2; const k = 1 / sqrt(12); const a = (k / 2 + 1) * 3; var wye = { draw(context, size) { const r = sqrt(size / a); const x0 = r / 2, y0 = r * k; const x1 = x0, y1 = r * k + r; const x2 = -x1, y2 = y1; context.moveTo(x0, y0); context.lineTo(x1, y1); context.lineTo(x2, y2); context.lineTo(c * x0 - s * y0, s * x0 + c * y0); context.lineTo(c * x1 - s * y1, s * x1 + c * y1); context.lineTo(c * x2 - s * y2, s * x2 + c * y2); context.lineTo(c * x0 + s * y0, c * y0 - s * x0); context.lineTo(c * x1 + s * y1, c * y1 - s * x1); context.lineTo(c * x2 + s * y2, c * y2 - s * x2); context.closePath(); } }; var times = { draw(context, size) { const r = sqrt(size - min(size / 6, 1.7)) * 0.6189; context.moveTo(-r, -r); context.lineTo(r, r); context.moveTo(-r, r); context.lineTo(r, -r); } }; // These symbols are designed to be filled. const symbolsFill = [ circle, cross, diamond, square, star, triangle, wye ]; // These symbols are designed to be stroked (with a width of 1.5px and round caps). const symbolsStroke = [ circle, plus, times, triangle2, asterisk, square2, diamond2 ]; function Symbol(type, size) { let context = null, path = withPath(symbol); type = typeof type === "function" ? type : constant(type || circle); size = typeof size === "function" ? size : constant(size === undefined ? 64 : +size); function symbol() { let buffer; if (!context) context = buffer = path(); type.apply(this, arguments).draw(context, +size.apply(this, arguments)); if (buffer) return context = null, buffer + "" || null; } symbol.type = function(_) { return arguments.length ? (type = typeof _ === "function" ? _ : constant(_), symbol) : type; }; symbol.size = function(_) { return arguments.length ? (size = typeof _ === "function" ? _ : constant(+_), symbol) : size; }; symbol.context = function(_) { return arguments.length ? (context = _ == null ? null : _, symbol) : context; }; return symbol; } function noop() {} function point$3(that, x, y) { that._context.bezierCurveTo( (2 * that._x0 + that._x1) / 3, (2 * that._y0 + that._y1) / 3, (that._x0 + 2 * that._x1) / 3, (that._y0 + 2 * that._y1) / 3, (that._x0 + 4 * that._x1 + x) / 6, (that._y0 + 4 * that._y1 + y) / 6 ); } function Basis(context) { this._context = context; } Basis.prototype = { areaStart: function() { this._line = 0; }, areaEnd: function() { this._line = NaN; }, lineStart: function() { this._x0 = this._x1 = this._y0 = this._y1 = NaN; this._point = 0; }, lineEnd: function() { switch (this._point) { case 3: point$3(this, this._x1, this._y1); // falls through case 2: this._context.lineTo(this._x1, this._y1); break; } if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); this._line = 1 - this._line; }, point: function(x, y) { x = +x, y = +y; switch (this._point) { case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; case 1: this._point = 2; break; case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // falls through default: point$3(this, x, y); break; } this._x0 = this._x1, this._x1 = x; this._y0 = this._y1, this._y1 = y; } }; function basis(context) { return new Basis(context); } function BasisClosed(context) { this._context = context; } BasisClosed.prototype = { areaStart: noop, areaEnd: noop, lineStart: function() { this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN; this._point = 0; }, lineEnd: function() { switch (this._point) { case 1: { this._context.moveTo(this._x2, this._y2); this._context.closePath(); break; } case 2: { this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3); this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3); this._context.closePath(); break; } case 3: { this.point(this._x2, this._y2); this.point(this._x3, this._y3); this.point(this._x4, this._y4); break; } } }, point: function(x, y) { x = +x, y = +y; switch (this._point) { case 0: this._point = 1; this._x2 = x, this._y2 = y; break; case 1: this._point = 2; this._x3 = x, this._y3 = y; break; case 2: this._point = 3; this._x4 = x, this._y4 = y; this._context.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y) / 6); break; default: point$3(this, x, y); break; } this._x0 = this._x1, this._x1 = x; this._y0 = this._y1, this._y1 = y; } }; function basisClosed(context) { return new BasisClosed(context); } function BasisOpen(context) { this._context = context; } BasisOpen.prototype = { areaStart: function() { this._line = 0; }, areaEnd: function() { this._line = NaN; }, lineStart: function() { this._x0 = this._x1 = this._y0 = this._y1 = NaN; this._point = 0; }, lineEnd: function() { if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath(); this._line = 1 - this._line; }, point: function(x, y) { x = +x, y = +y; switch (this._point) { case 0: this._point = 1; break; case 1: this._point = 2; break; case 2: this._point = 3; var x0 = (this._x0 + 4 * this._x1 + x) / 6, y0 = (this._y0 + 4 * this._y1 + y) / 6; this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0); break; case 3: this._point = 4; // falls through default: point$3(this, x, y); break; } this._x0 = this._x1, this._x1 = x; this._y0 = this._y1, this._y1 = y; } }; function basisOpen(context) { return new BasisOpen(context); } function Bundle(context, beta) { this._basis = new Basis(context); this._beta = beta; } Bundle.prototype = { lineStart: function() { this._x = []; this._y = []; this._basis.lineStart(); }, lineEnd: function() { var x = this._x, y = this._y, j = x.length - 1; if (j > 0) { var x0 = x[0], y0 = y[0], dx = x[j] - x0, dy = y[j] - y0, i = -1, t; while (++i <= j) { t = i / j; this._basis.point( this._beta * x[i] + (1 - this._beta) * (x0 + t * dx), this._beta * y[i] + (1 - this._beta) * (y0 + t * dy) ); } } this._x = this._y = null; this._basis.lineEnd(); }, point: function(x, y) { this._x.push(+x); this._y.push(+y); } }; var bundle = (function custom(beta) { function bundle(context) { return beta === 1 ? new Basis(context) : new Bundle(context, beta); } bundle.beta = function(beta) { return custom(+beta); }; return bundle; })(0.85); function point$2(that, x, y) { that._context.bezierCurveTo( that._x1 + that._k * (that._x2 - that._x0), that._y1 + that._k * (that._y2 - that._y0), that._x2 + that._k * (that._x1 - x), that._y2 + that._k * (that._y1 - y), that._x2, that._y2 ); } function Cardinal(context, tension) { this._context = context; this._k = (1 - tension) / 6; } Cardinal.prototype = { areaStart: function() { this._line = 0; }, areaEnd: function() { this._line = NaN; }, lineStart: function() { this._x0 = this._x1 = this._x2 = this._y0 = this._y1 = this._y2 = NaN; this._point = 0; }, lineEnd: function() { switch (this._point) { case 2: this._context.lineTo(this._x2, this._y2); break; case 3: point$2(this, this._x1, this._y1); break; } if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); this._line = 1 - this._line; }, point: function(x, y) { x = +x, y = +y; switch (this._point) { case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; case 1: this._point = 2; this._x1 = x, this._y1 = y; break; case 2: this._point = 3; // falls through default: point$2(this, x, y); break; } this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; } }; var cardinal = (function custom(tension) { function cardinal(context) { return new Cardinal(context, tension); } cardinal.tension = function(tension) { return custom(+tension); }; return cardinal; })(0); function CardinalClosed(context, tension) { this._context = context; this._k = (1 - tension) / 6; } CardinalClosed.prototype = { areaStart: noop, areaEnd: noop, lineStart: function() { this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 = this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN; this._point = 0; }, lineEnd: function() { switch (this._point) { case 1: { this._context.moveTo(this._x3, this._y3); this._context.closePath(); break; } case 2: { this._context.lineTo(this._x3, this._y3); this._context.closePath(); break; } case 3: { this.point(this._x3, this._y3); this.point(this._x4, this._y4); this.point(this._x5, this._y5); break; } } }, point: function(x, y) { x = +x, y = +y; switch (this._point) { case 0: this._point = 1; this._x3 = x, this._y3 = y; break; case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break; case 2: this._point = 3; this._x5 = x, this._y5 = y; break; default: point$2(this, x, y); break; } this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; } }; var cardinalClosed = (function custom(tension) { function cardinal(context) { return new CardinalClosed(context, tension); } cardinal.tension = function(tension) { return custom(+tension); }; return cardinal; })(0); function CardinalOpen(context, tension) { this._context = context; this._k = (1 - tension) / 6; } CardinalOpen.prototype = { areaStart: function() { this._line = 0; }, areaEnd: function() { this._line = NaN; }, lineStart: function() { this._x0 = this._x1 = this._x2 = this._y0 = this._y1 = this._y2 = NaN; this._point = 0; }, lineEnd: function() { if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath(); this._line = 1 - this._line; }, point: function(x, y) { x = +x, y = +y; switch (this._point) { case 0: this._point = 1; break; case 1: this._point = 2; break; case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break; case 3: this._point = 4; // falls through default: point$2(this, x, y); break; } this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; } }; var cardinalOpen = (function custom(tension) { function cardinal(context) { return new CardinalOpen(context, tension); } cardinal.tension = function(tension) { return custom(+tension); }; return cardinal; })(0); function point$1(that, x, y) { var x1 = that._x1, y1 = that._y1, x2 = that._x2, y2 = that._y2; if (that._l01_a > epsilon) { var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a, n = 3 * that._l01_a * (that._l01_a + that._l12_a); x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n; y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n; } if (that._l23_a > epsilon) { var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a, m = 3 * that._l23_a * (that._l23_a + that._l12_a); x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m; y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m; } that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2); } function CatmullRom(context, alpha) { this._context = context; this._alpha = alpha; } CatmullRom.prototype = { areaStart: function() { this._line = 0; }, areaEnd: function() { this._line = NaN; }, lineStart: function() { this._x0 = this._x1 = this._x2 = this._y0 = this._y1 = this._y2 = NaN; this._l01_a = this._l12_a = this._l23_a = this._l01_2a = this._l12_2a = this._l23_2a = this._point = 0; }, lineEnd: function() { switch (this._point) { case 2: this._context.lineTo(this._x2, this._y2); break; case 3: this.point(this._x2, this._y2); break; } if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); this._line = 1 - this._line; }, point: function(x, y) { x = +x, y = +y; if (this._point) { var x23 = this._x2 - x, y23 = this._y2 - y; this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha)); } switch (this._point) { case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; case 1: this._point = 2; break; case 2: this._point = 3; // falls through default: point$1(this, x, y); break; } this._l01_a = this._l12_a, this._l12_a = this._l23_a; this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a; this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; } }; var catmullRom = (function custom(alpha) { function catmullRom(context) { return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0); } catmullRom.alpha = function(alpha) { return custom(+alpha); }; return catmullRom; })(0.5); function CatmullRomClosed(context, alpha) { this._context = context; this._alpha = alpha; } CatmullRomClosed.prototype = { areaStart: noop, areaEnd: noop, lineStart: function() { this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 = this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN; this._l01_a = this._l12_a = this._l23_a = this._l01_2a = this._l12_2a = this._l23_2a = this._point = 0; }, lineEnd: function() { switch (this._point) { case 1: { this._context.moveTo(this._x3, this._y3); this._context.closePath(); break; } case 2: { this._context.lineTo(this._x3, this._y3); this._context.closePath(); break; } case 3: { this.point(this._x3, this._y3); this.point(this._x4, this._y4); this.point(this._x5, this._y5); break; } } }, point: function(x, y) { x = +x, y = +y; if (this._point) { var x23 = this._x2 - x, y23 = this._y2 - y; this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha)); } switch (this._point) { case 0: this._point = 1; this._x3 = x, this._y3 = y; break; case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break; case 2: this._point = 3; this._x5 = x, this._y5 = y; break; default: point$1(this, x, y); break; } this._l01_a = this._l12_a, this._l12_a = this._l23_a; this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a; this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; } }; var catmullRomClosed = (function custom(alpha) { function catmullRom(context) { return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0); } catmullRom.alpha = function(alpha) { return custom(+alpha); }; return catmullRom; })(0.5); function CatmullRomOpen(context, alpha) { this._context = context; this._alpha = alpha; } CatmullRomOpen.prototype = { areaStart: function() { this._line = 0; }, areaEnd: function() { this._line = NaN; }, lineStart: function() { this._x0 = this._x1 = this._x2 = this._y0 = this._y1 = this._y2 = NaN; this._l01_a = this._l12_a = this._l23_a = this._l01_2a = this._l12_2a = this._l23_2a = this._point = 0; }, lineEnd: function() { if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath(); this._line = 1 - this._line; }, point: function(x, y) { x = +x, y = +y; if (this._point) { var x23 = this._x2 - x, y23 = this._y2 - y; this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha)); } switch (this._point) { case 0: this._point = 1; break; case 1: this._point = 2; break; case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break; case 3: this._point = 4; // falls through default: point$1(this, x, y); break; } this._l01_a = this._l12_a, this._l12_a = this._l23_a; this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a; this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; } }; var catmullRomOpen = (function custom(alpha) { function catmullRom(context) { return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0); } catmullRom.alpha = function(alpha) { return custom(+alpha); }; return catmullRom; })(0.5); function LinearClosed(context) { this._context = context; } LinearClosed.prototype = { areaStart: noop, areaEnd: noop, lineStart: function() { this._point = 0; }, lineEnd: function() { if (this._point) this._context.closePath(); }, point: function(x, y) { x = +x, y = +y; if (this._point) this._context.lineTo(x, y); else this._point = 1, this._context.moveTo(x, y); } }; function linearClosed(context) { return new LinearClosed(context); } function sign(x) { return x < 0 ? -1 : 1; } // Calculate the slopes of the tangents (Hermite-type interpolation) based on // the following paper: Steffen, M. 1990. A Simple Method for Monotonic // Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO. // NOV(II), P. 443, 1990. function slope3(that, x2, y2) { var h0 = that._x1 - that._x0, h1 = x2 - that._x1, s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0), s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0), p = (s0 * h1 + s1 * h0) / (h0 + h1); return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0; } // Calculate a one-sided slope. function slope2(that, t) { var h = that._x1 - that._x0; return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t; } // According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations // "you can express cubic Hermite interpolation in terms of cubic Bézier curves // with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1". function point(that, t0, t1) { var x0 = that._x0, y0 = that._y0, x1 = that._x1, y1 = that._y1, dx = (x1 - x0) / 3; that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1); } function MonotoneX(context) { this._context = context; } MonotoneX.prototype = { areaStart: function() { this._line = 0; }, areaEnd: function() { this._line = NaN; }, lineStart: function() { this._x0 = this._x1 = this._y0 = this._y1 = this._t0 = NaN; this._point = 0; }, lineEnd: function() { switch (this._point) { case 2: this._context.lineTo(this._x1, this._y1); break; case 3: point(this, this._t0, slope2(this, this._t0)); break; } if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); this._line = 1 - this._line; }, point: function(x, y) { var t1 = NaN; x = +x, y = +y; if (x === this._x1 && y === this._y1) return; // Ignore coincident points. switch (this._point) { case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; case 1: this._point = 2; break; case 2: this._point = 3; point(this, slope2(this, t1 = slope3(this, x, y)), t1); break; default: point(this, this._t0, t1 = slope3(this, x, y)); break; } this._x0 = this._x1, this._x1 = x; this._y0 = this._y1, this._y1 = y; this._t0 = t1; } }; function MonotoneY(context) { this._context = new ReflectContext(context); } (MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) { MonotoneX.prototype.point.call(this, y, x); }; function ReflectContext(context) { this._context = context; } ReflectContext.prototype = { moveTo: function(x, y) { this._context.moveTo(y, x); }, closePath: function() { this._context.closePath(); }, lineTo: function(x, y) { this._context.lineTo(y, x); }, bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); } }; function monotoneX(context) { return new MonotoneX(context); } function monotoneY(context) { return new MonotoneY(context); } function Natural(context) { this._context = context; } Natural.prototype = { areaStart: function() { this._line = 0; }, areaEnd: function() { this._line = NaN; }, lineStart: function() { this._x = []; this._y = []; }, lineEnd: function() { var x = this._x, y = this._y, n = x.length; if (n) { this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]); if (n === 2) { this._context.lineTo(x[1], y[1]); } else { var px = controlPoints(x), py = controlPoints(y); for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) { this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]); } } } if (this._line || (this._line !== 0 && n === 1)) this._context.closePath(); this._line = 1 - this._line; this._x = this._y = null; }, point: function(x, y) { this._x.push(+x); this._y.push(+y); } }; // See https://www.particleincell.com/2012/bezier-splines/ for derivation. function controlPoints(x) { var i, n = x.length - 1, m, a = new Array(n), b = new Array(n), r = new Array(n); a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1]; for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1]; a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n]; for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1]; a[n - 1] = r[n - 1] / b[n - 1]; for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i]; b[n - 1] = (x[n] + a[n - 1]) / 2; for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1]; return [a, b]; } function natural(context) { return new Natural(context); } function Step(context, t) { this._context = context; this._t = t; } Step.prototype = { areaStart: function() { this._line = 0; }, areaEnd: function() { this._line = NaN; }, lineStart: function() { this._x = this._y = NaN; this._point = 0; }, lineEnd: function() { if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y); if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line; }, point: function(x, y) { x = +x, y = +y; switch (this._point) { case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; case 1: this._point = 2; // falls through default: { if (this._t <= 0) { this._context.lineTo(this._x, y); this._context.lineTo(x, y); } else { var x1 = this._x * (1 - this._t) + x * this._t; this._context.lineTo(x1, this._y); this._context.lineTo(x1, y); } break; } } this._x = x, this._y = y; } }; function step(context) { return new Step(context, 0.5); } function stepBefore(context) { return new Step(context, 0); } function stepAfter(context) { return new Step(context, 1); } function none$1(series, order) { if (!((n = series.length) > 1)) return; for (var i = 1, j, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) { s0 = s1, s1 = series[order[i]]; for (j = 0; j < m; ++j) { s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1]; } } } function none(series) { var n = series.length, o = new Array(n); while (--n >= 0) o[n] = n; return o; } function stackValue(d, key) { return d[key]; } function stackSeries(key) { const series = []; series.key = key; return series; } function stack() { var keys = constant([]), order = none, offset = none$1, value = stackValue; function stack(data) { var sz = Array.from(keys.apply(this, arguments), stackSeries), i, n = sz.length, j = -1, oz; for (const d of data) { for (i = 0, ++j; i < n; ++i) { (sz[i][j] = [0, +value(d, sz[i].key, j, data)]).data = d; } } for (i = 0, oz = array(order(sz)); i < n; ++i) { sz[oz[i]].index = i; } offset(sz, oz); return sz; } stack.keys = function(_) { return arguments.length ? (keys = typeof _ === "function" ? _ : constant(Array.from(_)), stack) : keys; }; stack.value = function(_) { return arguments.length ? (value = typeof _ === "function" ? _ : constant(+_), stack) : value; }; stack.order = function(_) { return arguments.length ? (order = _ == null ? none : typeof _ === "function" ? _ : constant(Array.from(_)), stack) : order; }; stack.offset = function(_) { return arguments.length ? (offset = _ == null ? none$1 : _, stack) : offset; }; return stack; } function expand(series, order) { if (!((n = series.length) > 0)) return; for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) { for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0; if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y; } none$1(series, order); } function diverging(series, order) { if (!((n = series.length) > 0)) return; for (var i, j = 0, d, dy, yp, yn, n, m = series[order[0]].length; j < m; ++j) { for (yp = yn = 0, i = 0; i < n; ++i) { if ((dy = (d = series[order[i]][j])[1] - d[0]) > 0) { d[0] = yp, d[1] = yp += dy; } else if (dy < 0) { d[1] = yn, d[0] = yn += dy; } else { d[0] = 0, d[1] = dy; } } } } function silhouette(series, order) { if (!((n = series.length) > 0)) return; for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) { for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0; s0[j][1] += s0[j][0] = -y / 2; } none$1(series, order); } function wiggle(series, order) { if (!((n = series.length) > 0) || !((m = (s0 = series[order[0]]).length) > 0)) return; for (var y = 0, j = 1, s0, m, n; j < m; ++j) { for (var i = 0, s1 = 0, s2 = 0; i < n; ++i) { var si = series[order[i]], sij0 = si[j][1] || 0, sij1 = si[j - 1][1] || 0, s3 = (sij0 - sij1) / 2; for (var k = 0; k < i; ++k) { var sk = series[order[k]], skj0 = sk[j][1] || 0, skj1 = sk[j - 1][1] || 0; s3 += skj0 - skj1; } s1 += sij0, s2 += s3 * sij0; } s0[j - 1][1] += s0[j - 1][0] = y; if (s1) y -= s2 / s1; } s0[j - 1][1] += s0[j - 1][0] = y; none$1(series, order); } function appearance(series) { var peaks = series.map(peak); return none(series).sort(function(a, b) { return peaks[a] - peaks[b]; }); } function peak(series) { var i = -1, j = 0, n = series.length, vi, vj = -Infinity; while (++i < n) if ((vi = +series[i][1]) > vj) vj = vi, j = i; return j; } function ascending(series) { var sums = series.map(sum); return none(series).sort(function(a, b) { return sums[a] - sums[b]; }); } function sum(series) { var s = 0, i = -1, n = series.length, v; while (++i < n) if (v = +series[i][1]) s += v; return s; } function descending(series) { return ascending(series).reverse(); } function insideOut(series) { var n = series.length, i, j, sums = series.map(sum), order = appearance(series), top = 0, bottom = 0, tops = [], bottoms = []; for (i = 0; i < n; ++i) { j = order[i]; if (top < bottom) { top += sums[j]; tops.push(j); } else { bottom += sums[j]; bottoms.push(j); } } return bottoms.reverse().concat(tops); } function reverse(series) { return none(series).reverse(); } exports.arc = arc; exports.area = area; exports.areaRadial = areaRadial; exports.curveBasis = basis; exports.curveBasisClosed = basisClosed; exports.curveBasisOpen = basisOpen; exports.curveBumpX = bumpX; exports.curveBumpY = bumpY; exports.curveBundle = bundle; exports.curveCardinal = cardinal; exports.curveCardinalClosed = cardinalClosed; exports.curveCardinalOpen = cardinalOpen; exports.curveCatmullRom = catmullRom; exports.curveCatmullRomClosed = catmullRomClosed; exports.curveCatmullRomOpen = catmullRomOpen; exports.curveLinear = curveLinear; exports.curveLinearClosed = linearClosed; exports.curveMonotoneX = monotoneX; exports.curveMonotoneY = monotoneY; exports.curveNatural = natural; exports.curveStep = step; exports.curveStepAfter = stepAfter; exports.curveStepBefore = stepBefore; exports.line = line; exports.lineRadial = lineRadial$1; exports.link = link; exports.linkHorizontal = linkHorizontal; exports.linkRadial = linkRadial; exports.linkVertical = linkVertical; exports.pie = pie; exports.pointRadial = pointRadial; exports.radialArea = areaRadial; exports.radialLine = lineRadial$1; exports.stack = stack; exports.stackOffsetDiverging = diverging; exports.stackOffsetExpand = expand; exports.stackOffsetNone = none$1; exports.stackOffsetSilhouette = silhouette; exports.stackOffsetWiggle = wiggle; exports.stackOrderAppearance = appearance; exports.stackOrderAscending = ascending; exports.stackOrderDescending = descending; exports.stackOrderInsideOut = insideOut; exports.stackOrderNone = none; exports.stackOrderReverse = reverse; exports.symbol = Symbol; exports.symbolAsterisk = asterisk; exports.symbolCircle = circle; exports.symbolCross = cross; exports.symbolDiamond = diamond; exports.symbolDiamond2 = diamond2; exports.symbolPlus = plus; exports.symbolSquare = square; exports.symbolSquare2 = square2; exports.symbolStar = star; exports.symbolTimes = times; exports.symbolTriangle = triangle; exports.symbolTriangle2 = triangle2; exports.symbolWye = wye; exports.symbolX = times; exports.symbols = symbolsFill; exports.symbolsFill = symbolsFill; exports.symbolsStroke = symbolsStroke; }));