ford
ford copied to clipboard
Graphs with long edge labels become degenerated
If a derived type has many components of the same type, inheritance graphs becomes degenerated, as edges length depends on length of label. In order to handle this, I added linebreaks. Additionally items from the label list are dropped if there are too many (more than 3 lines of width 40 required).
Here is a contrived example module
module test
implicit none
private
type, public :: t0
end type t0
type, extends(t0), public :: t1
end type t1
type, public :: t2
type(t1) :: component_1
type(t1) :: component_2
type(t1) :: component_3
type(t1) :: component_4
type(t1) :: component_5
type(t1) :: component_6
type(t1) :: component_7
type(t1) :: component_8
type(t1) :: component_9
end type t2
type, extends(t2), public :: t3
end type t3
type, extends(t3), public :: t4
end type t4
end module test
The code in commit 185121f is a proof of concept, but works fine so far.
Something a bit simpler that might be sufficient:
modified ford/graphs.py
@@ -450,11 +450,11 @@ class TypeNode(BaseNode):
node.visible = getattr(proto, "visible", True)
if self in node.comp_of:
- node.comp_of[self] += ", " + var.name
+ node.comp_of[self] += f"\n{var.name}"
else:
node.comp_of[self] = var.name
if node in self.comp_types:
- self.comp_types[node] += ", " + var.name
+ self.comp_types[node] += f"\n{var.name}"
else:
self.comp_types[node] = var.name
This stacks names in a column, instead of printing them in a row, right? I have tried this, and it is definitely an improvement. But from looking at some of my graphs, I concluded that a compact box (a few lines with restricted width) uses the typical real estate in a graph optimally. That's why I arrived at my rather complex logic. I definitely would restrict the size of the label horizontally as well as vertically if there are too many items to avoid degenerating the graph.
Have you looked at textwrap.wrap?
I do also think the graphs should be comprehensive rather than compact, so I don't think it should cut off components.
Thanks for pointing to this module, did not know about it. Indeed something like textwrap.fill(s, width=40, max_lines=3, placeholder='...') yields the same result as my code block.
This is not about having compact graphs. It is about having readable graphs. I have already replaced the container by a container-fluid to really use my screen size for graphs, otherwise most graphs are unusable, see #293. With long edges (or long nodes), the whole graph shrinks and labels become unreadable without zooming.
One could question whether nesting levels greater than 2 or 3 are really necessary. But it really helps with refactoring and decoupling in a matured and grown code base.