From f22488bc1a63ac8070c5ac4e5d97e50395dbf887 Mon Sep 17 00:00:00 2001 From: midichef <67946319+midichef@users.noreply.github.com> Date: Wed, 16 Aug 2023 17:41:52 -0700 Subject: [PATCH] [graph] widen left margin to hold y-axis labels and let rightmost x label use extra right margin --- visidata/canvas.py | 12 +++++++----- visidata/graph.py | 15 +++++++++++++-- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/visidata/canvas.py b/visidata/canvas.py index 5056456e2..1006b3dd1 100644 --- a/visidata/canvas.py +++ b/visidata/canvas.py @@ -326,6 +326,7 @@ class Canvas(Plotter): bottomMarginPixels = 1*4 # reserve bottom line for x axis def __init__(self, *names, **kwargs): + self.left_margin = self.leftMarginPixels super().__init__(*names, **kwargs) self.canvasBox = None # bounding box of entire canvas, in canvas units @@ -351,6 +352,7 @@ def nRows(self): def reset(self): 'clear everything in preparation for a fresh reload()' self.polylines.clear() + self.left_margin = self.leftMarginPixels self.legends.clear() self.legendwidth = 0 self.plotAttrs.clear() @@ -386,13 +388,13 @@ def resetCanvasDimensions(self, windowHeight, windowWidth): # +4 = 1 empty space after the graph + 2 characters for the legend prefixes of "1:", "2:", etc + # 1 character for the empty rightmost column new_margin = max(self.rightMarginPixels, (self.legendwidth+4)*2) - pvbox_w = self.plotwidth-new_margin-1 + pvbox_xmax = self.plotwidth-new_margin-1 # ensure the graph data takes up at least 3/4 of the width of the screen no matter how wide the legend gets - pvbox_w = max(pvbox_w, math.ceil(self.plotwidth * 3/4)//2*2 + 1) + pvbox_xmax = max(pvbox_xmax, math.ceil(self.plotwidth * 3/4)//2*2 + 1) else: - pvbox_w = self.plotwidth-self.rightMarginPixels-1 - self.plotviewBox = BoundingBox(self.leftMarginPixels, self.topMarginPixels, - pvbox_w, self.plotheight-self.bottomMarginPixels-1) + pvbox_xmax = self.plotwidth-self.rightMarginPixels-1 + self.plotviewBox = BoundingBox(self.left_margin, self.topMarginPixels, + pvbox_xmax, self.plotheight-self.bottomMarginPixels-1) if [self.plotheight, self.plotwidth] != old_plotsize: if hasattr(self, 'cursorBox') and self.cursorBox: self.setCursorSizeInPlotterPixels(2, 4) diff --git a/visidata/graph.py b/visidata/graph.py index 79a71da39..11650716c 100644 --- a/visidata/graph.py +++ b/visidata/graph.py @@ -55,11 +55,17 @@ def startCursor(self): # provides axis labels, legend class GraphSheet(InvertedCanvas): def __init__(self, *names, **kwargs): + self.ylabel_maxw = 0 super().__init__(*names, **kwargs) vd.numericCols(self.xcols) or vd.fail('at least one numeric key col necessary for x-axis') self.ycols or vd.fail('%s is non-numeric' % '/'.join(yc.name for yc in kwargs.get('ycols'))) + def resetCanvasDimensions(self, windowHeight, windowWidth): + if self.left_margin < self.ylabel_maxw: + self.left_margin = self.ylabel_maxw + super().resetCanvasDimensions(windowHeight, windowWidth) + @asyncthread def reload(self): nerrors = 0 @@ -145,6 +151,9 @@ def parseY(self, txt): def add_y_axis_label(self, frac): txt = self.formatYLabel(self.visibleBox.ymin + frac*self.visibleBox.h) + w = (dispwidth(txt)+1)*2 + if self.ylabel_maxw < w: + self.ylabel_maxw = w # plot y-axis labels on the far left of the canvas, but within the plotview height-wise attr = colors.color_graph_axis @@ -161,7 +170,8 @@ def add_x_axis_label(self, frac): if frac < 1.0: txt = tick + txt else: - if (len(txt)+len(tick))*2 <= self.rightMarginPixels: + right_margin = self.plotwidth - 1 - self.plotviewBox.xmax + if (len(txt)+len(tick))*2 <= right_margin: txt = tick + txt else: # shift rightmost label to be left of its tick @@ -174,6 +184,7 @@ def add_x_axis_label(self, frac): def createLabels(self): self.gridlabels = [] + self.ylabel_maxw = self.leftMarginPixels # y-axis self.add_y_axis_label(1.00) @@ -193,7 +204,7 @@ def createLabels(self): # TODO: grid lines corresponding to axis labels xname = ','.join(xcol.name for xcol in self.xcols if vd.isNumeric(xcol)) or 'row#' - xname, _ = clipstr(xname, self.leftMarginPixels//2-2) + xname, _ = clipstr(xname, self.left_margin//2-2) self.plotlabel(0, self.plotviewBox.ymax+4, xname+'ยป', colors.color_graph_axis)