From 185121fc1b9f63eab542f52be44ee3f66e942f45 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Mon, 26 Feb 2024 10:17:39 +0100 Subject: [PATCH] add line breaks in edge labels if too long * with many components of the same type, edge description gets much too long in graphs, * shorten very long items, add line breaks, and even drop items if too many see issue #293 see issue #628 --- ford/graphs.py | 64 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/ford/graphs.py b/ford/graphs.py index 0b13bbcf..76b8c701 100644 --- a/ford/graphs.py +++ b/ford/graphs.py @@ -603,6 +603,68 @@ def __init__(self, obj, gd, hist=None): def _edge( tail: BaseNode, head: BaseNode, style: str, colour: str, label: Optional[str] = None ) -> Dict: + + if label != None: + len_max = 40 + nblines_max = 3 + + # simple variant with one line abbreviation + #if len(label) > len_max: + # label_cut = label[:(len_max-3)] + '...' + if len(label) > len_max: + label_list = re.split('\s*,\s*', label) + nblines = 1 + + # avoid special case of first item in loop below + l = label_list[0] + label_cut = l + lencurr = len(l) + + for i in range(1,len(label_list)): + l = label_list[i] + is_last = (i == len(label_list)-1) + if len(l) > (len_max-1): + # first shorten very long names, reserve five characters for either a comma or ', ...' + l = l[:(len_max-3-5)] + '...' + + if (nblines < nblines_max): + # not the last line + # if last item in label_list: use full len_max character length + # if not last item in label_list: reserve 1 character for ',' before linebreak + if ((is_last and (lencurr + 2 + len(l) > len_max)) or + ((not is_last) and (lencurr + 2 + len(l) > (len_max-1)))): + label_cut = label_cut + ',\n' + l + # new line, reset lencurr to length of current line which contains only l + lencurr = len(l) + nblines = nblines + 1 + else: + # item fits onto line + label_cut = label_cut + ', ' + l + # add length of l and ', ' to length of last line + lencurr = lencurr + 2 + len(l) + + else: + # last line, no more linebreaks + + # if last item in label_list: use full len_max character length + # if not last item in label_list: reserve 5 characters for ', ...' + if ((is_last and (lencurr + 2 + len(l) > len_max)) or + ((not is_last) and (lencurr + 2 + len(l) > (len_max-5)))): + # abort by finishing the current and last line by ', ...' + label_cut = label_cut + ', ...' + break + + else: + # item fits onto line + label_cut = label_cut + ', ' + l + # add length of l and ', ' to length of last line + lencurr = lencurr + 2 + len(l) + + else: + label_cut = label + else: + label_cut = None + return { "tail_node": tail, "head_node": head, @@ -611,7 +673,7 @@ def _edge( "head_name": head.ident, "style": style, "color": colour, - "label": label, + "label": label_cut, }, }