Implement bundle part number rendering

This commit is contained in:
Daniel Rojas 2022-08-05 16:52:24 +02:00 committed by Laurier Loiselle
parent df914dabce
commit 38f8147a7f
No known key found for this signature in database
GPG Key ID: 345920CC72089A3F
3 changed files with 67 additions and 75 deletions

View File

@ -42,14 +42,42 @@ PART_NUMBER_HEADERS = PartNumberInfo(
)
def partnumbers_to_list(partnumbers: PartNumberInfo) -> List[str]:
cell_contents = [
pn_info_string(PART_NUMBER_HEADERS.pn, None, partnumbers.pn),
pn_info_string(
def partnumbers2list(
partnumbers: PartNumberInfo, parent_partnumbers: PartNumberInfo = None
) -> List[str]:
if parent_partnumbers is None:
_is_toplevel = True
parent_partnumbers = partnumbers
else:
_is_toplevel = False
# Note: != operator used as XOR in the following section (https://stackoverflow.com/a/433161)
if _is_toplevel != isinstance(parent_partnumbers.pn, List):
# top level and not a list, or wire level and list
cell_pn = pn_info_string(PART_NUMBER_HEADERS.pn, None, partnumbers.pn)
else:
# top level and list -> do per wire later
# wire level and not list -> already done at top level
cell_pn = None
if _is_toplevel != isinstance(parent_partnumbers.mpn, List):
# TODO: edge case: different manufacturers, but same MPN?
cell_mpn = pn_info_string(
PART_NUMBER_HEADERS.mpn, partnumbers.manufacturer, partnumbers.mpn
),
pn_info_string(PART_NUMBER_HEADERS.spn, partnumbers.supplier, partnumbers.spn),
]
)
else:
cell_mpn = None
if _is_toplevel != isinstance(parent_partnumbers.spn, List):
# TODO: edge case: different suppliers, but same SPN?
cell_spn = pn_info_string(
PART_NUMBER_HEADERS.spn, partnumbers.supplier, partnumbers.spn
)
else:
cell_spn = None
cell_contents = [cell_pn, cell_mpn, cell_spn]
if any(cell_contents):
return [html_line_breaks(cell) for cell in cell_contents]
else:

View File

@ -630,18 +630,20 @@ class Cable(TopLevelGraphicalComponent):
return desc
def _get_wire_partnumber(self, idx) -> PartNumberInfo:
def _get_correct_element(inp, idx):
return inp[idx] if isinstance(inp, List) else inp
# TODO: possibly make more robust/elegant
if self.category == "bundle":
if isinstance(self.partnumbers.pn, List):
return PartNumberInfo(
self.partnumbers.pn[idx],
self.partnumbers.manufacturer[idx],
self.partnumbers.mpn[idx],
self.partnumbers.supplier[idx],
self.partnumbers.spn[idx],
)
else:
return None
return PartNumberInfo(
_get_correct_element(self.partnumbers.pn, idx),
_get_correct_element(self.partnumbers.manufacturer, idx),
_get_correct_element(self.partnumbers.mpn, idx),
_get_correct_element(self.partnumbers.supplier, idx),
_get_correct_element(self.partnumbers.spn, idx),
)
else:
return None # non-bundles do not support lists of part data
def __post_init__(self) -> None:
@ -654,6 +656,10 @@ class Cable(TopLevelGraphicalComponent):
if isinstance(self.image, dict):
self.image = Image(**self.image)
# TODO:
# allow gauge, length, and other fields to be lists too (like part numbers),
# and assign them the same way to bundles.
self.gauge = self.parse_number_and_unit(self.gauge, "mm2")
self.length = self.parse_number_and_unit(self.length, "m")
self.amount = self.length # for BOM
@ -690,17 +696,6 @@ class Cable(TopLevelGraphicalComponent):
# if lists of part numbers are provided,
# check this is a bundle and that it matches the wirecount.
# TODO:
# if it is a bundle, each wire will show up as separate BOM entry.
# therefore, for any bundle, pn info should be inherited into the wire objects.
# if a field is a list, then assign each wire its corresponding entry from that list, by index.
# if a field is not a list, assign all wires in the cable the same field value, assumed to be valid for all wires.
# then, checking whether bundle or not is the only check required to decide how to handle bom info.
# TODO:
# allow gauge, length, and other fields to be lists too, and assign them the same way to bundles.
for idfield in [self.manufacturer, self.mpn, self.supplier, self.spn, self.pn]:
if isinstance(idfield, list):
if self.category == "bundle":

