scripts: maps: Fixed some aspect ratio issues, limited scope
Replacing -R/--aspect-ratio, --to-ratio now calculates the width/height
_before_ adding decoration such as headers, stack info, etc.
I toying around with generalizing -R/--aspect-ratio to include
decorations, but when Wolfram Alpha spit this mess for the post-header
formula:
header*r - sqrt(4*v*r + padding^2*r)
w = ------------------------------------
2
I decided maybe a generalized -R/--aspect-ratio is a _bit_ too
complicated for what are supposed to be small standalone Python
scripts...
---
Also fixed the scaling formula, which should've taken the sqrt _after_
multiplying by the aspect ratio:
w = sqrt(v*r)
I only noticed while trying to solve for the more complicated
post-decoration formula, the difference is pretty minor.
This commit is contained in:
+23
-33
@@ -781,7 +781,7 @@ def partition_dice(children, total, x, y, width, height):
|
|||||||
y_ += t.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)):
|
aspect_ratio=1/1):
|
||||||
# this algorithm is described here:
|
# this algorithm is described here:
|
||||||
# https://www.win.tue.nl/~vanwijk/stm.pdf
|
# https://www.win.tue.nl/~vanwijk/stm.pdf
|
||||||
i = 0
|
i = 0
|
||||||
@@ -792,8 +792,7 @@ def partition_squarify(children, total, x, y, width, height, *,
|
|||||||
height_ = height
|
height_ = height
|
||||||
# note we don't really care about width vs height until
|
# note we don't really care about width vs height until
|
||||||
# actually slicing
|
# actually slicing
|
||||||
ratio = max(aspect_ratio[0] / aspect_ratio[1],
|
ratio = max(aspect_ratio, 1/aspect_ratio)
|
||||||
aspect_ratio[1] / aspect_ratio[0])
|
|
||||||
|
|
||||||
while i < len(children):
|
while i < len(children):
|
||||||
# calculate initial aspect ratio
|
# calculate initial aspect ratio
|
||||||
@@ -910,7 +909,7 @@ def main_(f, paths, *,
|
|||||||
height=None,
|
height=None,
|
||||||
no_header=False,
|
no_header=False,
|
||||||
to_scale=None,
|
to_scale=None,
|
||||||
aspect_ratio=(1,1),
|
to_ratio=1/1,
|
||||||
tiny=False,
|
tiny=False,
|
||||||
title=None,
|
title=None,
|
||||||
padding=0,
|
padding=0,
|
||||||
@@ -1196,33 +1195,23 @@ def main_(f, paths, *,
|
|||||||
else totals.get('frame', 0) if not nil_frames
|
else totals.get('frame', 0) if not nil_frames
|
||||||
else totals.get('ctx', 0))
|
else totals.get('ctx', 0))
|
||||||
if total_value:
|
if total_value:
|
||||||
# scale if needed
|
# don't include header in scale
|
||||||
if braille:
|
width__ = width_
|
||||||
xscale, yscale = 2, 4
|
height__ = height_ - (1 if not no_header else 0)
|
||||||
elif dots:
|
|
||||||
xscale, yscale = 1, 2
|
|
||||||
else:
|
|
||||||
xscale, yscale = 1, 1
|
|
||||||
|
|
||||||
# scale width only
|
# scale width only
|
||||||
if height is not None:
|
if height is not None:
|
||||||
width_ = mt.ceil(
|
width__ = mt.ceil((total_value * to_scale) / max(height__, 1))
|
||||||
((total_value * to_scale) / (height_*yscale))
|
|
||||||
/ xscale)
|
|
||||||
# scale height only
|
# scale height only
|
||||||
elif width is not None:
|
elif width is not None:
|
||||||
height_ = mt.ceil(
|
height__ = mt.ceil((total_value * to_scale) / max(width__, 1))
|
||||||
((total_value * to_scale) / (width_*xscale))
|
|
||||||
/ yscale)
|
|
||||||
# scale based on aspect-ratio
|
# scale based on aspect-ratio
|
||||||
else:
|
else:
|
||||||
width_ = mt.ceil(
|
width__ = mt.ceil(mt.sqrt(total_value * to_scale * to_ratio))
|
||||||
(mt.sqrt(total_value * to_scale)
|
height__ = mt.ceil((total_value * to_scale) / max(width__, 1))
|
||||||
* (aspect_ratio[0] / aspect_ratio[1]))
|
|
||||||
/ xscale)
|
width_ = width__
|
||||||
height_ = mt.ceil(
|
height_ = height__ + (1 if not no_header else 0)
|
||||||
((total_value * to_scale) / (width_*xscale))
|
|
||||||
/ yscale)
|
|
||||||
|
|
||||||
# as a special case, if height is implicit and we have nothing to
|
# as a special case, if height is implicit and we have nothing to
|
||||||
# show, don't print anything
|
# show, don't print anything
|
||||||
@@ -1278,11 +1267,12 @@ def main_(f, paths, *,
|
|||||||
or args.get('rectify')):
|
or args.get('rectify')):
|
||||||
partition_squarify(tile.children, tile.value,
|
partition_squarify(tile.children, tile.value,
|
||||||
x__, y__, width__, height__,
|
x__, y__, width__, height__,
|
||||||
aspect_ratio=(args['squarify_ratio'], 1)
|
aspect_ratio=(
|
||||||
|
args['squarify_ratio']
|
||||||
if args.get('squarify_ratio')
|
if args.get('squarify_ratio')
|
||||||
else (width_, height_)
|
else width_/height_
|
||||||
if args.get('rectify')
|
if args.get('rectify')
|
||||||
else (1, 1))
|
else 1/1))
|
||||||
else:
|
else:
|
||||||
# default to binary partitioning
|
# default to binary partitioning
|
||||||
partition_binary(tile.children, tile.value,
|
partition_binary(tile.children, tile.value,
|
||||||
@@ -1608,8 +1598,8 @@ if __name__ == "__main__":
|
|||||||
type=lambda x: (
|
type=lambda x: (
|
||||||
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
||||||
if ':' in x else float(x)),
|
if ':' in x else float(x)),
|
||||||
help="Specify an explicit ratio for the squarify algorithm. "
|
help="Specify an explicit aspect ratio for the squarify "
|
||||||
"Implies --squarify.")
|
"algorithm. Implies --squarify.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--to-scale',
|
'--to-scale',
|
||||||
nargs='?',
|
nargs='?',
|
||||||
@@ -1617,13 +1607,13 @@ if __name__ == "__main__":
|
|||||||
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
||||||
if ':' in x else float(x)),
|
if ':' in x else float(x)),
|
||||||
const=1,
|
const=1,
|
||||||
help="Scale the resulting treemap such that 1 pixel ~= 1/scale "
|
help="Scale the resulting treemap such that 1 char ~= 1/scale "
|
||||||
"units. Defaults to scale=1. ")
|
"units. Defaults to scale=1. ")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-R', '--aspect-ratio',
|
'--to-ratio',
|
||||||
type=lambda x: (
|
type=lambda x: (
|
||||||
tuple(float(v) for v in x.split(':', 1))
|
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
||||||
if ':' in x else (float(x), 1)),
|
if ':' in x else float(x)),
|
||||||
help="Aspect ratio to use with --to-scale. Defaults to 1:1.")
|
help="Aspect ratio to use with --to-scale. Defaults to 1:1.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-t', '--tiny',
|
'-t', '--tiny',
|
||||||
|
|||||||
+30
-35
@@ -501,7 +501,7 @@ def partition_dice(children, total, x, y, width, height):
|
|||||||
y_ += t.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)):
|
aspect_ratio=1/1):
|
||||||
# this algorithm is described here:
|
# this algorithm is described here:
|
||||||
# https://www.win.tue.nl/~vanwijk/stm.pdf
|
# https://www.win.tue.nl/~vanwijk/stm.pdf
|
||||||
i = 0
|
i = 0
|
||||||
@@ -512,8 +512,7 @@ def partition_squarify(children, total, x, y, width, height, *,
|
|||||||
height_ = height
|
height_ = height
|
||||||
# note we don't really care about width vs height until
|
# note we don't really care about width vs height until
|
||||||
# actually slicing
|
# actually slicing
|
||||||
ratio = max(aspect_ratio[0] / aspect_ratio[1],
|
ratio = max(aspect_ratio, 1/aspect_ratio)
|
||||||
aspect_ratio[1] / aspect_ratio[0])
|
|
||||||
|
|
||||||
while i < len(children):
|
while i < len(children):
|
||||||
# calculate initial aspect ratio
|
# calculate initial aspect ratio
|
||||||
@@ -637,7 +636,7 @@ def main(paths, output, *,
|
|||||||
mode_callees=False,
|
mode_callees=False,
|
||||||
mode_callers=False,
|
mode_callers=False,
|
||||||
to_scale=None,
|
to_scale=None,
|
||||||
aspect_ratio=(1,1),
|
to_ratio=1/1,
|
||||||
title=None,
|
title=None,
|
||||||
padding=1,
|
padding=1,
|
||||||
no_label=False,
|
no_label=False,
|
||||||
@@ -993,36 +992,31 @@ def main(paths, output, *,
|
|||||||
else totals.get('frame', 0) if not nil_frames
|
else totals.get('frame', 0) if not nil_frames
|
||||||
else totals.get('ctx', 0))
|
else totals.get('ctx', 0))
|
||||||
if total_value:
|
if total_value:
|
||||||
|
# don't include header/stack in scale
|
||||||
|
width__ = width_
|
||||||
|
height__ = height_
|
||||||
|
if not no_header:
|
||||||
|
height__ -= mt.ceil(FONT_SIZE * 1.3)
|
||||||
|
if not no_stack:
|
||||||
|
width__ *= (1 - stack_ratio)
|
||||||
|
|
||||||
# scale width only
|
# scale width only
|
||||||
if height is not None:
|
if height is not None:
|
||||||
if not no_stack:
|
width__ = mt.ceil((total_value * to_scale) / max(height__, 1))
|
||||||
width_ = mt.ceil(((total_value * to_scale) / height_)
|
|
||||||
# add space for stack
|
|
||||||
/ (1 - stack_ratio))
|
|
||||||
else:
|
|
||||||
width_ = mt.ceil((total_value * to_scale) / height_)
|
|
||||||
# scale height only
|
# scale height only
|
||||||
elif width is not None:
|
elif width is not None:
|
||||||
if not no_stack:
|
height__ = mt.ceil((total_value * to_scale) / max(width__, 1))
|
||||||
height_ = mt.ceil((total_value * to_scale)
|
|
||||||
# carve out space for stack
|
|
||||||
/ (width_ * (1 - stack_ratio)))
|
|
||||||
else:
|
|
||||||
height_ = mt.ceil((total_value * to_scale) / width_)
|
|
||||||
# scale based on aspect-ratio
|
# scale based on aspect-ratio
|
||||||
else:
|
else:
|
||||||
|
width__ = mt.ceil(mt.sqrt(total_value * to_scale * to_ratio))
|
||||||
|
height__ = mt.ceil((total_value * to_scale) / max(width__, 1))
|
||||||
|
|
||||||
if not no_stack:
|
if not no_stack:
|
||||||
width_ = mt.ceil(mt.sqrt(total_value * to_scale)
|
width__ /= (1 - stack_ratio)
|
||||||
* (aspect_ratio[0] / aspect_ratio[1])
|
if not no_header:
|
||||||
# add space for stack
|
height__ += mt.ceil(FONT_SIZE * 1.3)
|
||||||
/ (1 - stack_ratio))
|
width_ = width__
|
||||||
height_ = mt.ceil((total_value * to_scale)
|
height_ = height__
|
||||||
# carve out space for stack
|
|
||||||
/ (width_ * (1 - stack_ratio)))
|
|
||||||
else:
|
|
||||||
width_ = mt.ceil(mt.sqrt(total_value * to_scale)
|
|
||||||
* (aspect_ratio[0] / aspect_ratio[1]))
|
|
||||||
height_ = mt.ceil((total_value * to_scale) / width_)
|
|
||||||
|
|
||||||
# our general purpose partition function
|
# our general purpose partition function
|
||||||
def partition(tile, **args):
|
def partition(tile, **args):
|
||||||
@@ -1073,11 +1067,12 @@ def main(paths, output, *,
|
|||||||
or args.get('rectify')):
|
or args.get('rectify')):
|
||||||
partition_squarify(tile.children, tile.value,
|
partition_squarify(tile.children, tile.value,
|
||||||
x__, y__, width__, height__,
|
x__, y__, width__, height__,
|
||||||
aspect_ratio=(args['squarify_ratio'], 1)
|
aspect_ratio=(
|
||||||
|
args['squarify_ratio']
|
||||||
if args.get('squarify_ratio')
|
if args.get('squarify_ratio')
|
||||||
else (width_, height_)
|
else width_/height_
|
||||||
if args.get('rectify')
|
if args.get('rectify')
|
||||||
else (1, 1))
|
else 1/1))
|
||||||
else:
|
else:
|
||||||
# default to binary partitioning
|
# default to binary partitioning
|
||||||
partition_binary(tile.children, tile.value,
|
partition_binary(tile.children, tile.value,
|
||||||
@@ -2278,8 +2273,8 @@ if __name__ == "__main__":
|
|||||||
type=lambda x: (
|
type=lambda x: (
|
||||||
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
||||||
if ':' in x else float(x)),
|
if ':' in x else float(x)),
|
||||||
help="Specify an explicit ratio for the squarify algorithm. "
|
help="Specify an explicit aspect ratio for the squarify "
|
||||||
"Implies --squarify.")
|
"algorithm. Implies --squarify.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--to-scale',
|
'--to-scale',
|
||||||
nargs='?',
|
nargs='?',
|
||||||
@@ -2290,10 +2285,10 @@ if __name__ == "__main__":
|
|||||||
help="Scale the resulting treemap such that 1 pixel ~= 1/scale "
|
help="Scale the resulting treemap such that 1 pixel ~= 1/scale "
|
||||||
"units. Defaults to scale=1. ")
|
"units. Defaults to scale=1. ")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-R', '--aspect-ratio',
|
'--to-ratio',
|
||||||
type=lambda x: (
|
type=lambda x: (
|
||||||
tuple(float(v) for v in x.split(':', 1))
|
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
||||||
if ':' in x else (float(x), 1)),
|
if ':' in x else float(x)),
|
||||||
help="Aspect ratio to use with --to-scale. Defaults to 1:1.")
|
help="Aspect ratio to use with --to-scale. Defaults to 1:1.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-t', '--tiny',
|
'-t', '--tiny',
|
||||||
|
|||||||
+16
-10
@@ -4350,7 +4350,7 @@ def main_(f, disk, mroots=None, *,
|
|||||||
lebesgue=False,
|
lebesgue=False,
|
||||||
contiguous=False,
|
contiguous=False,
|
||||||
to_scale=None,
|
to_scale=None,
|
||||||
aspect_ratio=(1,1),
|
to_ratio=1/1,
|
||||||
tiny=False,
|
tiny=False,
|
||||||
title=None,
|
title=None,
|
||||||
title_littlefs=False,
|
title_littlefs=False,
|
||||||
@@ -4542,17 +4542,23 @@ def main_(f, disk, mroots=None, *,
|
|||||||
# scale width/height if requested
|
# scale width/height if requested
|
||||||
if (to_scale is not None
|
if (to_scale is not None
|
||||||
and (width is None or height is None)):
|
and (width is None or height is None)):
|
||||||
|
# don't include header in scale
|
||||||
|
width__ = width_
|
||||||
|
height__ = height_ - (1 if not no_header else 0)
|
||||||
|
|
||||||
# scale width only
|
# scale width only
|
||||||
if height is not None:
|
if height is not None:
|
||||||
width_ = mt.ceil((len(bmap) * to_scale) / height_)
|
width__ = mt.ceil((len(bmap) * to_scale) / max(height__, 1))
|
||||||
# scale height only
|
# scale height only
|
||||||
elif width is not None:
|
elif width is not None:
|
||||||
height_ = mt.ceil((len(bmap) * to_scale) / width_)
|
height__ = mt.ceil((len(bmap) * to_scale) / max(width__, 1))
|
||||||
# scale based on aspect-ratio
|
# scale based on aspect-ratio
|
||||||
else:
|
else:
|
||||||
width_ = mt.ceil(mt.sqrt(len(bmap) * to_scale)
|
width__ = mt.ceil(mt.sqrt(len(bmap) * to_scale * to_ratio))
|
||||||
* (aspect_ratio[0] / aspect_ratio[1]))
|
height__ = mt.ceil((len(bmap) * to_scale) / max(width__, 1))
|
||||||
height_ = mt.ceil((len(bmap) * to_scale) / width_)
|
|
||||||
|
width_ = width__
|
||||||
|
height_ = height__ + (1 if not no_header else 0)
|
||||||
|
|
||||||
# create a canvas
|
# create a canvas
|
||||||
canvas = Canvas(
|
canvas = Canvas(
|
||||||
@@ -5048,13 +5054,13 @@ if __name__ == "__main__":
|
|||||||
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
||||||
if ':' in x else float(x)),
|
if ':' in x else float(x)),
|
||||||
const=1,
|
const=1,
|
||||||
help="Scale the resulting map such that 1 pixel ~= 1/scale "
|
help="Scale the resulting map such that 1 char ~= 1/scale "
|
||||||
"blocks. Defaults to scale=1. ")
|
"blocks. Defaults to scale=1. ")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-R', '--aspect-ratio',
|
'--to-ratio',
|
||||||
type=lambda x: (
|
type=lambda x: (
|
||||||
tuple(float(v) for v in x.split(':', 1))
|
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
||||||
if ':' in x else (float(x), 1)),
|
if ':' in x else float(x)),
|
||||||
help="Aspect ratio to use with --to-scale. Defaults to 1:1.")
|
help="Aspect ratio to use with --to-scale. Defaults to 1:1.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-t', '--tiny',
|
'-t', '--tiny',
|
||||||
|
|||||||
+19
-9
@@ -4666,7 +4666,7 @@ def main(disk, output, mroots=None, *,
|
|||||||
mode_references=False,
|
mode_references=False,
|
||||||
mode_redund=False,
|
mode_redund=False,
|
||||||
to_scale=None,
|
to_scale=None,
|
||||||
aspect_ratio=(1,1),
|
to_ratio=1/1,
|
||||||
tiny=False,
|
tiny=False,
|
||||||
title=None,
|
title=None,
|
||||||
title_littlefs=False,
|
title_littlefs=False,
|
||||||
@@ -4872,17 +4872,27 @@ def main(disk, output, mroots=None, *,
|
|||||||
# scale width/height if requested
|
# scale width/height if requested
|
||||||
if (to_scale is not None
|
if (to_scale is not None
|
||||||
and (width is None or height is None)):
|
and (width is None or height is None)):
|
||||||
|
# don't include header in scale
|
||||||
|
width__ = width_
|
||||||
|
height__ = height_
|
||||||
|
if not no_header:
|
||||||
|
height__ -= mt.ceil(FONT_SIZE * 1.3)
|
||||||
|
|
||||||
# scale width only
|
# scale width only
|
||||||
if height is not None:
|
if height is not None:
|
||||||
width_ = mt.ceil((len(bmap) * to_scale) / height_)
|
width__ = mt.ceil((len(bmap) * to_scale) / max(height__, 1))
|
||||||
# scale height only
|
# scale height only
|
||||||
elif width is not None:
|
elif width is not None:
|
||||||
height_ = mt.ceil((len(bmap) * to_scale) / width_)
|
height__ = mt.ceil((len(bmap) * to_scale) / max(width__, 1))
|
||||||
# scale based on aspect-ratio
|
# scale based on aspect-ratio
|
||||||
else:
|
else:
|
||||||
width_ = mt.ceil(mt.sqrt(len(bmap) * to_scale)
|
width__ = mt.ceil(mt.sqrt(len(bmap) * to_scale * to_ratio))
|
||||||
* (aspect_ratio[0] / aspect_ratio[1]))
|
height__ = mt.ceil((len(bmap) * to_scale) / max(width__, 1))
|
||||||
height_ = mt.ceil((len(bmap) * to_scale) / width_)
|
|
||||||
|
if not no_header:
|
||||||
|
height__ += mt.ceil(FONT_SIZE * 1.3)
|
||||||
|
width_ = width__
|
||||||
|
height_ = height__
|
||||||
|
|
||||||
# create space for header
|
# create space for header
|
||||||
x__ = 0
|
x__ = 0
|
||||||
@@ -5953,10 +5963,10 @@ if __name__ == "__main__":
|
|||||||
help="Scale the resulting treemap such that 1 pixel ~= 1/scale "
|
help="Scale the resulting treemap such that 1 pixel ~= 1/scale "
|
||||||
"blocks. Defaults to scale=1. ")
|
"blocks. Defaults to scale=1. ")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-R', '--aspect-ratio',
|
'--to-ratio',
|
||||||
type=lambda x: (
|
type=lambda x: (
|
||||||
tuple(float(v) for v in x.split(':', 1))
|
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
||||||
if ':' in x else (float(x), 1)),
|
if ':' in x else float(x)),
|
||||||
help="Aspect ratio to use with --to-scale. Defaults to 1:1.")
|
help="Aspect ratio to use with --to-scale. Defaults to 1:1.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-t', '--tiny',
|
'-t', '--tiny',
|
||||||
|
|||||||
+16
-10
@@ -1413,7 +1413,7 @@ def main(path='-', *,
|
|||||||
lebesgue=False,
|
lebesgue=False,
|
||||||
contiguous=False,
|
contiguous=False,
|
||||||
to_scale=None,
|
to_scale=None,
|
||||||
aspect_ratio=(1,1),
|
to_ratio=1/1,
|
||||||
tiny=False,
|
tiny=False,
|
||||||
title=None,
|
title=None,
|
||||||
padding=0,
|
padding=0,
|
||||||
@@ -1748,17 +1748,23 @@ def main(path='-', *,
|
|||||||
# scale width/height if requested
|
# scale width/height if requested
|
||||||
if (to_scale is not None
|
if (to_scale is not None
|
||||||
and (width is None or height is None)):
|
and (width is None or height is None)):
|
||||||
|
# don't include header in scale
|
||||||
|
width__ = width_
|
||||||
|
height__ = height_ - (1 if not no_header else 0)
|
||||||
|
|
||||||
# scale width only
|
# scale width only
|
||||||
if height is not None:
|
if height is not None:
|
||||||
width_ = mt.ceil((len(bmap) * to_scale) / height_)
|
width__ = mt.ceil((len(bmap) * to_scale) / max(height__, 1))
|
||||||
# scale height only
|
# scale height only
|
||||||
elif width is not None:
|
elif width is not None:
|
||||||
height_ = mt.ceil((len(bmap) * to_scale) / width_)
|
height__ = mt.ceil((len(bmap) * to_scale) / max(width__, 1))
|
||||||
# scale based on aspect-ratio
|
# scale based on aspect-ratio
|
||||||
else:
|
else:
|
||||||
width_ = mt.ceil(mt.sqrt(len(bmap) * to_scale)
|
width__ = mt.ceil(mt.sqrt(len(bmap) * to_scale * to_ratio))
|
||||||
* (aspect_ratio[0] / aspect_ratio[1]))
|
height__ = mt.ceil((len(bmap) * to_scale) / max(width__, 1))
|
||||||
height_ = mt.ceil((len(bmap) * to_scale) / width_)
|
|
||||||
|
width_ = width__
|
||||||
|
height_ = height__ + (1 if not no_header else 0)
|
||||||
|
|
||||||
# create a canvas
|
# create a canvas
|
||||||
canvas = Canvas(
|
canvas = Canvas(
|
||||||
@@ -2749,13 +2755,13 @@ if __name__ == "__main__":
|
|||||||
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
||||||
if ':' in x else float(x)),
|
if ':' in x else float(x)),
|
||||||
const=1,
|
const=1,
|
||||||
help="Scale the resulting map such that 1 pixel ~= 1/scale "
|
help="Scale the resulting map such that 1 char ~= 1/scale "
|
||||||
"blocks. Defaults to scale=1. ")
|
"blocks. Defaults to scale=1. ")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-R', '--aspect-ratio',
|
'--to-ratio',
|
||||||
type=lambda x: (
|
type=lambda x: (
|
||||||
tuple(float(v) for v in x.split(':', 1))
|
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
||||||
if ':' in x else (float(x), 1)),
|
if ':' in x else float(x)),
|
||||||
help="Aspect ratio to use with --to-scale. Defaults to 1:1.")
|
help="Aspect ratio to use with --to-scale. Defaults to 1:1.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-t', '--tiny',
|
'-t', '--tiny',
|
||||||
|
|||||||
+29
-41
@@ -850,7 +850,7 @@ def partition_dice(children, total, x, y, width, height):
|
|||||||
y_ += t.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)):
|
aspect_ratio=1/1):
|
||||||
# this algorithm is described here:
|
# this algorithm is described here:
|
||||||
# https://www.win.tue.nl/~vanwijk/stm.pdf
|
# https://www.win.tue.nl/~vanwijk/stm.pdf
|
||||||
i = 0
|
i = 0
|
||||||
@@ -861,8 +861,7 @@ def partition_squarify(children, total, x, y, width, height, *,
|
|||||||
height_ = height
|
height_ = height
|
||||||
# note we don't really care about width vs height until
|
# note we don't really care about width vs height until
|
||||||
# actually slicing
|
# actually slicing
|
||||||
ratio = max(aspect_ratio[0] / aspect_ratio[1],
|
ratio = max(aspect_ratio, 1/aspect_ratio)
|
||||||
aspect_ratio[1] / aspect_ratio[0])
|
|
||||||
|
|
||||||
while i < len(children):
|
while i < len(children):
|
||||||
# calculate initial aspect ratio
|
# calculate initial aspect ratio
|
||||||
@@ -924,7 +923,7 @@ def main_(f, csv_paths, *,
|
|||||||
no_header=False,
|
no_header=False,
|
||||||
no_stats=False,
|
no_stats=False,
|
||||||
to_scale=None,
|
to_scale=None,
|
||||||
aspect_ratio=(1,1),
|
to_ratio=1/1,
|
||||||
tiny=False,
|
tiny=False,
|
||||||
title=None,
|
title=None,
|
||||||
padding=0,
|
padding=0,
|
||||||
@@ -951,6 +950,10 @@ def main_(f, csv_paths, *,
|
|||||||
to_scale = 1
|
to_scale = 1
|
||||||
no_header = True
|
no_header = True
|
||||||
|
|
||||||
|
# no title + no_stats implies no_header
|
||||||
|
if title is None and no_stats:
|
||||||
|
no_header = True
|
||||||
|
|
||||||
# what chars/colors/labels to use?
|
# what chars/colors/labels to use?
|
||||||
chars_ = []
|
chars_ = []
|
||||||
for char in chars:
|
for char in chars:
|
||||||
@@ -973,10 +976,7 @@ def main_(f, csv_paths, *,
|
|||||||
width_ = max(0, shutil.get_terminal_size((80, 5))[0] + width)
|
width_ = max(0, shutil.get_terminal_size((80, 5))[0] + width)
|
||||||
|
|
||||||
if height is None:
|
if height is None:
|
||||||
height_ = (2
|
height_ = 2 if not no_header else 1
|
||||||
if not no_header
|
|
||||||
and (title is not None or not no_stats)
|
|
||||||
else 1)
|
|
||||||
elif height > 0:
|
elif height > 0:
|
||||||
height_ = height
|
height_ = height
|
||||||
else:
|
else:
|
||||||
@@ -1062,33 +1062,23 @@ def main_(f, csv_paths, *,
|
|||||||
if (to_scale
|
if (to_scale
|
||||||
and (width is None or height is None)
|
and (width is None or height is None)
|
||||||
and tile.value != 0):
|
and tile.value != 0):
|
||||||
# scale if needed
|
# don't include header in scale
|
||||||
if braille:
|
width__ = width_
|
||||||
xscale, yscale = 2, 4
|
height__ = height_ - (1 if not no_header else 0)
|
||||||
elif dots:
|
|
||||||
xscale, yscale = 1, 2
|
|
||||||
else:
|
|
||||||
xscale, yscale = 1, 1
|
|
||||||
|
|
||||||
# scale width only
|
# scale width only
|
||||||
if height is not None:
|
if height is not None:
|
||||||
width_ = mt.ceil(
|
width__ = mt.ceil((tile.value * to_scale) / max(height__, 1))
|
||||||
((tile.value * to_scale) / (height_*yscale))
|
|
||||||
/ xscale)
|
|
||||||
# scale height only
|
# scale height only
|
||||||
elif width is not None:
|
elif width is not None:
|
||||||
height_ = mt.ceil(
|
height__ = mt.ceil((tile.value * to_scale) / max(width__, 1))
|
||||||
((tile.value * to_scale) / (width_*xscale))
|
|
||||||
/ yscale)
|
|
||||||
# scale based on aspect-ratio
|
# scale based on aspect-ratio
|
||||||
else:
|
else:
|
||||||
width_ = mt.ceil(
|
width__ = mt.ceil(mt.sqrt(tile.value * to_scale * to_ratio))
|
||||||
(mt.sqrt(tile.value * to_scale)
|
height__ = mt.ceil((tile.value * to_scale) / max(width__, 1))
|
||||||
* (aspect_ratio[0] / aspect_ratio[1]))
|
|
||||||
/ xscale)
|
width_ = width__
|
||||||
height_ = mt.ceil(
|
height_ = height__ + (1 if not no_header else 0)
|
||||||
((tile.value * to_scale) / (width_*xscale))
|
|
||||||
/ yscale)
|
|
||||||
|
|
||||||
# as a special case, if height is implicit and we have nothing to
|
# as a special case, if height is implicit and we have nothing to
|
||||||
# show, don't print anything
|
# show, don't print anything
|
||||||
@@ -1098,10 +1088,7 @@ def main_(f, csv_paths, *,
|
|||||||
# create a canvas
|
# create a canvas
|
||||||
canvas = Canvas(
|
canvas = Canvas(
|
||||||
width_,
|
width_,
|
||||||
height_ - (1
|
height_ - (1 if not no_header else 0),
|
||||||
if not no_header
|
|
||||||
and (title is not None or not no_stats)
|
|
||||||
else 0),
|
|
||||||
color=color,
|
color=color,
|
||||||
dots=dots,
|
dots=dots,
|
||||||
braille=braille)
|
braille=braille)
|
||||||
@@ -1162,11 +1149,12 @@ def main_(f, csv_paths, *,
|
|||||||
or args.get('rectify')):
|
or args.get('rectify')):
|
||||||
partition_squarify(tile.children, tile.value,
|
partition_squarify(tile.children, tile.value,
|
||||||
x__, y__, width__, height__,
|
x__, y__, width__, height__,
|
||||||
aspect_ratio=(args['squarify_ratio'], 1)
|
aspect_ratio=(
|
||||||
|
args['squarify_ratio']
|
||||||
if args.get('squarify_ratio')
|
if args.get('squarify_ratio')
|
||||||
else (width_, height_)
|
else width_/height_
|
||||||
if args.get('rectify')
|
if args.get('rectify')
|
||||||
else (1, 1))
|
else 1/1))
|
||||||
else:
|
else:
|
||||||
# default to binary partitioning
|
# default to binary partitioning
|
||||||
partition_binary(tile.children, tile.value,
|
partition_binary(tile.children, tile.value,
|
||||||
@@ -1469,8 +1457,8 @@ if __name__ == "__main__":
|
|||||||
type=lambda x: (
|
type=lambda x: (
|
||||||
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
||||||
if ':' in x else float(x)),
|
if ':' in x else float(x)),
|
||||||
help="Specify an explicit ratio for the squarify algorithm. "
|
help="Specify an explicit aspect ratio for the squarify "
|
||||||
"Implies --squarify.")
|
"algorithm. Implies --squarify.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--to-scale',
|
'--to-scale',
|
||||||
nargs='?',
|
nargs='?',
|
||||||
@@ -1478,13 +1466,13 @@ if __name__ == "__main__":
|
|||||||
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
||||||
if ':' in x else float(x)),
|
if ':' in x else float(x)),
|
||||||
const=1,
|
const=1,
|
||||||
help="Scale the resulting treemap such that 1 pixel ~= 1/scale "
|
help="Scale the resulting treemap such that 1 char ~= 1/scale "
|
||||||
"units. Defaults to scale=1.")
|
"units. Defaults to scale=1.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-R', '--aspect-ratio',
|
'--to-ratio',
|
||||||
type=lambda x: (
|
type=lambda x: (
|
||||||
tuple(float(v) for v in x.split(':', 1))
|
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
||||||
if ':' in x else (float(x), 1)),
|
if ':' in x else float(x)),
|
||||||
help="Aspect ratio to use with --to-scale. Defaults to 1:1.")
|
help="Aspect ratio to use with --to-scale. Defaults to 1:1.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-t', '--tiny',
|
'-t', '--tiny',
|
||||||
|
|||||||
+33
-19
@@ -570,7 +570,7 @@ def partition_dice(children, total, x, y, width, height):
|
|||||||
y_ += t.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)):
|
aspect_ratio=1/1):
|
||||||
# this algorithm is described here:
|
# this algorithm is described here:
|
||||||
# https://www.win.tue.nl/~vanwijk/stm.pdf
|
# https://www.win.tue.nl/~vanwijk/stm.pdf
|
||||||
i = 0
|
i = 0
|
||||||
@@ -581,8 +581,7 @@ def partition_squarify(children, total, x, y, width, height, *,
|
|||||||
height_ = height
|
height_ = height
|
||||||
# note we don't really care about width vs height until
|
# note we don't really care about width vs height until
|
||||||
# actually slicing
|
# actually slicing
|
||||||
ratio = max(aspect_ratio[0] / aspect_ratio[1],
|
ratio = max(aspect_ratio, 1/aspect_ratio)
|
||||||
aspect_ratio[1] / aspect_ratio[0])
|
|
||||||
|
|
||||||
while i < len(children):
|
while i < len(children):
|
||||||
# calculate initial aspect ratio
|
# calculate initial aspect ratio
|
||||||
@@ -641,7 +640,7 @@ def main(csv_paths, output, *,
|
|||||||
no_header=False,
|
no_header=False,
|
||||||
no_stats=False,
|
no_stats=False,
|
||||||
to_scale=None,
|
to_scale=None,
|
||||||
aspect_ratio=(1,1),
|
to_ratio=1/1,
|
||||||
tiny=False,
|
tiny=False,
|
||||||
nested=False,
|
nested=False,
|
||||||
title=None,
|
title=None,
|
||||||
@@ -659,6 +658,10 @@ def main(csv_paths, output, *,
|
|||||||
no_header = True
|
no_header = True
|
||||||
no_label = True
|
no_label = True
|
||||||
|
|
||||||
|
# no title + no_stats implies no_header
|
||||||
|
if title is None and no_stats:
|
||||||
|
no_header = True
|
||||||
|
|
||||||
# what colors/labels to use?
|
# what colors/labels to use?
|
||||||
colors_ = Attr(colors, defaults=COLORS_DARK if dark else COLORS)
|
colors_ = Attr(colors, defaults=COLORS_DARK if dark else COLORS)
|
||||||
|
|
||||||
@@ -753,17 +756,27 @@ def main(csv_paths, output, *,
|
|||||||
if (to_scale is not None
|
if (to_scale is not None
|
||||||
and (width is None or height is None)
|
and (width is None or height is None)
|
||||||
and tile.value != 0):
|
and tile.value != 0):
|
||||||
|
# don't include header in scale
|
||||||
|
width__ = width_
|
||||||
|
height__ = height_
|
||||||
|
if not no_header:
|
||||||
|
height__ -= mt.ceil(FONT_SIZE * 1.3)
|
||||||
|
|
||||||
# scale width only
|
# scale width only
|
||||||
if height is not None:
|
if height is not None:
|
||||||
width_ = mt.ceil((tile.value * to_scale) / height_)
|
width__ = mt.ceil((tile.value * to_scale) / max(height__, 1))
|
||||||
# scale height only
|
# scale height only
|
||||||
elif width is not None:
|
elif width is not None:
|
||||||
height_ = mt.ceil((tile.value * to_scale) / width_)
|
height__ = mt.ceil((tile.value * to_scale) / max(width__, 1))
|
||||||
# scale based on aspect-ratio
|
# scale based on aspect-ratio
|
||||||
else:
|
else:
|
||||||
width_ = mt.ceil(mt.sqrt(tile.value * to_scale)
|
width__ = mt.ceil(mt.sqrt(tile.value * to_scale * to_ratio))
|
||||||
* (aspect_ratio[0] / aspect_ratio[1]))
|
height__ = mt.ceil((tile.value * to_scale) / max(width__, 1))
|
||||||
height_ = mt.ceil((tile.value * to_scale) / width_)
|
|
||||||
|
if not no_header:
|
||||||
|
height__ += mt.ceil(FONT_SIZE * 1.3)
|
||||||
|
width_ = width__
|
||||||
|
height_ = height__
|
||||||
|
|
||||||
# sort
|
# sort
|
||||||
tile.sort()
|
tile.sort()
|
||||||
@@ -791,7 +804,7 @@ def main(csv_paths, output, *,
|
|||||||
height__ = tile.height
|
height__ = tile.height
|
||||||
|
|
||||||
# create space for header
|
# create space for header
|
||||||
if not no_header and (title is not None or not no_stats):
|
if not no_header:
|
||||||
y__ += mt.ceil(FONT_SIZE * 1.3)
|
y__ += mt.ceil(FONT_SIZE * 1.3)
|
||||||
height__ -= min(mt.ceil(FONT_SIZE * 1.3), height__)
|
height__ -= min(mt.ceil(FONT_SIZE * 1.3), height__)
|
||||||
|
|
||||||
@@ -837,11 +850,12 @@ def main(csv_paths, output, *,
|
|||||||
or args.get('rectify')):
|
or args.get('rectify')):
|
||||||
partition_squarify(tile.children, tile.value,
|
partition_squarify(tile.children, tile.value,
|
||||||
x__, y__, width__, height__,
|
x__, y__, width__, height__,
|
||||||
aspect_ratio=(args['squarify_ratio'], 1)
|
aspect_ratio=(
|
||||||
|
args['squarify_ratio']
|
||||||
if args.get('squarify_ratio')
|
if args.get('squarify_ratio')
|
||||||
else (width_, height_)
|
else width_/height_
|
||||||
if args.get('rectify')
|
if args.get('rectify')
|
||||||
else (1, 1))
|
else 1/1))
|
||||||
else:
|
else:
|
||||||
# default to binary partitioning
|
# default to binary partitioning
|
||||||
partition_binary(tile.children, tile.value,
|
partition_binary(tile.children, tile.value,
|
||||||
@@ -880,7 +894,7 @@ def main(csv_paths, output, *,
|
|||||||
background=background_))
|
background=background_))
|
||||||
|
|
||||||
# create header
|
# create header
|
||||||
if not no_header and (title is not None or not no_stats):
|
if not no_header:
|
||||||
f.write('<text fill="%(color)s">' % dict(
|
f.write('<text fill="%(color)s">' % dict(
|
||||||
color='#ffffff' if dark else '#000000'))
|
color='#ffffff' if dark else '#000000'))
|
||||||
if not no_stats:
|
if not no_stats:
|
||||||
@@ -1114,8 +1128,8 @@ if __name__ == "__main__":
|
|||||||
type=lambda x: (
|
type=lambda x: (
|
||||||
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
||||||
if ':' in x else float(x)),
|
if ':' in x else float(x)),
|
||||||
help="Specify an explicit ratio for the squarify algorithm. "
|
help="Specify an explicit aspect ratio for the squarify "
|
||||||
"Implies --squarify.")
|
"algorithm. Implies --squarify.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--to-scale',
|
'--to-scale',
|
||||||
nargs='?',
|
nargs='?',
|
||||||
@@ -1126,10 +1140,10 @@ if __name__ == "__main__":
|
|||||||
help="Scale the resulting treemap such that 1 pixel ~= 1/scale "
|
help="Scale the resulting treemap such that 1 pixel ~= 1/scale "
|
||||||
"units. Defaults to scale=1. ")
|
"units. Defaults to scale=1. ")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-R', '--aspect-ratio',
|
'--to-ratio',
|
||||||
type=lambda x: (
|
type=lambda x: (
|
||||||
tuple(float(v) for v in x.split(':', 1))
|
(lambda a, b: a / b)(*(float(v) for v in x.split(':', 1)))
|
||||||
if ':' in x else (float(x), 1)),
|
if ':' in x else float(x)),
|
||||||
help="Aspect ratio to use with --to-scale. Defaults to 1:1.")
|
help="Aspect ratio to use with --to-scale. Defaults to 1:1.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-t', '--tiny',
|
'-t', '--tiny',
|
||||||
|
|||||||
Reference in New Issue
Block a user