wireviz / WireViz

Easily document cables and wiring harnesses.
GNU General Public License v3.0
4.23k stars 218 forks source link

Ability to Specify Jumpers #286

Open AlanLivingston opened 1 year ago

AlanLivingston commented 1 year ago

Currently, if I want to jump from a connector pin 3 to pin 4, I have to create a wire set, and in the connections, specify the connection like: connectors: X6: pinlabels: [+28VDC, +28VDC RTN, Token-In REF, Token-In, NC, NC, RS-485+, RS-485-, RS-485 Shield] type: P1 `cables:` ` W5:` ` colors: [BU]` connections: - - X6: 3 - W5: 1 - X6: 4

But this creates a very bulky diagram, when what I really want is a jumper from pin 3 to pin 4 on the left side of connector X6.

kvid commented 1 year ago

I agree the current version (v0.3.2) doesn't handle such loops in the diagram very well, but there is an optional loops attribute you can use for connectors that should fit well in your use case:

connectors:
  X6:
    pinlabels: [+28VDC, +28VDC RTN, Token-In REF, Token-In, NC, NC, RS-485+, RS-485-, RS-485 Shield]
    type: P1
    loops:
      - [3, 4]

issue286-loop

See the syntax doc, and also #48 where this feature and some possible alternatives are discussed.

AlanLivingston commented 1 year ago

I missed the loops attribute. That is, indeed, what I wanted.

As mentioned in #48, the length of the shorting wire needs some control. It overlapped the wire description box:

image

I was able to work around this by reordering the pins:

  X2:   # D369-P99-NS1
    pins: [1, 2, 5, 6, 7, 8, 9, 3, 4]
    pinlabels: [+28VDC, +28VDC RTN, NC, NC, RS-485+, RS-485-, RS-485 Shield, Token-In REF, Token-In]
    type: P1
    subtype: Deutsch D369-P99-NS1 9-Pin Receptacle Connector
    loops:
      - [8, 9]

image

I had to refer to the loop by the pin index within pins, and not its value. I don't know if this is intended or a bug.

Anyway, I have a suitable solution. Thanks!

kvid commented 1 year ago

I missed the loops attribute. That is, indeed, what I wanted.

👍

As mentioned in #48, the length of the shorting wire needs some control. It overlapped the wire description box:

Suggestions about how to solve this are welcome! The overlap and spline lengths are controlled by the Graphviz dot tool, and I don't know if any of the input parameters of this tool can override such features.

I had to refer to the loop by the pin index within pins, and not its value. I don't know if this is intended or a bug.

I would say it sounds like an unwanted feature.

riv-david commented 1 year ago

A quick hacky solution would be to increase or give control of the spacing for tables such that the loops generated wouldn't overlap them.

moving X2 table 30mm to the right would make this useable

image

kvid commented 1 year ago

Increasing the horizontal spacing, as suggested by @rr-david, can be done like this:

connectors:
  X2:
    pinlabels: [+28VDC, +28VDC RTN, Token-In REF, Token-In, NC, NC, RS-485+, RS-485-, RS-485 Shield]
    type: P1
    loops:
      - [3, 4]
cables:
  W1:
    colors: [RD, BK, IV, BU, GN]
connections:
  - - W1: [1-5]
    - X2: [1-2, 7-9]
tweak:
  override:
    graph:
      ranksep: "3"  # Increase the horizontal spacing (default 2)

However, be aware that this is a global setting that affects spacing in the whole diagram. issue286-loop2-

blackbit42 commented 1 year ago

Increasing the horizontal spacing is useful for the current implementation of loops as it helps with the wire table not overlapping the loop(s). Though, doing so is only necessary because loops are currently very pronounced... well, loops.

Is there perhaps a clever way to use GraphViz tweaking to influence the appearance of loops?

In case that cannot be done just for loops, I could imagine that a hint to GraphViz not to generally make bends less pronounced on a global level would potentially not hurt regular wires much but improve the appearance of loops.

kvid commented 1 year ago

@blackbit42 wrote:

Increasing the horizontal spacing is useful for the current implementation of loops as it helps with the wire table not overlapping the loop(s). Though, doing so is only necessary because loops are currently very pronounced... well, loops.

How wide the loops become seems to be dependent on other elements in the diagram, their spacing, or some other relations. Compare the small loop in my single connector diagram above with the wider loops in the larger diagrams. This dependency is also mentioned in #288.

The reason behind such a difference has to be connected to the internal algorithms of Graphviz - that I don't know much about. Please search/ask at Graphviz user phorums to investigate further.

