scripts: treemap[d3].py: Squared --squarify, added --rectify

This adds --rectify for a parent-aspect-ratio-preserving --squarify
variant, reverting squarify to try to match the aspect ratio of a
square (1:1).

I can see arguments for both of these. On one hand --squarify makes the
squarest squares, which according to Mark Bruls et al's paper on the
topic is easier visually compare. On the other hand --rectify may be
more visually pleasing and fit into parent tiles better.

d3 allows for any ratio, but at the moment I'm not seeing a strong
reason for the extra parameter.
This commit is contained in:
Christopher Haster
2025-02-17 14:03:05 -06:00
parent 2135c6a003
commit 1c92b7e892
2 changed files with 48 additions and 8 deletions

View File

@@ -489,7 +489,16 @@ def partition_dice(children, total, x, y, width, height):
y_ += t.height
def partition_squarify(children, total, x, y, width, height):
def partition_squarify(children, total, x, y, width, height, *,
aspect_ratio=(1,1)):
if width == 0 or height == 0:
for t in children:
t.x = x
t.y = y
t.width = width
t.height = height
return
# this algorithm is described here:
# https://www.win.tue.nl/~vanwijk/stm.pdf
i = 0
@@ -498,9 +507,10 @@ def partition_squarify(children, total, x, y, width, height):
total_ = total
width_ = width
height_ = height
# derive target aspect ratio from top-level tile, note we don't
# really care about width vs height until actually slicing
ratio = max(width/height, height/width)
# note we don't really care about width vs height until
# actually slicing
ratio = max(aspect_ratio[0]/aspect_ratio[1],
aspect_ratio[1]/aspect_ratio[0])
while i < len(children):
# calculate initial aspect ratio
@@ -734,6 +744,10 @@ def main(csv_paths, *,
elif args.get('squarify'):
partition_squarify(tile.children, tile.value,
x__, y__, width__, height__)
elif args.get('rectify'):
partition_squarify(tile.children, tile.value,
x__, y__, width__, height__,
aspect_ratio=(width_, height_))
else:
# default to binary partitioning
partition_binary(tile.children, tile.value,
@@ -912,6 +926,12 @@ if __name__ == "__main__":
help="Use the squarify partitioning scheme. This is a greedy "
"algorithm created by Mark Bruls et al that tries to "
"minimize tile aspect ratios.")
parser.add_argument(
'--rectify',
action='store_true',
help="Use the rectify partitioning scheme. This is like "
"squarify, but tries to match the aspect ratio of the "
"window.")
parser.add_argument(
'--to-scale',
nargs='?',