Device names overflow rack unit boundaries in SVG rendering #11389

Closed
opened 2025-12-29 21:44:31 +01:00 by adam · 5 comments
Owner

Originally created by @MarcoSpiz on GitHub (Jul 17, 2025).

Originally assigned to: @MarcoSpiz on GitHub.

NetBox version

v4.3.4

Feature type

Change to existing functionality

Proposed functionality

In the rack elevation SVG rendering, device names should be automatically truncated if they exceed a reasonable length, to ensure they remain within the visual bounds of the device slot. The truncation should append an ellipsis (…) to indicate the text was shortened. This approach preserves readability and prevents label overflow without requiring layout changes.

A possible implementation could be:
dcim/svg/racks.py

def _truncate_text(self, text, max_chars):
    return text if len(text) <= max_chars else text[:max_chars - 1] + '…'

And in the _draw_device method:

font_size = 14  # derived from .875rem = 14px
char_width = font_size * 0.6  # average character width in px
max_chars = int(size[0] / char_width)
display_name = self._truncate_text(name, max_chars)
...
link.add(Text(display_name, ...)

From this:

Image

To this:
Image

Use case

This functionality increases the usability of the elevation function, allowing good graphic rendering even with long names,
without removing any functionality, still allowing users to see the complete name by hovering over it with the mouse.

Database changes

No response

External dependencies

No response

Originally created by @MarcoSpiz on GitHub (Jul 17, 2025). Originally assigned to: @MarcoSpiz on GitHub. ### NetBox version v4.3.4 ### Feature type Change to existing functionality ### Proposed functionality In the rack elevation SVG rendering, device names should be automatically truncated if they exceed a reasonable length, to ensure they remain within the visual bounds of the device slot. The truncation should append an ellipsis (…) to indicate the text was shortened. This approach preserves readability and prevents label overflow without requiring layout changes. A possible implementation could be: `dcim/svg/racks.py` ```python def _truncate_text(self, text, max_chars): return text if len(text) <= max_chars else text[:max_chars - 1] + '…' ``` And in the `_draw_device` method: ```python font_size = 14 # derived from .875rem = 14px char_width = font_size * 0.6 # average character width in px max_chars = int(size[0] / char_width) display_name = self._truncate_text(name, max_chars) ... link.add(Text(display_name, ...) ``` From this: <img width="319" height="126" alt="Image" src="https://github.com/user-attachments/assets/50b9ea90-ca31-442d-8c1f-10fda59f39a6" /> To this: <img width="387" height="228" alt="Image" src="https://github.com/user-attachments/assets/8fbcec21-9924-4d12-a616-54dd663786e7" /> ### Use case This functionality increases the usability of the elevation function, allowing good graphic rendering even with long names, without removing any functionality, still allowing users to see the complete name by hovering over it with the mouse. ### Database changes _No response_ ### External dependencies _No response_
adam added the status: acceptedtype: featurecomplexity: low labels 2025-12-29 21:44:31 +01:00
adam closed this issue 2025-12-29 21:44:32 +01:00
Author
Owner

@jeremystretch commented on GitHub (Jul 17, 2025):

I could swear we addressed this or a similar bug some time ago, but I haven't been able to find it.

Simply truncating the text to be rendered probably isn't feasible, given that's impossible to know how much space will be needed when using a variable-width font, especially in such a small area. It would be preferable to clip overflowing text within the rectangle, if possible.

@jeremystretch commented on GitHub (Jul 17, 2025): I could swear we addressed this or a similar bug some time ago, but I haven't been able to find it. Simply truncating the text to be rendered probably isn't feasible, given that's impossible to know how much space will be needed when using a variable-width font, especially in such a small area. It would be preferable to clip overflowing text within the rectangle, if possible.
Author
Owner

@MarcoSpiz commented on GitHub (Jul 18, 2025):

Yeah, I see your point and you're absolutely right.
However the svgwrite library does include a ClipPath class that behaves just like you suggested, it's not complex to implement
but it does introduce an extra layer of logic. Do you think it's worth it?
Here's a quick example:

clip_id = f'clip-{device.id}'

clip_path = ClipPath(id=clip_id)
clip_path.add(Rect(coords, size))
self.drawing.defs.add(clip_path)

...

link.add(Text(name, insert=text_coords, fill=text_color,clip_path=f'url(#{clip_id})', class_=f'label{css_extra}'))

This is the result:

Image

Let me know what you think!

@MarcoSpiz commented on GitHub (Jul 18, 2025): Yeah, I see your point and you're absolutely right. However the `svgwrite` library does include a `ClipPath` class that behaves just like you suggested, it's not complex to implement but it does introduce an extra layer of logic. Do you think it's worth it? Here's a quick example: ```python clip_id = f'clip-{device.id}' clip_path = ClipPath(id=clip_id) clip_path.add(Rect(coords, size)) self.drawing.defs.add(clip_path) ... link.add(Text(name, insert=text_coords, fill=text_color,clip_path=f'url(#{clip_id})', class_=f'label{css_extra}')) ``` This is the result: <img width="778" height="351" alt="Image" src="https://github.com/user-attachments/assets/15c6ca27-eb35-4355-bdf5-0f8d45c7fa8a" /> Let me know what you think!
Author
Owner

@jeremystretch commented on GitHub (Jul 18, 2025):

Yeah, that looks like the way to go. It probably wouldn't hurt to also truncate the name as you suggested above, to limit the amount of offset from centering the text.

@MarcoSpiz want to put in a PR for this?

@jeremystretch commented on GitHub (Jul 18, 2025): Yeah, that looks like the way to go. It probably wouldn't hurt to also truncate the name as you suggested above, to limit the amount of offset from centering the text. @MarcoSpiz want to put in a PR for this?
Author
Owner

@MarcoSpiz commented on GitHub (Jul 18, 2025):

Sure, I can do it.

@MarcoSpiz commented on GitHub (Jul 18, 2025): Sure, I can do it.
Author
Owner

@jeremystretch commented on GitHub (Jul 18, 2025):

Thanks @MarcoSpiz, I've assigned this to you.

@jeremystretch commented on GitHub (Jul 18, 2025): Thanks @MarcoSpiz, I've assigned this to you.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#11389