Is there perhaps a clever way to use GraphViz tweaking to influence the appearance of loops?

I recommend editing the .gv file to try out possible changes and run it through the Graphviz dot tool to see the result. When you know what to change, then we can see if it can be done with the tweak functionality.

In case that cannot be done just for loops, I could imagine that a hint to GraphViz not to generally make bends less pronounced on a global level would potentially not hurt regular wires much but improve the appearance of loops.

This is a question you should ask at some Graphviz phorum. In #3 you can find some examples on advanced Graphviz attributes for controlling the wire curves in a twisted wire usecase, and in #120 you can find some alternative ways to call Graphviz. Maybe any of those can be of any help.

kvid commented 2 months ago

I stumbled on a possible solution to this issue today when reading this: https://stackoverflow.com/questions/70996779/graphviz-edges-between-cells-in-the-same-html-table-are-too-long

@AlanLivingston, @rr-david, @blackbit42, and others with similar use cases - please try this work-around (adding an empty label to all edges) for your use cases, and report here if it works or if you find any unexpected side effects:

connectors:
  X2:
    pinlabels: [+28VDC, +28VDC RTN, Token-In REF, Token-In, NC, NC, RS-485+, RS-485-, RS-485 Shield]
    type: P1
    loops:
      - [3, 4]
cables:
  W1:
    colors: [RD, BK, IV, BU, GN]
connections:
  - - W1: [1-5]
    - X2: [1-2, 7-9]
tweak:
  override:
    edge:
      label: " "

issue286-loop3-

martinrieder commented 2 months ago

Instead of defining the loop by a single edge, I would simply split it into two edges, running through a node (shape as either point or none). This should allow for a higher degree of freedom for Graphviz. Another side effect is that it will avoid edges overlapping the nodes. In effect, this is similar to the concept of virtual splices.

The definition of a "jumper cable" is possible though, which could even be associated with more than two pins. This cable would connect all loop wires into a virtual splice. It also allows the loop/jumper to be displayed with some wire definitions, if needed.

explicit

Using a tweak, you could hide/shrink the cable and the splice for this approach:

tweak:
  override:
    SPLICE:
      shape: point
    JUMPER:
      style: invis
      fixedsize: "true"

implicit

Refer to the example that I provided for displaying twisted wires https://github.com/wireviz/WireViz/issues/3#issuecomment-2109969132

tobiasfalk commented 1 month ago

Wouldn't be a solution similar to this betrer: IMG-20240517-WA0008.jpg

This way the Jumper can not interfier with any wires and it is clear that Jumpers are meant.

kvid commented 1 month ago

@tobiasfalk - your suggestion is very similar to the 4 year old suggestion in https://github.com/wireviz/WireViz/issues/48#issuecomment-656802355.

If you find a way to implement this in the Graphviz HTML syntax (in a .gv file), please share that - preferably in a new issue (or PR if you create code for it too). Such a visualization might also be useful for other features.

tobiasfalk commented 1 month ago

@kvid I have no idea about GraphViz, it was only a idea that I thought I share

tobiasfalk commented 1 month ago

I have tried this in the table:

   <tr>
    <td port="p1l">1</td>
    <td>+28VDC</td>
    <td port="p1J">&#11044;</td>
   </tr>
   <tr>
    <td port="p2l">2</td>
    <td>+28VDC RTN</td>0x00002B24
    <td port="p2J">⬤</td>
   </tr>

and:

    X2:p1J:c -- X2:p2J:c

