From ce044fc0c3a2258c24681e3ec24cf061c4383699 Mon Sep 17 00:00:00 2001 From: Neil Vaytet Date: Tue, 11 Nov 2025 17:13:39 +0100 Subject: [PATCH] fix firefox by removing use of calc --- src/matplotgl/axes.py | 76 +++++++++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 28 deletions(-) diff --git a/src/matplotgl/axes.py b/src/matplotgl/axes.py index 36893f2..9bed444 100644 --- a/src/matplotgl/axes.py +++ b/src/matplotgl/axes.py @@ -15,14 +15,36 @@ from .widgets import ClickableHTML -def min_with_none(a, b): +def _min_with_none(a, b): return a if b is None else min(a, b) -def max_with_none(a, b): +def _max_with_none(a, b): return a if b is None else max(a, b) +def _em_to_px(em_value): + """Convert em units to pixels using standard conversion (1em = 16px).""" + return int(em_value * 16) + + +def _multiply_font_size(fontsize, multiplier): + """ + Multiply a font size by a factor. + + Args: + fontsize: Font size string (e.g., "1.2em", "14px", "10pt") + multiplier: Factor to multiply by + + Returns: + String with multiplied font size + """ + value = float(fontsize[:-2]) + unit = fontsize[-2:] + result_value = value * multiplier + return f"{result_value}{unit}" + + class Axes(ipw.GridBox): def __init__(self, *, ax: MplAxes, figure=None) -> None: self.background_color = "#ffffff" @@ -305,10 +327,10 @@ def autoscale(self): ymax = None for artist in self._artists: lims = artist.get_bbox() - xmin = min_with_none(lims["left"], xmin) - xmax = max_with_none(lims["right"], xmax) - ymin = min_with_none(lims["bottom"], ymin) - ymax = max_with_none(lims["top"], ymax) + xmin = _min_with_none(lims["left"], xmin) + xmax = _max_with_none(lims["right"], xmax) + ymin = _min_with_none(lims["bottom"], ymin) + ymax = _max_with_none(lims["top"], ymax) self._xmin = ( xmin if xmin is not None @@ -355,13 +377,11 @@ def _make_xticks(self): trans_data = self._ax.transData xticks_axes = inv_trans_axes.transform(trans_data.transform(xy))[:, 0] - # width = f"calc({self.width}px + 0.5em)" - + height_px = _em_to_px(1.2) + tick_length + label_offset bottom_string = [ ( - f'' ) @@ -426,16 +446,16 @@ def _make_yticks(self): # Predict width of the left margin based on the longest label # Need to convert to integer to avoid sub-pixel rendering issues max_length = math.ceil(max(lab.get_tightbbox().width for lab in ylabels)) - width = f"calc({max_length}px + {tick_length}px + {label_offset}px)" - width1 = f"calc({max_length}px + {label_offset}px)" - width2 = f"calc({max_length}px)" - width3 = f"calc({max_length}px + {tick_length * 0.3}px + {label_offset}px)" + width_px = max_length + tick_length + label_offset + width1_px = max_length + label_offset + width2_px = max_length + width3_px = max_length + int(tick_length * 0.3) + label_offset left_string = [ ( - f'' - f'' + f'' ) ] @@ -451,13 +471,13 @@ def _make_yticks(self): continue y = self.height - (tick * self.height) left_string.append( - f'' ) left_string.append( - f'' f"{html_to_svg(latex_to_html(label), baseline='middle')}" ) @@ -472,8 +492,8 @@ def _make_yticks(self): continue y = self.height - (tick * self.height) left_string.append( - f'' ) @@ -621,12 +641,10 @@ def toggle_pan(self, value): def set_xlabel(self, label, fontsize="1.1em"): if label: - # Height should be 115% of fontsize to account for line height - # height = "calc(1.15 * {fontsize})" + height = _multiply_font_size(fontsize, 1.3) self._margins["xlabel"].value = ( '
' - f'width: {self.width}px; height: calc(1.3 * {fontsize});">' + f'width: {self.width}px; height: {height};">' '
{label.replace(" ", " ")}
' @@ -640,9 +658,10 @@ def get_xlabel(self): def set_ylabel(self, label, fontsize="1.1em"): if label: + width = _multiply_font_size(fontsize, 1.25) self._margins["ylabel"].value = ( '
' + f'width: {width}; height: {self.height}px;">' '
' + f'width: {self.width}px; height: {height};">' '
{title.replace(" ", " ")}
'