mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-22 20:12:00 -06:00
Closes #19902: add clip path to avoid overflow of device name, truncate text to improve centering (#19913)
This commit is contained in:
parent
2129355c30
commit
d571cb4867
@ -3,6 +3,7 @@ import svgwrite
|
||||
from svgwrite.container import Hyperlink
|
||||
from svgwrite.image import Image
|
||||
from svgwrite.gradients import LinearGradient
|
||||
from svgwrite.masking import ClipPath
|
||||
from svgwrite.shapes import Rect
|
||||
from svgwrite.text import Text
|
||||
|
||||
@ -67,6 +68,20 @@ def get_device_description(device):
|
||||
return description
|
||||
|
||||
|
||||
def truncate_text(text, width, font_size=15):
|
||||
"""
|
||||
Truncate text to fit within the width of a rectangle.
|
||||
|
||||
:param text: The text to truncate
|
||||
:param width: Width of rectangle
|
||||
:param font_size: Font size (default is 15, ~0.875rem)
|
||||
"""
|
||||
char_width = font_size * 0.6 # 0.6 is an approximation of the average character width in pixels
|
||||
max_char = int(width / char_width)
|
||||
|
||||
return text if len(text) <= max_char else text[:max_char] + '...'
|
||||
|
||||
|
||||
class RackElevationSVG:
|
||||
"""
|
||||
Use this class to render a rack elevation as an SVG image.
|
||||
@ -177,12 +192,26 @@ class RackElevationSVG:
|
||||
link = Hyperlink(href=f'{self.base_url}{device.get_absolute_url()}', target="_parent")
|
||||
link.set_desc(description)
|
||||
|
||||
# Create clipPath element
|
||||
# This is necessary as fallback because the truncate_text method is an approximation
|
||||
clip_id = f"clip-{device.id}"
|
||||
clip_path = ClipPath(id=clip_id)
|
||||
clip_path.add(Rect(coords, size))
|
||||
|
||||
self.drawing.defs.add(clip_path)
|
||||
|
||||
# Name to display
|
||||
display_name = truncate_text(name, size[0])
|
||||
|
||||
# Add rect element to hyperlink
|
||||
if color:
|
||||
link.add(Rect(coords, size, style=f'fill: #{color}', class_=f'slot{css_extra}'))
|
||||
else:
|
||||
link.add(Rect(coords, size, class_=f'slot blocked{css_extra}'))
|
||||
link.add(Text(name, insert=text_coords, fill=text_color, class_=f'label{css_extra}'))
|
||||
link.add(
|
||||
Text(display_name, insert=text_coords, fill=text_color, clip_path=f"url(#{clip_id})",
|
||||
class_=f'label{css_extra}')
|
||||
)
|
||||
|
||||
# Embed device type image if provided
|
||||
if self.include_images and image:
|
||||
|
Loading…
Reference in New Issue
Block a user