mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-23 17:08:41 -06:00
Add SVG trace support for ProviderNetwork attachments
This commit is contained in:
parent
9f615cde79
commit
8b571912cf
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
netbox/project-static/dist/cable_trace.css
vendored
BIN
netbox/project-static/dist/cable_trace.css
vendored
Binary file not shown.
@ -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"]}
|
BIN
netbox/project-static/dist/netbox-dark.css
vendored
BIN
netbox/project-static/dist/netbox-dark.css
vendored
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
netbox/project-static/dist/netbox-light.css
vendored
BIN
netbox/project-static/dist/netbox-light.css
vendored
Binary file not shown.
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user