Repository: netbox-community/netbox

Issue:
Front/rear image obscures device name
### NetBox version

v2.11.10

### Feature type

Change to existing functionality

### Proposed functionality

I have just started using the front/rear images functionality.  I found that the SVG is built up in the following sequence:

* background rectangle
* device name
* device image

This means that once you add images, you no longer can see the device names.

I propose simply reordering the rendering sequence so that the text is added after the image.  Before:

![image](https://user-images.githubusercontent.com/44789/128155180-0b19027c-757a-49d1-ba2e-1e43f1e7a4a3.png)

After:

![image](https://user-images.githubusercontent.com/44789/128155242-75d2f98b-18bc-4792-ae61-cb3ece388c39.png)

Doing the same for rear suffers from the default text colour being black.  Before:

![image](https://user-images.githubusercontent.com/44789/128155481-58785302-9f01-4f53-a4cc-412b3635812f.png)

After:

![image](https://user-images.githubusercontent.com/44789/128155525-81ebb88d-64c7-47e0-829a-117811054a7a.png)

I would therefore change the colour to white when there's an image, on the assumption that most images are "dark-like".  It then becomes:

![image](https://user-images.githubusercontent.com/44789/128157187-992e0678-3333-480f-88c3-cdb89b870419.png)

Or else have setting(s) in the device type to select the text colour for the front and rear text when images are present.

### Use case

Being able to see at-a-glance the positions and the *names* of all the devices in a rack is an important use for rack elevations.

I do realise that there's a button to turn images on and off.  However, images without device names is pretty but not very useful.  This means that generally I would have to turn the images off all the time, which in turn means there is no point uploading images in the first place.

Potentially the button could be changed to a 3-state (show names and images; show names only; show images only).  But for me, the "images without names" variation is not something I'd use.

### Database changes

None

### External dependencies

None


Discussion:
I would definitely like to see the option to specify the text color. I think black or white would be sufficient, but I don't know if it's easier to use the existing color picker. We have a fair bit of white, beige, and light grey equipment in our environment that I don't think would meet web accessibility guidelines with pure white text. Another option would be black or white text with a small opposite-colored outline or drop shadow around it, which should provide sufficient contrast on any background color as well as some visual separation for busier images.

I would also like to see the option for displaying the images without the names. When doing physical site audits, it's more important for us to see the images clearly than the names of the devices. Also, when displaying the names, I wonder if it's possible to truncate them to the width of the rack or possibly wrap them for multi-U devices. Maybe it wouldn't be as bad with them in front of the images, but long names look really weird today peeking out from behind the images and extending beyond the bounds of the rack. This is especially prevalent on unnamed devices that default to the manufacturer and device type.
@sleepinggenius2: what do you think of the renderings [here](https://github.com/netbox-community/netbox/pull/6880#issuecomment-893505701) and [here](https://github.com/netbox-community/netbox/pull/6880#issuecomment-893659449) ?

These put a halo around the text in the role colour.  This means the text contrast is the same as if the image were not displayed at all, and the halo vanishes when the images are turned off (as it's the same colour as the plain role background).

Changing the toggle to display images without names ought to be doable, either by having a 3-state toggle or separate toggles for text and images.

I think name truncation should be a separate feature request.
While I think it looks okay for the red and blue colors in the examples, I'm concerned with how it's going to look across the full range of colors. Looking through the current NetBox interface, it looks like there is some logic to change the foreground color to black or white to provide contrast against the selected background color. I'm not sure how that is being calculated, as the white on aqua that is in place today fails WCAG guideline with a ratio of only 1.25:1. Also want to make sure that none of this is affected by the dark mode option in the new UI.

However you do the toggles, I would like to see the "images or text" option, like the system defaults to today. This seems to be the most useful option for our use case, as we typically use the elevations for site audits and build-out documentation, but I know some people prefer turning the images off to make the elevations "less busy" when they're just doing design and space allocation. I can't see a use case for images only without the text for devices without an image, so the display options I would want to see are "Text only", "Images or text", and "Images and text", basically that last option would trigger this feature request.

Resolving patch:
diff --git a/netbox/dcim/svg.py b/netbox/dcim/svg.py
--- a/netbox/dcim/svg.py
+++ b/netbox/dcim/svg.py
@@ -112,6 +112,9 @@ def _draw_device_front(self, drawing, device, start, end, text):
             )
             image.fit(scale='slice')
             link.add(image)
+            link.add(drawing.text(str(name), insert=text, stroke='black',
+                     stroke_width='0.2em', stroke_linejoin='round', class_='device-image-label'))
+            link.add(drawing.text(str(name), insert=text, fill='white', class_='device-image-label'))
 
     def _draw_device_rear(self, drawing, device, start, end, text):
         rect = drawing.rect(start, end, class_="slot blocked")
@@ -129,6 +132,9 @@ def _draw_device_rear(self, drawing, device, start, end, text):
             )
             image.fit(scale='slice')
             drawing.add(image)
+            drawing.add(drawing.text(str(device), insert=text, stroke='black',
+                        stroke_width='0.2em', stroke_linejoin='round', class_='device-image-label'))
+            drawing.add(drawing.text(str(device), insert=text, fill='white', class_='device-image-label'))
 
     @staticmethod
     def _draw_empty(drawing, rack, start, end, text, id_, face_id, class_, reservation):


Test patch: