+66
@@ -0,0 +1,66 @@
|
||||
import treemapDice from "./dice.js";
|
||||
import treemapSlice from "./slice.js";
|
||||
|
||||
export var phi = (1 + Math.sqrt(5)) / 2;
|
||||
|
||||
export function squarifyRatio(ratio, parent, x0, y0, x1, y1) {
|
||||
var rows = [],
|
||||
nodes = parent.children,
|
||||
row,
|
||||
nodeValue,
|
||||
i0 = 0,
|
||||
i1 = 0,
|
||||
n = nodes.length,
|
||||
dx, dy,
|
||||
value = parent.value,
|
||||
sumValue,
|
||||
minValue,
|
||||
maxValue,
|
||||
newRatio,
|
||||
minRatio,
|
||||
alpha,
|
||||
beta;
|
||||
|
||||
while (i0 < n) {
|
||||
dx = x1 - x0, dy = y1 - y0;
|
||||
|
||||
// Find the next non-empty node.
|
||||
do sumValue = nodes[i1++].value; while (!sumValue && i1 < n);
|
||||
minValue = maxValue = sumValue;
|
||||
alpha = Math.max(dy / dx, dx / dy) / (value * ratio);
|
||||
beta = sumValue * sumValue * alpha;
|
||||
minRatio = Math.max(maxValue / beta, beta / minValue);
|
||||
|
||||
// Keep adding nodes while the aspect ratio maintains or improves.
|
||||
for (; i1 < n; ++i1) {
|
||||
sumValue += nodeValue = nodes[i1].value;
|
||||
if (nodeValue < minValue) minValue = nodeValue;
|
||||
if (nodeValue > maxValue) maxValue = nodeValue;
|
||||
beta = sumValue * sumValue * alpha;
|
||||
newRatio = Math.max(maxValue / beta, beta / minValue);
|
||||
if (newRatio > minRatio) { sumValue -= nodeValue; break; }
|
||||
minRatio = newRatio;
|
||||
}
|
||||
|
||||
// Position and record the row orientation.
|
||||
rows.push(row = {value: sumValue, dice: dx < dy, children: nodes.slice(i0, i1)});
|
||||
if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1);
|
||||
else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1);
|
||||
value -= sumValue, i0 = i1;
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
export default (function custom(ratio) {
|
||||
|
||||
function squarify(parent, x0, y0, x1, y1) {
|
||||
squarifyRatio(ratio, parent, x0, y0, x1, y1);
|
||||
}
|
||||
|
||||
squarify.ratio = function(x) {
|
||||
return custom((x = +x) > 1 ? x : 1);
|
||||
};
|
||||
|
||||
return squarify;
|
||||
})(phi);
|
||||
Reference in New Issue
Block a user