Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix unusable legend size with long filenames on Mac #2264

Merged
merged 11 commits into from
Oct 27, 2022
64 changes: 24 additions & 40 deletions src/sas/qtgui/Plotting/Plotter.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import math

from PyQt5 import QtGui
from PyQt5 import QtWidgets

import functools
import copy
import sys
import matplotlib as mpl
import numpy as np
import textwrap
from matplotlib.font_manager import FontProperties
from packaging import version

Expand All @@ -24,29 +26,7 @@
import sas.qtgui.Utilities.GuiUtils as GuiUtils
import sas.qtgui.Plotting.PlotUtilities as PlotUtilities

def _legendResize(width, parent):
"""
resize factor for the legend, based on total canvas width
"""
# The factor 4.0 was chosen to look similar in size/ratio to what we had in 4.x
if not hasattr(parent.parent, "manager"):
return None
if parent is None or parent.parent is None or parent.parent.manager is None \
or parent.parent.manager.parent is None or parent.parent.manager.parent._parent is None:
return None

screen_width = parent.parent.manager.parent._parent.screen_width
screen_height = parent.parent.manager.parent._parent.screen_height
screen_factor = screen_width * screen_height

if sys.platform == 'win32':
factor = 4
denomintor = 100
scale_factor = width/denomintor + factor
else:
#Function inferred based on tests for several resolutions
scale_factor = (3e-6*screen_factor + 1)*width/640
return scale_factor
from sas import config

class PlotterWidget(PlotterBase):
"""
Expand Down Expand Up @@ -253,14 +233,28 @@ def plot(self, data=None, color=None, marker=None, hide_error=False, transform=T

# Now add the legend with some customizations.
if self.showLegend:
width=_legendResize(self.canvas.size().width(), self.parent)
if width is not None:
self.legend = ax.legend(loc='upper right', shadow=True, prop={'size':width})
max_legend_width = config.FITTING_PLOT_LEGEND_MAX_LINE_LENGTH
handles, labels = ax.get_legend_handles_labels()
newhandles = []
newlabels = []
for h,l in zip(handles,labels):
if config.FITTING_PLOT_LEGEND_TRUNCATE:
if len(l)> config.FITTING_PLOT_LEGEND_MAX_LINE_LENGTH:
half_legend_width = math.floor(max_legend_width/2)
newlabels.append(f'{l[0:half_legend_width-3]} .. {l[-half_legend_width+3:]}')
else:
newlabels.append(l)
else:
newlabels.append(textwrap.fill(l,max_legend_width))
newhandles.append(h)

if config.FITTING_PLOT_FULL_WIDTH_LEGENDS:
self.legend = ax.legend(newhandles,newlabels,loc='best', mode='expand')
else:
self.legend = ax.legend(loc='upper right', shadow=True)
if self.legend:
self.legend.set_picker(True)
self.legend = ax.legend(newhandles,newlabels,loc='best', shadow=True)
self.legend.set_picker(True)
self.legend.set_visible(self.legendVisible)

# Current labels for axes
if self.yLabel and not is_fit:
ax.set_ylabel(self.yLabel)
Expand Down Expand Up @@ -301,16 +295,6 @@ def plot(self, data=None, color=None, marker=None, hide_error=False, transform=T
# refresh canvas
self.canvas.draw_idle()

def onResize(self, event):
"""
Resize the legend window/font on canvas resize
"""
if not self.showLegend or not self.legendVisible:
return
width = _legendResize(event.width, self.parent)
# resize the legend to follow the canvas width.
if width is not None:
self.legend.prop.set_size(width)

def createContextMenu(self):
"""
Expand Down
8 changes: 8 additions & 0 deletions src/sas/system/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,15 @@ def __init__(self):
# Time out for updating sasview
self.UPDATE_TIMEOUT = 2

# If True, use an ugly but more robust legend plotting method in Fitting that results in full-
# width legends.
self.FITTING_PLOT_FULL_WIDTH_LEGENDS = False

# If True, truncates names in Fitting plot legends such that each name is maximum one line.
self.FITTING_PLOT_LEGEND_TRUNCATE = False

# sets the maximum number of characters per Fitting plot legend entry.
self.FITTING_PLOT_LEGEND_MAX_LINE_LENGTH = 30
#
# Lock the class down, this is necessary both for
# securing the class, and for setting up reading/writing files
Expand Down