And the SVG displays the Circle quite nicely, but the PNG is the Problem: SVG(converted with Inkscape: test_gv_ink PNG: test_gv

I also do not know how to make the strait lines between the centers of the circles but one step at a time.

tobiasfalk commented 1 month ago

The Problem seams to be the font(arial) what is a bit confusing. By setting it to Adobe Kaiti Std it works but I get this: (dot.exe:19780): Pango-WARNING **: couldn't load font "Adobe Kaiti Std Not-Rotated 14", falling back to "Sans Not-Rotated 14", expect ugly output. https://stackoverflow.com/questions/6743382/graphviz-not-supporting-utf-8-encoding

martinrieder commented 1 month ago

@tobiasfalk The PNG rendering is a Unicode issue that can probably be solved. See here: https://graphviz.org/doc/char.html I am not sure how you would get the edge rendered in a straight dashed line though....

Note that I have updated https://github.com/wireviz/WireViz/issues/286#issuecomment-2116112620 with some pictures above.

tobiasfalk commented 1 month ago

It works when specefing the font: <FONT FACE="Sans Not-Rotated 14" POINT-SIZE="13.0">&#11044;</FONT> The point sice change, since the circle would be clipd on the bottom if not

tobiasfalk commented 1 month ago

For the beginngin something without the doted line between the circle could be a start: test_gv

tobiasfalk commented 1 month ago

Here they talk about starting the line in the center of the node, with this it should be posible to do the dotet lines between the Point/Circles. I am currently not at my PC so I am not able to try it.

tobiasfalk commented 1 month ago

It seams with when the attributes [headclip=false, tailclip=false] are set this way than it begins and ends in the center but also is straight. Edit: One most likely also needs to write node:c that it works

tobiasfalk commented 1 month ago

Since doing the dashed line between the point may be not possible or at least quite hard, I though that coloring the point could improve readability. I also asked for help on the WireViz forum: https://forum.graphviz.org/t/straitening-one-line-throu-a-table/2196

martinrieder commented 4 weeks ago

@AlanLivingston please verify, if PR #369 by @tobiasfalk poses an even better solution to your issue.

@AlanLivingston wrote:

I missed the loops attribute. That is, indeed, what I wanted. [...] Anyway, I have a suitable solution. Thanks!

I propose to close this issue and continue the discussion here:

AlanLivingston commented 4 weeks ago

From the diagrams, PR #369 is preferable to me. I'll have to figure out how to build the development branch to test.

AlanLivingston commented 4 weeks ago

I performed a quick test with the code that's in branch pr/369, adding an example ajl.yml and letting build_examples build it.

The resulting .png file didn't render the black dot, instead a rectangle with numbering is rendered. The svg has the black circle, but the connecting lines are not centered.

I believe both of these issues are mentioned in #350 but maybe the changes didn't make it into the PR?

martinrieder commented 4 weeks ago

@AlanLivingston Seems to be a Unicode issue. What is your system configuration? Which version of Graphviz are you using? Could you upload the ajl.yml file here, so @tobiasfalk and myself can try to reproduce it?

AlanLivingston commented 4 weeks ago

Here's the yaml:

connectors: # This is based on ex1 and adds some Shorts to the connectors
X1: # An example of Shorts with more information
  pinlabels: [GND, VCC, RX, TX, GND, VCC, GND]
X2: # An example of a simple short definition
  pinlabels: [GND, VCC, RX, TX, GND, VCC, GND]
  shorts: # The definition is the same as above but there is no additional_components for more information
    - SH1: [1, 5, 7]
    - SH2: [2, 6]

cables:
  W1:
    wirecount: 4
    shield: true

connections:
  -
    - X1: [1-4]
    - W1: [1-4]
    - X2: [1,2,4,3]
  -
    - X1: 1
    - W1: s

graphviz v0.20.3 Python v3.12.3 Windows 11 23H2 OS Build 22631.3737

martinrieder commented 4 weeks ago

Your connectors need some indentation, otherwise they will not be recognized at all.

AlanLivingston commented 4 weeks ago

Your connectors need some indentation, otherwise they will not be recognized at all.

I think that's because I suck at GitHub markdown! X1 and X2 are indented in the .yml file.

AlanLivingston commented 4 weeks ago

Here's the file, renamed as .log so GitHub will link it. It's really ajl.yml.

ajl.log

tobiasfalk commented 4 weeks ago

I am using Win10 with dot - graphviz version 11.0.0 (20240428.1522) and the PNG output works fine: ex17

I have created a new branch (Jumpes_sync)where I removed the Face attribute for the Black Circle, this breaks it on my system, but could you try it? My result(PNG): ex17

tobiasfalk commented 4 weeks ago

@AlanLivingston Your YAML code is ex17

tobiasfalk commented 4 weeks ago

As for the offset Circle in SVG, I have no Idea how to solve this, since this is a GraphViz Problem, mentioned here https://github.com/wireviz/WireViz/issues/350#issuecomment-2119239205 or scnorth@https://forum.graphviz.org/t/text-in-table-in-svg-output-not-completly-centered/2199

That’s curious. The native SVG driver is capable of generating text using text-anchor="middle", but the HTML table rows use text-anchor="start". Because the downstream SVG renderer cannot be relied on to use the same fonts or to render them in the same way as when Graphviz computes text box sizes, this can happen. Maybe the problem would be solved by using dot -Tsvg:cairo because cairo embeds fonts in the output (which is more precise, but at the cost of larger SVG files that are more difficult to process downstream and for humans to read and understand.)

Someone could also look into whether lib/common/htmltable.c could be enhanced to call gvrender_textspan() with centered instead of left-justified text as needed. Offhand my hunch is this may not be as obviously easy as one might hope.

This would require a separate Cairo installation that currently can not be achieved with pip (to my knowledge) and I tried many things and was not able to install it in a way that I could test dot -Tsvg:cairo. Side note, if one is able to enable this with a pip install of GraphViz and Cairo it would also allow many other cool SVG inserten and manupulation stuff, but to be honest it was not on my top priorety list.

tobiasfalk commented 3 weeks ago

@AlanLivingston Could you also try https://github.com/tobiasfalk/WireViz/tree/Jumpers_Test_2 with some other changes, in this branch ex17(your code) does not exist, but you can look at ex15.

AlanLivingston commented 3 weeks ago

Here's ex17.png from branch Jumpes_sync:

ex17

And here's ex15.png from Jumpers_Test_2:

ex15

martinrieder commented 3 weeks ago

@AlanLivingston wrote:

graphviz v0.20.3

This is the latest version of the Python wrapper from PyPI, not the actual version of the Graphviz executable from www.graphviz.org

AlanLivingston commented 3 weeks ago

I realized that this morning after trying to match Tobias' graphviz version. The version I have installed is 11.0.0:

C:\Users\alivingston>dot -v dot - graphviz version 11.0.0 (20240428.1522) libdir = "C:\Program Files\Graphviz\bin" Activated plugin library: gvplugin_dot_layout.dll Using layout: dot:dot_layout Activated plugin library: gvplugin_core.dll Using render: dot:core Using device: dot:dot:core The plugin configuration file: C:\Program Files\Graphviz\bin\config6 was successfully loaded. render : cairo dot dot_json fig gdiplus json json0 map mp pic pov ps svg svg_inline tk xdot xdot_json layout : circo dot fdp neato nop nop1 nop2 osage patchwork sfdp twopi textlayout : textlayout device : bmp canon cmap cmapx cmapx_np dot dot_json emf emfplus eps fig gif gv imap imap_np ismap jpe jpeg jpg json json0 metafile mp pdf pic plain plain-ext png pov ps ps2 svg svg_inline svgz tif tiff tk xdot xdot1.2 xdot1.4 xdot_json loadimage : (lib) bmp eps gif jpe jpeg jpg png ps svg

tobiasfalk commented 3 weeks ago

I am working on a solution with a image of a Black circle instead. This should sollen the Charakter debacle and the maybe the SVG offset problem, but I am not sure about the later one.

tobiasfalk commented 3 weeks ago

@AlanLivingston could you test the latest Version of my Jumpers Branch, it now no longer uses characters but some GraphViz magic to draw dots at the ends of lines

tobiasfalk commented 3 weeks ago

This not only eliminates potential Character Problems but also solves the SVG offset problem. It also does not requere any Pictures or so to be inserted, which may bloade files or make processing longer My ex15: ex15

AlanLivingston commented 3 weeks ago

I concur. I tested on my system with both ex15.yml and my funky test, ajl.yml, and both .png and .svg files render properly!

formatc1702 commented 3 days ago

Those latest renders look excellent!

My main thought is whether the individual short groups need to have names (SH1, SH2), or if in most cases, it would be obvious by seeing which pins are shorted (all GNDs, all VCCs, ...) and having duplicate info just clutters the table. There's a point to be made for both variants, and the header row could be omitted if no named short lists exist (see image below).

shorts:
- [1,2,3]  # if its obvious
- NAME: [4,5,6]  # if it's not

The other question is whether "shorts" is the proper word, since to me, a short circuit sounds like a fault. Some words that come to mind: jumpers, joints, common, shared, bridge(d)

Final point: having colorful short dots could be helpful, but I would lean towards black lines+dots, with optional colorful filling, to preserve full legibility even when printing in B&W or using very light colors (yellow, white). Bonus points for adding some white outline to avoid collisions between the "short lines" and the table borders!

image

tobiasfalk commented 3 days ago

My main thought is whether the individual short groups need to have names (SH1, SH2), or if in most cases, it would be obvious by seeing which pins are shorted (all GNDs, all VCCs, ...) and having duplicate info just clutters the table. There's a point to be made for both variants, and the header row could be omitted if no named short lists exist (see image below).

shorts:
- [1,2,3]  # if its obvious
- NAME: [4,5,6]  # if it's not

You are right about both, for not showing the short name in the diagram, I would add the option to hide them. For not having names, I can currently not test how to do this but it is highly possible that it may not possible to Mix both. Partially because not having names I directly Sets the hide names to true.

The other question is whether "shorts" is the proper word, since to me, a short circuit sounds like a fault. Some words that come to mind: jumpers, joints, common, shared, bridge(d)

I see your point, and yes Jumpers or Bridges Sound good.

Final point: having colorful short dots could be helpful, but I would lean towards black lines+dots, with optional colorful filling, to preserve full legibility even when printing in B&W or using very light colors (yellow, white).

Not sure if I currently can color the dot like it is in your example, but yes makes sense.

Bonus points for adding some white outline to avoid collisions between the "short lines" and the table borders!

So you want the line color String something like this: <bgk_color>::BLACK::<bgk_color>

bgk_color: Background Color, since this may not be white.

martinrieder commented 3 days ago

My ex15: ex15

Comparing the left and right connector, I came to realize, a systematic behavior should define which columns the Jumpers are drawn into. Pin numbers may appear on the left or right side, sometimes even both. Should the pin names and labels really be separated from their numbers (as seen in the left connector)?

formatc1702 commented 3 days ago

Should the pin names and labels really be separated from their numbers?

I've split off this discussion into #404

formatc1702 commented 3 days ago

Comparing the left and right connector, I came to realize, a systematic behavior should define which columns the Jumpers are drawn into.

Regarding the order in which individual jumpers should appear (left to right), the simplest solution would be, the topmost pin that is part of a jumper set gets the leftmost column, and so on successively. Another (even simpler, code-wise) option is listing them simply in the order in which they were defined.

Theoretically, it could be possible to stack jumper sets vertically if there is no collision (e.g. pins 1+2 shorted, pins 3+4 shorted, pins 5+6 shorted, could all share one column), but this breaks down if jumper sets are meant to be named, and the algorithm will be more complex ;-)

