Add SVG trace support for ProviderNetwork attachments

This commit is contained in:
jeremystretch 2021-07-14 15:55:18 -04:00
parent 9f615cde79
commit 8b571912cf
8 changed files with 83 additions and 38 deletions

View File

@ -349,7 +349,7 @@ class CableTraceSVG:
:param url: Hyperlink URL :param url: Hyperlink URL
:param labels: Iterable of text labels :param labels: Iterable of text labels
""" """
group = Group() group = Group(class_='connector')
# Draw cable (line) # Draw cable (line)
start = (OFFSET + self.center, self.cursor) start = (OFFSET + self.center, self.cursor)
@ -374,6 +374,29 @@ class CableTraceSVG:
return group return group
def _draw_attachment(self):
"""
Return an SVG group containing a line element and "Attachment" label.
"""
group = Group(class_='connector')
# Draw attachment (line)
start = (OFFSET + self.center, self.cursor)
height = PADDING * 2 + LINE_HEIGHT + PADDING * 2
end = (start[0], start[1] + height)
line = Line(start=start, end=end, class_='attachment')
group.add(line)
self.cursor += PADDING * 2
# Add label
self.cursor += LINE_HEIGHT
text_coords = (self.center + PADDING * 2, self.cursor - LINE_HEIGHT / 2)
text = Text('Attachment', insert=text_coords)
group.add(text)
self.cursor += PADDING * 2
return group
def render(self): def render(self):
""" """
Return an SVG document representing a cable trace. Return an SVG document representing a cable trace.
@ -383,11 +406,11 @@ class CableTraceSVG:
# Prep elements list # Prep elements list
parent_objects = [] parent_objects = []
terminations = [] terminations = []
cables = [] connectors = []
# Iterate through each (term, cable, term) segment in the path # Iterate through each (term, cable, term) segment in the path
for i, segment in enumerate(traced_path): for i, segment in enumerate(traced_path):
near_end, cable, far_end = segment near_end, connector, far_end = segment
# Near end parent # Near end parent
if i == 0: if i == 0:
@ -412,38 +435,57 @@ class CableTraceSVG:
) )
terminations.append(termination) terminations.append(termination)
# Cable # Connector (either a Cable or attachment to a ProviderNetwork)
cable = self._draw_cable( if connector is not None:
color=cable.color or '000000',
url=cable.get_absolute_url(),
labels=[f'Cable {cable}', cable.get_status_display()]
)
cables.append(cable)
# Far end termination # Cable
termination = self._draw_box( cable = self._draw_cable(
width=self.width * .8, color=connector.color or '000000',
color=self._get_color(far_end), url=connector.get_absolute_url(),
url=far_end.get_absolute_url(), labels=[f'Cable {connector}', connector.get_status_display()]
labels=[str(far_end)], )
radius=5 connectors.append(cable)
)
terminations.append(termination)
# Far end parent # Far end termination
parent_object = self._draw_box( termination = self._draw_box(
width=self.width, width=self.width * .8,
color=self._get_color(far_end.parent_object), color=self._get_color(far_end),
url=far_end.parent_object.get_absolute_url(), url=far_end.get_absolute_url(),
labels=self._get_labels(far_end.parent_object), labels=[str(far_end)],
y_indent=PADDING, radius=5
padding_multiplier=2 )
) terminations.append(termination)
parent_objects.append(parent_object)
# Far end parent
parent_object = self._draw_box(
width=self.width,
color=self._get_color(far_end.parent_object),
url=far_end.parent_object.get_absolute_url(),
labels=self._get_labels(far_end.parent_object),
y_indent=PADDING,
padding_multiplier=2
)
parent_objects.append(parent_object)
else:
# Attachment
attachment = self._draw_attachment()
connectors.append(attachment)
# ProviderNetwork
parent_object = self._draw_box(
width=self.width,
color=self._get_color(far_end),
url=far_end.get_absolute_url(),
labels=self._get_labels(far_end),
padding_multiplier=2
)
parent_objects.append(parent_object)
# Determine drawing size # Determine drawing size
self.drawing = svgwrite.Drawing( self.drawing = svgwrite.Drawing(
size=(self.width, self.cursor) size=(self.width, self.cursor + 2)
) )
# Attach CSS stylesheet # Attach CSS stylesheet
@ -451,7 +493,7 @@ class CableTraceSVG:
self.drawing.defs.add(self.drawing.style(css_file.read())) self.drawing.defs.add(self.drawing.style(css_file.read()))
# Add elements to the drawing in order of depth (Z axis) # Add elements to the drawing in order of depth (Z axis)
for element in parent_objects + terminations + cables: for element in connectors + parent_objects + terminations:
self.drawing.add(element) self.drawing.add(element)
return self.drawing return self.drawing

View File

@ -14,12 +14,15 @@ svg {
stroke-width: 1; stroke-width: 1;
} }
/* Cables */ /* Connectors */
.connector text {
text-anchor: start;
}
line { line {
stroke-width: 3; stroke-width: 3;
} }
line.attachment {
text.cable { stroke: #c0c0c0;
text-anchor: start; stroke-dasharray: 5px,5px;
} }
} }

Binary file not shown.

View File

@ -1 +1 @@
{"version":3,"sources":["_cable_trace.scss"],"names":[],"mappings":"AAAA,EACI,sBAAA,CACA,eAEJ,KACI,kBAAA,CACA,yBAKF,SACE,cAAA,CACA,eAIF,SACE,eAGF,eACE","file":"cable_trace.css","sourceRoot":"..","sourcesContent":["* {\n font-family: sans-serif;\n font-size: 13px;\n}\ntext {\n text-anchor: middle;\n dominant-baseline: middle;\n}\n\nsvg {\n /* Boxes */\n rect {\n stroke: #303030;\n stroke-width: 1;\n }\n\n /* Cables */\n line {\n stroke-width: 3;\n }\n\n text.cable {\n text-anchor: start;\n }\n}\n"]} {"version":3,"sources":["_cable_trace.scss"],"names":[],"mappings":"AAAA,EACI,sBAAA,CACA,eAEJ,KACI,kBAAA,CACA,yBAKF,SACE,cAAA,CACA,eAIF,oBACE,kBAEF,SACE,eAEF,oBACE,aAAA,CACA","file":"cable_trace.css","sourceRoot":"..","sourcesContent":["* {\n font-family: sans-serif;\n font-size: 13px;\n}\ntext {\n text-anchor: middle;\n dominant-baseline: middle;\n}\n\nsvg {\n /* Boxes */\n rect {\n stroke: #303030;\n stroke-width: 1;\n }\n\n /* Connectors */\n .connector text {\n text-anchor: start;\n }\n line {\n stroke-width: 3;\n }\n line.attachment {\n stroke: #c0c0c0;\n stroke-dasharray: 5px,5px;\n }\n}\n"]}

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long