| 1 | // https://d3js.org/d3-hierarchy/ v3.1.2 Copyright 2010-2021 Mike Bostock
|
|---|
| 2 | (function (global, factory) {
|
|---|
| 3 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|---|
| 4 | typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|---|
| 5 | (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = global.d3 || {}));
|
|---|
| 6 | })(this, (function (exports) { 'use strict';
|
|---|
| 7 |
|
|---|
| 8 | function defaultSeparation$1(a, b) {
|
|---|
| 9 | return a.parent === b.parent ? 1 : 2;
|
|---|
| 10 | }
|
|---|
| 11 |
|
|---|
| 12 | function meanX(children) {
|
|---|
| 13 | return children.reduce(meanXReduce, 0) / children.length;
|
|---|
| 14 | }
|
|---|
| 15 |
|
|---|
| 16 | function meanXReduce(x, c) {
|
|---|
| 17 | return x + c.x;
|
|---|
| 18 | }
|
|---|
| 19 |
|
|---|
| 20 | function maxY(children) {
|
|---|
| 21 | return 1 + children.reduce(maxYReduce, 0);
|
|---|
| 22 | }
|
|---|
| 23 |
|
|---|
| 24 | function maxYReduce(y, c) {
|
|---|
| 25 | return Math.max(y, c.y);
|
|---|
| 26 | }
|
|---|
| 27 |
|
|---|
| 28 | function leafLeft(node) {
|
|---|
| 29 | var children;
|
|---|
| 30 | while (children = node.children) node = children[0];
|
|---|
| 31 | return node;
|
|---|
| 32 | }
|
|---|
| 33 |
|
|---|
| 34 | function leafRight(node) {
|
|---|
| 35 | var children;
|
|---|
| 36 | while (children = node.children) node = children[children.length - 1];
|
|---|
| 37 | return node;
|
|---|
| 38 | }
|
|---|
| 39 |
|
|---|
| 40 | function cluster() {
|
|---|
| 41 | var separation = defaultSeparation$1,
|
|---|
| 42 | dx = 1,
|
|---|
| 43 | dy = 1,
|
|---|
| 44 | nodeSize = false;
|
|---|
| 45 |
|
|---|
| 46 | function cluster(root) {
|
|---|
| 47 | var previousNode,
|
|---|
| 48 | x = 0;
|
|---|
| 49 |
|
|---|
| 50 | // First walk, computing the initial x & y values.
|
|---|
| 51 | root.eachAfter(function(node) {
|
|---|
| 52 | var children = node.children;
|
|---|
| 53 | if (children) {
|
|---|
| 54 | node.x = meanX(children);
|
|---|
| 55 | node.y = maxY(children);
|
|---|
| 56 | } else {
|
|---|
| 57 | node.x = previousNode ? x += separation(node, previousNode) : 0;
|
|---|
| 58 | node.y = 0;
|
|---|
| 59 | previousNode = node;
|
|---|
| 60 | }
|
|---|
| 61 | });
|
|---|
| 62 |
|
|---|
| 63 | var left = leafLeft(root),
|
|---|
| 64 | right = leafRight(root),
|
|---|
| 65 | x0 = left.x - separation(left, right) / 2,
|
|---|
| 66 | x1 = right.x + separation(right, left) / 2;
|
|---|
| 67 |
|
|---|
| 68 | // Second walk, normalizing x & y to the desired size.
|
|---|
| 69 | return root.eachAfter(nodeSize ? function(node) {
|
|---|
| 70 | node.x = (node.x - root.x) * dx;
|
|---|
| 71 | node.y = (root.y - node.y) * dy;
|
|---|
| 72 | } : function(node) {
|
|---|
| 73 | node.x = (node.x - x0) / (x1 - x0) * dx;
|
|---|
| 74 | node.y = (1 - (root.y ? node.y / root.y : 1)) * dy;
|
|---|
| 75 | });
|
|---|
| 76 | }
|
|---|
| 77 |
|
|---|
| 78 | cluster.separation = function(x) {
|
|---|
| 79 | return arguments.length ? (separation = x, cluster) : separation;
|
|---|
| 80 | };
|
|---|
| 81 |
|
|---|
| 82 | cluster.size = function(x) {
|
|---|
| 83 | return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? null : [dx, dy]);
|
|---|
| 84 | };
|
|---|
| 85 |
|
|---|
| 86 | cluster.nodeSize = function(x) {
|
|---|
| 87 | return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? [dx, dy] : null);
|
|---|
| 88 | };
|
|---|
| 89 |
|
|---|
| 90 | return cluster;
|
|---|
| 91 | }
|
|---|
| 92 |
|
|---|
| 93 | function count(node) {
|
|---|
| 94 | var sum = 0,
|
|---|
| 95 | children = node.children,
|
|---|
| 96 | i = children && children.length;
|
|---|
| 97 | if (!i) sum = 1;
|
|---|
| 98 | else while (--i >= 0) sum += children[i].value;
|
|---|
| 99 | node.value = sum;
|
|---|
| 100 | }
|
|---|
| 101 |
|
|---|
| 102 | function node_count() {
|
|---|
| 103 | return this.eachAfter(count);
|
|---|
| 104 | }
|
|---|
| 105 |
|
|---|
| 106 | function node_each(callback, that) {
|
|---|
| 107 | let index = -1;
|
|---|
| 108 | for (const node of this) {
|
|---|
| 109 | callback.call(that, node, ++index, this);
|
|---|
| 110 | }
|
|---|
| 111 | return this;
|
|---|
| 112 | }
|
|---|
| 113 |
|
|---|
| 114 | function node_eachBefore(callback, that) {
|
|---|
| 115 | var node = this, nodes = [node], children, i, index = -1;
|
|---|
| 116 | while (node = nodes.pop()) {
|
|---|
| 117 | callback.call(that, node, ++index, this);
|
|---|
| 118 | if (children = node.children) {
|
|---|
| 119 | for (i = children.length - 1; i >= 0; --i) {
|
|---|
| 120 | nodes.push(children[i]);
|
|---|
| 121 | }
|
|---|
| 122 | }
|
|---|
| 123 | }
|
|---|
| 124 | return this;
|
|---|
| 125 | }
|
|---|
| 126 |
|
|---|
| 127 | function node_eachAfter(callback, that) {
|
|---|
| 128 | var node = this, nodes = [node], next = [], children, i, n, index = -1;
|
|---|
| 129 | while (node = nodes.pop()) {
|
|---|
| 130 | next.push(node);
|
|---|
| 131 | if (children = node.children) {
|
|---|
| 132 | for (i = 0, n = children.length; i < n; ++i) {
|
|---|
| 133 | nodes.push(children[i]);
|
|---|
| 134 | }
|
|---|
| 135 | }
|
|---|
| 136 | }
|
|---|
| 137 | while (node = next.pop()) {
|
|---|
| 138 | callback.call(that, node, ++index, this);
|
|---|
| 139 | }
|
|---|
| 140 | return this;
|
|---|
| 141 | }
|
|---|
| 142 |
|
|---|
| 143 | function node_find(callback, that) {
|
|---|
| 144 | let index = -1;
|
|---|
| 145 | for (const node of this) {
|
|---|
| 146 | if (callback.call(that, node, ++index, this)) {
|
|---|
| 147 | return node;
|
|---|
| 148 | }
|
|---|
| 149 | }
|
|---|
| 150 | }
|
|---|
| 151 |
|
|---|
| 152 | function node_sum(value) {
|
|---|
| 153 | return this.eachAfter(function(node) {
|
|---|
| 154 | var sum = +value(node.data) || 0,
|
|---|
| 155 | children = node.children,
|
|---|
| 156 | i = children && children.length;
|
|---|
| 157 | while (--i >= 0) sum += children[i].value;
|
|---|
| 158 | node.value = sum;
|
|---|
| 159 | });
|
|---|
| 160 | }
|
|---|
| 161 |
|
|---|
| 162 | function node_sort(compare) {
|
|---|
| 163 | return this.eachBefore(function(node) {
|
|---|
| 164 | if (node.children) {
|
|---|
| 165 | node.children.sort(compare);
|
|---|
| 166 | }
|
|---|
| 167 | });
|
|---|
| 168 | }
|
|---|
| 169 |
|
|---|
| 170 | function node_path(end) {
|
|---|
| 171 | var start = this,
|
|---|
| 172 | ancestor = leastCommonAncestor(start, end),
|
|---|
| 173 | nodes = [start];
|
|---|
| 174 | while (start !== ancestor) {
|
|---|
| 175 | start = start.parent;
|
|---|
| 176 | nodes.push(start);
|
|---|
| 177 | }
|
|---|
| 178 | var k = nodes.length;
|
|---|
| 179 | while (end !== ancestor) {
|
|---|
| 180 | nodes.splice(k, 0, end);
|
|---|
| 181 | end = end.parent;
|
|---|
| 182 | }
|
|---|
| 183 | return nodes;
|
|---|
| 184 | }
|
|---|
| 185 |
|
|---|
| 186 | function leastCommonAncestor(a, b) {
|
|---|
| 187 | if (a === b) return a;
|
|---|
| 188 | var aNodes = a.ancestors(),
|
|---|
| 189 | bNodes = b.ancestors(),
|
|---|
| 190 | c = null;
|
|---|
| 191 | a = aNodes.pop();
|
|---|
| 192 | b = bNodes.pop();
|
|---|
| 193 | while (a === b) {
|
|---|
| 194 | c = a;
|
|---|
| 195 | a = aNodes.pop();
|
|---|
| 196 | b = bNodes.pop();
|
|---|
| 197 | }
|
|---|
| 198 | return c;
|
|---|
| 199 | }
|
|---|
| 200 |
|
|---|
| 201 | function node_ancestors() {
|
|---|
| 202 | var node = this, nodes = [node];
|
|---|
| 203 | while (node = node.parent) {
|
|---|
| 204 | nodes.push(node);
|
|---|
| 205 | }
|
|---|
| 206 | return nodes;
|
|---|
| 207 | }
|
|---|
| 208 |
|
|---|
| 209 | function node_descendants() {
|
|---|
| 210 | return Array.from(this);
|
|---|
| 211 | }
|
|---|
| 212 |
|
|---|
| 213 | function node_leaves() {
|
|---|
| 214 | var leaves = [];
|
|---|
| 215 | this.eachBefore(function(node) {
|
|---|
| 216 | if (!node.children) {
|
|---|
| 217 | leaves.push(node);
|
|---|
| 218 | }
|
|---|
| 219 | });
|
|---|
| 220 | return leaves;
|
|---|
| 221 | }
|
|---|
| 222 |
|
|---|
| 223 | function node_links() {
|
|---|
| 224 | var root = this, links = [];
|
|---|
| 225 | root.each(function(node) {
|
|---|
| 226 | if (node !== root) { // Don’t include the root’s parent, if any.
|
|---|
| 227 | links.push({source: node.parent, target: node});
|
|---|
| 228 | }
|
|---|
| 229 | });
|
|---|
| 230 | return links;
|
|---|
| 231 | }
|
|---|
| 232 |
|
|---|
| 233 | function* node_iterator() {
|
|---|
| 234 | var node = this, current, next = [node], children, i, n;
|
|---|
| 235 | do {
|
|---|
| 236 | current = next.reverse(), next = [];
|
|---|
| 237 | while (node = current.pop()) {
|
|---|
| 238 | yield node;
|
|---|
| 239 | if (children = node.children) {
|
|---|
| 240 | for (i = 0, n = children.length; i < n; ++i) {
|
|---|
| 241 | next.push(children[i]);
|
|---|
| 242 | }
|
|---|
| 243 | }
|
|---|
| 244 | }
|
|---|
| 245 | } while (next.length);
|
|---|
| 246 | }
|
|---|
| 247 |
|
|---|
| 248 | function hierarchy(data, children) {
|
|---|
| 249 | if (data instanceof Map) {
|
|---|
| 250 | data = [undefined, data];
|
|---|
| 251 | if (children === undefined) children = mapChildren;
|
|---|
| 252 | } else if (children === undefined) {
|
|---|
| 253 | children = objectChildren;
|
|---|
| 254 | }
|
|---|
| 255 |
|
|---|
| 256 | var root = new Node$1(data),
|
|---|
| 257 | node,
|
|---|
| 258 | nodes = [root],
|
|---|
| 259 | child,
|
|---|
| 260 | childs,
|
|---|
| 261 | i,
|
|---|
| 262 | n;
|
|---|
| 263 |
|
|---|
| 264 | while (node = nodes.pop()) {
|
|---|
| 265 | if ((childs = children(node.data)) && (n = (childs = Array.from(childs)).length)) {
|
|---|
| 266 | node.children = childs;
|
|---|
| 267 | for (i = n - 1; i >= 0; --i) {
|
|---|
| 268 | nodes.push(child = childs[i] = new Node$1(childs[i]));
|
|---|
| 269 | child.parent = node;
|
|---|
| 270 | child.depth = node.depth + 1;
|
|---|
| 271 | }
|
|---|
| 272 | }
|
|---|
| 273 | }
|
|---|
| 274 |
|
|---|
| 275 | return root.eachBefore(computeHeight);
|
|---|
| 276 | }
|
|---|
| 277 |
|
|---|
| 278 | function node_copy() {
|
|---|
| 279 | return hierarchy(this).eachBefore(copyData);
|
|---|
| 280 | }
|
|---|
| 281 |
|
|---|
| 282 | function objectChildren(d) {
|
|---|
| 283 | return d.children;
|
|---|
| 284 | }
|
|---|
| 285 |
|
|---|
| 286 | function mapChildren(d) {
|
|---|
| 287 | return Array.isArray(d) ? d[1] : null;
|
|---|
| 288 | }
|
|---|
| 289 |
|
|---|
| 290 | function copyData(node) {
|
|---|
| 291 | if (node.data.value !== undefined) node.value = node.data.value;
|
|---|
| 292 | node.data = node.data.data;
|
|---|
| 293 | }
|
|---|
| 294 |
|
|---|
| 295 | function computeHeight(node) {
|
|---|
| 296 | var height = 0;
|
|---|
| 297 | do node.height = height;
|
|---|
| 298 | while ((node = node.parent) && (node.height < ++height));
|
|---|
| 299 | }
|
|---|
| 300 |
|
|---|
| 301 | function Node$1(data) {
|
|---|
| 302 | this.data = data;
|
|---|
| 303 | this.depth =
|
|---|
| 304 | this.height = 0;
|
|---|
| 305 | this.parent = null;
|
|---|
| 306 | }
|
|---|
| 307 |
|
|---|
| 308 | Node$1.prototype = hierarchy.prototype = {
|
|---|
| 309 | constructor: Node$1,
|
|---|
| 310 | count: node_count,
|
|---|
| 311 | each: node_each,
|
|---|
| 312 | eachAfter: node_eachAfter,
|
|---|
| 313 | eachBefore: node_eachBefore,
|
|---|
| 314 | find: node_find,
|
|---|
| 315 | sum: node_sum,
|
|---|
| 316 | sort: node_sort,
|
|---|
| 317 | path: node_path,
|
|---|
| 318 | ancestors: node_ancestors,
|
|---|
| 319 | descendants: node_descendants,
|
|---|
| 320 | leaves: node_leaves,
|
|---|
| 321 | links: node_links,
|
|---|
| 322 | copy: node_copy,
|
|---|
| 323 | [Symbol.iterator]: node_iterator
|
|---|
| 324 | };
|
|---|
| 325 |
|
|---|
| 326 | function optional(f) {
|
|---|
| 327 | return f == null ? null : required(f);
|
|---|
| 328 | }
|
|---|
| 329 |
|
|---|
| 330 | function required(f) {
|
|---|
| 331 | if (typeof f !== "function") throw new Error;
|
|---|
| 332 | return f;
|
|---|
| 333 | }
|
|---|
| 334 |
|
|---|
| 335 | function constantZero() {
|
|---|
| 336 | return 0;
|
|---|
| 337 | }
|
|---|
| 338 |
|
|---|
| 339 | function constant(x) {
|
|---|
| 340 | return function() {
|
|---|
| 341 | return x;
|
|---|
| 342 | };
|
|---|
| 343 | }
|
|---|
| 344 |
|
|---|
| 345 | // https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use
|
|---|
| 346 | const a = 1664525;
|
|---|
| 347 | const c = 1013904223;
|
|---|
| 348 | const m = 4294967296; // 2^32
|
|---|
| 349 |
|
|---|
| 350 | function lcg() {
|
|---|
| 351 | let s = 1;
|
|---|
| 352 | return () => (s = (a * s + c) % m) / m;
|
|---|
| 353 | }
|
|---|
| 354 |
|
|---|
| 355 | function array(x) {
|
|---|
| 356 | return typeof x === "object" && "length" in x
|
|---|
| 357 | ? x // Array, TypedArray, NodeList, array-like
|
|---|
| 358 | : Array.from(x); // Map, Set, iterable, string, or anything else
|
|---|
| 359 | }
|
|---|
| 360 |
|
|---|
| 361 | function shuffle(array, random) {
|
|---|
| 362 | let m = array.length,
|
|---|
| 363 | t,
|
|---|
| 364 | i;
|
|---|
| 365 |
|
|---|
| 366 | while (m) {
|
|---|
| 367 | i = random() * m-- | 0;
|
|---|
| 368 | t = array[m];
|
|---|
| 369 | array[m] = array[i];
|
|---|
| 370 | array[i] = t;
|
|---|
| 371 | }
|
|---|
| 372 |
|
|---|
| 373 | return array;
|
|---|
| 374 | }
|
|---|
| 375 |
|
|---|
| 376 | function enclose(circles) {
|
|---|
| 377 | return packEncloseRandom(circles, lcg());
|
|---|
| 378 | }
|
|---|
| 379 |
|
|---|
| 380 | function packEncloseRandom(circles, random) {
|
|---|
| 381 | var i = 0, n = (circles = shuffle(Array.from(circles), random)).length, B = [], p, e;
|
|---|
| 382 |
|
|---|
| 383 | while (i < n) {
|
|---|
| 384 | p = circles[i];
|
|---|
| 385 | if (e && enclosesWeak(e, p)) ++i;
|
|---|
| 386 | else e = encloseBasis(B = extendBasis(B, p)), i = 0;
|
|---|
| 387 | }
|
|---|
| 388 |
|
|---|
| 389 | return e;
|
|---|
| 390 | }
|
|---|
| 391 |
|
|---|
| 392 | function extendBasis(B, p) {
|
|---|
| 393 | var i, j;
|
|---|
| 394 |
|
|---|
| 395 | if (enclosesWeakAll(p, B)) return [p];
|
|---|
| 396 |
|
|---|
| 397 | // If we get here then B must have at least one element.
|
|---|
| 398 | for (i = 0; i < B.length; ++i) {
|
|---|
| 399 | if (enclosesNot(p, B[i])
|
|---|
| 400 | && enclosesWeakAll(encloseBasis2(B[i], p), B)) {
|
|---|
| 401 | return [B[i], p];
|
|---|
| 402 | }
|
|---|
| 403 | }
|
|---|
| 404 |
|
|---|
| 405 | // If we get here then B must have at least two elements.
|
|---|
| 406 | for (i = 0; i < B.length - 1; ++i) {
|
|---|
| 407 | for (j = i + 1; j < B.length; ++j) {
|
|---|
| 408 | if (enclosesNot(encloseBasis2(B[i], B[j]), p)
|
|---|
| 409 | && enclosesNot(encloseBasis2(B[i], p), B[j])
|
|---|
| 410 | && enclosesNot(encloseBasis2(B[j], p), B[i])
|
|---|
| 411 | && enclosesWeakAll(encloseBasis3(B[i], B[j], p), B)) {
|
|---|
| 412 | return [B[i], B[j], p];
|
|---|
| 413 | }
|
|---|
| 414 | }
|
|---|
| 415 | }
|
|---|
| 416 |
|
|---|
| 417 | // If we get here then something is very wrong.
|
|---|
| 418 | throw new Error;
|
|---|
| 419 | }
|
|---|
| 420 |
|
|---|
| 421 | function enclosesNot(a, b) {
|
|---|
| 422 | var dr = a.r - b.r, dx = b.x - a.x, dy = b.y - a.y;
|
|---|
| 423 | return dr < 0 || dr * dr < dx * dx + dy * dy;
|
|---|
| 424 | }
|
|---|
| 425 |
|
|---|
| 426 | function enclosesWeak(a, b) {
|
|---|
| 427 | var dr = a.r - b.r + Math.max(a.r, b.r, 1) * 1e-9, dx = b.x - a.x, dy = b.y - a.y;
|
|---|
| 428 | return dr > 0 && dr * dr > dx * dx + dy * dy;
|
|---|
| 429 | }
|
|---|
| 430 |
|
|---|
| 431 | function enclosesWeakAll(a, B) {
|
|---|
| 432 | for (var i = 0; i < B.length; ++i) {
|
|---|
| 433 | if (!enclosesWeak(a, B[i])) {
|
|---|
| 434 | return false;
|
|---|
| 435 | }
|
|---|
| 436 | }
|
|---|
| 437 | return true;
|
|---|
| 438 | }
|
|---|
| 439 |
|
|---|
| 440 | function encloseBasis(B) {
|
|---|
| 441 | switch (B.length) {
|
|---|
| 442 | case 1: return encloseBasis1(B[0]);
|
|---|
| 443 | case 2: return encloseBasis2(B[0], B[1]);
|
|---|
| 444 | case 3: return encloseBasis3(B[0], B[1], B[2]);
|
|---|
| 445 | }
|
|---|
| 446 | }
|
|---|
| 447 |
|
|---|
| 448 | function encloseBasis1(a) {
|
|---|
| 449 | return {
|
|---|
| 450 | x: a.x,
|
|---|
| 451 | y: a.y,
|
|---|
| 452 | r: a.r
|
|---|
| 453 | };
|
|---|
| 454 | }
|
|---|
| 455 |
|
|---|
| 456 | function encloseBasis2(a, b) {
|
|---|
| 457 | var x1 = a.x, y1 = a.y, r1 = a.r,
|
|---|
| 458 | x2 = b.x, y2 = b.y, r2 = b.r,
|
|---|
| 459 | x21 = x2 - x1, y21 = y2 - y1, r21 = r2 - r1,
|
|---|
| 460 | l = Math.sqrt(x21 * x21 + y21 * y21);
|
|---|
| 461 | return {
|
|---|
| 462 | x: (x1 + x2 + x21 / l * r21) / 2,
|
|---|
| 463 | y: (y1 + y2 + y21 / l * r21) / 2,
|
|---|
| 464 | r: (l + r1 + r2) / 2
|
|---|
| 465 | };
|
|---|
| 466 | }
|
|---|
| 467 |
|
|---|
| 468 | function encloseBasis3(a, b, c) {
|
|---|
| 469 | var x1 = a.x, y1 = a.y, r1 = a.r,
|
|---|
| 470 | x2 = b.x, y2 = b.y, r2 = b.r,
|
|---|
| 471 | x3 = c.x, y3 = c.y, r3 = c.r,
|
|---|
| 472 | a2 = x1 - x2,
|
|---|
| 473 | a3 = x1 - x3,
|
|---|
| 474 | b2 = y1 - y2,
|
|---|
| 475 | b3 = y1 - y3,
|
|---|
| 476 | c2 = r2 - r1,
|
|---|
| 477 | c3 = r3 - r1,
|
|---|
| 478 | d1 = x1 * x1 + y1 * y1 - r1 * r1,
|
|---|
| 479 | d2 = d1 - x2 * x2 - y2 * y2 + r2 * r2,
|
|---|
| 480 | d3 = d1 - x3 * x3 - y3 * y3 + r3 * r3,
|
|---|
| 481 | ab = a3 * b2 - a2 * b3,
|
|---|
| 482 | xa = (b2 * d3 - b3 * d2) / (ab * 2) - x1,
|
|---|
| 483 | xb = (b3 * c2 - b2 * c3) / ab,
|
|---|
| 484 | ya = (a3 * d2 - a2 * d3) / (ab * 2) - y1,
|
|---|
| 485 | yb = (a2 * c3 - a3 * c2) / ab,
|
|---|
| 486 | A = xb * xb + yb * yb - 1,
|
|---|
| 487 | B = 2 * (r1 + xa * xb + ya * yb),
|
|---|
| 488 | C = xa * xa + ya * ya - r1 * r1,
|
|---|
| 489 | r = -(Math.abs(A) > 1e-6 ? (B + Math.sqrt(B * B - 4 * A * C)) / (2 * A) : C / B);
|
|---|
| 490 | return {
|
|---|
| 491 | x: x1 + xa + xb * r,
|
|---|
| 492 | y: y1 + ya + yb * r,
|
|---|
| 493 | r: r
|
|---|
| 494 | };
|
|---|
| 495 | }
|
|---|
| 496 |
|
|---|
| 497 | function place(b, a, c) {
|
|---|
| 498 | var dx = b.x - a.x, x, a2,
|
|---|
| 499 | dy = b.y - a.y, y, b2,
|
|---|
| 500 | d2 = dx * dx + dy * dy;
|
|---|
| 501 | if (d2) {
|
|---|
| 502 | a2 = a.r + c.r, a2 *= a2;
|
|---|
| 503 | b2 = b.r + c.r, b2 *= b2;
|
|---|
| 504 | if (a2 > b2) {
|
|---|
| 505 | x = (d2 + b2 - a2) / (2 * d2);
|
|---|
| 506 | y = Math.sqrt(Math.max(0, b2 / d2 - x * x));
|
|---|
| 507 | c.x = b.x - x * dx - y * dy;
|
|---|
| 508 | c.y = b.y - x * dy + y * dx;
|
|---|
| 509 | } else {
|
|---|
| 510 | x = (d2 + a2 - b2) / (2 * d2);
|
|---|
| 511 | y = Math.sqrt(Math.max(0, a2 / d2 - x * x));
|
|---|
| 512 | c.x = a.x + x * dx - y * dy;
|
|---|
| 513 | c.y = a.y + x * dy + y * dx;
|
|---|
| 514 | }
|
|---|
| 515 | } else {
|
|---|
| 516 | c.x = a.x + c.r;
|
|---|
| 517 | c.y = a.y;
|
|---|
| 518 | }
|
|---|
| 519 | }
|
|---|
| 520 |
|
|---|
| 521 | function intersects(a, b) {
|
|---|
| 522 | var dr = a.r + b.r - 1e-6, dx = b.x - a.x, dy = b.y - a.y;
|
|---|
| 523 | return dr > 0 && dr * dr > dx * dx + dy * dy;
|
|---|
| 524 | }
|
|---|
| 525 |
|
|---|
| 526 | function score(node) {
|
|---|
| 527 | var a = node._,
|
|---|
| 528 | b = node.next._,
|
|---|
| 529 | ab = a.r + b.r,
|
|---|
| 530 | dx = (a.x * b.r + b.x * a.r) / ab,
|
|---|
| 531 | dy = (a.y * b.r + b.y * a.r) / ab;
|
|---|
| 532 | return dx * dx + dy * dy;
|
|---|
| 533 | }
|
|---|
| 534 |
|
|---|
| 535 | function Node(circle) {
|
|---|
| 536 | this._ = circle;
|
|---|
| 537 | this.next = null;
|
|---|
| 538 | this.previous = null;
|
|---|
| 539 | }
|
|---|
| 540 |
|
|---|
| 541 | function packSiblingsRandom(circles, random) {
|
|---|
| 542 | if (!(n = (circles = array(circles)).length)) return 0;
|
|---|
| 543 |
|
|---|
| 544 | var a, b, c, n, aa, ca, i, j, k, sj, sk;
|
|---|
| 545 |
|
|---|
| 546 | // Place the first circle.
|
|---|
| 547 | a = circles[0], a.x = 0, a.y = 0;
|
|---|
| 548 | if (!(n > 1)) return a.r;
|
|---|
| 549 |
|
|---|
| 550 | // Place the second circle.
|
|---|
| 551 | b = circles[1], a.x = -b.r, b.x = a.r, b.y = 0;
|
|---|
| 552 | if (!(n > 2)) return a.r + b.r;
|
|---|
| 553 |
|
|---|
| 554 | // Place the third circle.
|
|---|
| 555 | place(b, a, c = circles[2]);
|
|---|
| 556 |
|
|---|
| 557 | // Initialize the front-chain using the first three circles a, b and c.
|
|---|
| 558 | a = new Node(a), b = new Node(b), c = new Node(c);
|
|---|
| 559 | a.next = c.previous = b;
|
|---|
| 560 | b.next = a.previous = c;
|
|---|
| 561 | c.next = b.previous = a;
|
|---|
| 562 |
|
|---|
| 563 | // Attempt to place each remaining circle…
|
|---|
| 564 | pack: for (i = 3; i < n; ++i) {
|
|---|
| 565 | place(a._, b._, c = circles[i]), c = new Node(c);
|
|---|
| 566 |
|
|---|
| 567 | // Find the closest intersecting circle on the front-chain, if any.
|
|---|
| 568 | // “Closeness” is determined by linear distance along the front-chain.
|
|---|
| 569 | // “Ahead” or “behind” is likewise determined by linear distance.
|
|---|
| 570 | j = b.next, k = a.previous, sj = b._.r, sk = a._.r;
|
|---|
| 571 | do {
|
|---|
| 572 | if (sj <= sk) {
|
|---|
| 573 | if (intersects(j._, c._)) {
|
|---|
| 574 | b = j, a.next = b, b.previous = a, --i;
|
|---|
| 575 | continue pack;
|
|---|
| 576 | }
|
|---|
| 577 | sj += j._.r, j = j.next;
|
|---|
| 578 | } else {
|
|---|
| 579 | if (intersects(k._, c._)) {
|
|---|
| 580 | a = k, a.next = b, b.previous = a, --i;
|
|---|
| 581 | continue pack;
|
|---|
| 582 | }
|
|---|
| 583 | sk += k._.r, k = k.previous;
|
|---|
| 584 | }
|
|---|
| 585 | } while (j !== k.next);
|
|---|
| 586 |
|
|---|
| 587 | // Success! Insert the new circle c between a and b.
|
|---|
| 588 | c.previous = a, c.next = b, a.next = b.previous = b = c;
|
|---|
| 589 |
|
|---|
| 590 | // Compute the new closest circle pair to the centroid.
|
|---|
| 591 | aa = score(a);
|
|---|
| 592 | while ((c = c.next) !== b) {
|
|---|
| 593 | if ((ca = score(c)) < aa) {
|
|---|
| 594 | a = c, aa = ca;
|
|---|
| 595 | }
|
|---|
| 596 | }
|
|---|
| 597 | b = a.next;
|
|---|
| 598 | }
|
|---|
| 599 |
|
|---|
| 600 | // Compute the enclosing circle of the front chain.
|
|---|
| 601 | a = [b._], c = b; while ((c = c.next) !== b) a.push(c._); c = packEncloseRandom(a, random);
|
|---|
| 602 |
|
|---|
| 603 | // Translate the circles to put the enclosing circle around the origin.
|
|---|
| 604 | for (i = 0; i < n; ++i) a = circles[i], a.x -= c.x, a.y -= c.y;
|
|---|
| 605 |
|
|---|
| 606 | return c.r;
|
|---|
| 607 | }
|
|---|
| 608 |
|
|---|
| 609 | function siblings(circles) {
|
|---|
| 610 | packSiblingsRandom(circles, lcg());
|
|---|
| 611 | return circles;
|
|---|
| 612 | }
|
|---|
| 613 |
|
|---|
| 614 | function defaultRadius(d) {
|
|---|
| 615 | return Math.sqrt(d.value);
|
|---|
| 616 | }
|
|---|
| 617 |
|
|---|
| 618 | function index$1() {
|
|---|
| 619 | var radius = null,
|
|---|
| 620 | dx = 1,
|
|---|
| 621 | dy = 1,
|
|---|
| 622 | padding = constantZero;
|
|---|
| 623 |
|
|---|
| 624 | function pack(root) {
|
|---|
| 625 | const random = lcg();
|
|---|
| 626 | root.x = dx / 2, root.y = dy / 2;
|
|---|
| 627 | if (radius) {
|
|---|
| 628 | root.eachBefore(radiusLeaf(radius))
|
|---|
| 629 | .eachAfter(packChildrenRandom(padding, 0.5, random))
|
|---|
| 630 | .eachBefore(translateChild(1));
|
|---|
| 631 | } else {
|
|---|
| 632 | root.eachBefore(radiusLeaf(defaultRadius))
|
|---|
| 633 | .eachAfter(packChildrenRandom(constantZero, 1, random))
|
|---|
| 634 | .eachAfter(packChildrenRandom(padding, root.r / Math.min(dx, dy), random))
|
|---|
| 635 | .eachBefore(translateChild(Math.min(dx, dy) / (2 * root.r)));
|
|---|
| 636 | }
|
|---|
| 637 | return root;
|
|---|
| 638 | }
|
|---|
| 639 |
|
|---|
| 640 | pack.radius = function(x) {
|
|---|
| 641 | return arguments.length ? (radius = optional(x), pack) : radius;
|
|---|
| 642 | };
|
|---|
| 643 |
|
|---|
| 644 | pack.size = function(x) {
|
|---|
| 645 | return arguments.length ? (dx = +x[0], dy = +x[1], pack) : [dx, dy];
|
|---|
| 646 | };
|
|---|
| 647 |
|
|---|
| 648 | pack.padding = function(x) {
|
|---|
| 649 | return arguments.length ? (padding = typeof x === "function" ? x : constant(+x), pack) : padding;
|
|---|
| 650 | };
|
|---|
| 651 |
|
|---|
| 652 | return pack;
|
|---|
| 653 | }
|
|---|
| 654 |
|
|---|
| 655 | function radiusLeaf(radius) {
|
|---|
| 656 | return function(node) {
|
|---|
| 657 | if (!node.children) {
|
|---|
| 658 | node.r = Math.max(0, +radius(node) || 0);
|
|---|
| 659 | }
|
|---|
| 660 | };
|
|---|
| 661 | }
|
|---|
| 662 |
|
|---|
| 663 | function packChildrenRandom(padding, k, random) {
|
|---|
| 664 | return function(node) {
|
|---|
| 665 | if (children = node.children) {
|
|---|
| 666 | var children,
|
|---|
| 667 | i,
|
|---|
| 668 | n = children.length,
|
|---|
| 669 | r = padding(node) * k || 0,
|
|---|
| 670 | e;
|
|---|
| 671 |
|
|---|
| 672 | if (r) for (i = 0; i < n; ++i) children[i].r += r;
|
|---|
| 673 | e = packSiblingsRandom(children, random);
|
|---|
| 674 | if (r) for (i = 0; i < n; ++i) children[i].r -= r;
|
|---|
| 675 | node.r = e + r;
|
|---|
| 676 | }
|
|---|
| 677 | };
|
|---|
| 678 | }
|
|---|
| 679 |
|
|---|
| 680 | function translateChild(k) {
|
|---|
| 681 | return function(node) {
|
|---|
| 682 | var parent = node.parent;
|
|---|
| 683 | node.r *= k;
|
|---|
| 684 | if (parent) {
|
|---|
| 685 | node.x = parent.x + k * node.x;
|
|---|
| 686 | node.y = parent.y + k * node.y;
|
|---|
| 687 | }
|
|---|
| 688 | };
|
|---|
| 689 | }
|
|---|
| 690 |
|
|---|
| 691 | function roundNode(node) {
|
|---|
| 692 | node.x0 = Math.round(node.x0);
|
|---|
| 693 | node.y0 = Math.round(node.y0);
|
|---|
| 694 | node.x1 = Math.round(node.x1);
|
|---|
| 695 | node.y1 = Math.round(node.y1);
|
|---|
| 696 | }
|
|---|
| 697 |
|
|---|
| 698 | function treemapDice(parent, x0, y0, x1, y1) {
|
|---|
| 699 | var nodes = parent.children,
|
|---|
| 700 | node,
|
|---|
| 701 | i = -1,
|
|---|
| 702 | n = nodes.length,
|
|---|
| 703 | k = parent.value && (x1 - x0) / parent.value;
|
|---|
| 704 |
|
|---|
| 705 | while (++i < n) {
|
|---|
| 706 | node = nodes[i], node.y0 = y0, node.y1 = y1;
|
|---|
| 707 | node.x0 = x0, node.x1 = x0 += node.value * k;
|
|---|
| 708 | }
|
|---|
| 709 | }
|
|---|
| 710 |
|
|---|
| 711 | function partition() {
|
|---|
| 712 | var dx = 1,
|
|---|
| 713 | dy = 1,
|
|---|
| 714 | padding = 0,
|
|---|
| 715 | round = false;
|
|---|
| 716 |
|
|---|
| 717 | function partition(root) {
|
|---|
| 718 | var n = root.height + 1;
|
|---|
| 719 | root.x0 =
|
|---|
| 720 | root.y0 = padding;
|
|---|
| 721 | root.x1 = dx;
|
|---|
| 722 | root.y1 = dy / n;
|
|---|
| 723 | root.eachBefore(positionNode(dy, n));
|
|---|
| 724 | if (round) root.eachBefore(roundNode);
|
|---|
| 725 | return root;
|
|---|
| 726 | }
|
|---|
| 727 |
|
|---|
| 728 | function positionNode(dy, n) {
|
|---|
| 729 | return function(node) {
|
|---|
| 730 | if (node.children) {
|
|---|
| 731 | treemapDice(node, node.x0, dy * (node.depth + 1) / n, node.x1, dy * (node.depth + 2) / n);
|
|---|
| 732 | }
|
|---|
| 733 | var x0 = node.x0,
|
|---|
| 734 | y0 = node.y0,
|
|---|
| 735 | x1 = node.x1 - padding,
|
|---|
| 736 | y1 = node.y1 - padding;
|
|---|
| 737 | if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
|
|---|
| 738 | if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
|
|---|
| 739 | node.x0 = x0;
|
|---|
| 740 | node.y0 = y0;
|
|---|
| 741 | node.x1 = x1;
|
|---|
| 742 | node.y1 = y1;
|
|---|
| 743 | };
|
|---|
| 744 | }
|
|---|
| 745 |
|
|---|
| 746 | partition.round = function(x) {
|
|---|
| 747 | return arguments.length ? (round = !!x, partition) : round;
|
|---|
| 748 | };
|
|---|
| 749 |
|
|---|
| 750 | partition.size = function(x) {
|
|---|
| 751 | return arguments.length ? (dx = +x[0], dy = +x[1], partition) : [dx, dy];
|
|---|
| 752 | };
|
|---|
| 753 |
|
|---|
| 754 | partition.padding = function(x) {
|
|---|
| 755 | return arguments.length ? (padding = +x, partition) : padding;
|
|---|
| 756 | };
|
|---|
| 757 |
|
|---|
| 758 | return partition;
|
|---|
| 759 | }
|
|---|
| 760 |
|
|---|
| 761 | var preroot = {depth: -1},
|
|---|
| 762 | ambiguous = {},
|
|---|
| 763 | imputed = {};
|
|---|
| 764 |
|
|---|
| 765 | function defaultId(d) {
|
|---|
| 766 | return d.id;
|
|---|
| 767 | }
|
|---|
| 768 |
|
|---|
| 769 | function defaultParentId(d) {
|
|---|
| 770 | return d.parentId;
|
|---|
| 771 | }
|
|---|
| 772 |
|
|---|
| 773 | function stratify() {
|
|---|
| 774 | var id = defaultId,
|
|---|
| 775 | parentId = defaultParentId,
|
|---|
| 776 | path;
|
|---|
| 777 |
|
|---|
| 778 | function stratify(data) {
|
|---|
| 779 | var nodes = Array.from(data),
|
|---|
| 780 | currentId = id,
|
|---|
| 781 | currentParentId = parentId,
|
|---|
| 782 | n,
|
|---|
| 783 | d,
|
|---|
| 784 | i,
|
|---|
| 785 | root,
|
|---|
| 786 | parent,
|
|---|
| 787 | node,
|
|---|
| 788 | nodeId,
|
|---|
| 789 | nodeKey,
|
|---|
| 790 | nodeByKey = new Map;
|
|---|
| 791 |
|
|---|
| 792 | if (path != null) {
|
|---|
| 793 | const I = nodes.map((d, i) => normalize(path(d, i, data)));
|
|---|
| 794 | const P = I.map(parentof);
|
|---|
| 795 | const S = new Set(I).add("");
|
|---|
| 796 | for (const i of P) {
|
|---|
| 797 | if (!S.has(i)) {
|
|---|
| 798 | S.add(i);
|
|---|
| 799 | I.push(i);
|
|---|
| 800 | P.push(parentof(i));
|
|---|
| 801 | nodes.push(imputed);
|
|---|
| 802 | }
|
|---|
| 803 | }
|
|---|
| 804 | currentId = (_, i) => I[i];
|
|---|
| 805 | currentParentId = (_, i) => P[i];
|
|---|
| 806 | }
|
|---|
| 807 |
|
|---|
| 808 | for (i = 0, n = nodes.length; i < n; ++i) {
|
|---|
| 809 | d = nodes[i], node = nodes[i] = new Node$1(d);
|
|---|
| 810 | if ((nodeId = currentId(d, i, data)) != null && (nodeId += "")) {
|
|---|
| 811 | nodeKey = node.id = nodeId;
|
|---|
| 812 | nodeByKey.set(nodeKey, nodeByKey.has(nodeKey) ? ambiguous : node);
|
|---|
| 813 | }
|
|---|
| 814 | if ((nodeId = currentParentId(d, i, data)) != null && (nodeId += "")) {
|
|---|
| 815 | node.parent = nodeId;
|
|---|
| 816 | }
|
|---|
| 817 | }
|
|---|
| 818 |
|
|---|
| 819 | for (i = 0; i < n; ++i) {
|
|---|
| 820 | node = nodes[i];
|
|---|
| 821 | if (nodeId = node.parent) {
|
|---|
| 822 | parent = nodeByKey.get(nodeId);
|
|---|
| 823 | if (!parent) throw new Error("missing: " + nodeId);
|
|---|
| 824 | if (parent === ambiguous) throw new Error("ambiguous: " + nodeId);
|
|---|
| 825 | if (parent.children) parent.children.push(node);
|
|---|
| 826 | else parent.children = [node];
|
|---|
| 827 | node.parent = parent;
|
|---|
| 828 | } else {
|
|---|
| 829 | if (root) throw new Error("multiple roots");
|
|---|
| 830 | root = node;
|
|---|
| 831 | }
|
|---|
| 832 | }
|
|---|
| 833 |
|
|---|
| 834 | if (!root) throw new Error("no root");
|
|---|
| 835 |
|
|---|
| 836 | // When imputing internal nodes, only introduce roots if needed.
|
|---|
| 837 | // Then replace the imputed marker data with null.
|
|---|
| 838 | if (path != null) {
|
|---|
| 839 | while (root.data === imputed && root.children.length === 1) {
|
|---|
| 840 | root = root.children[0], --n;
|
|---|
| 841 | }
|
|---|
| 842 | for (let i = nodes.length - 1; i >= 0; --i) {
|
|---|
| 843 | node = nodes[i];
|
|---|
| 844 | if (node.data !== imputed) break;
|
|---|
| 845 | node.data = null;
|
|---|
| 846 | }
|
|---|
| 847 | }
|
|---|
| 848 |
|
|---|
| 849 | root.parent = preroot;
|
|---|
| 850 | root.eachBefore(function(node) { node.depth = node.parent.depth + 1; --n; }).eachBefore(computeHeight);
|
|---|
| 851 | root.parent = null;
|
|---|
| 852 | if (n > 0) throw new Error("cycle");
|
|---|
| 853 |
|
|---|
| 854 | return root;
|
|---|
| 855 | }
|
|---|
| 856 |
|
|---|
| 857 | stratify.id = function(x) {
|
|---|
| 858 | return arguments.length ? (id = optional(x), stratify) : id;
|
|---|
| 859 | };
|
|---|
| 860 |
|
|---|
| 861 | stratify.parentId = function(x) {
|
|---|
| 862 | return arguments.length ? (parentId = optional(x), stratify) : parentId;
|
|---|
| 863 | };
|
|---|
| 864 |
|
|---|
| 865 | stratify.path = function(x) {
|
|---|
| 866 | return arguments.length ? (path = optional(x), stratify) : path;
|
|---|
| 867 | };
|
|---|
| 868 |
|
|---|
| 869 | return stratify;
|
|---|
| 870 | }
|
|---|
| 871 |
|
|---|
| 872 | // To normalize a path, we coerce to a string, strip the trailing slash if any
|
|---|
| 873 | // (as long as the trailing slash is not immediately preceded by another slash),
|
|---|
| 874 | // and add leading slash if missing.
|
|---|
| 875 | function normalize(path) {
|
|---|
| 876 | path = `${path}`;
|
|---|
| 877 | let i = path.length;
|
|---|
| 878 | if (slash(path, i - 1) && !slash(path, i - 2)) path = path.slice(0, -1);
|
|---|
| 879 | return path[0] === "/" ? path : `/${path}`;
|
|---|
| 880 | }
|
|---|
| 881 |
|
|---|
| 882 | // Walk backwards to find the first slash that is not the leading slash, e.g.:
|
|---|
| 883 | // "/foo/bar" ⇥ "/foo", "/foo" ⇥ "/", "/" ↦ "". (The root is special-cased
|
|---|
| 884 | // because the id of the root must be a truthy value.)
|
|---|
| 885 | function parentof(path) {
|
|---|
| 886 | let i = path.length;
|
|---|
| 887 | if (i < 2) return "";
|
|---|
| 888 | while (--i > 1) if (slash(path, i)) break;
|
|---|
| 889 | return path.slice(0, i);
|
|---|
| 890 | }
|
|---|
| 891 |
|
|---|
| 892 | // Slashes can be escaped; to determine whether a slash is a path delimiter, we
|
|---|
| 893 | // count the number of preceding backslashes escaping the forward slash: an odd
|
|---|
| 894 | // number indicates an escaped forward slash.
|
|---|
| 895 | function slash(path, i) {
|
|---|
| 896 | if (path[i] === "/") {
|
|---|
| 897 | let k = 0;
|
|---|
| 898 | while (i > 0 && path[--i] === "\\") ++k;
|
|---|
| 899 | if ((k & 1) === 0) return true;
|
|---|
| 900 | }
|
|---|
| 901 | return false;
|
|---|
| 902 | }
|
|---|
| 903 |
|
|---|
| 904 | function defaultSeparation(a, b) {
|
|---|
| 905 | return a.parent === b.parent ? 1 : 2;
|
|---|
| 906 | }
|
|---|
| 907 |
|
|---|
| 908 | // function radialSeparation(a, b) {
|
|---|
| 909 | // return (a.parent === b.parent ? 1 : 2) / a.depth;
|
|---|
| 910 | // }
|
|---|
| 911 |
|
|---|
| 912 | // This function is used to traverse the left contour of a subtree (or
|
|---|
| 913 | // subforest). It returns the successor of v on this contour. This successor is
|
|---|
| 914 | // either given by the leftmost child of v or by the thread of v. The function
|
|---|
| 915 | // returns null if and only if v is on the highest level of its subtree.
|
|---|
| 916 | function nextLeft(v) {
|
|---|
| 917 | var children = v.children;
|
|---|
| 918 | return children ? children[0] : v.t;
|
|---|
| 919 | }
|
|---|
| 920 |
|
|---|
| 921 | // This function works analogously to nextLeft.
|
|---|
| 922 | function nextRight(v) {
|
|---|
| 923 | var children = v.children;
|
|---|
| 924 | return children ? children[children.length - 1] : v.t;
|
|---|
| 925 | }
|
|---|
| 926 |
|
|---|
| 927 | // Shifts the current subtree rooted at w+. This is done by increasing
|
|---|
| 928 | // prelim(w+) and mod(w+) by shift.
|
|---|
| 929 | function moveSubtree(wm, wp, shift) {
|
|---|
| 930 | var change = shift / (wp.i - wm.i);
|
|---|
| 931 | wp.c -= change;
|
|---|
| 932 | wp.s += shift;
|
|---|
| 933 | wm.c += change;
|
|---|
| 934 | wp.z += shift;
|
|---|
| 935 | wp.m += shift;
|
|---|
| 936 | }
|
|---|
| 937 |
|
|---|
| 938 | // All other shifts, applied to the smaller subtrees between w- and w+, are
|
|---|
| 939 | // performed by this function. To prepare the shifts, we have to adjust
|
|---|
| 940 | // change(w+), shift(w+), and change(w-).
|
|---|
| 941 | function executeShifts(v) {
|
|---|
| 942 | var shift = 0,
|
|---|
| 943 | change = 0,
|
|---|
| 944 | children = v.children,
|
|---|
| 945 | i = children.length,
|
|---|
| 946 | w;
|
|---|
| 947 | while (--i >= 0) {
|
|---|
| 948 | w = children[i];
|
|---|
| 949 | w.z += shift;
|
|---|
| 950 | w.m += shift;
|
|---|
| 951 | shift += w.s + (change += w.c);
|
|---|
| 952 | }
|
|---|
| 953 | }
|
|---|
| 954 |
|
|---|
| 955 | // If vi-’s ancestor is a sibling of v, returns vi-’s ancestor. Otherwise,
|
|---|
| 956 | // returns the specified (default) ancestor.
|
|---|
| 957 | function nextAncestor(vim, v, ancestor) {
|
|---|
| 958 | return vim.a.parent === v.parent ? vim.a : ancestor;
|
|---|
| 959 | }
|
|---|
| 960 |
|
|---|
| 961 | function TreeNode(node, i) {
|
|---|
| 962 | this._ = node;
|
|---|
| 963 | this.parent = null;
|
|---|
| 964 | this.children = null;
|
|---|
| 965 | this.A = null; // default ancestor
|
|---|
| 966 | this.a = this; // ancestor
|
|---|
| 967 | this.z = 0; // prelim
|
|---|
| 968 | this.m = 0; // mod
|
|---|
| 969 | this.c = 0; // change
|
|---|
| 970 | this.s = 0; // shift
|
|---|
| 971 | this.t = null; // thread
|
|---|
| 972 | this.i = i; // number
|
|---|
| 973 | }
|
|---|
| 974 |
|
|---|
| 975 | TreeNode.prototype = Object.create(Node$1.prototype);
|
|---|
| 976 |
|
|---|
| 977 | function treeRoot(root) {
|
|---|
| 978 | var tree = new TreeNode(root, 0),
|
|---|
| 979 | node,
|
|---|
| 980 | nodes = [tree],
|
|---|
| 981 | child,
|
|---|
| 982 | children,
|
|---|
| 983 | i,
|
|---|
| 984 | n;
|
|---|
| 985 |
|
|---|
| 986 | while (node = nodes.pop()) {
|
|---|
| 987 | if (children = node._.children) {
|
|---|
| 988 | node.children = new Array(n = children.length);
|
|---|
| 989 | for (i = n - 1; i >= 0; --i) {
|
|---|
| 990 | nodes.push(child = node.children[i] = new TreeNode(children[i], i));
|
|---|
| 991 | child.parent = node;
|
|---|
| 992 | }
|
|---|
| 993 | }
|
|---|
| 994 | }
|
|---|
| 995 |
|
|---|
| 996 | (tree.parent = new TreeNode(null, 0)).children = [tree];
|
|---|
| 997 | return tree;
|
|---|
| 998 | }
|
|---|
| 999 |
|
|---|
| 1000 | // Node-link tree diagram using the Reingold-Tilford "tidy" algorithm
|
|---|
| 1001 | function tree() {
|
|---|
| 1002 | var separation = defaultSeparation,
|
|---|
| 1003 | dx = 1,
|
|---|
| 1004 | dy = 1,
|
|---|
| 1005 | nodeSize = null;
|
|---|
| 1006 |
|
|---|
| 1007 | function tree(root) {
|
|---|
| 1008 | var t = treeRoot(root);
|
|---|
| 1009 |
|
|---|
| 1010 | // Compute the layout using Buchheim et al.’s algorithm.
|
|---|
| 1011 | t.eachAfter(firstWalk), t.parent.m = -t.z;
|
|---|
| 1012 | t.eachBefore(secondWalk);
|
|---|
| 1013 |
|
|---|
| 1014 | // If a fixed node size is specified, scale x and y.
|
|---|
| 1015 | if (nodeSize) root.eachBefore(sizeNode);
|
|---|
| 1016 |
|
|---|
| 1017 | // If a fixed tree size is specified, scale x and y based on the extent.
|
|---|
| 1018 | // Compute the left-most, right-most, and depth-most nodes for extents.
|
|---|
| 1019 | else {
|
|---|
| 1020 | var left = root,
|
|---|
| 1021 | right = root,
|
|---|
| 1022 | bottom = root;
|
|---|
| 1023 | root.eachBefore(function(node) {
|
|---|
| 1024 | if (node.x < left.x) left = node;
|
|---|
| 1025 | if (node.x > right.x) right = node;
|
|---|
| 1026 | if (node.depth > bottom.depth) bottom = node;
|
|---|
| 1027 | });
|
|---|
| 1028 | var s = left === right ? 1 : separation(left, right) / 2,
|
|---|
| 1029 | tx = s - left.x,
|
|---|
| 1030 | kx = dx / (right.x + s + tx),
|
|---|
| 1031 | ky = dy / (bottom.depth || 1);
|
|---|
| 1032 | root.eachBefore(function(node) {
|
|---|
| 1033 | node.x = (node.x + tx) * kx;
|
|---|
| 1034 | node.y = node.depth * ky;
|
|---|
| 1035 | });
|
|---|
| 1036 | }
|
|---|
| 1037 |
|
|---|
| 1038 | return root;
|
|---|
| 1039 | }
|
|---|
| 1040 |
|
|---|
| 1041 | // Computes a preliminary x-coordinate for v. Before that, FIRST WALK is
|
|---|
| 1042 | // applied recursively to the children of v, as well as the function
|
|---|
| 1043 | // APPORTION. After spacing out the children by calling EXECUTE SHIFTS, the
|
|---|
| 1044 | // node v is placed to the midpoint of its outermost children.
|
|---|
| 1045 | function firstWalk(v) {
|
|---|
| 1046 | var children = v.children,
|
|---|
| 1047 | siblings = v.parent.children,
|
|---|
| 1048 | w = v.i ? siblings[v.i - 1] : null;
|
|---|
| 1049 | if (children) {
|
|---|
| 1050 | executeShifts(v);
|
|---|
| 1051 | var midpoint = (children[0].z + children[children.length - 1].z) / 2;
|
|---|
| 1052 | if (w) {
|
|---|
| 1053 | v.z = w.z + separation(v._, w._);
|
|---|
| 1054 | v.m = v.z - midpoint;
|
|---|
| 1055 | } else {
|
|---|
| 1056 | v.z = midpoint;
|
|---|
| 1057 | }
|
|---|
| 1058 | } else if (w) {
|
|---|
| 1059 | v.z = w.z + separation(v._, w._);
|
|---|
| 1060 | }
|
|---|
| 1061 | v.parent.A = apportion(v, w, v.parent.A || siblings[0]);
|
|---|
| 1062 | }
|
|---|
| 1063 |
|
|---|
| 1064 | // Computes all real x-coordinates by summing up the modifiers recursively.
|
|---|
| 1065 | function secondWalk(v) {
|
|---|
| 1066 | v._.x = v.z + v.parent.m;
|
|---|
| 1067 | v.m += v.parent.m;
|
|---|
| 1068 | }
|
|---|
| 1069 |
|
|---|
| 1070 | // The core of the algorithm. Here, a new subtree is combined with the
|
|---|
| 1071 | // previous subtrees. Threads are used to traverse the inside and outside
|
|---|
| 1072 | // contours of the left and right subtree up to the highest common level. The
|
|---|
| 1073 | // vertices used for the traversals are vi+, vi-, vo-, and vo+, where the
|
|---|
| 1074 | // superscript o means outside and i means inside, the subscript - means left
|
|---|
| 1075 | // subtree and + means right subtree. For summing up the modifiers along the
|
|---|
| 1076 | // contour, we use respective variables si+, si-, so-, and so+. Whenever two
|
|---|
| 1077 | // nodes of the inside contours conflict, we compute the left one of the
|
|---|
| 1078 | // greatest uncommon ancestors using the function ANCESTOR and call MOVE
|
|---|
| 1079 | // SUBTREE to shift the subtree and prepare the shifts of smaller subtrees.
|
|---|
| 1080 | // Finally, we add a new thread (if necessary).
|
|---|
| 1081 | function apportion(v, w, ancestor) {
|
|---|
| 1082 | if (w) {
|
|---|
| 1083 | var vip = v,
|
|---|
| 1084 | vop = v,
|
|---|
| 1085 | vim = w,
|
|---|
| 1086 | vom = vip.parent.children[0],
|
|---|
| 1087 | sip = vip.m,
|
|---|
| 1088 | sop = vop.m,
|
|---|
| 1089 | sim = vim.m,
|
|---|
| 1090 | som = vom.m,
|
|---|
| 1091 | shift;
|
|---|
| 1092 | while (vim = nextRight(vim), vip = nextLeft(vip), vim && vip) {
|
|---|
| 1093 | vom = nextLeft(vom);
|
|---|
| 1094 | vop = nextRight(vop);
|
|---|
| 1095 | vop.a = v;
|
|---|
| 1096 | shift = vim.z + sim - vip.z - sip + separation(vim._, vip._);
|
|---|
| 1097 | if (shift > 0) {
|
|---|
| 1098 | moveSubtree(nextAncestor(vim, v, ancestor), v, shift);
|
|---|
| 1099 | sip += shift;
|
|---|
| 1100 | sop += shift;
|
|---|
| 1101 | }
|
|---|
| 1102 | sim += vim.m;
|
|---|
| 1103 | sip += vip.m;
|
|---|
| 1104 | som += vom.m;
|
|---|
| 1105 | sop += vop.m;
|
|---|
| 1106 | }
|
|---|
| 1107 | if (vim && !nextRight(vop)) {
|
|---|
| 1108 | vop.t = vim;
|
|---|
| 1109 | vop.m += sim - sop;
|
|---|
| 1110 | }
|
|---|
| 1111 | if (vip && !nextLeft(vom)) {
|
|---|
| 1112 | vom.t = vip;
|
|---|
| 1113 | vom.m += sip - som;
|
|---|
| 1114 | ancestor = v;
|
|---|
| 1115 | }
|
|---|
| 1116 | }
|
|---|
| 1117 | return ancestor;
|
|---|
| 1118 | }
|
|---|
| 1119 |
|
|---|
| 1120 | function sizeNode(node) {
|
|---|
| 1121 | node.x *= dx;
|
|---|
| 1122 | node.y = node.depth * dy;
|
|---|
| 1123 | }
|
|---|
| 1124 |
|
|---|
| 1125 | tree.separation = function(x) {
|
|---|
| 1126 | return arguments.length ? (separation = x, tree) : separation;
|
|---|
| 1127 | };
|
|---|
| 1128 |
|
|---|
| 1129 | tree.size = function(x) {
|
|---|
| 1130 | return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], tree) : (nodeSize ? null : [dx, dy]);
|
|---|
| 1131 | };
|
|---|
| 1132 |
|
|---|
| 1133 | tree.nodeSize = function(x) {
|
|---|
| 1134 | return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], tree) : (nodeSize ? [dx, dy] : null);
|
|---|
| 1135 | };
|
|---|
| 1136 |
|
|---|
| 1137 | return tree;
|
|---|
| 1138 | }
|
|---|
| 1139 |
|
|---|
| 1140 | function treemapSlice(parent, x0, y0, x1, y1) {
|
|---|
| 1141 | var nodes = parent.children,
|
|---|
| 1142 | node,
|
|---|
| 1143 | i = -1,
|
|---|
| 1144 | n = nodes.length,
|
|---|
| 1145 | k = parent.value && (y1 - y0) / parent.value;
|
|---|
| 1146 |
|
|---|
| 1147 | while (++i < n) {
|
|---|
| 1148 | node = nodes[i], node.x0 = x0, node.x1 = x1;
|
|---|
| 1149 | node.y0 = y0, node.y1 = y0 += node.value * k;
|
|---|
| 1150 | }
|
|---|
| 1151 | }
|
|---|
| 1152 |
|
|---|
| 1153 | var phi = (1 + Math.sqrt(5)) / 2;
|
|---|
| 1154 |
|
|---|
| 1155 | function squarifyRatio(ratio, parent, x0, y0, x1, y1) {
|
|---|
| 1156 | var rows = [],
|
|---|
| 1157 | nodes = parent.children,
|
|---|
| 1158 | row,
|
|---|
| 1159 | nodeValue,
|
|---|
| 1160 | i0 = 0,
|
|---|
| 1161 | i1 = 0,
|
|---|
| 1162 | n = nodes.length,
|
|---|
| 1163 | dx, dy,
|
|---|
| 1164 | value = parent.value,
|
|---|
| 1165 | sumValue,
|
|---|
| 1166 | minValue,
|
|---|
| 1167 | maxValue,
|
|---|
| 1168 | newRatio,
|
|---|
| 1169 | minRatio,
|
|---|
| 1170 | alpha,
|
|---|
| 1171 | beta;
|
|---|
| 1172 |
|
|---|
| 1173 | while (i0 < n) {
|
|---|
| 1174 | dx = x1 - x0, dy = y1 - y0;
|
|---|
| 1175 |
|
|---|
| 1176 | // Find the next non-empty node.
|
|---|
| 1177 | do sumValue = nodes[i1++].value; while (!sumValue && i1 < n);
|
|---|
| 1178 | minValue = maxValue = sumValue;
|
|---|
| 1179 | alpha = Math.max(dy / dx, dx / dy) / (value * ratio);
|
|---|
| 1180 | beta = sumValue * sumValue * alpha;
|
|---|
| 1181 | minRatio = Math.max(maxValue / beta, beta / minValue);
|
|---|
| 1182 |
|
|---|
| 1183 | // Keep adding nodes while the aspect ratio maintains or improves.
|
|---|
| 1184 | for (; i1 < n; ++i1) {
|
|---|
| 1185 | sumValue += nodeValue = nodes[i1].value;
|
|---|
| 1186 | if (nodeValue < minValue) minValue = nodeValue;
|
|---|
| 1187 | if (nodeValue > maxValue) maxValue = nodeValue;
|
|---|
| 1188 | beta = sumValue * sumValue * alpha;
|
|---|
| 1189 | newRatio = Math.max(maxValue / beta, beta / minValue);
|
|---|
| 1190 | if (newRatio > minRatio) { sumValue -= nodeValue; break; }
|
|---|
| 1191 | minRatio = newRatio;
|
|---|
| 1192 | }
|
|---|
| 1193 |
|
|---|
| 1194 | // Position and record the row orientation.
|
|---|
| 1195 | rows.push(row = {value: sumValue, dice: dx < dy, children: nodes.slice(i0, i1)});
|
|---|
| 1196 | if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1);
|
|---|
| 1197 | else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1);
|
|---|
| 1198 | value -= sumValue, i0 = i1;
|
|---|
| 1199 | }
|
|---|
| 1200 |
|
|---|
| 1201 | return rows;
|
|---|
| 1202 | }
|
|---|
| 1203 |
|
|---|
| 1204 | var squarify = (function custom(ratio) {
|
|---|
| 1205 |
|
|---|
| 1206 | function squarify(parent, x0, y0, x1, y1) {
|
|---|
| 1207 | squarifyRatio(ratio, parent, x0, y0, x1, y1);
|
|---|
| 1208 | }
|
|---|
| 1209 |
|
|---|
| 1210 | squarify.ratio = function(x) {
|
|---|
| 1211 | return custom((x = +x) > 1 ? x : 1);
|
|---|
| 1212 | };
|
|---|
| 1213 |
|
|---|
| 1214 | return squarify;
|
|---|
| 1215 | })(phi);
|
|---|
| 1216 |
|
|---|
| 1217 | function index() {
|
|---|
| 1218 | var tile = squarify,
|
|---|
| 1219 | round = false,
|
|---|
| 1220 | dx = 1,
|
|---|
| 1221 | dy = 1,
|
|---|
| 1222 | paddingStack = [0],
|
|---|
| 1223 | paddingInner = constantZero,
|
|---|
| 1224 | paddingTop = constantZero,
|
|---|
| 1225 | paddingRight = constantZero,
|
|---|
| 1226 | paddingBottom = constantZero,
|
|---|
| 1227 | paddingLeft = constantZero;
|
|---|
| 1228 |
|
|---|
| 1229 | function treemap(root) {
|
|---|
| 1230 | root.x0 =
|
|---|
| 1231 | root.y0 = 0;
|
|---|
| 1232 | root.x1 = dx;
|
|---|
| 1233 | root.y1 = dy;
|
|---|
| 1234 | root.eachBefore(positionNode);
|
|---|
| 1235 | paddingStack = [0];
|
|---|
| 1236 | if (round) root.eachBefore(roundNode);
|
|---|
| 1237 | return root;
|
|---|
| 1238 | }
|
|---|
| 1239 |
|
|---|
| 1240 | function positionNode(node) {
|
|---|
| 1241 | var p = paddingStack[node.depth],
|
|---|
| 1242 | x0 = node.x0 + p,
|
|---|
| 1243 | y0 = node.y0 + p,
|
|---|
| 1244 | x1 = node.x1 - p,
|
|---|
| 1245 | y1 = node.y1 - p;
|
|---|
| 1246 | if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
|
|---|
| 1247 | if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
|
|---|
| 1248 | node.x0 = x0;
|
|---|
| 1249 | node.y0 = y0;
|
|---|
| 1250 | node.x1 = x1;
|
|---|
| 1251 | node.y1 = y1;
|
|---|
| 1252 | if (node.children) {
|
|---|
| 1253 | p = paddingStack[node.depth + 1] = paddingInner(node) / 2;
|
|---|
| 1254 | x0 += paddingLeft(node) - p;
|
|---|
| 1255 | y0 += paddingTop(node) - p;
|
|---|
| 1256 | x1 -= paddingRight(node) - p;
|
|---|
| 1257 | y1 -= paddingBottom(node) - p;
|
|---|
| 1258 | if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
|
|---|
| 1259 | if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
|
|---|
| 1260 | tile(node, x0, y0, x1, y1);
|
|---|
| 1261 | }
|
|---|
| 1262 | }
|
|---|
| 1263 |
|
|---|
| 1264 | treemap.round = function(x) {
|
|---|
| 1265 | return arguments.length ? (round = !!x, treemap) : round;
|
|---|
| 1266 | };
|
|---|
| 1267 |
|
|---|
| 1268 | treemap.size = function(x) {
|
|---|
| 1269 | return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy];
|
|---|
| 1270 | };
|
|---|
| 1271 |
|
|---|
| 1272 | treemap.tile = function(x) {
|
|---|
| 1273 | return arguments.length ? (tile = required(x), treemap) : tile;
|
|---|
| 1274 | };
|
|---|
| 1275 |
|
|---|
| 1276 | treemap.padding = function(x) {
|
|---|
| 1277 | return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner();
|
|---|
| 1278 | };
|
|---|
| 1279 |
|
|---|
| 1280 | treemap.paddingInner = function(x) {
|
|---|
| 1281 | return arguments.length ? (paddingInner = typeof x === "function" ? x : constant(+x), treemap) : paddingInner;
|
|---|
| 1282 | };
|
|---|
| 1283 |
|
|---|
| 1284 | treemap.paddingOuter = function(x) {
|
|---|
| 1285 | return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop();
|
|---|
| 1286 | };
|
|---|
| 1287 |
|
|---|
| 1288 | treemap.paddingTop = function(x) {
|
|---|
| 1289 | return arguments.length ? (paddingTop = typeof x === "function" ? x : constant(+x), treemap) : paddingTop;
|
|---|
| 1290 | };
|
|---|
| 1291 |
|
|---|
| 1292 | treemap.paddingRight = function(x) {
|
|---|
| 1293 | return arguments.length ? (paddingRight = typeof x === "function" ? x : constant(+x), treemap) : paddingRight;
|
|---|
| 1294 | };
|
|---|
| 1295 |
|
|---|
| 1296 | treemap.paddingBottom = function(x) {
|
|---|
| 1297 | return arguments.length ? (paddingBottom = typeof x === "function" ? x : constant(+x), treemap) : paddingBottom;
|
|---|
| 1298 | };
|
|---|
| 1299 |
|
|---|
| 1300 | treemap.paddingLeft = function(x) {
|
|---|
| 1301 | return arguments.length ? (paddingLeft = typeof x === "function" ? x : constant(+x), treemap) : paddingLeft;
|
|---|
| 1302 | };
|
|---|
| 1303 |
|
|---|
| 1304 | return treemap;
|
|---|
| 1305 | }
|
|---|
| 1306 |
|
|---|
| 1307 | function binary(parent, x0, y0, x1, y1) {
|
|---|
| 1308 | var nodes = parent.children,
|
|---|
| 1309 | i, n = nodes.length,
|
|---|
| 1310 | sum, sums = new Array(n + 1);
|
|---|
| 1311 |
|
|---|
| 1312 | for (sums[0] = sum = i = 0; i < n; ++i) {
|
|---|
| 1313 | sums[i + 1] = sum += nodes[i].value;
|
|---|
| 1314 | }
|
|---|
| 1315 |
|
|---|
| 1316 | partition(0, n, parent.value, x0, y0, x1, y1);
|
|---|
| 1317 |
|
|---|
| 1318 | function partition(i, j, value, x0, y0, x1, y1) {
|
|---|
| 1319 | if (i >= j - 1) {
|
|---|
| 1320 | var node = nodes[i];
|
|---|
| 1321 | node.x0 = x0, node.y0 = y0;
|
|---|
| 1322 | node.x1 = x1, node.y1 = y1;
|
|---|
| 1323 | return;
|
|---|
| 1324 | }
|
|---|
| 1325 |
|
|---|
| 1326 | var valueOffset = sums[i],
|
|---|
| 1327 | valueTarget = (value / 2) + valueOffset,
|
|---|
| 1328 | k = i + 1,
|
|---|
| 1329 | hi = j - 1;
|
|---|
| 1330 |
|
|---|
| 1331 | while (k < hi) {
|
|---|
| 1332 | var mid = k + hi >>> 1;
|
|---|
| 1333 | if (sums[mid] < valueTarget) k = mid + 1;
|
|---|
| 1334 | else hi = mid;
|
|---|
| 1335 | }
|
|---|
| 1336 |
|
|---|
| 1337 | if ((valueTarget - sums[k - 1]) < (sums[k] - valueTarget) && i + 1 < k) --k;
|
|---|
| 1338 |
|
|---|
| 1339 | var valueLeft = sums[k] - valueOffset,
|
|---|
| 1340 | valueRight = value - valueLeft;
|
|---|
| 1341 |
|
|---|
| 1342 | if ((x1 - x0) > (y1 - y0)) {
|
|---|
| 1343 | var xk = value ? (x0 * valueRight + x1 * valueLeft) / value : x1;
|
|---|
| 1344 | partition(i, k, valueLeft, x0, y0, xk, y1);
|
|---|
| 1345 | partition(k, j, valueRight, xk, y0, x1, y1);
|
|---|
| 1346 | } else {
|
|---|
| 1347 | var yk = value ? (y0 * valueRight + y1 * valueLeft) / value : y1;
|
|---|
| 1348 | partition(i, k, valueLeft, x0, y0, x1, yk);
|
|---|
| 1349 | partition(k, j, valueRight, x0, yk, x1, y1);
|
|---|
| 1350 | }
|
|---|
| 1351 | }
|
|---|
| 1352 | }
|
|---|
| 1353 |
|
|---|
| 1354 | function sliceDice(parent, x0, y0, x1, y1) {
|
|---|
| 1355 | (parent.depth & 1 ? treemapSlice : treemapDice)(parent, x0, y0, x1, y1);
|
|---|
| 1356 | }
|
|---|
| 1357 |
|
|---|
| 1358 | var resquarify = (function custom(ratio) {
|
|---|
| 1359 |
|
|---|
| 1360 | function resquarify(parent, x0, y0, x1, y1) {
|
|---|
| 1361 | if ((rows = parent._squarify) && (rows.ratio === ratio)) {
|
|---|
| 1362 | var rows,
|
|---|
| 1363 | row,
|
|---|
| 1364 | nodes,
|
|---|
| 1365 | i,
|
|---|
| 1366 | j = -1,
|
|---|
| 1367 | n,
|
|---|
| 1368 | m = rows.length,
|
|---|
| 1369 | value = parent.value;
|
|---|
| 1370 |
|
|---|
| 1371 | while (++j < m) {
|
|---|
| 1372 | row = rows[j], nodes = row.children;
|
|---|
| 1373 | for (i = row.value = 0, n = nodes.length; i < n; ++i) row.value += nodes[i].value;
|
|---|
| 1374 | if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += (y1 - y0) * row.value / value : y1);
|
|---|
| 1375 | else treemapSlice(row, x0, y0, value ? x0 += (x1 - x0) * row.value / value : x1, y1);
|
|---|
| 1376 | value -= row.value;
|
|---|
| 1377 | }
|
|---|
| 1378 | } else {
|
|---|
| 1379 | parent._squarify = rows = squarifyRatio(ratio, parent, x0, y0, x1, y1);
|
|---|
| 1380 | rows.ratio = ratio;
|
|---|
| 1381 | }
|
|---|
| 1382 | }
|
|---|
| 1383 |
|
|---|
| 1384 | resquarify.ratio = function(x) {
|
|---|
| 1385 | return custom((x = +x) > 1 ? x : 1);
|
|---|
| 1386 | };
|
|---|
| 1387 |
|
|---|
| 1388 | return resquarify;
|
|---|
| 1389 | })(phi);
|
|---|
| 1390 |
|
|---|
| 1391 | exports.Node = Node$1;
|
|---|
| 1392 | exports.cluster = cluster;
|
|---|
| 1393 | exports.hierarchy = hierarchy;
|
|---|
| 1394 | exports.pack = index$1;
|
|---|
| 1395 | exports.packEnclose = enclose;
|
|---|
| 1396 | exports.packSiblings = siblings;
|
|---|
| 1397 | exports.partition = partition;
|
|---|
| 1398 | exports.stratify = stratify;
|
|---|
| 1399 | exports.tree = tree;
|
|---|
| 1400 | exports.treemap = index;
|
|---|
| 1401 | exports.treemapBinary = binary;
|
|---|
| 1402 | exports.treemapDice = treemapDice;
|
|---|
| 1403 | exports.treemapResquarify = resquarify;
|
|---|
| 1404 | exports.treemapSlice = treemapSlice;
|
|---|
| 1405 | exports.treemapSliceDice = sliceDice;
|
|---|
| 1406 | exports.treemapSquarify = squarify;
|
|---|
| 1407 |
|
|---|
| 1408 | Object.defineProperty(exports, '__esModule', { value: true });
|
|---|
| 1409 |
|
|---|
| 1410 | }));
|
|---|