Systematic vs compact (neater but difficult to implement for labeled jumper sets) image image

More complex example, systematic vs compact. A bit contrived maybe, but worth thinking about.

image
martinrieder commented 3 days ago

How about an explicit definition of the compact jumper set?

shorts:
- [ [1,2], [3,4] ]  # 1st column
- NAME: [5,6] # 2nd column named

I would vote against some magical algorithm that reorders things on its own.

formatc1702 commented 3 days ago

After some thinking, my preference would be, no smart nesting, and use the order in which they are defined, to preserve the intention of the harness designer. E.g. they could want a pin-wise systematic ordering (as I sketched above), alphabetical based on the name of the jumper set, by groups (GND first, then voltages ascending, ...).

shorts:
- [ [1,2], [3,4] ]  # 1st column
- NAME: [5,6] # 2nd column named

I like the approach! Code would need to handle lists (unnamed sets), dicts (named sets) and lists of lists (multiple sets in one column).

And what happens if there's a collision within a column that would cause the sets to be drawn on top of each other?

shorts:
- [ [1,3], [2,4] ]
tobiasfalk commented 3 days ago

How about an explicit definition of the compact jumper set?

shorts:
- [ [1,2], [3,4] ]  # 1st column
- NAME: [5,6] # 2nd column named

I would vote against some magical algorithm that reorders things on its own.