View File

@ -5,7 +5,7 @@ from itertools import zip_longest
from typing import Any, List, Optional, Union
from wireviz import APP_NAME, APP_URL, __version__
from wireviz.wv_bom import partnumbers_to_list
from wireviz.wv_bom import partnumbers2list
from wireviz.wv_colors import MultiColor
from wireviz.wv_dataclasses import (
ArrowDirection,
@ -37,7 +37,7 @@ def gv_node_component(component: Component) -> Table:
else:
line_name = None
line_pn = partnumbers_to_list(component.partnumbers)
line_pn = partnumbers2list(component.partnumbers)
is_simple_connector = (
isinstance(component, Connector) and component.style == "simple"
@ -283,7 +283,6 @@ def gv_conductor_table(cable) -> Table:
cells_above = [
Td(" " + ", ".join(ins), align="left"),
# Td(":-)"),
Td(bom_bubble(wire.bom_id)) if cable.category == "bundle" else None,
Td(":".join([wi for wi in wireinfo if wi is not None and wi != ""])),
Td(", ".join(outs) + " ", align="right"),
@ -295,8 +294,20 @@ def gv_conductor_table(cable) -> Table:
rows.append(Tr(gv_wire_cell(wire, len(cells_above))))
# row below the wire
# TODO: PN stuff for bundles
# wire_pn_stuff() see below
if wire.partnumbers:
cells_below = partnumbers2list(
wire.partnumbers, parent_partnumbers=cable.partnumbers
)
if cells_below is not None and len(cells_below) > 0:
table_below = (
Table(
Tr([Td(cell) for cell in cells_below]),
border=0,
cellborder=0,
cellspacing=0,
),
)
rows.append(Tr(Td(table_below, colspan=len(cells_above))))
rows.append(Tr(Td(" "))) # spacer row on bottom
tbl = Table(rows, border=0, cellborder=0, cellspacing=0)
@ -334,48 +345,6 @@ def gv_wire_cell(wire: Union[WireClass, ShieldClass], colspan: int) -> Td:
return wire_outer_cell
def wire_pn_stuff():
# # for bundles, individual wires can have part information
# if cable.category == "bundle":
# # create a list of wire parameters
# wireidentification = []
# if isinstance(cable.pn, list):
# wireidentification.append(
# pn_info_string(
# HEADER_PN, None, remove_links(cable.pn[i - 1])
# )
# )
# manufacturer_info = pn_info_string(
# HEADER_MPN,
# cable.manufacturer[i - 1]
# if isinstance(cable.manufacturer, list)
# else None,
# cable.mpn[i - 1] if isinstance(cable.mpn, list) else None,
# )
# supplier_info = pn_info_string(
# HEADER_SPN,
# cable.supplier[i - 1]
# if isinstance(cable.supplier, list)
# else None,
# cable.spn[i - 1] if isinstance(cable.spn, list) else None,
# )
# if manufacturer_info:
# wireidentification.append(html_line_breaks(manufacturer_info))
# if supplier_info:
# wireidentification.append(html_line_breaks(supplier_info))
# # print parameters into a table row under the wire
# if len(wireidentification) > 0:
# # fmt: off
# wirehtml.append(' <tr><td colspan="3">')
# wirehtml.append(' <table border="0" cellspacing="0" cellborder="0"><tr>')
# for attrib in wireidentification:
# wirehtml.append(f" <td>{attrib}</td>")
# wirehtml.append(" </tr></table>")
# wirehtml.append(" </td></tr>")
# # fmt: on
pass
def gv_edge_wire(harness, cable, connection) -> (str, str, str):
if connection.via.color:
# check if it's an actual wire and not a shield