Node-RED-UI Image Grid

Hey guys,

Is there a way to have something like an image grid in the dashboard?

I have images of chess figures, and I would like them to arrange according to the data I am sending in the flow.

I tried with the ui-table node, it has an Image option, but for some reason, it doesn't display the image.

Does someone have an example of the usage of a ui-table node with images? If it works it would be great since the table is basically a 2D grid.

If there is a better way, please let me know.
Thanks for the help.

This should be the end result:

I'd propose a UI template node with a table or grid of divs.

Give each cell a uniform ID or class (e.g. a1 ~ h8)

Then using something like msg.topic as the grid address and msg.payload as the image source.

This is what I currently have:

Image in code:
<img src="data:image/png;base64,{{payload}}"style="width="500" height="500""/>

template code:

    <td ng-bind-html="msg.payload" id = "A1"></td>

I'm not sure how to use ID/class and msg.topic with angular.

There is info in the side panel help on how to handle incoming msgs.

Here is something to get you moving...


Demo flow...

[{"id":"dac0c1824c37b7c7","type":"ui_template","z":"e78eac1c.8b9cf","group":"dce9e7a2.d20c78","name":"","order":1,"width":"9","height":"9","format":"<style>\n    table.chess-board {\n        border-spacing: 0px;\n        border-width: 1px;\n    }\n    table.chess-board td {\n        border: 1px solid black;\n        padding: 0px;\n        width: 50px;\n        height: 50px;\n        font-size: 30px;\n        text-align: center;\n        vertical-align: middle;\n    }\n    .chess-board td.light {\n        background-color: ivory;\n    }\n    .chess-board td.dark {\n        background-color: lightslategray;\n    }\n    \n</style>\n\n\n<table class=\"chess-board\">\n    <tr class=\"a\">\n        <td class=\"a1 light\"></td> <td class=\"a2 dark\"></td> <td class=\"a3 light\"></td> <td class=\"a4 dark\"></td> <td class=\"a5 light\"></td> <td class=\"a6 dark\"></td> <td class=\"a7 light\"></td> <td class=\"a8 dark\"></td>\n    </tr>\n    <tr class=\"b\">\n        <td class=\"b1 dark\"></td> <td class=\"b2 light\"></td> <td class=\"b3 dark\"></td> <td class=\"b4 light\"></td> <td class=\"b5 dark\"></td> <td class=\"b6 light\"></td> <td class=\"b7 dark\"></td> <td class=\"b8 light\"></td>\n    </tr>\n    <tr class=\"c\">\n        <td class=\"c1 light\"></td> <td class=\"c2 dark\"></td> <td class=\"c3 light\"></td> <td class=\"c4 dark\"></td> <td class=\"c5 light\"></td> <td class=\"c6 dark\"></td> <td class=\"c7 light\"></td> <td class=\"c8 dark\"></td>\n    </tr>\n    <tr class=\"d\">\n        <td class=\"d1 dark\"></td> <td class=\"d2 light\"></td> <td class=\"d3 dark\"></td> <td class=\"d4 light\"></td> <td class=\"d5 dark\"></td> <td class=\"d6 light\"></td> <td class=\"d7 dark\"></td> <td class=\"d8 light\"></td>\n    </tr>\n    <tr class=\"e\">\n        <td class=\"e1 light\"></td> <td class=\"e2 dark\"></td> <td class=\"e3 light\"></td> <td class=\"e4 dark\"></td> <td class=\"e5 light\"></td> <td class=\"e6 dark\"></td> <td class=\"e7 light\"></td> <td class=\"e8 dark\"></td>\n    </tr>\n    <tr class=\"f\">\n        <td class=\"f1 dark\"></td> <td class=\"f2 light\"></td> <td class=\"f3 dark\"></td> <td class=\"f4 light\"></td> <td class=\"f5 dark\"></td> <td class=\"f6 light\"></td> <td class=\"f7 dark\"></td> <td class=\"f8 light\"></td>\n    </tr>\n    <tr class=\"g\">\n        <td class=\"g1 light\"></td> <td class=\"g2 dark\"></td> <td class=\"g3 light\"></td> <td class=\"g4 dark\"></td> <td class=\"g5 light\"></td> <td class=\"g6 dark\"></td> <td class=\"g7 light\"></td> <td class=\"g8 dark\"></td>\n    </tr>\n    <tr class=\"h\">\n        <td class=\"h1 dark\"></td> <td class=\"h2 light\"></td> <td class=\"h3 dark\"></td> <td class=\"h4 light\"></td> <td class=\"h5 dark\"></td> <td class=\"h6 light\"></td> <td class=\"h7 dark\"></td> <td class=\"h8 light\"></td>\n    </tr>\n</table>\n\n\n<script type=\"text/javascript\">\n    (function(scope) {\n        const _scope = scope;\n        scope.$watch('msg', function(msg) {\n            if(msg && msg.topic && msg.payload) {\n                const el = $(msg.topic); \n                el.text(msg.payload);\n            }\n        });\n    })(scope);\n</script>\n\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","className":"","x":1580,"y":300,"wires":[[]]},{"id":"a4a9f0052a91b6d6","type":"inject","z":"e78eac1c.8b9cf","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":".chess-board .a3","payload":"♗","payloadType":"str","x":1330,"y":220,"wires":[["dac0c1824c37b7c7"]]},{"id":"fa2b5b70eeb5bc8d","type":"inject","z":"e78eac1c.8b9cf","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":".chess-board .a1","payload":"♕","payloadType":"str","x":1330,"y":140,"wires":[["dac0c1824c37b7c7"]]},{"id":"2a602aba971e708f","type":"inject","z":"e78eac1c.8b9cf","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":".chess-board .a2","payload":"♘","payloadType":"str","x":1330,"y":180,"wires":[["dac0c1824c37b7c7"]]},{"id":"b784c50a1d976d51","type":"inject","z":"e78eac1c.8b9cf","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":".chess-board .h2","payload":"♞","payloadType":"str","x":1330,"y":380,"wires":[["dac0c1824c37b7c7"]]},{"id":"c3c4f09e3e5a8f62","type":"inject","z":"e78eac1c.8b9cf","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":".chess-board .h1","payload":"♛","payloadType":"str","x":1330,"y":340,"wires":[["dac0c1824c37b7c7"]]},{"id":"7f4acdca20a3afeb","type":"inject","z":"e78eac1c.8b9cf","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":".chess-board .h3","payload":"♝","payloadType":"str","x":1330,"y":420,"wires":[["dac0c1824c37b7c7"]]},{"id":"e363989376c50302","type":"inject","z":"e78eac1c.8b9cf","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":".chess-board tr.b td","payload":"♙","payloadType":"str","x":1320,"y":260,"wires":[["dac0c1824c37b7c7"]]},{"id":"236329b893a0e0d9","type":"inject","z":"e78eac1c.8b9cf","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":".chess-board tr.g td","payload":"♟","payloadType":"str","x":1320,"y":460,"wires":[["dac0c1824c37b7c7"]]},{"id":"dce9e7a2.d20c78","type":"ui_group","name":"Object detection","tab":"5132060d.4cde48","order":1,"disp":true,"width":"9","collapse":false},{"id":"5132060d.4cde48","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]


In this ↑ demo, I dont use images - i use chess characters copied from here & set the .text() to msg.payload

I use CSS selectors to address the grid items e.g...

  • a CSS selector of .chess-board .a1 in msg.topic will set the text() of the 1st cell to the value in msg.payload
  • a CSS selector of .chess-board .b in msg.topic will set the text() of all cells in row 2 to the value in msg.payload
  • a CSS selector of .chess-board td in msg.topic will set the text() of all cells the value in msg.payload

Not specifically topic related, but in Dark mode the text is white. I am too new to CSS to quite figure out how to change the colour of the placed text (not wanting to change everything)... if possible. I looked through the code, but only see how to change the backgrounds.


Figured it out... went down the ui.control node path with no results until I realized... Since it changed due to Dark mode, then perhaps :thinking:... yep... Theme had a custom option with text colours :sunglasses: And I learned more about ui.control (albeit using a change node and not the ui.control node... go fig).

UPDATE: And while that worked, perhaps it was not the best way after all. CSS in the Template node to the rescue :grin:


.nr-dashboard-theme ui-card-panel {
    color: #606060;

Wow! Thanks a lot. This is very very helpful. :smiley: :smiley: :smiley:

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.