diff --git a/examples/demo02.yml b/examples/demo02.yml
index f03e7a2b..00ee5546 100644
--- a/examples/demo02.yml
+++ b/examples/demo02.yml
@@ -13,7 +13,6 @@ ferrules:
ferrule_crimp:
type: Crimp ferrule
subtype: 0.25 mm²
- color: YE
connectors:
X1:
diff --git a/src/wireviz/Harness.py b/src/wireviz/Harness.py
index d47aa048..394640ac 100644
--- a/src/wireviz/Harness.py
+++ b/src/wireviz/Harness.py
@@ -4,7 +4,7 @@
from wireviz.DataClasses import Connector, Cable
from graphviz import Graph
from wireviz import wv_colors
-from wireviz.wv_helper import awg_equiv, mm2_equiv, tuplelist2tsv, nested, flatten2d, index_if_list
+from wireviz.wv_helper import awg_equiv, mm2_equiv, tuplelist2tsv, nested, nested_html_table, flatten2d, index_if_list, html_line_breaks, graphviz_line_breaks, remove_line_breaks
from collections import Counter
from typing import List
@@ -60,24 +60,18 @@ def create_graph(self):
for key, connector in self.connectors.items():
if connector.category == 'ferrule':
- rows = [[connector.type, connector.subtype, connector.color, '' if connector.color else None],
+ rows = [[html_line_breaks(connector.type), html_line_breaks(connector.subtype), connector.color, '' if connector.color else None],
[connector.manufacturer,
f'MPN: {connector.manufacturer_part_number}' if connector.manufacturer_part_number else None,
- f'IPN: {connector.internal_part_number}' if connector.internal_part_number else None]]
+ f'IPN: {connector.internal_part_number}' if connector.internal_part_number else None],
+ [html_line_breaks(connector.notes)]]
rows = [list(filter(None, row)) for row in rows] # remove missing attributes
- html = '
'
- for row in rows:
- if len(row) > 0:
- html = f'{html}'
- for cell in row:
- html = f'{html}{cell} | '
- html = f'{html}
|
'
- html = f'{html}
'
+ html = nested_html_table(rows)
if connector.color: # add color bar next to color info, if present
- colorbar = f' | '
- html = html.replace(' | ', colorbar)
+ colorbar = f' bgcolor="{wv_colors.translate_color(connector.color, "HEX")}" width="4">' # leave out ' tag
+ html = html.replace('> | ', colorbar)
dot.node(key, label=f'<{html}>', shape='none', margin='0', style='filled', fillcolor='white')
@@ -86,8 +80,8 @@ def create_graph(self):
f'MPN: {connector.manufacturer_part_number}' if connector.manufacturer_part_number else '',
f'IPN: {connector.internal_part_number}' if connector.internal_part_number else '']
- attributes = [connector.type,
- connector.subtype,
+ attributes = [graphviz_line_breaks(connector.type),
+ graphviz_line_breaks(connector.subtype),
f'{connector.pincount}-pin' if connector.show_pincount else'']
pinouts = [[], [], []]
for pinnumber, pinname in zip(connector.pinnumbers, connector.pinout):
@@ -98,7 +92,7 @@ def create_graph(self):
pinouts[0].append(f'{pinnumber}')
if connector.ports_right:
pinouts[2].append(f'
{pinnumber}')
- label = [connector.name if connector.show_name else '', identification, attributes, pinouts, connector.notes]
+ label = [connector.name if connector.show_name else '', identification, attributes, pinouts, graphviz_line_breaks(connector.notes)]
dot.node(key, label=nested(label))
if len(connector.loops) > 0:
@@ -132,7 +126,7 @@ def create_graph(self):
f'IPN: {cable.internal_part_number}' if (cable.internal_part_number and not isinstance(cable.internal_part_number, list)) else '']
identification = list(filter(None, identification))
- attributes = [f'{cable.type}' if cable.type else '',
+ attributes = [html_line_breaks(cable.type) if cable.type else '',
f'{len(cable.colors)}x' if cable.show_wirecount else '',
f'{cable.gauge} {cable.gauge_unit}{awg_fmt}' if cable.gauge else '',
'+ S' if cable.shield else '',
@@ -153,7 +147,7 @@ def create_graph(self):
html = f'{html}' # end identification row
html = f'{html}
' # attribute row
for attrib in attributes:
- html = f'{html}{attrib} | '
+ html = f'{html}{attrib} | '
html = f'{html}
' # attribute row
html = f'{html}' # name+attributes table
@@ -204,7 +198,7 @@ def create_graph(self):
html = f'{html}' # main table
if cable.notes:
- html = f'{html}{cable.notes} |
' # notes table
+ html = f'{html}{html_line_breaks(cable.notes)} |
' # notes table
html = f'{html} |
' # spacer at the end
html = f'{html}' # main table
@@ -308,8 +302,8 @@ def bom(self):
shared = next(iter(items.values()))
designators = list(items.keys())
designators.sort()
- conn_type = f', {shared.type}' if shared.type else ''
- conn_subtype = f', {shared.subtype}' if shared.subtype else ''
+ conn_type = f', {remove_line_breaks(shared.type)}' if shared.type else ''
+ conn_subtype = f', {remove_line_breaks(shared.subtype)}' if shared.subtype else ''
conn_pincount = f', {shared.pincount} pins' if shared.category != 'ferrule' else ''
conn_color = f', {shared.color}' if shared.color else ''
name = f'Connector{conn_type}{conn_subtype}{conn_pincount}{conn_color}'
@@ -328,7 +322,7 @@ def bom(self):
designators = list(items.keys())
designators.sort()
total_length = sum(i.length for i in items.values())
- cable_type = f', {shared.type}' if shared.type else ''
+ cable_type = f', {remove_line_breaks(shared.type)}' if shared.type else ''
gauge_name = f' x {shared.gauge} {shared.gauge_unit}' if shared.gauge else ' wires'
shield_name = ' shielded' if shared.shield else ''
name = f'Cable{cable_type}, {shared.wirecount}{gauge_name}{shield_name}'
@@ -342,7 +336,7 @@ def bom(self):
if bundle.category == 'bundle':
# add each wire from each bundle to the wirelist
for index, color in enumerate(bundle.colors, 0):
- wirelist.append({'gauge': bundle.gauge, 'gauge_unit': bundle.gauge_unit, 'length': bundle.length, 'color': color, 'designator': bundle.name,
+ wirelist.append({'type': bundle.type, 'gauge': bundle.gauge, 'gauge_unit': bundle.gauge_unit, 'length': bundle.length, 'color': color, 'designator': bundle.name,
'manufacturer': index_if_list(bundle.manufacturer, index),
'manufacturer part number': index_if_list(bundle.manufacturer_part_number, index),
'internal part number': index_if_list(bundle.internal_part_number, index)})
@@ -355,8 +349,8 @@ def bom(self):
designators = list(dict.fromkeys(designators)) # remove duplicates
designators.sort()
total_length = sum(i['length'] for i in items)
- wire_type = f', {shared["type"]}' if 'type' in shared else ''
- gauge_name = f', {shared["gauge"]} {shared["gauge_unit"]}' if 'gauge' in shared else ''
+ wire_type = f', {remove_line_breaks(shared["type"])}' if shared.get('type', None) else ''
+ gauge_name = f', {shared["gauge"]} {shared["gauge_unit"]}' if shared.get('gauge', None) else ''
gauge_color = f', {shared["color"]}' if 'color' in shared != '' else ''
name = f'Wire{wire_type}{gauge_name}{gauge_color}'
item = {'item': name, 'qty': round(total_length, 3), 'unit': 'm', 'designators': designators,
diff --git a/src/wireviz/wv_helper.py b/src/wireviz/wv_helper.py
index 69d65507..83ee46ee 100644
--- a/src/wireviz/wv_helper.py
+++ b/src/wireviz/wv_helper.py
@@ -44,6 +44,20 @@ def nested(inp):
l.append(str(x))
return '|'.join(l)
+def nested_html_table(rows):
+ # input: list of lists
+ # output: a parent table with one child table per parent list item
+ # purpose: create the appearance of one table, where cell widths are independent between rows
+ html = ''
+ for row in rows:
+ if len(row) > 0:
+ html = f'{html}'
+ for cell in row:
+ html = f'{html}{cell} | '
+ html = f'{html}
|
'
+ html = f'{html}
'
+ return html
+
def int2tuple(inp):
if isinstance(inp, tuple):
@@ -69,3 +83,12 @@ def tuplelist2tsv(inp, header=None):
# Return the value indexed if it is a list, or simply the value otherwise.
def index_if_list(value, index):
return value[index] if isinstance(value, list) else value
+
+def html_line_breaks(inp):
+ return inp.replace('\n', '
') if isinstance(inp, str) else inp
+
+def graphviz_line_breaks(inp):
+ return inp.replace('\n', '\\l') if isinstance(inp, str) else inp # \l generates left-aligned new lines. http://www.graphviz.org/doc/info/attrs.html#k:escString
+
+def remove_line_breaks(inp):
+ return inp.replace('\n', ' ').rstrip() if isinstance(inp, str) else inp
diff --git a/tutorial/tutorial06.yml b/tutorial/tutorial06.yml
index 7ff042f8..f69499c3 100644
--- a/tutorial/tutorial06.yml
+++ b/tutorial/tutorial06.yml
@@ -5,7 +5,7 @@ connectors:
subtype: female
F_10_1: # manually define a ferrule (with unique designator)
category: ferrule
- type: Crimp ferrule
+ type: Ferrule, crimp
subtype: 1.0 mm²
color: YE