Yes, it could be done and looks good, but I would for now implement the "basic" jumpers, maybe without naming, but I would make naming mandatory at the beginning and then add the option to not display the name and after thet that the name is not needed in the syntax. When these are done, I would add the adition of having a list of jumpers in one jumper instance(your #1 colomm), maybe with colistition detection. Another option would be to automatically change the color of the line(maybe with a black border) when a collisions occurs.

tobiasfalk commented 3 days ago

How about an explicit definition of the compact jumper set?

shorts:
- [ [1,2], [3,4] ]  # 1st column
- NAME: [5,6] # 2nd column named

I would vote against some magical algorithm that reorders things on its own.

Yes, it could be done and looks good, but I would for now implement the "basic" jumpers, maybe without naming, but I would make naming mandatory at the beginning and then add the option to not display the name and after thet that the name is not needed in the syntax. When these are done, I would add the adition of having a list of jumpers in one jumper instance(your #1 colomm), maybe with colistition detection. Another option would be to automatically change the color of the line(maybe with a black border) when a collisions occurs.

kvid commented 3 days ago

As an additional usage of such optional labels in both loops and shorts, I suggested in my https://github.com/wireviz/WireViz/issues/224#issuecomment-2163805131 to optionally allow specifying more details of each entry as equally labeled entries in additional_components in the same connector, but still allowing labeled and unlabeled loops/shorts entries without matching entries in additional_components, and also still allowing other entries in additional_components that don't match any loops/shorts.

My main motivation was to avoid separate lists with very similar entries of loop wires, short components, and the general additional_components. A future benefit might be to also allow the dot syntax for such labels (I also called them Local designators) to support both named and unnamed entries, etc.