| [e4c61dd] | 1 | import treemapDice from "./dice.js";
|
|---|
| 2 | import treemapSlice from "./slice.js";
|
|---|
| 3 |
|
|---|
| 4 | export var phi = (1 + Math.sqrt(5)) / 2;
|
|---|
| 5 |
|
|---|
| 6 | export function squarifyRatio(ratio, parent, x0, y0, x1, y1) {
|
|---|
| 7 | var rows = [],
|
|---|
| 8 | nodes = parent.children,
|
|---|
| 9 | row,
|
|---|
| 10 | nodeValue,
|
|---|
| 11 | i0 = 0,
|
|---|
| 12 | i1 = 0,
|
|---|
| 13 | n = nodes.length,
|
|---|
| 14 | dx, dy,
|
|---|
| 15 | value = parent.value,
|
|---|
| 16 | sumValue,
|
|---|
| 17 | minValue,
|
|---|
| 18 | maxValue,
|
|---|
| 19 | newRatio,
|
|---|
| 20 | minRatio,
|
|---|
| 21 | alpha,
|
|---|
| 22 | beta;
|
|---|
| 23 |
|
|---|
| 24 | while (i0 < n) {
|
|---|
| 25 | dx = x1 - x0, dy = y1 - y0;
|
|---|
| 26 |
|
|---|
| 27 | // Find the next non-empty node.
|
|---|
| 28 | do sumValue = nodes[i1++].value; while (!sumValue && i1 < n);
|
|---|
| 29 | minValue = maxValue = sumValue;
|
|---|
| 30 | alpha = Math.max(dy / dx, dx / dy) / (value * ratio);
|
|---|
| 31 | beta = sumValue * sumValue * alpha;
|
|---|
| 32 | minRatio = Math.max(maxValue / beta, beta / minValue);
|
|---|
| 33 |
|
|---|
| 34 | // Keep adding nodes while the aspect ratio maintains or improves.
|
|---|
| 35 | for (; i1 < n; ++i1) {
|
|---|
| 36 | sumValue += nodeValue = nodes[i1].value;
|
|---|
| 37 | if (nodeValue < minValue) minValue = nodeValue;
|
|---|
| 38 | if (nodeValue > maxValue) maxValue = nodeValue;
|
|---|
| 39 | beta = sumValue * sumValue * alpha;
|
|---|
| 40 | newRatio = Math.max(maxValue / beta, beta / minValue);
|
|---|
| 41 | if (newRatio > minRatio) { sumValue -= nodeValue; break; }
|
|---|
| 42 | minRatio = newRatio;
|
|---|
| 43 | }
|
|---|
| 44 |
|
|---|
| 45 | // Position and record the row orientation.
|
|---|
| 46 | rows.push(row = {value: sumValue, dice: dx < dy, children: nodes.slice(i0, i1)});
|
|---|
| 47 | if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1);
|
|---|
| 48 | else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1);
|
|---|
| 49 | value -= sumValue, i0 = i1;
|
|---|
| 50 | }
|
|---|
| 51 |
|
|---|
| 52 | return rows;
|
|---|
| 53 | }
|
|---|
| 54 |
|
|---|
| 55 | export default (function custom(ratio) {
|
|---|
| 56 |
|
|---|
| 57 | function squarify(parent, x0, y0, x1, y1) {
|
|---|
| 58 | squarifyRatio(ratio, parent, x0, y0, x1, y1);
|
|---|
| 59 | }
|
|---|
| 60 |
|
|---|
| 61 | squarify.ratio = function(x) {
|
|---|
| 62 | return custom((x = +x) > 1 ? x : 1);
|
|---|
| 63 | };
|
|---|
| 64 |
|
|---|
| 65 | return squarify;
|
|---|
| 66 | })(phi);
|
|---|