| 1 | // https://d3js.org/d3-shape/ v3.2.0 Copyright 2010-2022 Mike Bostock
|
|---|
| 2 | (function (global, factory) {
|
|---|
| 3 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-path')) :
|
|---|
| 4 | typeof define === 'function' && define.amd ? define(['exports', 'd3-path'], factory) :
|
|---|
| 5 | (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = global.d3 || {}, global.d3));
|
|---|
| 6 | })(this, (function (exports, d3Path) { 'use strict';
|
|---|
| 7 |
|
|---|
| 8 | function constant(x) {
|
|---|
| 9 | return function constant() {
|
|---|
| 10 | return x;
|
|---|
| 11 | };
|
|---|
| 12 | }
|
|---|
| 13 |
|
|---|
| 14 | const abs = Math.abs;
|
|---|
| 15 | const atan2 = Math.atan2;
|
|---|
| 16 | const cos = Math.cos;
|
|---|
| 17 | const max = Math.max;
|
|---|
| 18 | const min = Math.min;
|
|---|
| 19 | const sin = Math.sin;
|
|---|
| 20 | const sqrt = Math.sqrt;
|
|---|
| 21 |
|
|---|
| 22 | const epsilon = 1e-12;
|
|---|
| 23 | const pi = Math.PI;
|
|---|
| 24 | const halfPi = pi / 2;
|
|---|
| 25 | const tau = 2 * pi;
|
|---|
| 26 |
|
|---|
| 27 | function acos(x) {
|
|---|
| 28 | return x > 1 ? 0 : x < -1 ? pi : Math.acos(x);
|
|---|
| 29 | }
|
|---|
| 30 |
|
|---|
| 31 | function asin(x) {
|
|---|
| 32 | return x >= 1 ? halfPi : x <= -1 ? -halfPi : Math.asin(x);
|
|---|
| 33 | }
|
|---|
| 34 |
|
|---|
| 35 | function withPath(shape) {
|
|---|
| 36 | let digits = 3;
|
|---|
| 37 |
|
|---|
| 38 | shape.digits = function(_) {
|
|---|
| 39 | if (!arguments.length) return digits;
|
|---|
| 40 | if (_ == null) {
|
|---|
| 41 | digits = null;
|
|---|
| 42 | } else {
|
|---|
| 43 | const d = Math.floor(_);
|
|---|
| 44 | if (!(d >= 0)) throw new RangeError(`invalid digits: ${_}`);
|
|---|
| 45 | digits = d;
|
|---|
| 46 | }
|
|---|
| 47 | return shape;
|
|---|
| 48 | };
|
|---|
| 49 |
|
|---|
| 50 | return () => new d3Path.Path(digits);
|
|---|
| 51 | }
|
|---|
| 52 |
|
|---|
| 53 | function arcInnerRadius(d) {
|
|---|
| 54 | return d.innerRadius;
|
|---|
| 55 | }
|
|---|
| 56 |
|
|---|
| 57 | function arcOuterRadius(d) {
|
|---|
| 58 | return d.outerRadius;
|
|---|
| 59 | }
|
|---|
| 60 |
|
|---|
| 61 | function arcStartAngle(d) {
|
|---|
| 62 | return d.startAngle;
|
|---|
| 63 | }
|
|---|
| 64 |
|
|---|
| 65 | function arcEndAngle(d) {
|
|---|
| 66 | return d.endAngle;
|
|---|
| 67 | }
|
|---|
| 68 |
|
|---|
| 69 | function arcPadAngle(d) {
|
|---|
| 70 | return d && d.padAngle; // Note: optional!
|
|---|
| 71 | }
|
|---|
| 72 |
|
|---|
| 73 | function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
|
|---|
| 74 | var x10 = x1 - x0, y10 = y1 - y0,
|
|---|
| 75 | x32 = x3 - x2, y32 = y3 - y2,
|
|---|
| 76 | t = y32 * x10 - x32 * y10;
|
|---|
| 77 | if (t * t < epsilon) return;
|
|---|
| 78 | t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / t;
|
|---|
| 79 | return [x0 + t * x10, y0 + t * y10];
|
|---|
| 80 | }
|
|---|
| 81 |
|
|---|
| 82 | // Compute perpendicular offset line of length rc.
|
|---|
| 83 | // http://mathworld.wolfram.com/Circle-LineIntersection.html
|
|---|
| 84 | function cornerTangents(x0, y0, x1, y1, r1, rc, cw) {
|
|---|
| 85 | var x01 = x0 - x1,
|
|---|
| 86 | y01 = y0 - y1,
|
|---|
| 87 | lo = (cw ? rc : -rc) / sqrt(x01 * x01 + y01 * y01),
|
|---|
| 88 | ox = lo * y01,
|
|---|
| 89 | oy = -lo * x01,
|
|---|
| 90 | x11 = x0 + ox,
|
|---|
| 91 | y11 = y0 + oy,
|
|---|
| 92 | x10 = x1 + ox,
|
|---|
| 93 | y10 = y1 + oy,
|
|---|
| 94 | x00 = (x11 + x10) / 2,
|
|---|
| 95 | y00 = (y11 + y10) / 2,
|
|---|
| 96 | dx = x10 - x11,
|
|---|
| 97 | dy = y10 - y11,
|
|---|
| 98 | d2 = dx * dx + dy * dy,
|
|---|
| 99 | r = r1 - rc,
|
|---|
| 100 | D = x11 * y10 - x10 * y11,
|
|---|
| 101 | d = (dy < 0 ? -1 : 1) * sqrt(max(0, r * r * d2 - D * D)),
|
|---|
| 102 | cx0 = (D * dy - dx * d) / d2,
|
|---|
| 103 | cy0 = (-D * dx - dy * d) / d2,
|
|---|
| 104 | cx1 = (D * dy + dx * d) / d2,
|
|---|
| 105 | cy1 = (-D * dx + dy * d) / d2,
|
|---|
| 106 | dx0 = cx0 - x00,
|
|---|
| 107 | dy0 = cy0 - y00,
|
|---|
| 108 | dx1 = cx1 - x00,
|
|---|
| 109 | dy1 = cy1 - y00;
|
|---|
| 110 |
|
|---|
| 111 | // Pick the closer of the two intersection points.
|
|---|
| 112 | // TODO Is there a faster way to determine which intersection to use?
|
|---|
| 113 | if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;
|
|---|
| 114 |
|
|---|
| 115 | return {
|
|---|
| 116 | cx: cx0,
|
|---|
| 117 | cy: cy0,
|
|---|
| 118 | x01: -ox,
|
|---|
| 119 | y01: -oy,
|
|---|
| 120 | x11: cx0 * (r1 / r - 1),
|
|---|
| 121 | y11: cy0 * (r1 / r - 1)
|
|---|
| 122 | };
|
|---|
| 123 | }
|
|---|
| 124 |
|
|---|
| 125 | function arc() {
|
|---|
| 126 | var innerRadius = arcInnerRadius,
|
|---|
| 127 | outerRadius = arcOuterRadius,
|
|---|
| 128 | cornerRadius = constant(0),
|
|---|
| 129 | padRadius = null,
|
|---|
| 130 | startAngle = arcStartAngle,
|
|---|
| 131 | endAngle = arcEndAngle,
|
|---|
| 132 | padAngle = arcPadAngle,
|
|---|
| 133 | context = null,
|
|---|
| 134 | path = withPath(arc);
|
|---|
| 135 |
|
|---|
| 136 | function arc() {
|
|---|
| 137 | var buffer,
|
|---|
| 138 | r,
|
|---|
| 139 | r0 = +innerRadius.apply(this, arguments),
|
|---|
| 140 | r1 = +outerRadius.apply(this, arguments),
|
|---|
| 141 | a0 = startAngle.apply(this, arguments) - halfPi,
|
|---|
| 142 | a1 = endAngle.apply(this, arguments) - halfPi,
|
|---|
| 143 | da = abs(a1 - a0),
|
|---|
| 144 | cw = a1 > a0;
|
|---|
| 145 |
|
|---|
| 146 | if (!context) context = buffer = path();
|
|---|
| 147 |
|
|---|
| 148 | // Ensure that the outer radius is always larger than the inner radius.
|
|---|
| 149 | if (r1 < r0) r = r1, r1 = r0, r0 = r;
|
|---|
| 150 |
|
|---|
| 151 | // Is it a point?
|
|---|
| 152 | if (!(r1 > epsilon)) context.moveTo(0, 0);
|
|---|
| 153 |
|
|---|
| 154 | // Or is it a circle or annulus?
|
|---|
| 155 | else if (da > tau - epsilon) {
|
|---|
| 156 | context.moveTo(r1 * cos(a0), r1 * sin(a0));
|
|---|
| 157 | context.arc(0, 0, r1, a0, a1, !cw);
|
|---|
| 158 | if (r0 > epsilon) {
|
|---|
| 159 | context.moveTo(r0 * cos(a1), r0 * sin(a1));
|
|---|
| 160 | context.arc(0, 0, r0, a1, a0, cw);
|
|---|
| 161 | }
|
|---|
| 162 | }
|
|---|
| 163 |
|
|---|
| 164 | // Or is it a circular or annular sector?
|
|---|
| 165 | else {
|
|---|
| 166 | var a01 = a0,
|
|---|
| 167 | a11 = a1,
|
|---|
| 168 | a00 = a0,
|
|---|
| 169 | a10 = a1,
|
|---|
| 170 | da0 = da,
|
|---|
| 171 | da1 = da,
|
|---|
| 172 | ap = padAngle.apply(this, arguments) / 2,
|
|---|
| 173 | rp = (ap > epsilon) && (padRadius ? +padRadius.apply(this, arguments) : sqrt(r0 * r0 + r1 * r1)),
|
|---|
| 174 | rc = min(abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),
|
|---|
| 175 | rc0 = rc,
|
|---|
| 176 | rc1 = rc,
|
|---|
| 177 | t0,
|
|---|
| 178 | t1;
|
|---|
| 179 |
|
|---|
| 180 | // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.
|
|---|
| 181 | if (rp > epsilon) {
|
|---|
| 182 | var p0 = asin(rp / r0 * sin(ap)),
|
|---|
| 183 | p1 = asin(rp / r1 * sin(ap));
|
|---|
| 184 | if ((da0 -= p0 * 2) > epsilon) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;
|
|---|
| 185 | else da0 = 0, a00 = a10 = (a0 + a1) / 2;
|
|---|
| 186 | if ((da1 -= p1 * 2) > epsilon) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;
|
|---|
| 187 | else da1 = 0, a01 = a11 = (a0 + a1) / 2;
|
|---|
| 188 | }
|
|---|
| 189 |
|
|---|
| 190 | var x01 = r1 * cos(a01),
|
|---|
| 191 | y01 = r1 * sin(a01),
|
|---|
| 192 | x10 = r0 * cos(a10),
|
|---|
| 193 | y10 = r0 * sin(a10);
|
|---|
| 194 |
|
|---|
| 195 | // Apply rounded corners?
|
|---|
| 196 | if (rc > epsilon) {
|
|---|
| 197 | var x11 = r1 * cos(a11),
|
|---|
| 198 | y11 = r1 * sin(a11),
|
|---|
| 199 | x00 = r0 * cos(a00),
|
|---|
| 200 | y00 = r0 * sin(a00),
|
|---|
| 201 | oc;
|
|---|
| 202 |
|
|---|
| 203 | // Restrict the corner radius according to the sector angle. If this
|
|---|
| 204 | // intersection fails, it’s probably because the arc is too small, so
|
|---|
| 205 | // disable the corner radius entirely.
|
|---|
| 206 | if (da < pi) {
|
|---|
| 207 | if (oc = intersect(x01, y01, x00, y00, x11, y11, x10, y10)) {
|
|---|
| 208 | var ax = x01 - oc[0],
|
|---|
| 209 | ay = y01 - oc[1],
|
|---|
| 210 | bx = x11 - oc[0],
|
|---|
| 211 | by = y11 - oc[1],
|
|---|
| 212 | kc = 1 / sin(acos((ax * bx + ay * by) / (sqrt(ax * ax + ay * ay) * sqrt(bx * bx + by * by))) / 2),
|
|---|
| 213 | lc = sqrt(oc[0] * oc[0] + oc[1] * oc[1]);
|
|---|
| 214 | rc0 = min(rc, (r0 - lc) / (kc - 1));
|
|---|
| 215 | rc1 = min(rc, (r1 - lc) / (kc + 1));
|
|---|
| 216 | } else {
|
|---|
| 217 | rc0 = rc1 = 0;
|
|---|
| 218 | }
|
|---|
| 219 | }
|
|---|
| 220 | }
|
|---|
| 221 |
|
|---|
| 222 | // Is the sector collapsed to a line?
|
|---|
| 223 | if (!(da1 > epsilon)) context.moveTo(x01, y01);
|
|---|
| 224 |
|
|---|
| 225 | // Does the sector’s outer ring have rounded corners?
|
|---|
| 226 | else if (rc1 > epsilon) {
|
|---|
| 227 | t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);
|
|---|
| 228 | t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);
|
|---|
| 229 |
|
|---|
| 230 | context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);
|
|---|
| 231 |
|
|---|
| 232 | // Have the corners merged?
|
|---|
| 233 | if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw);
|
|---|
| 234 |
|
|---|
| 235 | // Otherwise, draw the two corners and the ring.
|
|---|
| 236 | else {
|
|---|
| 237 | context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw);
|
|---|
| 238 | context.arc(0, 0, r1, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw);
|
|---|
| 239 | context.arc(t1.cx, t1.cy, rc1, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw);
|
|---|
| 240 | }
|
|---|
| 241 | }
|
|---|
| 242 |
|
|---|
| 243 | // Or is the outer ring just a circular arc?
|
|---|
| 244 | else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);
|
|---|
| 245 |
|
|---|
| 246 | // Is there no inner ring, and it’s a circular sector?
|
|---|
| 247 | // Or perhaps it’s an annular sector collapsed due to padding?
|
|---|
| 248 | if (!(r0 > epsilon) || !(da0 > epsilon)) context.lineTo(x10, y10);
|
|---|
| 249 |
|
|---|
| 250 | // Does the sector’s inner ring (or point) have rounded corners?
|
|---|
| 251 | else if (rc0 > epsilon) {
|
|---|
| 252 | t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);
|
|---|
| 253 | t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);
|
|---|
| 254 |
|
|---|
| 255 | context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);
|
|---|
| 256 |
|
|---|
| 257 | // Have the corners merged?
|
|---|
| 258 | if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw);
|
|---|
| 259 |
|
|---|
| 260 | // Otherwise, draw the two corners and the ring.
|
|---|
| 261 | else {
|
|---|
| 262 | context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw);
|
|---|
| 263 | context.arc(0, 0, r0, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw);
|
|---|
| 264 | context.arc(t1.cx, t1.cy, rc0, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw);
|
|---|
| 265 | }
|
|---|
| 266 | }
|
|---|
| 267 |
|
|---|
| 268 | // Or is the inner ring just a circular arc?
|
|---|
| 269 | else context.arc(0, 0, r0, a10, a00, cw);
|
|---|
| 270 | }
|
|---|
| 271 |
|
|---|
| 272 | context.closePath();
|
|---|
| 273 |
|
|---|
| 274 | if (buffer) return context = null, buffer + "" || null;
|
|---|
| 275 | }
|
|---|
| 276 |
|
|---|
| 277 | arc.centroid = function() {
|
|---|
| 278 | var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,
|
|---|
| 279 | a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi / 2;
|
|---|
| 280 | return [cos(a) * r, sin(a) * r];
|
|---|
| 281 | };
|
|---|
| 282 |
|
|---|
| 283 | arc.innerRadius = function(_) {
|
|---|
| 284 | return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant(+_), arc) : innerRadius;
|
|---|
| 285 | };
|
|---|
| 286 |
|
|---|
| 287 | arc.outerRadius = function(_) {
|
|---|
| 288 | return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant(+_), arc) : outerRadius;
|
|---|
| 289 | };
|
|---|
| 290 |
|
|---|
| 291 | arc.cornerRadius = function(_) {
|
|---|
| 292 | return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant(+_), arc) : cornerRadius;
|
|---|
| 293 | };
|
|---|
| 294 |
|
|---|
| 295 | arc.padRadius = function(_) {
|
|---|
| 296 | return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant(+_), arc) : padRadius;
|
|---|
| 297 | };
|
|---|
| 298 |
|
|---|
| 299 | arc.startAngle = function(_) {
|
|---|
| 300 | return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant(+_), arc) : startAngle;
|
|---|
| 301 | };
|
|---|
| 302 |
|
|---|
| 303 | arc.endAngle = function(_) {
|
|---|
| 304 | return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant(+_), arc) : endAngle;
|
|---|
| 305 | };
|
|---|
| 306 |
|
|---|
| 307 | arc.padAngle = function(_) {
|
|---|
| 308 | return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant(+_), arc) : padAngle;
|
|---|
| 309 | };
|
|---|
| 310 |
|
|---|
| 311 | arc.context = function(_) {
|
|---|
| 312 | return arguments.length ? ((context = _ == null ? null : _), arc) : context;
|
|---|
| 313 | };
|
|---|
| 314 |
|
|---|
| 315 | return arc;
|
|---|
| 316 | }
|
|---|
| 317 |
|
|---|
| 318 | var slice = Array.prototype.slice;
|
|---|
| 319 |
|
|---|
| 320 | function array(x) {
|
|---|
| 321 | return typeof x === "object" && "length" in x
|
|---|
| 322 | ? x // Array, TypedArray, NodeList, array-like
|
|---|
| 323 | : Array.from(x); // Map, Set, iterable, string, or anything else
|
|---|
| 324 | }
|
|---|
| 325 |
|
|---|
| 326 | function Linear(context) {
|
|---|
| 327 | this._context = context;
|
|---|
| 328 | }
|
|---|
| 329 |
|
|---|
| 330 | Linear.prototype = {
|
|---|
| 331 | areaStart: function() {
|
|---|
| 332 | this._line = 0;
|
|---|
| 333 | },
|
|---|
| 334 | areaEnd: function() {
|
|---|
| 335 | this._line = NaN;
|
|---|
| 336 | },
|
|---|
| 337 | lineStart: function() {
|
|---|
| 338 | this._point = 0;
|
|---|
| 339 | },
|
|---|
| 340 | lineEnd: function() {
|
|---|
| 341 | if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
|
|---|
| 342 | this._line = 1 - this._line;
|
|---|
| 343 | },
|
|---|
| 344 | point: function(x, y) {
|
|---|
| 345 | x = +x, y = +y;
|
|---|
| 346 | switch (this._point) {
|
|---|
| 347 | case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
|
|---|
| 348 | case 1: this._point = 2; // falls through
|
|---|
| 349 | default: this._context.lineTo(x, y); break;
|
|---|
| 350 | }
|
|---|
| 351 | }
|
|---|
| 352 | };
|
|---|
| 353 |
|
|---|
| 354 | function curveLinear(context) {
|
|---|
| 355 | return new Linear(context);
|
|---|
| 356 | }
|
|---|
| 357 |
|
|---|
| 358 | function x(p) {
|
|---|
| 359 | return p[0];
|
|---|
| 360 | }
|
|---|
| 361 |
|
|---|
| 362 | function y(p) {
|
|---|
| 363 | return p[1];
|
|---|
| 364 | }
|
|---|
| 365 |
|
|---|
| 366 | function line(x$1, y$1) {
|
|---|
| 367 | var defined = constant(true),
|
|---|
| 368 | context = null,
|
|---|
| 369 | curve = curveLinear,
|
|---|
| 370 | output = null,
|
|---|
| 371 | path = withPath(line);
|
|---|
| 372 |
|
|---|
| 373 | x$1 = typeof x$1 === "function" ? x$1 : (x$1 === undefined) ? x : constant(x$1);
|
|---|
| 374 | y$1 = typeof y$1 === "function" ? y$1 : (y$1 === undefined) ? y : constant(y$1);
|
|---|
| 375 |
|
|---|
| 376 | function line(data) {
|
|---|
| 377 | var i,
|
|---|
| 378 | n = (data = array(data)).length,
|
|---|
| 379 | d,
|
|---|
| 380 | defined0 = false,
|
|---|
| 381 | buffer;
|
|---|
| 382 |
|
|---|
| 383 | if (context == null) output = curve(buffer = path());
|
|---|
| 384 |
|
|---|
| 385 | for (i = 0; i <= n; ++i) {
|
|---|
| 386 | if (!(i < n && defined(d = data[i], i, data)) === defined0) {
|
|---|
| 387 | if (defined0 = !defined0) output.lineStart();
|
|---|
| 388 | else output.lineEnd();
|
|---|
| 389 | }
|
|---|
| 390 | if (defined0) output.point(+x$1(d, i, data), +y$1(d, i, data));
|
|---|
| 391 | }
|
|---|
| 392 |
|
|---|
| 393 | if (buffer) return output = null, buffer + "" || null;
|
|---|
| 394 | }
|
|---|
| 395 |
|
|---|
| 396 | line.x = function(_) {
|
|---|
| 397 | return arguments.length ? (x$1 = typeof _ === "function" ? _ : constant(+_), line) : x$1;
|
|---|
| 398 | };
|
|---|
| 399 |
|
|---|
| 400 | line.y = function(_) {
|
|---|
| 401 | return arguments.length ? (y$1 = typeof _ === "function" ? _ : constant(+_), line) : y$1;
|
|---|
| 402 | };
|
|---|
| 403 |
|
|---|
| 404 | line.defined = function(_) {
|
|---|
| 405 | return arguments.length ? (defined = typeof _ === "function" ? _ : constant(!!_), line) : defined;
|
|---|
| 406 | };
|
|---|
| 407 |
|
|---|
| 408 | line.curve = function(_) {
|
|---|
| 409 | return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;
|
|---|
| 410 | };
|
|---|
| 411 |
|
|---|
| 412 | line.context = function(_) {
|
|---|
| 413 | return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;
|
|---|
| 414 | };
|
|---|
| 415 |
|
|---|
| 416 | return line;
|
|---|
| 417 | }
|
|---|
| 418 |
|
|---|
| 419 | function area(x0, y0, y1) {
|
|---|
| 420 | var x1 = null,
|
|---|
| 421 | defined = constant(true),
|
|---|
| 422 | context = null,
|
|---|
| 423 | curve = curveLinear,
|
|---|
| 424 | output = null,
|
|---|
| 425 | path = withPath(area);
|
|---|
| 426 |
|
|---|
| 427 | x0 = typeof x0 === "function" ? x0 : (x0 === undefined) ? x : constant(+x0);
|
|---|
| 428 | y0 = typeof y0 === "function" ? y0 : (y0 === undefined) ? constant(0) : constant(+y0);
|
|---|
| 429 | y1 = typeof y1 === "function" ? y1 : (y1 === undefined) ? y : constant(+y1);
|
|---|
| 430 |
|
|---|
| 431 | function area(data) {
|
|---|
| 432 | var i,
|
|---|
| 433 | j,
|
|---|
| 434 | k,
|
|---|
| 435 | n = (data = array(data)).length,
|
|---|
| 436 | d,
|
|---|
| 437 | defined0 = false,
|
|---|
| 438 | buffer,
|
|---|
| 439 | x0z = new Array(n),
|
|---|
| 440 | y0z = new Array(n);
|
|---|
| 441 |
|
|---|
| 442 | if (context == null) output = curve(buffer = path());
|
|---|
| 443 |
|
|---|
| 444 | for (i = 0; i <= n; ++i) {
|
|---|
| 445 | if (!(i < n && defined(d = data[i], i, data)) === defined0) {
|
|---|
| 446 | if (defined0 = !defined0) {
|
|---|
| 447 | j = i;
|
|---|
| 448 | output.areaStart();
|
|---|
| 449 | output.lineStart();
|
|---|
| 450 | } else {
|
|---|
| 451 | output.lineEnd();
|
|---|
| 452 | output.lineStart();
|
|---|
| 453 | for (k = i - 1; k >= j; --k) {
|
|---|
| 454 | output.point(x0z[k], y0z[k]);
|
|---|
| 455 | }
|
|---|
| 456 | output.lineEnd();
|
|---|
| 457 | output.areaEnd();
|
|---|
| 458 | }
|
|---|
| 459 | }
|
|---|
| 460 | if (defined0) {
|
|---|
| 461 | x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);
|
|---|
| 462 | output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);
|
|---|
| 463 | }
|
|---|
| 464 | }
|
|---|
| 465 |
|
|---|
| 466 | if (buffer) return output = null, buffer + "" || null;
|
|---|
| 467 | }
|
|---|
| 468 |
|
|---|
| 469 | function arealine() {
|
|---|
| 470 | return line().defined(defined).curve(curve).context(context);
|
|---|
| 471 | }
|
|---|
| 472 |
|
|---|
| 473 | area.x = function(_) {
|
|---|
| 474 | return arguments.length ? (x0 = typeof _ === "function" ? _ : constant(+_), x1 = null, area) : x0;
|
|---|
| 475 | };
|
|---|
| 476 |
|
|---|
| 477 | area.x0 = function(_) {
|
|---|
| 478 | return arguments.length ? (x0 = typeof _ === "function" ? _ : constant(+_), area) : x0;
|
|---|
| 479 | };
|
|---|
| 480 |
|
|---|
| 481 | area.x1 = function(_) {
|
|---|
| 482 | return arguments.length ? (x1 = _ == null ? null : typeof _ === "function" ? _ : constant(+_), area) : x1;
|
|---|
| 483 | };
|
|---|
| 484 |
|
|---|
| 485 | area.y = function(_) {
|
|---|
| 486 | return arguments.length ? (y0 = typeof _ === "function" ? _ : constant(+_), y1 = null, area) : y0;
|
|---|
| 487 | };
|
|---|
| 488 |
|
|---|
| 489 | area.y0 = function(_) {
|
|---|
| 490 | return arguments.length ? (y0 = typeof _ === "function" ? _ : constant(+_), area) : y0;
|
|---|
| 491 | };
|
|---|
| 492 |
|
|---|
| 493 | area.y1 = function(_) {
|
|---|
| 494 | return arguments.length ? (y1 = _ == null ? null : typeof _ === "function" ? _ : constant(+_), area) : y1;
|
|---|
| 495 | };
|
|---|
| 496 |
|
|---|
| 497 | area.lineX0 =
|
|---|
| 498 | area.lineY0 = function() {
|
|---|
| 499 | return arealine().x(x0).y(y0);
|
|---|
| 500 | };
|
|---|
| 501 |
|
|---|
| 502 | area.lineY1 = function() {
|
|---|
| 503 | return arealine().x(x0).y(y1);
|
|---|
| 504 | };
|
|---|
| 505 |
|
|---|
| 506 | area.lineX1 = function() {
|
|---|
| 507 | return arealine().x(x1).y(y0);
|
|---|
| 508 | };
|
|---|
| 509 |
|
|---|
| 510 | area.defined = function(_) {
|
|---|
| 511 | return arguments.length ? (defined = typeof _ === "function" ? _ : constant(!!_), area) : defined;
|
|---|
| 512 | };
|
|---|
| 513 |
|
|---|
| 514 | area.curve = function(_) {
|
|---|
| 515 | return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve;
|
|---|
| 516 | };
|
|---|
| 517 |
|
|---|
| 518 | area.context = function(_) {
|
|---|
| 519 | return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;
|
|---|
| 520 | };
|
|---|
| 521 |
|
|---|
| 522 | return area;
|
|---|
| 523 | }
|
|---|
| 524 |
|
|---|
| 525 | function descending$1(a, b) {
|
|---|
| 526 | return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
|
|---|
| 527 | }
|
|---|
| 528 |
|
|---|
| 529 | function identity(d) {
|
|---|
| 530 | return d;
|
|---|
| 531 | }
|
|---|
| 532 |
|
|---|
| 533 | function pie() {
|
|---|
| 534 | var value = identity,
|
|---|
| 535 | sortValues = descending$1,
|
|---|
| 536 | sort = null,
|
|---|
| 537 | startAngle = constant(0),
|
|---|
| 538 | endAngle = constant(tau),
|
|---|
| 539 | padAngle = constant(0);
|
|---|
| 540 |
|
|---|
| 541 | function pie(data) {
|
|---|
| 542 | var i,
|
|---|
| 543 | n = (data = array(data)).length,
|
|---|
| 544 | j,
|
|---|
| 545 | k,
|
|---|
| 546 | sum = 0,
|
|---|
| 547 | index = new Array(n),
|
|---|
| 548 | arcs = new Array(n),
|
|---|
| 549 | a0 = +startAngle.apply(this, arguments),
|
|---|
| 550 | da = Math.min(tau, Math.max(-tau, endAngle.apply(this, arguments) - a0)),
|
|---|
| 551 | a1,
|
|---|
| 552 | p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)),
|
|---|
| 553 | pa = p * (da < 0 ? -1 : 1),
|
|---|
| 554 | v;
|
|---|
| 555 |
|
|---|
| 556 | for (i = 0; i < n; ++i) {
|
|---|
| 557 | if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) {
|
|---|
| 558 | sum += v;
|
|---|
| 559 | }
|
|---|
| 560 | }
|
|---|
| 561 |
|
|---|
| 562 | // Optionally sort the arcs by previously-computed values or by data.
|
|---|
| 563 | if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); });
|
|---|
| 564 | else if (sort != null) index.sort(function(i, j) { return sort(data[i], data[j]); });
|
|---|
| 565 |
|
|---|
| 566 | // Compute the arcs! They are stored in the original data's order.
|
|---|
| 567 | for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) {
|
|---|
| 568 | j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = {
|
|---|
| 569 | data: data[j],
|
|---|
| 570 | index: i,
|
|---|
| 571 | value: v,
|
|---|
| 572 | startAngle: a0,
|
|---|
| 573 | endAngle: a1,
|
|---|
| 574 | padAngle: p
|
|---|
| 575 | };
|
|---|
| 576 | }
|
|---|
| 577 |
|
|---|
| 578 | return arcs;
|
|---|
| 579 | }
|
|---|
| 580 |
|
|---|
| 581 | pie.value = function(_) {
|
|---|
| 582 | return arguments.length ? (value = typeof _ === "function" ? _ : constant(+_), pie) : value;
|
|---|
| 583 | };
|
|---|
| 584 |
|
|---|
| 585 | pie.sortValues = function(_) {
|
|---|
| 586 | return arguments.length ? (sortValues = _, sort = null, pie) : sortValues;
|
|---|
| 587 | };
|
|---|
| 588 |
|
|---|
| 589 | pie.sort = function(_) {
|
|---|
| 590 | return arguments.length ? (sort = _, sortValues = null, pie) : sort;
|
|---|
| 591 | };
|
|---|
| 592 |
|
|---|
| 593 | pie.startAngle = function(_) {
|
|---|
| 594 | return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant(+_), pie) : startAngle;
|
|---|
| 595 | };
|
|---|
| 596 |
|
|---|
| 597 | pie.endAngle = function(_) {
|
|---|
| 598 | return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant(+_), pie) : endAngle;
|
|---|
| 599 | };
|
|---|
| 600 |
|
|---|
| 601 | pie.padAngle = function(_) {
|
|---|
| 602 | return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant(+_), pie) : padAngle;
|
|---|
| 603 | };
|
|---|
| 604 |
|
|---|
| 605 | return pie;
|
|---|
| 606 | }
|
|---|
| 607 |
|
|---|
| 608 | var curveRadialLinear = curveRadial(curveLinear);
|
|---|
| 609 |
|
|---|
| 610 | function Radial(curve) {
|
|---|
| 611 | this._curve = curve;
|
|---|
| 612 | }
|
|---|
| 613 |
|
|---|
| 614 | Radial.prototype = {
|
|---|
| 615 | areaStart: function() {
|
|---|
| 616 | this._curve.areaStart();
|
|---|
| 617 | },
|
|---|
| 618 | areaEnd: function() {
|
|---|
| 619 | this._curve.areaEnd();
|
|---|
| 620 | },
|
|---|
| 621 | lineStart: function() {
|
|---|
| 622 | this._curve.lineStart();
|
|---|
| 623 | },
|
|---|
| 624 | lineEnd: function() {
|
|---|
| 625 | this._curve.lineEnd();
|
|---|
| 626 | },
|
|---|
| 627 | point: function(a, r) {
|
|---|
| 628 | this._curve.point(r * Math.sin(a), r * -Math.cos(a));
|
|---|
| 629 | }
|
|---|
| 630 | };
|
|---|
| 631 |
|
|---|
| 632 | function curveRadial(curve) {
|
|---|
| 633 |
|
|---|
| 634 | function radial(context) {
|
|---|
| 635 | return new Radial(curve(context));
|
|---|
| 636 | }
|
|---|
| 637 |
|
|---|
| 638 | radial._curve = curve;
|
|---|
| 639 |
|
|---|
| 640 | return radial;
|
|---|
| 641 | }
|
|---|
| 642 |
|
|---|
| 643 | function lineRadial(l) {
|
|---|
| 644 | var c = l.curve;
|
|---|
| 645 |
|
|---|
| 646 | l.angle = l.x, delete l.x;
|
|---|
| 647 | l.radius = l.y, delete l.y;
|
|---|
| 648 |
|
|---|
| 649 | l.curve = function(_) {
|
|---|
| 650 | return arguments.length ? c(curveRadial(_)) : c()._curve;
|
|---|
| 651 | };
|
|---|
| 652 |
|
|---|
| 653 | return l;
|
|---|
| 654 | }
|
|---|
| 655 |
|
|---|
| 656 | function lineRadial$1() {
|
|---|
| 657 | return lineRadial(line().curve(curveRadialLinear));
|
|---|
| 658 | }
|
|---|
| 659 |
|
|---|
| 660 | function areaRadial() {
|
|---|
| 661 | var a = area().curve(curveRadialLinear),
|
|---|
| 662 | c = a.curve,
|
|---|
| 663 | x0 = a.lineX0,
|
|---|
| 664 | x1 = a.lineX1,
|
|---|
| 665 | y0 = a.lineY0,
|
|---|
| 666 | y1 = a.lineY1;
|
|---|
| 667 |
|
|---|
| 668 | a.angle = a.x, delete a.x;
|
|---|
| 669 | a.startAngle = a.x0, delete a.x0;
|
|---|
| 670 | a.endAngle = a.x1, delete a.x1;
|
|---|
| 671 | a.radius = a.y, delete a.y;
|
|---|
| 672 | a.innerRadius = a.y0, delete a.y0;
|
|---|
| 673 | a.outerRadius = a.y1, delete a.y1;
|
|---|
| 674 | a.lineStartAngle = function() { return lineRadial(x0()); }, delete a.lineX0;
|
|---|
| 675 | a.lineEndAngle = function() { return lineRadial(x1()); }, delete a.lineX1;
|
|---|
| 676 | a.lineInnerRadius = function() { return lineRadial(y0()); }, delete a.lineY0;
|
|---|
| 677 | a.lineOuterRadius = function() { return lineRadial(y1()); }, delete a.lineY1;
|
|---|
| 678 |
|
|---|
| 679 | a.curve = function(_) {
|
|---|
| 680 | return arguments.length ? c(curveRadial(_)) : c()._curve;
|
|---|
| 681 | };
|
|---|
| 682 |
|
|---|
| 683 | return a;
|
|---|
| 684 | }
|
|---|
| 685 |
|
|---|
| 686 | function pointRadial(x, y) {
|
|---|
| 687 | return [(y = +y) * Math.cos(x -= Math.PI / 2), y * Math.sin(x)];
|
|---|
| 688 | }
|
|---|
| 689 |
|
|---|
| 690 | class Bump {
|
|---|
| 691 | constructor(context, x) {
|
|---|
| 692 | this._context = context;
|
|---|
| 693 | this._x = x;
|
|---|
| 694 | }
|
|---|
| 695 | areaStart() {
|
|---|
| 696 | this._line = 0;
|
|---|
| 697 | }
|
|---|
| 698 | areaEnd() {
|
|---|
| 699 | this._line = NaN;
|
|---|
| 700 | }
|
|---|
| 701 | lineStart() {
|
|---|
| 702 | this._point = 0;
|
|---|
| 703 | }
|
|---|
| 704 | lineEnd() {
|
|---|
| 705 | if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
|
|---|
| 706 | this._line = 1 - this._line;
|
|---|
| 707 | }
|
|---|
| 708 | point(x, y) {
|
|---|
| 709 | x = +x, y = +y;
|
|---|
| 710 | switch (this._point) {
|
|---|
| 711 | case 0: {
|
|---|
| 712 | this._point = 1;
|
|---|
| 713 | if (this._line) this._context.lineTo(x, y);
|
|---|
| 714 | else this._context.moveTo(x, y);
|
|---|
| 715 | break;
|
|---|
| 716 | }
|
|---|
| 717 | case 1: this._point = 2; // falls through
|
|---|
| 718 | default: {
|
|---|
| 719 | if (this._x) this._context.bezierCurveTo(this._x0 = (this._x0 + x) / 2, this._y0, this._x0, y, x, y);
|
|---|
| 720 | else this._context.bezierCurveTo(this._x0, this._y0 = (this._y0 + y) / 2, x, this._y0, x, y);
|
|---|
| 721 | break;
|
|---|
| 722 | }
|
|---|
| 723 | }
|
|---|
| 724 | this._x0 = x, this._y0 = y;
|
|---|
| 725 | }
|
|---|
| 726 | }
|
|---|
| 727 |
|
|---|
| 728 | class BumpRadial {
|
|---|
| 729 | constructor(context) {
|
|---|
| 730 | this._context = context;
|
|---|
| 731 | }
|
|---|
| 732 | lineStart() {
|
|---|
| 733 | this._point = 0;
|
|---|
| 734 | }
|
|---|
| 735 | lineEnd() {}
|
|---|
| 736 | point(x, y) {
|
|---|
| 737 | x = +x, y = +y;
|
|---|
| 738 | if (this._point === 0) {
|
|---|
| 739 | this._point = 1;
|
|---|
| 740 | } else {
|
|---|
| 741 | const p0 = pointRadial(this._x0, this._y0);
|
|---|
| 742 | const p1 = pointRadial(this._x0, this._y0 = (this._y0 + y) / 2);
|
|---|
| 743 | const p2 = pointRadial(x, this._y0);
|
|---|
| 744 | const p3 = pointRadial(x, y);
|
|---|
| 745 | this._context.moveTo(...p0);
|
|---|
| 746 | this._context.bezierCurveTo(...p1, ...p2, ...p3);
|
|---|
| 747 | }
|
|---|
| 748 | this._x0 = x, this._y0 = y;
|
|---|
| 749 | }
|
|---|
| 750 | }
|
|---|
| 751 |
|
|---|
| 752 | function bumpX(context) {
|
|---|
| 753 | return new Bump(context, true);
|
|---|
| 754 | }
|
|---|
| 755 |
|
|---|
| 756 | function bumpY(context) {
|
|---|
| 757 | return new Bump(context, false);
|
|---|
| 758 | }
|
|---|
| 759 |
|
|---|
| 760 | function bumpRadial(context) {
|
|---|
| 761 | return new BumpRadial(context);
|
|---|
| 762 | }
|
|---|
| 763 |
|
|---|
| 764 | function linkSource(d) {
|
|---|
| 765 | return d.source;
|
|---|
| 766 | }
|
|---|
| 767 |
|
|---|
| 768 | function linkTarget(d) {
|
|---|
| 769 | return d.target;
|
|---|
| 770 | }
|
|---|
| 771 |
|
|---|
| 772 | function link(curve) {
|
|---|
| 773 | let source = linkSource,
|
|---|
| 774 | target = linkTarget,
|
|---|
| 775 | x$1 = x,
|
|---|
| 776 | y$1 = y,
|
|---|
| 777 | context = null,
|
|---|
| 778 | output = null,
|
|---|
| 779 | path = withPath(link);
|
|---|
| 780 |
|
|---|
| 781 | function link() {
|
|---|
| 782 | let buffer;
|
|---|
| 783 | const argv = slice.call(arguments);
|
|---|
| 784 | const s = source.apply(this, argv);
|
|---|
| 785 | const t = target.apply(this, argv);
|
|---|
| 786 | if (context == null) output = curve(buffer = path());
|
|---|
| 787 | output.lineStart();
|
|---|
| 788 | argv[0] = s, output.point(+x$1.apply(this, argv), +y$1.apply(this, argv));
|
|---|
| 789 | argv[0] = t, output.point(+x$1.apply(this, argv), +y$1.apply(this, argv));
|
|---|
| 790 | output.lineEnd();
|
|---|
| 791 | if (buffer) return output = null, buffer + "" || null;
|
|---|
| 792 | }
|
|---|
| 793 |
|
|---|
| 794 | link.source = function(_) {
|
|---|
| 795 | return arguments.length ? (source = _, link) : source;
|
|---|
| 796 | };
|
|---|
| 797 |
|
|---|
| 798 | link.target = function(_) {
|
|---|
| 799 | return arguments.length ? (target = _, link) : target;
|
|---|
| 800 | };
|
|---|
| 801 |
|
|---|
| 802 | link.x = function(_) {
|
|---|
| 803 | return arguments.length ? (x$1 = typeof _ === "function" ? _ : constant(+_), link) : x$1;
|
|---|
| 804 | };
|
|---|
| 805 |
|
|---|
| 806 | link.y = function(_) {
|
|---|
| 807 | return arguments.length ? (y$1 = typeof _ === "function" ? _ : constant(+_), link) : y$1;
|
|---|
| 808 | };
|
|---|
| 809 |
|
|---|
| 810 | link.context = function(_) {
|
|---|
| 811 | return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), link) : context;
|
|---|
| 812 | };
|
|---|
| 813 |
|
|---|
| 814 | return link;
|
|---|
| 815 | }
|
|---|
| 816 |
|
|---|
| 817 | function linkHorizontal() {
|
|---|
| 818 | return link(bumpX);
|
|---|
| 819 | }
|
|---|
| 820 |
|
|---|
| 821 | function linkVertical() {
|
|---|
| 822 | return link(bumpY);
|
|---|
| 823 | }
|
|---|
| 824 |
|
|---|
| 825 | function linkRadial() {
|
|---|
| 826 | const l = link(bumpRadial);
|
|---|
| 827 | l.angle = l.x, delete l.x;
|
|---|
| 828 | l.radius = l.y, delete l.y;
|
|---|
| 829 | return l;
|
|---|
| 830 | }
|
|---|
| 831 |
|
|---|
| 832 | const sqrt3$2 = sqrt(3);
|
|---|
| 833 |
|
|---|
| 834 | var asterisk = {
|
|---|
| 835 | draw(context, size) {
|
|---|
| 836 | const r = sqrt(size + min(size / 28, 0.75)) * 0.59436;
|
|---|
| 837 | const t = r / 2;
|
|---|
| 838 | const u = t * sqrt3$2;
|
|---|
| 839 | context.moveTo(0, r);
|
|---|
| 840 | context.lineTo(0, -r);
|
|---|
| 841 | context.moveTo(-u, -t);
|
|---|
| 842 | context.lineTo(u, t);
|
|---|
| 843 | context.moveTo(-u, t);
|
|---|
| 844 | context.lineTo(u, -t);
|
|---|
| 845 | }
|
|---|
| 846 | };
|
|---|
| 847 |
|
|---|
| 848 | var circle = {
|
|---|
| 849 | draw(context, size) {
|
|---|
| 850 | const r = sqrt(size / pi);
|
|---|
| 851 | context.moveTo(r, 0);
|
|---|
| 852 | context.arc(0, 0, r, 0, tau);
|
|---|
| 853 | }
|
|---|
| 854 | };
|
|---|
| 855 |
|
|---|
| 856 | var cross = {
|
|---|
| 857 | draw(context, size) {
|
|---|
| 858 | const r = sqrt(size / 5) / 2;
|
|---|
| 859 | context.moveTo(-3 * r, -r);
|
|---|
| 860 | context.lineTo(-r, -r);
|
|---|
| 861 | context.lineTo(-r, -3 * r);
|
|---|
| 862 | context.lineTo(r, -3 * r);
|
|---|
| 863 | context.lineTo(r, -r);
|
|---|
| 864 | context.lineTo(3 * r, -r);
|
|---|
| 865 | context.lineTo(3 * r, r);
|
|---|
| 866 | context.lineTo(r, r);
|
|---|
| 867 | context.lineTo(r, 3 * r);
|
|---|
| 868 | context.lineTo(-r, 3 * r);
|
|---|
| 869 | context.lineTo(-r, r);
|
|---|
| 870 | context.lineTo(-3 * r, r);
|
|---|
| 871 | context.closePath();
|
|---|
| 872 | }
|
|---|
| 873 | };
|
|---|
| 874 |
|
|---|
| 875 | const tan30 = sqrt(1 / 3);
|
|---|
| 876 | const tan30_2 = tan30 * 2;
|
|---|
| 877 |
|
|---|
| 878 | var diamond = {
|
|---|
| 879 | draw(context, size) {
|
|---|
| 880 | const y = sqrt(size / tan30_2);
|
|---|
| 881 | const x = y * tan30;
|
|---|
| 882 | context.moveTo(0, -y);
|
|---|
| 883 | context.lineTo(x, 0);
|
|---|
| 884 | context.lineTo(0, y);
|
|---|
| 885 | context.lineTo(-x, 0);
|
|---|
| 886 | context.closePath();
|
|---|
| 887 | }
|
|---|
| 888 | };
|
|---|
| 889 |
|
|---|
| 890 | var diamond2 = {
|
|---|
| 891 | draw(context, size) {
|
|---|
| 892 | const r = sqrt(size) * 0.62625;
|
|---|
| 893 | context.moveTo(0, -r);
|
|---|
| 894 | context.lineTo(r, 0);
|
|---|
| 895 | context.lineTo(0, r);
|
|---|
| 896 | context.lineTo(-r, 0);
|
|---|
| 897 | context.closePath();
|
|---|
| 898 | }
|
|---|
| 899 | };
|
|---|
| 900 |
|
|---|
| 901 | var plus = {
|
|---|
| 902 | draw(context, size) {
|
|---|
| 903 | const r = sqrt(size - min(size / 7, 2)) * 0.87559;
|
|---|
| 904 | context.moveTo(-r, 0);
|
|---|
| 905 | context.lineTo(r, 0);
|
|---|
| 906 | context.moveTo(0, r);
|
|---|
| 907 | context.lineTo(0, -r);
|
|---|
| 908 | }
|
|---|
| 909 | };
|
|---|
| 910 |
|
|---|
| 911 | var square = {
|
|---|
| 912 | draw(context, size) {
|
|---|
| 913 | const w = sqrt(size);
|
|---|
| 914 | const x = -w / 2;
|
|---|
| 915 | context.rect(x, x, w, w);
|
|---|
| 916 | }
|
|---|
| 917 | };
|
|---|
| 918 |
|
|---|
| 919 | var square2 = {
|
|---|
| 920 | draw(context, size) {
|
|---|
| 921 | const r = sqrt(size) * 0.4431;
|
|---|
| 922 | context.moveTo(r, r);
|
|---|
| 923 | context.lineTo(r, -r);
|
|---|
| 924 | context.lineTo(-r, -r);
|
|---|
| 925 | context.lineTo(-r, r);
|
|---|
| 926 | context.closePath();
|
|---|
| 927 | }
|
|---|
| 928 | };
|
|---|
| 929 |
|
|---|
| 930 | const ka = 0.89081309152928522810;
|
|---|
| 931 | const kr = sin(pi / 10) / sin(7 * pi / 10);
|
|---|
| 932 | const kx = sin(tau / 10) * kr;
|
|---|
| 933 | const ky = -cos(tau / 10) * kr;
|
|---|
| 934 |
|
|---|
| 935 | var star = {
|
|---|
| 936 | draw(context, size) {
|
|---|
| 937 | const r = sqrt(size * ka);
|
|---|
| 938 | const x = kx * r;
|
|---|
| 939 | const y = ky * r;
|
|---|
| 940 | context.moveTo(0, -r);
|
|---|
| 941 | context.lineTo(x, y);
|
|---|
| 942 | for (let i = 1; i < 5; ++i) {
|
|---|
| 943 | const a = tau * i / 5;
|
|---|
| 944 | const c = cos(a);
|
|---|
| 945 | const s = sin(a);
|
|---|
| 946 | context.lineTo(s * r, -c * r);
|
|---|
| 947 | context.lineTo(c * x - s * y, s * x + c * y);
|
|---|
| 948 | }
|
|---|
| 949 | context.closePath();
|
|---|
| 950 | }
|
|---|
| 951 | };
|
|---|
| 952 |
|
|---|
| 953 | const sqrt3$1 = sqrt(3);
|
|---|
| 954 |
|
|---|
| 955 | var triangle = {
|
|---|
| 956 | draw(context, size) {
|
|---|
| 957 | const y = -sqrt(size / (sqrt3$1 * 3));
|
|---|
| 958 | context.moveTo(0, y * 2);
|
|---|
| 959 | context.lineTo(-sqrt3$1 * y, -y);
|
|---|
| 960 | context.lineTo(sqrt3$1 * y, -y);
|
|---|
| 961 | context.closePath();
|
|---|
| 962 | }
|
|---|
| 963 | };
|
|---|
| 964 |
|
|---|
| 965 | const sqrt3 = sqrt(3);
|
|---|
| 966 |
|
|---|
| 967 | var triangle2 = {
|
|---|
| 968 | draw(context, size) {
|
|---|
| 969 | const s = sqrt(size) * 0.6824;
|
|---|
| 970 | const t = s / 2;
|
|---|
| 971 | const u = (s * sqrt3) / 2; // cos(Math.PI / 6)
|
|---|
| 972 | context.moveTo(0, -s);
|
|---|
| 973 | context.lineTo(u, t);
|
|---|
| 974 | context.lineTo(-u, t);
|
|---|
| 975 | context.closePath();
|
|---|
| 976 | }
|
|---|
| 977 | };
|
|---|
| 978 |
|
|---|
| 979 | const c = -0.5;
|
|---|
| 980 | const s = sqrt(3) / 2;
|
|---|
| 981 | const k = 1 / sqrt(12);
|
|---|
| 982 | const a = (k / 2 + 1) * 3;
|
|---|
| 983 |
|
|---|
| 984 | var wye = {
|
|---|
| 985 | draw(context, size) {
|
|---|
| 986 | const r = sqrt(size / a);
|
|---|
| 987 | const x0 = r / 2, y0 = r * k;
|
|---|
| 988 | const x1 = x0, y1 = r * k + r;
|
|---|
| 989 | const x2 = -x1, y2 = y1;
|
|---|
| 990 | context.moveTo(x0, y0);
|
|---|
| 991 | context.lineTo(x1, y1);
|
|---|
| 992 | context.lineTo(x2, y2);
|
|---|
| 993 | context.lineTo(c * x0 - s * y0, s * x0 + c * y0);
|
|---|
| 994 | context.lineTo(c * x1 - s * y1, s * x1 + c * y1);
|
|---|
| 995 | context.lineTo(c * x2 - s * y2, s * x2 + c * y2);
|
|---|
| 996 | context.lineTo(c * x0 + s * y0, c * y0 - s * x0);
|
|---|
| 997 | context.lineTo(c * x1 + s * y1, c * y1 - s * x1);
|
|---|
| 998 | context.lineTo(c * x2 + s * y2, c * y2 - s * x2);
|
|---|
| 999 | context.closePath();
|
|---|
| 1000 | }
|
|---|
| 1001 | };
|
|---|
| 1002 |
|
|---|
| 1003 | var times = {
|
|---|
| 1004 | draw(context, size) {
|
|---|
| 1005 | const r = sqrt(size - min(size / 6, 1.7)) * 0.6189;
|
|---|
| 1006 | context.moveTo(-r, -r);
|
|---|
| 1007 | context.lineTo(r, r);
|
|---|
| 1008 | context.moveTo(-r, r);
|
|---|
| 1009 | context.lineTo(r, -r);
|
|---|
| 1010 | }
|
|---|
| 1011 | };
|
|---|
| 1012 |
|
|---|
| 1013 | // These symbols are designed to be filled.
|
|---|
| 1014 | const symbolsFill = [
|
|---|
| 1015 | circle,
|
|---|
| 1016 | cross,
|
|---|
| 1017 | diamond,
|
|---|
| 1018 | square,
|
|---|
| 1019 | star,
|
|---|
| 1020 | triangle,
|
|---|
| 1021 | wye
|
|---|
| 1022 | ];
|
|---|
| 1023 |
|
|---|
| 1024 | // These symbols are designed to be stroked (with a width of 1.5px and round caps).
|
|---|
| 1025 | const symbolsStroke = [
|
|---|
| 1026 | circle,
|
|---|
| 1027 | plus,
|
|---|
| 1028 | times,
|
|---|
| 1029 | triangle2,
|
|---|
| 1030 | asterisk,
|
|---|
| 1031 | square2,
|
|---|
| 1032 | diamond2
|
|---|
| 1033 | ];
|
|---|
| 1034 |
|
|---|
| 1035 | function Symbol(type, size) {
|
|---|
| 1036 | let context = null,
|
|---|
| 1037 | path = withPath(symbol);
|
|---|
| 1038 |
|
|---|
| 1039 | type = typeof type === "function" ? type : constant(type || circle);
|
|---|
| 1040 | size = typeof size === "function" ? size : constant(size === undefined ? 64 : +size);
|
|---|
| 1041 |
|
|---|
| 1042 | function symbol() {
|
|---|
| 1043 | let buffer;
|
|---|
| 1044 | if (!context) context = buffer = path();
|
|---|
| 1045 | type.apply(this, arguments).draw(context, +size.apply(this, arguments));
|
|---|
| 1046 | if (buffer) return context = null, buffer + "" || null;
|
|---|
| 1047 | }
|
|---|
| 1048 |
|
|---|
| 1049 | symbol.type = function(_) {
|
|---|
| 1050 | return arguments.length ? (type = typeof _ === "function" ? _ : constant(_), symbol) : type;
|
|---|
| 1051 | };
|
|---|
| 1052 |
|
|---|
| 1053 | symbol.size = function(_) {
|
|---|
| 1054 | return arguments.length ? (size = typeof _ === "function" ? _ : constant(+_), symbol) : size;
|
|---|
| 1055 | };
|
|---|
| 1056 |
|
|---|
| 1057 | symbol.context = function(_) {
|
|---|
| 1058 | return arguments.length ? (context = _ == null ? null : _, symbol) : context;
|
|---|
| 1059 | };
|
|---|
| 1060 |
|
|---|
| 1061 | return symbol;
|
|---|
| 1062 | }
|
|---|
| 1063 |
|
|---|
| 1064 | function noop() {}
|
|---|
| 1065 |
|
|---|
| 1066 | function point$3(that, x, y) {
|
|---|
| 1067 | that._context.bezierCurveTo(
|
|---|
| 1068 | (2 * that._x0 + that._x1) / 3,
|
|---|
| 1069 | (2 * that._y0 + that._y1) / 3,
|
|---|
| 1070 | (that._x0 + 2 * that._x1) / 3,
|
|---|
| 1071 | (that._y0 + 2 * that._y1) / 3,
|
|---|
| 1072 | (that._x0 + 4 * that._x1 + x) / 6,
|
|---|
| 1073 | (that._y0 + 4 * that._y1 + y) / 6
|
|---|
| 1074 | );
|
|---|
| 1075 | }
|
|---|
| 1076 |
|
|---|
| 1077 | function Basis(context) {
|
|---|
| 1078 | this._context = context;
|
|---|
| 1079 | }
|
|---|
| 1080 |
|
|---|
| 1081 | Basis.prototype = {
|
|---|
| 1082 | areaStart: function() {
|
|---|
| 1083 | this._line = 0;
|
|---|
| 1084 | },
|
|---|
| 1085 | areaEnd: function() {
|
|---|
| 1086 | this._line = NaN;
|
|---|
| 1087 | },
|
|---|
| 1088 | lineStart: function() {
|
|---|
| 1089 | this._x0 = this._x1 =
|
|---|
| 1090 | this._y0 = this._y1 = NaN;
|
|---|
| 1091 | this._point = 0;
|
|---|
| 1092 | },
|
|---|
| 1093 | lineEnd: function() {
|
|---|
| 1094 | switch (this._point) {
|
|---|
| 1095 | case 3: point$3(this, this._x1, this._y1); // falls through
|
|---|
| 1096 | case 2: this._context.lineTo(this._x1, this._y1); break;
|
|---|
| 1097 | }
|
|---|
| 1098 | if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
|
|---|
| 1099 | this._line = 1 - this._line;
|
|---|
| 1100 | },
|
|---|
| 1101 | point: function(x, y) {
|
|---|
| 1102 | x = +x, y = +y;
|
|---|
| 1103 | switch (this._point) {
|
|---|
| 1104 | case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
|
|---|
| 1105 | case 1: this._point = 2; break;
|
|---|
| 1106 | case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // falls through
|
|---|
| 1107 | default: point$3(this, x, y); break;
|
|---|
| 1108 | }
|
|---|
| 1109 | this._x0 = this._x1, this._x1 = x;
|
|---|
| 1110 | this._y0 = this._y1, this._y1 = y;
|
|---|
| 1111 | }
|
|---|
| 1112 | };
|
|---|
| 1113 |
|
|---|
| 1114 | function basis(context) {
|
|---|
| 1115 | return new Basis(context);
|
|---|
| 1116 | }
|
|---|
| 1117 |
|
|---|
| 1118 | function BasisClosed(context) {
|
|---|
| 1119 | this._context = context;
|
|---|
| 1120 | }
|
|---|
| 1121 |
|
|---|
| 1122 | BasisClosed.prototype = {
|
|---|
| 1123 | areaStart: noop,
|
|---|
| 1124 | areaEnd: noop,
|
|---|
| 1125 | lineStart: function() {
|
|---|
| 1126 | this._x0 = this._x1 = this._x2 = this._x3 = this._x4 =
|
|---|
| 1127 | this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;
|
|---|
| 1128 | this._point = 0;
|
|---|
| 1129 | },
|
|---|
| 1130 | lineEnd: function() {
|
|---|
| 1131 | switch (this._point) {
|
|---|
| 1132 | case 1: {
|
|---|
| 1133 | this._context.moveTo(this._x2, this._y2);
|
|---|
| 1134 | this._context.closePath();
|
|---|
| 1135 | break;
|
|---|
| 1136 | }
|
|---|
| 1137 | case 2: {
|
|---|
| 1138 | this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3);
|
|---|
| 1139 | this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3);
|
|---|
| 1140 | this._context.closePath();
|
|---|
| 1141 | break;
|
|---|
| 1142 | }
|
|---|
| 1143 | case 3: {
|
|---|
| 1144 | this.point(this._x2, this._y2);
|
|---|
| 1145 | this.point(this._x3, this._y3);
|
|---|
| 1146 | this.point(this._x4, this._y4);
|
|---|
| 1147 | break;
|
|---|
| 1148 | }
|
|---|
| 1149 | }
|
|---|
| 1150 | },
|
|---|
| 1151 | point: function(x, y) {
|
|---|
| 1152 | x = +x, y = +y;
|
|---|
| 1153 | switch (this._point) {
|
|---|
| 1154 | case 0: this._point = 1; this._x2 = x, this._y2 = y; break;
|
|---|
| 1155 | case 1: this._point = 2; this._x3 = x, this._y3 = y; break;
|
|---|
| 1156 | 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;
|
|---|
| 1157 | default: point$3(this, x, y); break;
|
|---|
| 1158 | }
|
|---|
| 1159 | this._x0 = this._x1, this._x1 = x;
|
|---|
| 1160 | this._y0 = this._y1, this._y1 = y;
|
|---|
| 1161 | }
|
|---|
| 1162 | };
|
|---|
| 1163 |
|
|---|
| 1164 | function basisClosed(context) {
|
|---|
| 1165 | return new BasisClosed(context);
|
|---|
| 1166 | }
|
|---|
| 1167 |
|
|---|
| 1168 | function BasisOpen(context) {
|
|---|
| 1169 | this._context = context;
|
|---|
| 1170 | }
|
|---|
| 1171 |
|
|---|
| 1172 | BasisOpen.prototype = {
|
|---|
| 1173 | areaStart: function() {
|
|---|
| 1174 | this._line = 0;
|
|---|
| 1175 | },
|
|---|
| 1176 | areaEnd: function() {
|
|---|
| 1177 | this._line = NaN;
|
|---|
| 1178 | },
|
|---|
| 1179 | lineStart: function() {
|
|---|
| 1180 | this._x0 = this._x1 =
|
|---|
| 1181 | this._y0 = this._y1 = NaN;
|
|---|
| 1182 | this._point = 0;
|
|---|
| 1183 | },
|
|---|
| 1184 | lineEnd: function() {
|
|---|
| 1185 | if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
|
|---|
| 1186 | this._line = 1 - this._line;
|
|---|
| 1187 | },
|
|---|
| 1188 | point: function(x, y) {
|
|---|
| 1189 | x = +x, y = +y;
|
|---|
| 1190 | switch (this._point) {
|
|---|
| 1191 | case 0: this._point = 1; break;
|
|---|
| 1192 | case 1: this._point = 2; break;
|
|---|
| 1193 | 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;
|
|---|
| 1194 | case 3: this._point = 4; // falls through
|
|---|
| 1195 | default: point$3(this, x, y); break;
|
|---|
| 1196 | }
|
|---|
| 1197 | this._x0 = this._x1, this._x1 = x;
|
|---|
| 1198 | this._y0 = this._y1, this._y1 = y;
|
|---|
| 1199 | }
|
|---|
| 1200 | };
|
|---|
| 1201 |
|
|---|
| 1202 | function basisOpen(context) {
|
|---|
| 1203 | return new BasisOpen(context);
|
|---|
| 1204 | }
|
|---|
| 1205 |
|
|---|
| 1206 | function Bundle(context, beta) {
|
|---|
| 1207 | this._basis = new Basis(context);
|
|---|
| 1208 | this._beta = beta;
|
|---|
| 1209 | }
|
|---|
| 1210 |
|
|---|
| 1211 | Bundle.prototype = {
|
|---|
| 1212 | lineStart: function() {
|
|---|
| 1213 | this._x = [];
|
|---|
| 1214 | this._y = [];
|
|---|
| 1215 | this._basis.lineStart();
|
|---|
| 1216 | },
|
|---|
| 1217 | lineEnd: function() {
|
|---|
| 1218 | var x = this._x,
|
|---|
| 1219 | y = this._y,
|
|---|
| 1220 | j = x.length - 1;
|
|---|
| 1221 |
|
|---|
| 1222 | if (j > 0) {
|
|---|
| 1223 | var x0 = x[0],
|
|---|
| 1224 | y0 = y[0],
|
|---|
| 1225 | dx = x[j] - x0,
|
|---|
| 1226 | dy = y[j] - y0,
|
|---|
| 1227 | i = -1,
|
|---|
| 1228 | t;
|
|---|
| 1229 |
|
|---|
| 1230 | while (++i <= j) {
|
|---|
| 1231 | t = i / j;
|
|---|
| 1232 | this._basis.point(
|
|---|
| 1233 | this._beta * x[i] + (1 - this._beta) * (x0 + t * dx),
|
|---|
| 1234 | this._beta * y[i] + (1 - this._beta) * (y0 + t * dy)
|
|---|
| 1235 | );
|
|---|
| 1236 | }
|
|---|
| 1237 | }
|
|---|
| 1238 |
|
|---|
| 1239 | this._x = this._y = null;
|
|---|
| 1240 | this._basis.lineEnd();
|
|---|
| 1241 | },
|
|---|
| 1242 | point: function(x, y) {
|
|---|
| 1243 | this._x.push(+x);
|
|---|
| 1244 | this._y.push(+y);
|
|---|
| 1245 | }
|
|---|
| 1246 | };
|
|---|
| 1247 |
|
|---|
| 1248 | var bundle = (function custom(beta) {
|
|---|
| 1249 |
|
|---|
| 1250 | function bundle(context) {
|
|---|
| 1251 | return beta === 1 ? new Basis(context) : new Bundle(context, beta);
|
|---|
| 1252 | }
|
|---|
| 1253 |
|
|---|
| 1254 | bundle.beta = function(beta) {
|
|---|
| 1255 | return custom(+beta);
|
|---|
| 1256 | };
|
|---|
| 1257 |
|
|---|
| 1258 | return bundle;
|
|---|
| 1259 | })(0.85);
|
|---|
| 1260 |
|
|---|
| 1261 | function point$2(that, x, y) {
|
|---|
| 1262 | that._context.bezierCurveTo(
|
|---|
| 1263 | that._x1 + that._k * (that._x2 - that._x0),
|
|---|
| 1264 | that._y1 + that._k * (that._y2 - that._y0),
|
|---|
| 1265 | that._x2 + that._k * (that._x1 - x),
|
|---|
| 1266 | that._y2 + that._k * (that._y1 - y),
|
|---|
| 1267 | that._x2,
|
|---|
| 1268 | that._y2
|
|---|
| 1269 | );
|
|---|
| 1270 | }
|
|---|
| 1271 |
|
|---|
| 1272 | function Cardinal(context, tension) {
|
|---|
| 1273 | this._context = context;
|
|---|
| 1274 | this._k = (1 - tension) / 6;
|
|---|
| 1275 | }
|
|---|
| 1276 |
|
|---|
| 1277 | Cardinal.prototype = {
|
|---|
| 1278 | areaStart: function() {
|
|---|
| 1279 | this._line = 0;
|
|---|
| 1280 | },
|
|---|
| 1281 | areaEnd: function() {
|
|---|
| 1282 | this._line = NaN;
|
|---|
| 1283 | },
|
|---|
| 1284 | lineStart: function() {
|
|---|
| 1285 | this._x0 = this._x1 = this._x2 =
|
|---|
| 1286 | this._y0 = this._y1 = this._y2 = NaN;
|
|---|
| 1287 | this._point = 0;
|
|---|
| 1288 | },
|
|---|
| 1289 | lineEnd: function() {
|
|---|
| 1290 | switch (this._point) {
|
|---|
| 1291 | case 2: this._context.lineTo(this._x2, this._y2); break;
|
|---|
| 1292 | case 3: point$2(this, this._x1, this._y1); break;
|
|---|
| 1293 | }
|
|---|
| 1294 | if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
|
|---|
| 1295 | this._line = 1 - this._line;
|
|---|
| 1296 | },
|
|---|
| 1297 | point: function(x, y) {
|
|---|
| 1298 | x = +x, y = +y;
|
|---|
| 1299 | switch (this._point) {
|
|---|
| 1300 | case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
|
|---|
| 1301 | case 1: this._point = 2; this._x1 = x, this._y1 = y; break;
|
|---|
| 1302 | case 2: this._point = 3; // falls through
|
|---|
| 1303 | default: point$2(this, x, y); break;
|
|---|
| 1304 | }
|
|---|
| 1305 | this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
|
|---|
| 1306 | this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
|
|---|
| 1307 | }
|
|---|
| 1308 | };
|
|---|
| 1309 |
|
|---|
| 1310 | var cardinal = (function custom(tension) {
|
|---|
| 1311 |
|
|---|
| 1312 | function cardinal(context) {
|
|---|
| 1313 | return new Cardinal(context, tension);
|
|---|
| 1314 | }
|
|---|
| 1315 |
|
|---|
| 1316 | cardinal.tension = function(tension) {
|
|---|
| 1317 | return custom(+tension);
|
|---|
| 1318 | };
|
|---|
| 1319 |
|
|---|
| 1320 | return cardinal;
|
|---|
| 1321 | })(0);
|
|---|
| 1322 |
|
|---|
| 1323 | function CardinalClosed(context, tension) {
|
|---|
| 1324 | this._context = context;
|
|---|
| 1325 | this._k = (1 - tension) / 6;
|
|---|
| 1326 | }
|
|---|
| 1327 |
|
|---|
| 1328 | CardinalClosed.prototype = {
|
|---|
| 1329 | areaStart: noop,
|
|---|
| 1330 | areaEnd: noop,
|
|---|
| 1331 | lineStart: function() {
|
|---|
| 1332 | this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
|
|---|
| 1333 | this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
|
|---|
| 1334 | this._point = 0;
|
|---|
| 1335 | },
|
|---|
| 1336 | lineEnd: function() {
|
|---|
| 1337 | switch (this._point) {
|
|---|
| 1338 | case 1: {
|
|---|
| 1339 | this._context.moveTo(this._x3, this._y3);
|
|---|
| 1340 | this._context.closePath();
|
|---|
| 1341 | break;
|
|---|
| 1342 | }
|
|---|
| 1343 | case 2: {
|
|---|
| 1344 | this._context.lineTo(this._x3, this._y3);
|
|---|
| 1345 | this._context.closePath();
|
|---|
| 1346 | break;
|
|---|
| 1347 | }
|
|---|
| 1348 | case 3: {
|
|---|
| 1349 | this.point(this._x3, this._y3);
|
|---|
| 1350 | this.point(this._x4, this._y4);
|
|---|
| 1351 | this.point(this._x5, this._y5);
|
|---|
| 1352 | break;
|
|---|
| 1353 | }
|
|---|
| 1354 | }
|
|---|
| 1355 | },
|
|---|
| 1356 | point: function(x, y) {
|
|---|
| 1357 | x = +x, y = +y;
|
|---|
| 1358 | switch (this._point) {
|
|---|
| 1359 | case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
|
|---|
| 1360 | case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
|
|---|
| 1361 | case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
|
|---|
| 1362 | default: point$2(this, x, y); break;
|
|---|
| 1363 | }
|
|---|
| 1364 | this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
|
|---|
| 1365 | this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
|
|---|
| 1366 | }
|
|---|
| 1367 | };
|
|---|
| 1368 |
|
|---|
| 1369 | var cardinalClosed = (function custom(tension) {
|
|---|
| 1370 |
|
|---|
| 1371 | function cardinal(context) {
|
|---|
| 1372 | return new CardinalClosed(context, tension);
|
|---|
| 1373 | }
|
|---|
| 1374 |
|
|---|
| 1375 | cardinal.tension = function(tension) {
|
|---|
| 1376 | return custom(+tension);
|
|---|
| 1377 | };
|
|---|
| 1378 |
|
|---|
| 1379 | return cardinal;
|
|---|
| 1380 | })(0);
|
|---|
| 1381 |
|
|---|
| 1382 | function CardinalOpen(context, tension) {
|
|---|
| 1383 | this._context = context;
|
|---|
| 1384 | this._k = (1 - tension) / 6;
|
|---|
| 1385 | }
|
|---|
| 1386 |
|
|---|
| 1387 | CardinalOpen.prototype = {
|
|---|
| 1388 | areaStart: function() {
|
|---|
| 1389 | this._line = 0;
|
|---|
| 1390 | },
|
|---|
| 1391 | areaEnd: function() {
|
|---|
| 1392 | this._line = NaN;
|
|---|
| 1393 | },
|
|---|
| 1394 | lineStart: function() {
|
|---|
| 1395 | this._x0 = this._x1 = this._x2 =
|
|---|
| 1396 | this._y0 = this._y1 = this._y2 = NaN;
|
|---|
| 1397 | this._point = 0;
|
|---|
| 1398 | },
|
|---|
| 1399 | lineEnd: function() {
|
|---|
| 1400 | if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
|
|---|
| 1401 | this._line = 1 - this._line;
|
|---|
| 1402 | },
|
|---|
| 1403 | point: function(x, y) {
|
|---|
| 1404 | x = +x, y = +y;
|
|---|
| 1405 | switch (this._point) {
|
|---|
| 1406 | case 0: this._point = 1; break;
|
|---|
| 1407 | case 1: this._point = 2; break;
|
|---|
| 1408 | case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
|
|---|
| 1409 | case 3: this._point = 4; // falls through
|
|---|
| 1410 | default: point$2(this, x, y); break;
|
|---|
| 1411 | }
|
|---|
| 1412 | this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
|
|---|
| 1413 | this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
|
|---|
| 1414 | }
|
|---|
| 1415 | };
|
|---|
| 1416 |
|
|---|
| 1417 | var cardinalOpen = (function custom(tension) {
|
|---|
| 1418 |
|
|---|
| 1419 | function cardinal(context) {
|
|---|
| 1420 | return new CardinalOpen(context, tension);
|
|---|
| 1421 | }
|
|---|
| 1422 |
|
|---|
| 1423 | cardinal.tension = function(tension) {
|
|---|
| 1424 | return custom(+tension);
|
|---|
| 1425 | };
|
|---|
| 1426 |
|
|---|
| 1427 | return cardinal;
|
|---|
| 1428 | })(0);
|
|---|
| 1429 |
|
|---|
| 1430 | function point$1(that, x, y) {
|
|---|
| 1431 | var x1 = that._x1,
|
|---|
| 1432 | y1 = that._y1,
|
|---|
| 1433 | x2 = that._x2,
|
|---|
| 1434 | y2 = that._y2;
|
|---|
| 1435 |
|
|---|
| 1436 | if (that._l01_a > epsilon) {
|
|---|
| 1437 | var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a,
|
|---|
| 1438 | n = 3 * that._l01_a * (that._l01_a + that._l12_a);
|
|---|
| 1439 | x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n;
|
|---|
| 1440 | y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n;
|
|---|
| 1441 | }
|
|---|
| 1442 |
|
|---|
| 1443 | if (that._l23_a > epsilon) {
|
|---|
| 1444 | var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a,
|
|---|
| 1445 | m = 3 * that._l23_a * (that._l23_a + that._l12_a);
|
|---|
| 1446 | x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m;
|
|---|
| 1447 | y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m;
|
|---|
| 1448 | }
|
|---|
| 1449 |
|
|---|
| 1450 | that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);
|
|---|
| 1451 | }
|
|---|
| 1452 |
|
|---|
| 1453 | function CatmullRom(context, alpha) {
|
|---|
| 1454 | this._context = context;
|
|---|
| 1455 | this._alpha = alpha;
|
|---|
| 1456 | }
|
|---|
| 1457 |
|
|---|
| 1458 | CatmullRom.prototype = {
|
|---|
| 1459 | areaStart: function() {
|
|---|
| 1460 | this._line = 0;
|
|---|
| 1461 | },
|
|---|
| 1462 | areaEnd: function() {
|
|---|
| 1463 | this._line = NaN;
|
|---|
| 1464 | },
|
|---|
| 1465 | lineStart: function() {
|
|---|
| 1466 | this._x0 = this._x1 = this._x2 =
|
|---|
| 1467 | this._y0 = this._y1 = this._y2 = NaN;
|
|---|
| 1468 | this._l01_a = this._l12_a = this._l23_a =
|
|---|
| 1469 | this._l01_2a = this._l12_2a = this._l23_2a =
|
|---|
| 1470 | this._point = 0;
|
|---|
| 1471 | },
|
|---|
| 1472 | lineEnd: function() {
|
|---|
| 1473 | switch (this._point) {
|
|---|
| 1474 | case 2: this._context.lineTo(this._x2, this._y2); break;
|
|---|
| 1475 | case 3: this.point(this._x2, this._y2); break;
|
|---|
| 1476 | }
|
|---|
| 1477 | if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
|
|---|
| 1478 | this._line = 1 - this._line;
|
|---|
| 1479 | },
|
|---|
| 1480 | point: function(x, y) {
|
|---|
| 1481 | x = +x, y = +y;
|
|---|
| 1482 |
|
|---|
| 1483 | if (this._point) {
|
|---|
| 1484 | var x23 = this._x2 - x,
|
|---|
| 1485 | y23 = this._y2 - y;
|
|---|
| 1486 | this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
|
|---|
| 1487 | }
|
|---|
| 1488 |
|
|---|
| 1489 | switch (this._point) {
|
|---|
| 1490 | case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
|
|---|
| 1491 | case 1: this._point = 2; break;
|
|---|
| 1492 | case 2: this._point = 3; // falls through
|
|---|
| 1493 | default: point$1(this, x, y); break;
|
|---|
| 1494 | }
|
|---|
| 1495 |
|
|---|
| 1496 | this._l01_a = this._l12_a, this._l12_a = this._l23_a;
|
|---|
| 1497 | this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
|
|---|
| 1498 | this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
|
|---|
| 1499 | this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
|
|---|
| 1500 | }
|
|---|
| 1501 | };
|
|---|
| 1502 |
|
|---|
| 1503 | var catmullRom = (function custom(alpha) {
|
|---|
| 1504 |
|
|---|
| 1505 | function catmullRom(context) {
|
|---|
| 1506 | return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0);
|
|---|
| 1507 | }
|
|---|
| 1508 |
|
|---|
| 1509 | catmullRom.alpha = function(alpha) {
|
|---|
| 1510 | return custom(+alpha);
|
|---|
| 1511 | };
|
|---|
| 1512 |
|
|---|
| 1513 | return catmullRom;
|
|---|
| 1514 | })(0.5);
|
|---|
| 1515 |
|
|---|
| 1516 | function CatmullRomClosed(context, alpha) {
|
|---|
| 1517 | this._context = context;
|
|---|
| 1518 | this._alpha = alpha;
|
|---|
| 1519 | }
|
|---|
| 1520 |
|
|---|
| 1521 | CatmullRomClosed.prototype = {
|
|---|
| 1522 | areaStart: noop,
|
|---|
| 1523 | areaEnd: noop,
|
|---|
| 1524 | lineStart: function() {
|
|---|
| 1525 | this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
|
|---|
| 1526 | this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
|
|---|
| 1527 | this._l01_a = this._l12_a = this._l23_a =
|
|---|
| 1528 | this._l01_2a = this._l12_2a = this._l23_2a =
|
|---|
| 1529 | this._point = 0;
|
|---|
| 1530 | },
|
|---|
| 1531 | lineEnd: function() {
|
|---|
| 1532 | switch (this._point) {
|
|---|
| 1533 | case 1: {
|
|---|
| 1534 | this._context.moveTo(this._x3, this._y3);
|
|---|
| 1535 | this._context.closePath();
|
|---|
| 1536 | break;
|
|---|
| 1537 | }
|
|---|
| 1538 | case 2: {
|
|---|
| 1539 | this._context.lineTo(this._x3, this._y3);
|
|---|
| 1540 | this._context.closePath();
|
|---|
| 1541 | break;
|
|---|
| 1542 | }
|
|---|
| 1543 | case 3: {
|
|---|
| 1544 | this.point(this._x3, this._y3);
|
|---|
| 1545 | this.point(this._x4, this._y4);
|
|---|
| 1546 | this.point(this._x5, this._y5);
|
|---|
| 1547 | break;
|
|---|
| 1548 | }
|
|---|
| 1549 | }
|
|---|
| 1550 | },
|
|---|
| 1551 | point: function(x, y) {
|
|---|
| 1552 | x = +x, y = +y;
|
|---|
| 1553 |
|
|---|
| 1554 | if (this._point) {
|
|---|
| 1555 | var x23 = this._x2 - x,
|
|---|
| 1556 | y23 = this._y2 - y;
|
|---|
| 1557 | this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
|
|---|
| 1558 | }
|
|---|
| 1559 |
|
|---|
| 1560 | switch (this._point) {
|
|---|
| 1561 | case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
|
|---|
| 1562 | case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
|
|---|
| 1563 | case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
|
|---|
| 1564 | default: point$1(this, x, y); break;
|
|---|
| 1565 | }
|
|---|
| 1566 |
|
|---|
| 1567 | this._l01_a = this._l12_a, this._l12_a = this._l23_a;
|
|---|
| 1568 | this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
|
|---|
| 1569 | this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
|
|---|
| 1570 | this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
|
|---|
| 1571 | }
|
|---|
| 1572 | };
|
|---|
| 1573 |
|
|---|
| 1574 | var catmullRomClosed = (function custom(alpha) {
|
|---|
| 1575 |
|
|---|
| 1576 | function catmullRom(context) {
|
|---|
| 1577 | return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0);
|
|---|
| 1578 | }
|
|---|
| 1579 |
|
|---|
| 1580 | catmullRom.alpha = function(alpha) {
|
|---|
| 1581 | return custom(+alpha);
|
|---|
| 1582 | };
|
|---|
| 1583 |
|
|---|
| 1584 | return catmullRom;
|
|---|
| 1585 | })(0.5);
|
|---|
| 1586 |
|
|---|
| 1587 | function CatmullRomOpen(context, alpha) {
|
|---|
| 1588 | this._context = context;
|
|---|
| 1589 | this._alpha = alpha;
|
|---|
| 1590 | }
|
|---|
| 1591 |
|
|---|
| 1592 | CatmullRomOpen.prototype = {
|
|---|
| 1593 | areaStart: function() {
|
|---|
| 1594 | this._line = 0;
|
|---|
| 1595 | },
|
|---|
| 1596 | areaEnd: function() {
|
|---|
| 1597 | this._line = NaN;
|
|---|
| 1598 | },
|
|---|
| 1599 | lineStart: function() {
|
|---|
| 1600 | this._x0 = this._x1 = this._x2 =
|
|---|
| 1601 | this._y0 = this._y1 = this._y2 = NaN;
|
|---|
| 1602 | this._l01_a = this._l12_a = this._l23_a =
|
|---|
| 1603 | this._l01_2a = this._l12_2a = this._l23_2a =
|
|---|
| 1604 | this._point = 0;
|
|---|
| 1605 | },
|
|---|
| 1606 | lineEnd: function() {
|
|---|
| 1607 | if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
|
|---|
| 1608 | this._line = 1 - this._line;
|
|---|
| 1609 | },
|
|---|
| 1610 | point: function(x, y) {
|
|---|
| 1611 | x = +x, y = +y;
|
|---|
| 1612 |
|
|---|
| 1613 | if (this._point) {
|
|---|
| 1614 | var x23 = this._x2 - x,
|
|---|
| 1615 | y23 = this._y2 - y;
|
|---|
| 1616 | this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
|
|---|
| 1617 | }
|
|---|
| 1618 |
|
|---|
| 1619 | switch (this._point) {
|
|---|
| 1620 | case 0: this._point = 1; break;
|
|---|
| 1621 | case 1: this._point = 2; break;
|
|---|
| 1622 | case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
|
|---|
| 1623 | case 3: this._point = 4; // falls through
|
|---|
| 1624 | default: point$1(this, x, y); break;
|
|---|
| 1625 | }
|
|---|
| 1626 |
|
|---|
| 1627 | this._l01_a = this._l12_a, this._l12_a = this._l23_a;
|
|---|
| 1628 | this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
|
|---|
| 1629 | this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
|
|---|
| 1630 | this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
|
|---|
| 1631 | }
|
|---|
| 1632 | };
|
|---|
| 1633 |
|
|---|
| 1634 | var catmullRomOpen = (function custom(alpha) {
|
|---|
| 1635 |
|
|---|
| 1636 | function catmullRom(context) {
|
|---|
| 1637 | return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0);
|
|---|
| 1638 | }
|
|---|
| 1639 |
|
|---|
| 1640 | catmullRom.alpha = function(alpha) {
|
|---|
| 1641 | return custom(+alpha);
|
|---|
| 1642 | };
|
|---|
| 1643 |
|
|---|
| 1644 | return catmullRom;
|
|---|
| 1645 | })(0.5);
|
|---|
| 1646 |
|
|---|
| 1647 | function LinearClosed(context) {
|
|---|
| 1648 | this._context = context;
|
|---|
| 1649 | }
|
|---|
| 1650 |
|
|---|
| 1651 | LinearClosed.prototype = {
|
|---|
| 1652 | areaStart: noop,
|
|---|
| 1653 | areaEnd: noop,
|
|---|
| 1654 | lineStart: function() {
|
|---|
| 1655 | this._point = 0;
|
|---|
| 1656 | },
|
|---|
| 1657 | lineEnd: function() {
|
|---|
| 1658 | if (this._point) this._context.closePath();
|
|---|
| 1659 | },
|
|---|
| 1660 | point: function(x, y) {
|
|---|
| 1661 | x = +x, y = +y;
|
|---|
| 1662 | if (this._point) this._context.lineTo(x, y);
|
|---|
| 1663 | else this._point = 1, this._context.moveTo(x, y);
|
|---|
| 1664 | }
|
|---|
| 1665 | };
|
|---|
| 1666 |
|
|---|
| 1667 | function linearClosed(context) {
|
|---|
| 1668 | return new LinearClosed(context);
|
|---|
| 1669 | }
|
|---|
| 1670 |
|
|---|
| 1671 | function sign(x) {
|
|---|
| 1672 | return x < 0 ? -1 : 1;
|
|---|
| 1673 | }
|
|---|
| 1674 |
|
|---|
| 1675 | // Calculate the slopes of the tangents (Hermite-type interpolation) based on
|
|---|
| 1676 | // the following paper: Steffen, M. 1990. A Simple Method for Monotonic
|
|---|
| 1677 | // Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.
|
|---|
| 1678 | // NOV(II), P. 443, 1990.
|
|---|
| 1679 | function slope3(that, x2, y2) {
|
|---|
| 1680 | var h0 = that._x1 - that._x0,
|
|---|
| 1681 | h1 = x2 - that._x1,
|
|---|
| 1682 | s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),
|
|---|
| 1683 | s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),
|
|---|
| 1684 | p = (s0 * h1 + s1 * h0) / (h0 + h1);
|
|---|
| 1685 | return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;
|
|---|
| 1686 | }
|
|---|
| 1687 |
|
|---|
| 1688 | // Calculate a one-sided slope.
|
|---|
| 1689 | function slope2(that, t) {
|
|---|
| 1690 | var h = that._x1 - that._x0;
|
|---|
| 1691 | return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;
|
|---|
| 1692 | }
|
|---|
| 1693 |
|
|---|
| 1694 | // According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations
|
|---|
| 1695 | // "you can express cubic Hermite interpolation in terms of cubic Bézier curves
|
|---|
| 1696 | // with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1".
|
|---|
| 1697 | function point(that, t0, t1) {
|
|---|
| 1698 | var x0 = that._x0,
|
|---|
| 1699 | y0 = that._y0,
|
|---|
| 1700 | x1 = that._x1,
|
|---|
| 1701 | y1 = that._y1,
|
|---|
| 1702 | dx = (x1 - x0) / 3;
|
|---|
| 1703 | that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);
|
|---|
| 1704 | }
|
|---|
| 1705 |
|
|---|
| 1706 | function MonotoneX(context) {
|
|---|
| 1707 | this._context = context;
|
|---|
| 1708 | }
|
|---|
| 1709 |
|
|---|
| 1710 | MonotoneX.prototype = {
|
|---|
| 1711 | areaStart: function() {
|
|---|
| 1712 | this._line = 0;
|
|---|
| 1713 | },
|
|---|
| 1714 | areaEnd: function() {
|
|---|
| 1715 | this._line = NaN;
|
|---|
| 1716 | },
|
|---|
| 1717 | lineStart: function() {
|
|---|
| 1718 | this._x0 = this._x1 =
|
|---|
| 1719 | this._y0 = this._y1 =
|
|---|
| 1720 | this._t0 = NaN;
|
|---|
| 1721 | this._point = 0;
|
|---|
| 1722 | },
|
|---|
| 1723 | lineEnd: function() {
|
|---|
| 1724 | switch (this._point) {
|
|---|
| 1725 | case 2: this._context.lineTo(this._x1, this._y1); break;
|
|---|
| 1726 | case 3: point(this, this._t0, slope2(this, this._t0)); break;
|
|---|
| 1727 | }
|
|---|
| 1728 | if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
|
|---|
| 1729 | this._line = 1 - this._line;
|
|---|
| 1730 | },
|
|---|
| 1731 | point: function(x, y) {
|
|---|
| 1732 | var t1 = NaN;
|
|---|
| 1733 |
|
|---|
| 1734 | x = +x, y = +y;
|
|---|
| 1735 | if (x === this._x1 && y === this._y1) return; // Ignore coincident points.
|
|---|
| 1736 | switch (this._point) {
|
|---|
| 1737 | case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
|
|---|
| 1738 | case 1: this._point = 2; break;
|
|---|
| 1739 | case 2: this._point = 3; point(this, slope2(this, t1 = slope3(this, x, y)), t1); break;
|
|---|
| 1740 | default: point(this, this._t0, t1 = slope3(this, x, y)); break;
|
|---|
| 1741 | }
|
|---|
| 1742 |
|
|---|
| 1743 | this._x0 = this._x1, this._x1 = x;
|
|---|
| 1744 | this._y0 = this._y1, this._y1 = y;
|
|---|
| 1745 | this._t0 = t1;
|
|---|
| 1746 | }
|
|---|
| 1747 | };
|
|---|
| 1748 |
|
|---|
| 1749 | function MonotoneY(context) {
|
|---|
| 1750 | this._context = new ReflectContext(context);
|
|---|
| 1751 | }
|
|---|
| 1752 |
|
|---|
| 1753 | (MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {
|
|---|
| 1754 | MonotoneX.prototype.point.call(this, y, x);
|
|---|
| 1755 | };
|
|---|
| 1756 |
|
|---|
| 1757 | function ReflectContext(context) {
|
|---|
| 1758 | this._context = context;
|
|---|
| 1759 | }
|
|---|
| 1760 |
|
|---|
| 1761 | ReflectContext.prototype = {
|
|---|
| 1762 | moveTo: function(x, y) { this._context.moveTo(y, x); },
|
|---|
| 1763 | closePath: function() { this._context.closePath(); },
|
|---|
| 1764 | lineTo: function(x, y) { this._context.lineTo(y, x); },
|
|---|
| 1765 | bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }
|
|---|
| 1766 | };
|
|---|
| 1767 |
|
|---|
| 1768 | function monotoneX(context) {
|
|---|
| 1769 | return new MonotoneX(context);
|
|---|
| 1770 | }
|
|---|
| 1771 |
|
|---|
| 1772 | function monotoneY(context) {
|
|---|
| 1773 | return new MonotoneY(context);
|
|---|
| 1774 | }
|
|---|
| 1775 |
|
|---|
| 1776 | function Natural(context) {
|
|---|
| 1777 | this._context = context;
|
|---|
| 1778 | }
|
|---|
| 1779 |
|
|---|
| 1780 | Natural.prototype = {
|
|---|
| 1781 | areaStart: function() {
|
|---|
| 1782 | this._line = 0;
|
|---|
| 1783 | },
|
|---|
| 1784 | areaEnd: function() {
|
|---|
| 1785 | this._line = NaN;
|
|---|
| 1786 | },
|
|---|
| 1787 | lineStart: function() {
|
|---|
| 1788 | this._x = [];
|
|---|
| 1789 | this._y = [];
|
|---|
| 1790 | },
|
|---|
| 1791 | lineEnd: function() {
|
|---|
| 1792 | var x = this._x,
|
|---|
| 1793 | y = this._y,
|
|---|
| 1794 | n = x.length;
|
|---|
| 1795 |
|
|---|
| 1796 | if (n) {
|
|---|
| 1797 | this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);
|
|---|
| 1798 | if (n === 2) {
|
|---|
| 1799 | this._context.lineTo(x[1], y[1]);
|
|---|
| 1800 | } else {
|
|---|
| 1801 | var px = controlPoints(x),
|
|---|
| 1802 | py = controlPoints(y);
|
|---|
| 1803 | for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {
|
|---|
| 1804 | this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);
|
|---|
| 1805 | }
|
|---|
| 1806 | }
|
|---|
| 1807 | }
|
|---|
| 1808 |
|
|---|
| 1809 | if (this._line || (this._line !== 0 && n === 1)) this._context.closePath();
|
|---|
| 1810 | this._line = 1 - this._line;
|
|---|
| 1811 | this._x = this._y = null;
|
|---|
| 1812 | },
|
|---|
| 1813 | point: function(x, y) {
|
|---|
| 1814 | this._x.push(+x);
|
|---|
| 1815 | this._y.push(+y);
|
|---|
| 1816 | }
|
|---|
| 1817 | };
|
|---|
| 1818 |
|
|---|
| 1819 | // See https://www.particleincell.com/2012/bezier-splines/ for derivation.
|
|---|
| 1820 | function controlPoints(x) {
|
|---|
| 1821 | var i,
|
|---|
| 1822 | n = x.length - 1,
|
|---|
| 1823 | m,
|
|---|
| 1824 | a = new Array(n),
|
|---|
| 1825 | b = new Array(n),
|
|---|
| 1826 | r = new Array(n);
|
|---|
| 1827 | a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];
|
|---|
| 1828 | for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];
|
|---|
| 1829 | a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];
|
|---|
| 1830 | for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];
|
|---|
| 1831 | a[n - 1] = r[n - 1] / b[n - 1];
|
|---|
| 1832 | for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];
|
|---|
| 1833 | b[n - 1] = (x[n] + a[n - 1]) / 2;
|
|---|
| 1834 | for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];
|
|---|
| 1835 | return [a, b];
|
|---|
| 1836 | }
|
|---|
| 1837 |
|
|---|
| 1838 | function natural(context) {
|
|---|
| 1839 | return new Natural(context);
|
|---|
| 1840 | }
|
|---|
| 1841 |
|
|---|
| 1842 | function Step(context, t) {
|
|---|
| 1843 | this._context = context;
|
|---|
| 1844 | this._t = t;
|
|---|
| 1845 | }
|
|---|
| 1846 |
|
|---|
| 1847 | Step.prototype = {
|
|---|
| 1848 | areaStart: function() {
|
|---|
| 1849 | this._line = 0;
|
|---|
| 1850 | },
|
|---|
| 1851 | areaEnd: function() {
|
|---|
| 1852 | this._line = NaN;
|
|---|
| 1853 | },
|
|---|
| 1854 | lineStart: function() {
|
|---|
| 1855 | this._x = this._y = NaN;
|
|---|
| 1856 | this._point = 0;
|
|---|
| 1857 | },
|
|---|
| 1858 | lineEnd: function() {
|
|---|
| 1859 | if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);
|
|---|
| 1860 | if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
|
|---|
| 1861 | if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;
|
|---|
| 1862 | },
|
|---|
| 1863 | point: function(x, y) {
|
|---|
| 1864 | x = +x, y = +y;
|
|---|
| 1865 | switch (this._point) {
|
|---|
| 1866 | case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
|
|---|
| 1867 | case 1: this._point = 2; // falls through
|
|---|
| 1868 | default: {
|
|---|
| 1869 | if (this._t <= 0) {
|
|---|
| 1870 | this._context.lineTo(this._x, y);
|
|---|
| 1871 | this._context.lineTo(x, y);
|
|---|
| 1872 | } else {
|
|---|
| 1873 | var x1 = this._x * (1 - this._t) + x * this._t;
|
|---|
| 1874 | this._context.lineTo(x1, this._y);
|
|---|
| 1875 | this._context.lineTo(x1, y);
|
|---|
| 1876 | }
|
|---|
| 1877 | break;
|
|---|
| 1878 | }
|
|---|
| 1879 | }
|
|---|
| 1880 | this._x = x, this._y = y;
|
|---|
| 1881 | }
|
|---|
| 1882 | };
|
|---|
| 1883 |
|
|---|
| 1884 | function step(context) {
|
|---|
| 1885 | return new Step(context, 0.5);
|
|---|
| 1886 | }
|
|---|
| 1887 |
|
|---|
| 1888 | function stepBefore(context) {
|
|---|
| 1889 | return new Step(context, 0);
|
|---|
| 1890 | }
|
|---|
| 1891 |
|
|---|
| 1892 | function stepAfter(context) {
|
|---|
| 1893 | return new Step(context, 1);
|
|---|
| 1894 | }
|
|---|
| 1895 |
|
|---|
| 1896 | function none$1(series, order) {
|
|---|
| 1897 | if (!((n = series.length) > 1)) return;
|
|---|
| 1898 | for (var i = 1, j, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) {
|
|---|
| 1899 | s0 = s1, s1 = series[order[i]];
|
|---|
| 1900 | for (j = 0; j < m; ++j) {
|
|---|
| 1901 | s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1];
|
|---|
| 1902 | }
|
|---|
| 1903 | }
|
|---|
| 1904 | }
|
|---|
| 1905 |
|
|---|
| 1906 | function none(series) {
|
|---|
| 1907 | var n = series.length, o = new Array(n);
|
|---|
| 1908 | while (--n >= 0) o[n] = n;
|
|---|
| 1909 | return o;
|
|---|
| 1910 | }
|
|---|
| 1911 |
|
|---|
| 1912 | function stackValue(d, key) {
|
|---|
| 1913 | return d[key];
|
|---|
| 1914 | }
|
|---|
| 1915 |
|
|---|
| 1916 | function stackSeries(key) {
|
|---|
| 1917 | const series = [];
|
|---|
| 1918 | series.key = key;
|
|---|
| 1919 | return series;
|
|---|
| 1920 | }
|
|---|
| 1921 |
|
|---|
| 1922 | function stack() {
|
|---|
| 1923 | var keys = constant([]),
|
|---|
| 1924 | order = none,
|
|---|
| 1925 | offset = none$1,
|
|---|
| 1926 | value = stackValue;
|
|---|
| 1927 |
|
|---|
| 1928 | function stack(data) {
|
|---|
| 1929 | var sz = Array.from(keys.apply(this, arguments), stackSeries),
|
|---|
| 1930 | i, n = sz.length, j = -1,
|
|---|
| 1931 | oz;
|
|---|
| 1932 |
|
|---|
| 1933 | for (const d of data) {
|
|---|
| 1934 | for (i = 0, ++j; i < n; ++i) {
|
|---|
| 1935 | (sz[i][j] = [0, +value(d, sz[i].key, j, data)]).data = d;
|
|---|
| 1936 | }
|
|---|
| 1937 | }
|
|---|
| 1938 |
|
|---|
| 1939 | for (i = 0, oz = array(order(sz)); i < n; ++i) {
|
|---|
| 1940 | sz[oz[i]].index = i;
|
|---|
| 1941 | }
|
|---|
| 1942 |
|
|---|
| 1943 | offset(sz, oz);
|
|---|
| 1944 | return sz;
|
|---|
| 1945 | }
|
|---|
| 1946 |
|
|---|
| 1947 | stack.keys = function(_) {
|
|---|
| 1948 | return arguments.length ? (keys = typeof _ === "function" ? _ : constant(Array.from(_)), stack) : keys;
|
|---|
| 1949 | };
|
|---|
| 1950 |
|
|---|
| 1951 | stack.value = function(_) {
|
|---|
| 1952 | return arguments.length ? (value = typeof _ === "function" ? _ : constant(+_), stack) : value;
|
|---|
| 1953 | };
|
|---|
| 1954 |
|
|---|
| 1955 | stack.order = function(_) {
|
|---|
| 1956 | return arguments.length ? (order = _ == null ? none : typeof _ === "function" ? _ : constant(Array.from(_)), stack) : order;
|
|---|
| 1957 | };
|
|---|
| 1958 |
|
|---|
| 1959 | stack.offset = function(_) {
|
|---|
| 1960 | return arguments.length ? (offset = _ == null ? none$1 : _, stack) : offset;
|
|---|
| 1961 | };
|
|---|
| 1962 |
|
|---|
| 1963 | return stack;
|
|---|
| 1964 | }
|
|---|
| 1965 |
|
|---|
| 1966 | function expand(series, order) {
|
|---|
| 1967 | if (!((n = series.length) > 0)) return;
|
|---|
| 1968 | for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) {
|
|---|
| 1969 | for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0;
|
|---|
| 1970 | if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y;
|
|---|
| 1971 | }
|
|---|
| 1972 | none$1(series, order);
|
|---|
| 1973 | }
|
|---|
| 1974 |
|
|---|
| 1975 | function diverging(series, order) {
|
|---|
| 1976 | if (!((n = series.length) > 0)) return;
|
|---|
| 1977 | for (var i, j = 0, d, dy, yp, yn, n, m = series[order[0]].length; j < m; ++j) {
|
|---|
| 1978 | for (yp = yn = 0, i = 0; i < n; ++i) {
|
|---|
| 1979 | if ((dy = (d = series[order[i]][j])[1] - d[0]) > 0) {
|
|---|
| 1980 | d[0] = yp, d[1] = yp += dy;
|
|---|
| 1981 | } else if (dy < 0) {
|
|---|
| 1982 | d[1] = yn, d[0] = yn += dy;
|
|---|
| 1983 | } else {
|
|---|
| 1984 | d[0] = 0, d[1] = dy;
|
|---|
| 1985 | }
|
|---|
| 1986 | }
|
|---|
| 1987 | }
|
|---|
| 1988 | }
|
|---|
| 1989 |
|
|---|
| 1990 | function silhouette(series, order) {
|
|---|
| 1991 | if (!((n = series.length) > 0)) return;
|
|---|
| 1992 | for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) {
|
|---|
| 1993 | for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0;
|
|---|
| 1994 | s0[j][1] += s0[j][0] = -y / 2;
|
|---|
| 1995 | }
|
|---|
| 1996 | none$1(series, order);
|
|---|
| 1997 | }
|
|---|
| 1998 |
|
|---|
| 1999 | function wiggle(series, order) {
|
|---|
| 2000 | if (!((n = series.length) > 0) || !((m = (s0 = series[order[0]]).length) > 0)) return;
|
|---|
| 2001 | for (var y = 0, j = 1, s0, m, n; j < m; ++j) {
|
|---|
| 2002 | for (var i = 0, s1 = 0, s2 = 0; i < n; ++i) {
|
|---|
| 2003 | var si = series[order[i]],
|
|---|
| 2004 | sij0 = si[j][1] || 0,
|
|---|
| 2005 | sij1 = si[j - 1][1] || 0,
|
|---|
| 2006 | s3 = (sij0 - sij1) / 2;
|
|---|
| 2007 | for (var k = 0; k < i; ++k) {
|
|---|
| 2008 | var sk = series[order[k]],
|
|---|
| 2009 | skj0 = sk[j][1] || 0,
|
|---|
| 2010 | skj1 = sk[j - 1][1] || 0;
|
|---|
| 2011 | s3 += skj0 - skj1;
|
|---|
| 2012 | }
|
|---|
| 2013 | s1 += sij0, s2 += s3 * sij0;
|
|---|
| 2014 | }
|
|---|
| 2015 | s0[j - 1][1] += s0[j - 1][0] = y;
|
|---|
| 2016 | if (s1) y -= s2 / s1;
|
|---|
| 2017 | }
|
|---|
| 2018 | s0[j - 1][1] += s0[j - 1][0] = y;
|
|---|
| 2019 | none$1(series, order);
|
|---|
| 2020 | }
|
|---|
| 2021 |
|
|---|
| 2022 | function appearance(series) {
|
|---|
| 2023 | var peaks = series.map(peak);
|
|---|
| 2024 | return none(series).sort(function(a, b) { return peaks[a] - peaks[b]; });
|
|---|
| 2025 | }
|
|---|
| 2026 |
|
|---|
| 2027 | function peak(series) {
|
|---|
| 2028 | var i = -1, j = 0, n = series.length, vi, vj = -Infinity;
|
|---|
| 2029 | while (++i < n) if ((vi = +series[i][1]) > vj) vj = vi, j = i;
|
|---|
| 2030 | return j;
|
|---|
| 2031 | }
|
|---|
| 2032 |
|
|---|
| 2033 | function ascending(series) {
|
|---|
| 2034 | var sums = series.map(sum);
|
|---|
| 2035 | return none(series).sort(function(a, b) { return sums[a] - sums[b]; });
|
|---|
| 2036 | }
|
|---|
| 2037 |
|
|---|
| 2038 | function sum(series) {
|
|---|
| 2039 | var s = 0, i = -1, n = series.length, v;
|
|---|
| 2040 | while (++i < n) if (v = +series[i][1]) s += v;
|
|---|
| 2041 | return s;
|
|---|
| 2042 | }
|
|---|
| 2043 |
|
|---|
| 2044 | function descending(series) {
|
|---|
| 2045 | return ascending(series).reverse();
|
|---|
| 2046 | }
|
|---|
| 2047 |
|
|---|
| 2048 | function insideOut(series) {
|
|---|
| 2049 | var n = series.length,
|
|---|
| 2050 | i,
|
|---|
| 2051 | j,
|
|---|
| 2052 | sums = series.map(sum),
|
|---|
| 2053 | order = appearance(series),
|
|---|
| 2054 | top = 0,
|
|---|
| 2055 | bottom = 0,
|
|---|
| 2056 | tops = [],
|
|---|
| 2057 | bottoms = [];
|
|---|
| 2058 |
|
|---|
| 2059 | for (i = 0; i < n; ++i) {
|
|---|
| 2060 | j = order[i];
|
|---|
| 2061 | if (top < bottom) {
|
|---|
| 2062 | top += sums[j];
|
|---|
| 2063 | tops.push(j);
|
|---|
| 2064 | } else {
|
|---|
| 2065 | bottom += sums[j];
|
|---|
| 2066 | bottoms.push(j);
|
|---|
| 2067 | }
|
|---|
| 2068 | }
|
|---|
| 2069 |
|
|---|
| 2070 | return bottoms.reverse().concat(tops);
|
|---|
| 2071 | }
|
|---|
| 2072 |
|
|---|
| 2073 | function reverse(series) {
|
|---|
| 2074 | return none(series).reverse();
|
|---|
| 2075 | }
|
|---|
| 2076 |
|
|---|
| 2077 | exports.arc = arc;
|
|---|
| 2078 | exports.area = area;
|
|---|
| 2079 | exports.areaRadial = areaRadial;
|
|---|
| 2080 | exports.curveBasis = basis;
|
|---|
| 2081 | exports.curveBasisClosed = basisClosed;
|
|---|
| 2082 | exports.curveBasisOpen = basisOpen;
|
|---|
| 2083 | exports.curveBumpX = bumpX;
|
|---|
| 2084 | exports.curveBumpY = bumpY;
|
|---|
| 2085 | exports.curveBundle = bundle;
|
|---|
| 2086 | exports.curveCardinal = cardinal;
|
|---|
| 2087 | exports.curveCardinalClosed = cardinalClosed;
|
|---|
| 2088 | exports.curveCardinalOpen = cardinalOpen;
|
|---|
| 2089 | exports.curveCatmullRom = catmullRom;
|
|---|
| 2090 | exports.curveCatmullRomClosed = catmullRomClosed;
|
|---|
| 2091 | exports.curveCatmullRomOpen = catmullRomOpen;
|
|---|
| 2092 | exports.curveLinear = curveLinear;
|
|---|
| 2093 | exports.curveLinearClosed = linearClosed;
|
|---|
| 2094 | exports.curveMonotoneX = monotoneX;
|
|---|
| 2095 | exports.curveMonotoneY = monotoneY;
|
|---|
| 2096 | exports.curveNatural = natural;
|
|---|
| 2097 | exports.curveStep = step;
|
|---|
| 2098 | exports.curveStepAfter = stepAfter;
|
|---|
| 2099 | exports.curveStepBefore = stepBefore;
|
|---|
| 2100 | exports.line = line;
|
|---|
| 2101 | exports.lineRadial = lineRadial$1;
|
|---|
| 2102 | exports.link = link;
|
|---|
| 2103 | exports.linkHorizontal = linkHorizontal;
|
|---|
| 2104 | exports.linkRadial = linkRadial;
|
|---|
| 2105 | exports.linkVertical = linkVertical;
|
|---|
| 2106 | exports.pie = pie;
|
|---|
| 2107 | exports.pointRadial = pointRadial;
|
|---|
| 2108 | exports.radialArea = areaRadial;
|
|---|
| 2109 | exports.radialLine = lineRadial$1;
|
|---|
| 2110 | exports.stack = stack;
|
|---|
| 2111 | exports.stackOffsetDiverging = diverging;
|
|---|
| 2112 | exports.stackOffsetExpand = expand;
|
|---|
| 2113 | exports.stackOffsetNone = none$1;
|
|---|
| 2114 | exports.stackOffsetSilhouette = silhouette;
|
|---|
| 2115 | exports.stackOffsetWiggle = wiggle;
|
|---|
| 2116 | exports.stackOrderAppearance = appearance;
|
|---|
| 2117 | exports.stackOrderAscending = ascending;
|
|---|
| 2118 | exports.stackOrderDescending = descending;
|
|---|
| 2119 | exports.stackOrderInsideOut = insideOut;
|
|---|
| 2120 | exports.stackOrderNone = none;
|
|---|
| 2121 | exports.stackOrderReverse = reverse;
|
|---|
| 2122 | exports.symbol = Symbol;
|
|---|
| 2123 | exports.symbolAsterisk = asterisk;
|
|---|
| 2124 | exports.symbolCircle = circle;
|
|---|
| 2125 | exports.symbolCross = cross;
|
|---|
| 2126 | exports.symbolDiamond = diamond;
|
|---|
| 2127 | exports.symbolDiamond2 = diamond2;
|
|---|
| 2128 | exports.symbolPlus = plus;
|
|---|
| 2129 | exports.symbolSquare = square;
|
|---|
| 2130 | exports.symbolSquare2 = square2;
|
|---|
| 2131 | exports.symbolStar = star;
|
|---|
| 2132 | exports.symbolTimes = times;
|
|---|
| 2133 | exports.symbolTriangle = triangle;
|
|---|
| 2134 | exports.symbolTriangle2 = triangle2;
|
|---|
| 2135 | exports.symbolWye = wye;
|
|---|
| 2136 | exports.symbolX = times;
|
|---|
| 2137 | exports.symbols = symbolsFill;
|
|---|
| 2138 | exports.symbolsFill = symbolsFill;
|
|---|
| 2139 | exports.symbolsStroke = symbolsStroke;
|
|---|
| 2140 |
|
|---|
| 2141 | }));
|
|---|