From ce4819cf857340edd0fee841e3edd81ba06eeb2d Mon Sep 17 00:00:00 2001 From: rocky Date: Tue, 17 Dec 2024 20:38:22 -0500 Subject: [PATCH] Start adding Alignment to InsetBox in 2D graphs Add the notion of text alignment of InsetBox which is typically used in drawing axes. The text for an x (horizontal) axis is under the ticks while the text for a y (vertical) axis is to the left. Here we've done this for asymptote and SVG. There is a lot more that could be done, but this is a small start. --- mathics/builtin/box/graphics.py | 13 +++++++++++++ mathics/format/asy.py | 20 ++++++++++++-------- mathics/format/svg.py | 12 +++++++++++- mathics/packages/Combinatorica-repo | 2 +- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/mathics/builtin/box/graphics.py b/mathics/builtin/box/graphics.py index af9487d74..a91b55ee3 100644 --- a/mathics/builtin/box/graphics.py +++ b/mathics/builtin/box/graphics.py @@ -802,6 +802,16 @@ def add_element(element): ), ] ): + # Where should the placement of tick mark labels go? + if index == 0: + # x labels go under tick marks + alignment = "bottom" + elif index == 1: + # y labels go to the left of tick marks + alignment = "left" + else: + alignment = None + if axes[index]: add_element( LineBox( @@ -858,6 +868,7 @@ def add_element(element): ), opos=p_self0(1), opacity=1.0, + alignment=alignment, ) ) for x in ticks_small: @@ -992,6 +1003,7 @@ def init( pos=None, opos=(0, 0), opacity=None, + alignment=None, ): super(InsetBox, self).init(graphics, item, style) @@ -1008,6 +1020,7 @@ def init( opacity = Opacity(1.0) self.opacity = opacity + self.alignment = alignment if item is not None: if len(item.elements) not in (1, 2, 3): diff --git a/mathics/format/asy.py b/mathics/format/asy.py index 2dd97edd3..c055619c9 100644 --- a/mathics/format/asy.py +++ b/mathics/format/asy.py @@ -409,6 +409,16 @@ def graphics_elements(self, **options) -> str: def inset_box(self, **options) -> str: """Asymptote formatting for boxing an Inset in a graphic.""" x, y = self.pos.pos() + + alignment = "SW" + if hasattr(self, "alignment"): + if self.alignment == "bottom": + # This is typically done for labels under the x axis. + alignment = "S" + elif self.alignment == "left": + # This is typically done for labels to the left of the y axis. + alignment = "W" + opacity_value = self.opacity.opacity if self.opacity else None content = self.content.boxes_to_tex(evaluation=self.graphics.evaluation) # FIXME: don't hard code text_style_opts, but allow these to be adjustable. @@ -416,14 +426,8 @@ def inset_box(self, **options) -> str: pen = asy_create_pens( edge_color=self.color, edge_opacity=opacity_value, fontsize=font_size ) - asy = """// InsetBox -label("$%s$", (%s,%s), %s, %s);\n""" % ( - content, - x, - y, - "align=SW", - pen, - ) + asy = f"""// InsetBox +label("${content}$", ({x},{y}), align={alignment}, {pen});\n""" return asy diff --git a/mathics/format/svg.py b/mathics/format/svg.py index 62d61ecee..6bb0392a5 100644 --- a/mathics/format/svg.py +++ b/mathics/format/svg.py @@ -391,8 +391,18 @@ def inset_box(self, **options) -> str: opacity=self.opacity.opacity, ) text_pos_opts = f'x="{x}" y="{y}" ox="{self.opos[0]}" oy="{self.opos[1]}"' + + alignment = " dominant-baseline:hanging;" + if hasattr(self, "alignment"): + if self.alignment == "bottom": + # This is typically done for labels under the x axis. + alignment = " dominant-baseline:hanging; text-anchor:middle;" + elif self.alignment == "left": + # This is typically done for labels to the left of the y axis. + alignment = " dominant-baseline:middle; text-anchor:end;" + # FIXME: don't hard code text_style_opts, but allow these to be adjustable. - text_style_opts = "text-anchor:end; dominant-baseline:hanging;" + text_style_opts = alignment content = self.content.boxes_to_text(evaluation=self.graphics.evaluation) font_size = f'''font-size="{options.get("point_size", "10px")}"''' svg = f'{content}' diff --git a/mathics/packages/Combinatorica-repo b/mathics/packages/Combinatorica-repo index 680999ee5..de634d143 160000 --- a/mathics/packages/Combinatorica-repo +++ b/mathics/packages/Combinatorica-repo @@ -1 +1 @@ -Subproject commit 680999ee557b434531ec20e466ae5035a277ba03 +Subproject commit de634d143512af6b2494fa691baa26ad36528bcf