| [e4c61dd] | 1 | import {optional} from "../accessors.js";
|
|---|
| 2 | import constant, {constantZero} from "../constant.js";
|
|---|
| 3 | import lcg from "../lcg.js";
|
|---|
| 4 | import {packSiblingsRandom} from "./siblings.js";
|
|---|
| 5 |
|
|---|
| 6 | function defaultRadius(d) {
|
|---|
| 7 | return Math.sqrt(d.value);
|
|---|
| 8 | }
|
|---|
| 9 |
|
|---|
| 10 | export default function() {
|
|---|
| 11 | var radius = null,
|
|---|
| 12 | dx = 1,
|
|---|
| 13 | dy = 1,
|
|---|
| 14 | padding = constantZero;
|
|---|
| 15 |
|
|---|
| 16 | function pack(root) {
|
|---|
| 17 | const random = lcg();
|
|---|
| 18 | root.x = dx / 2, root.y = dy / 2;
|
|---|
| 19 | if (radius) {
|
|---|
| 20 | root.eachBefore(radiusLeaf(radius))
|
|---|
| 21 | .eachAfter(packChildrenRandom(padding, 0.5, random))
|
|---|
| 22 | .eachBefore(translateChild(1));
|
|---|
| 23 | } else {
|
|---|
| 24 | root.eachBefore(radiusLeaf(defaultRadius))
|
|---|
| 25 | .eachAfter(packChildrenRandom(constantZero, 1, random))
|
|---|
| 26 | .eachAfter(packChildrenRandom(padding, root.r / Math.min(dx, dy), random))
|
|---|
| 27 | .eachBefore(translateChild(Math.min(dx, dy) / (2 * root.r)));
|
|---|
| 28 | }
|
|---|
| 29 | return root;
|
|---|
| 30 | }
|
|---|
| 31 |
|
|---|
| 32 | pack.radius = function(x) {
|
|---|
| 33 | return arguments.length ? (radius = optional(x), pack) : radius;
|
|---|
| 34 | };
|
|---|
| 35 |
|
|---|
| 36 | pack.size = function(x) {
|
|---|
| 37 | return arguments.length ? (dx = +x[0], dy = +x[1], pack) : [dx, dy];
|
|---|
| 38 | };
|
|---|
| 39 |
|
|---|
| 40 | pack.padding = function(x) {
|
|---|
| 41 | return arguments.length ? (padding = typeof x === "function" ? x : constant(+x), pack) : padding;
|
|---|
| 42 | };
|
|---|
| 43 |
|
|---|
| 44 | return pack;
|
|---|
| 45 | }
|
|---|
| 46 |
|
|---|
| 47 | function radiusLeaf(radius) {
|
|---|
| 48 | return function(node) {
|
|---|
| 49 | if (!node.children) {
|
|---|
| 50 | node.r = Math.max(0, +radius(node) || 0);
|
|---|
| 51 | }
|
|---|
| 52 | };
|
|---|
| 53 | }
|
|---|
| 54 |
|
|---|
| 55 | function packChildrenRandom(padding, k, random) {
|
|---|
| 56 | return function(node) {
|
|---|
| 57 | if (children = node.children) {
|
|---|
| 58 | var children,
|
|---|
| 59 | i,
|
|---|
| 60 | n = children.length,
|
|---|
| 61 | r = padding(node) * k || 0,
|
|---|
| 62 | e;
|
|---|
| 63 |
|
|---|
| 64 | if (r) for (i = 0; i < n; ++i) children[i].r += r;
|
|---|
| 65 | e = packSiblingsRandom(children, random);
|
|---|
| 66 | if (r) for (i = 0; i < n; ++i) children[i].r -= r;
|
|---|
| 67 | node.r = e + r;
|
|---|
| 68 | }
|
|---|
| 69 | };
|
|---|
| 70 | }
|
|---|
| 71 |
|
|---|
| 72 | function translateChild(k) {
|
|---|
| 73 | return function(node) {
|
|---|
| 74 | var parent = node.parent;
|
|---|
| 75 | node.r *= k;
|
|---|
| 76 | if (parent) {
|
|---|
| 77 | node.x = parent.x + k * node.x;
|
|---|
| 78 | node.y = parent.y + k * node.y;
|
|---|
| 79 | }
|
|---|
| 80 | };
|
|---|
| 81 | }
|
|---|