node-red-dashboard icon indicating copy to clipboard operation
node-red-dashboard copied to clipboard

Re-rendered dial gauges on widget add / remove

Open gayanSandamal opened this issue 1 year ago • 3 comments

Description

Problem

UI-Gauge (dial with needle) was loosing the track of its position when adding and removing widget into the same group.

Solution

Re-rendered the dial gauges upon adding / removing widgets in the same group as the same way tracked and re-rendered dial gauges on dynamic property changes

https://github.com/user-attachments/assets/e77bd56c-0fe0-428d-9d69-961ed0f2dfd9

Related Issue(s)

ui-gauge 2.0 1.17.1 - The needle loses track of it's position

This doesn't need documentation or E2E test update

Checklist

  • [x] I have read the contribution guidelines
  • [ ] Suitable unit/system level tests have been added and they pass
  • [ ] Documentation has been updated
    • [ ] Upgrade instructions
    • [ ] Configuration details
    • [ ] Concepts
  • [ ] Changes flowforge.yml?
    • [ ] Issue/PR raised on FlowFuse/helm to update ConfigMap Template
    • [ ] Issue/PR raised on FlowFuse/CloudProject to update values for Staging/Production

Labels

  • [ ] Includes a DB migration? -> add the area:migration label

gayanSandamal avatar Oct 01 '24 07:10 gayanSandamal

I've tried to re-create the problem in Chrome, and I couldn't. The underlying issue only seems to exist in Safari, where, even with these changes, the problem persists:

Screenshot 2024-10-01 at 13 14 18

joepavitt avatar Oct 01 '24 12:10 joepavitt

I've tried to re-create the problem in Chrome, and I couldn't. The underlying issue only seems to exist in Safari, where, even with these changes, the problem persists:

@joepavitt I noticed the needle problem in Chrome too. I just used the same flow given in the original issue and added a new gauge in the middle. And tried by enabling and disabling the gauge node using its NR edit window.

Luckily the units didn't get collided with others

The dashboard 2.0 flow I used is below 👇

[{"id":"8bc24fdfe79d7aa2","type":"ui-gauge","z":"80a7b66be7ea4735","name":"ampere","group":"f9fe8211d40a5300","order":8,"width":"3","height":"4","gtype":"gauge-34","gstyle":"needle","title":"ampere","units":"A","icon":"","prefix":"","suffix":"","segments":[{"from":"0","color":"#00f900"},{"from":"77","color":"#ff9300"},{"from":"100","color":"#ff2600"},{"from":"120","color":"#ff2600"}],"min":"0","max":"120","sizeThickness":16,"sizeGap":4,"sizeKeyThickness":8,"styleRounded":true,"styleGlow":false,"className":"","x":980,"y":400,"wires":[]},{"id":"fbee797bb24fbc0b","type":"ui-gauge","z":"80a7b66be7ea4735","name":"batteri amps","group":"f9fe8211d40a5300","order":3,"width":"3","height":"4","gtype":"gauge-34","gstyle":"needle","title":"ampere","units":"A","icon":"","prefix":"","suffix":"","segments":[{"from":"-120","color":"#ff9300"},{"from":"-110","color":"#00f900"},{"from":"0","color":"#00f900"},{"from":"110","color":"#00f900"},{"from":"111","color":"#ff9300"},{"from":"120","color":"#ff9300"}],"min":"-120","max":"120","sizeThickness":16,"sizeGap":4,"sizeKeyThickness":8,"styleRounded":true,"styleGlow":false,"className":"","x":990,"y":360,"wires":[]},{"id":"b12a10fe23e4b783","type":"ui-gauge","z":"80a7b66be7ea4735","name":"batt power watts","group":"f9fe8211d40a5300","order":9,"width":"3","height":"4","gtype":"gauge-34","gstyle":"rounded","title":"watt","units":"W","icon":"","prefix":"","suffix":"","segments":[{"from":"-3000","color":"#ff9300"},{"from":"-2400","color":"#00f900"},{"from":"0","color":"#00f900"},{"from":"2500","color":"#ff2600"},{"from":"3000","color":"#ff2600"}],"min":"-3000","max":"3000","sizeThickness":16,"sizeGap":4,"sizeKeyThickness":8,"styleRounded":true,"styleGlow":false,"className":"","x":1010,"y":440,"wires":[]},{"id":"cc05114576d9df0b","type":"ui-gauge","z":"80a7b66be7ea4735","name":"batt power +/-","group":"f9fe8211d40a5300","order":1,"width":"3","height":"4","gtype":"gauge-34","gstyle":"needle","title":"batt power +/-","units":"kW","icon":"","prefix":"","suffix":"","segments":[{"from":"-4","color":"#ff9300"},{"from":"","color":"#000000"},{"from":"-3.5","color":"#3a88fe"},{"from":"0","color":"#3a88fe"},{"from":"3.5","color":"#3a88fe"},{"from":"3.6","color":"#ff9300"},{"from":"4","color":"#ff9300"}],"min":"-4","max":"4","sizeThickness":16,"sizeGap":4,"sizeKeyThickness":8,"styleRounded":true,"styleGlow":false,"className":"","x":1000,"y":220,"wires":[]},{"id":"97e42e2a59246509","type":"ui-gauge","z":"80a7b66be7ea4735","name":"batteri volts","group":"f9fe8211d40a5300","order":4,"width":"3","height":"4","gtype":"gauge-34","gstyle":"needle","title":"volt","units":"V","icon":"","prefix":"","suffix":"","segments":[{"from":"10","color":"#ff2600"},{"from":"11.1","color":"#ff9300"},{"from":"11.8","color":"#5cd65c"},{"from":"14.3","color":"#ff2600"},{"from":"15","color":"#ff2600"}],"min":"10","max":"15","sizeThickness":16,"sizeGap":4,"sizeKeyThickness":8,"styleRounded":true,"styleGlow":false,"className":"","x":990,"y":260,"wires":[]},{"id":"74b4b2f72261eb22","type":"ui-gauge","z":"80a7b66be7ea4735","name":"batteri temperatur","group":"f9fe8211d40a5300","order":7,"width":"3","height":"4","gtype":"gauge-34","gstyle":"needle","title":"temp","units":"°C","icon":"","prefix":"","suffix":"","segments":[{"from":"-40","color":"#ff9300"},{"from":"5","color":"#ff9300"},{"from":"6","color":"#00f900"},{"from":"31","color":"#ff9300"},{"from":"40","color":"#ff2600"}],"min":"-40","max":"40","sizeThickness":16,"sizeGap":4,"sizeKeyThickness":8,"styleRounded":true,"styleGlow":false,"className":"","x":1010,"y":300,"wires":[]},{"id":"85fef5c0c179d8f1","type":"inject","z":"80a7b66be7ea4735","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"3","payloadType":"num","x":750,"y":440,"wires":[["fbee797bb24fbc0b","8bc24fdfe79d7aa2","b12a10fe23e4b783","cc05114576d9df0b","97e42e2a59246509","74b4b2f72261eb22","509686d704616771","349b7f3aca90ca05","3c75fc9fb80c159b"]]},{"id":"509686d704616771","type":"ui-gauge","z":"80a7b66be7ea4735","name":"batteri amps","group":"f9fe8211d40a5300","order":5,"width":"3","height":"4","gtype":"gauge-34","gstyle":"needle","title":"ampere","units":"A","icon":"","prefix":"","suffix":"","segments":[{"from":"-120","color":"#ff9300"},{"from":"-110","color":"#00f900"},{"from":"0","color":"#00f900"},{"from":"110","color":"#00f900"},{"from":"111","color":"#ff9300"},{"from":"120","color":"#ff9300"}],"min":"-120","max":"120","sizeThickness":16,"sizeGap":4,"sizeKeyThickness":8,"styleRounded":true,"styleGlow":false,"className":"","x":990,"y":500,"wires":[]},{"id":"349b7f3aca90ca05","type":"ui-gauge","z":"80a7b66be7ea4735","name":"batt power watts","group":"f9fe8211d40a5300","order":6,"width":"3","height":"4","gtype":"gauge-34","gstyle":"rounded","title":"watt","units":"W","icon":"","prefix":"","suffix":"","segments":[{"from":"-3000","color":"#ff9300"},{"from":"-2400","color":"#00f900"},{"from":"0","color":"#00f900"},{"from":"2500","color":"#ff2600"},{"from":"3000","color":"#ff2600"}],"min":"-3000","max":"3000","sizeThickness":16,"sizeGap":4,"sizeKeyThickness":8,"styleRounded":true,"styleGlow":false,"className":"","x":1010,"y":560,"wires":[]},{"id":"c83113e976a0c20b","type":"ui-slider","z":"80a7b66be7ea4735","group":"f9fe8211d40a5300","name":"","label":"slider","tooltip":"","order":10,"width":"6","height":"3","passthru":false,"outs":"all","topic":"topic","topicType":"msg","thumbLabel":"always","showTicks":"always","min":0,"max":"100","step":1,"className":"","iconPrepend":"","iconAppend":"","color":"","colorTrack":"","colorThumb":"","x":730,"y":360,"wires":[["cc05114576d9df0b","97e42e2a59246509","74b4b2f72261eb22","fbee797bb24fbc0b","8bc24fdfe79d7aa2","509686d704616771","b12a10fe23e4b783","349b7f3aca90ca05","3c75fc9fb80c159b"]]},{"id":"3c75fc9fb80c159b","type":"ui-gauge","z":"80a7b66be7ea4735","name":"New","group":"f9fe8211d40a5300","order":2,"width":"3","height":"6","gtype":"gauge-half","gstyle":"needle","title":"New gauge","units":"units","icon":"","prefix":"","suffix":"","segments":[{"from":"0","color":"#5cd65c"},{"from":"4","color":"#ffc800"},{"from":"7","color":"#ea5353"}],"min":0,"max":10,"sizeThickness":16,"sizeGap":4,"sizeKeyThickness":8,"styleRounded":true,"styleGlow":false,"className":"","x":970,"y":620,"wires":[]},{"id":"f9fe8211d40a5300","type":"ui-group","name":"g git 1","page":"e3f48fc6daf125cf","width":"6","height":"1","order":1,"showTitle":true,"className":"","visible":"true","disabled":"false"},{"id":"e3f48fc6daf125cf","type":"ui-page","name":"p git 1","ui":"a171c8195c1b8e57","path":"/git1","icon":"home","layout":"grid","theme":"a9af1506409fba49","breakpoints":[{"name":"Default","px":"0","cols":"3"},{"name":"Tablet","px":"576","cols":"6"},{"name":"Small Desktop","px":"768","cols":"9"},{"name":"Desktop","px":"1024","cols":"12"}],"order":2,"className":"","visible":true,"disabled":false},{"id":"a171c8195c1b8e57","type":"ui-base","name":"My Dashboard","path":"/dashboard","includeClientData":true,"acceptsClientConfig":["ui-control","ui-chart","ui-form","ui-file-input","ui-button","ui-button-group","ui-dropdown","ui-slider","ui-switch","ui-text","ui-markdown","ui-notification","ui-template","ui-table"],"showPathInSidebar":false,"showPageTitle":true,"navigationStyle":"icon","titleBarStyle":"default"},{"id":"a9af1506409fba49","type":"ui-theme","name":"black and grey","colors":{"surface":"#000000","primary":"#919191","bgPage":"#000000","groupBg":"#000000","groupOutline":"#000000"},"sizes":{"pagePadding":"2px","groupGap":"2px","groupBorderRadius":"2px","widgetGap":"3px","density":"compact"}}]

I will check in the Safari too

gayanSandamal avatar Oct 01 '24 18:10 gayanSandamal

Rather than watching the widgets array, if the issue is caused by the container of the gauge re-sizing when others are added/removed, why not put a ResizeObserver on the gauge itself, and then re-render in cases when the size changes?

joepavitt avatar Oct 04 '24 08:10 joepavitt

Rather than watching the widgets array, if the issue is caused by the container of the gauge re-sizing when others are added/removed, why not put a ResizeObserver on the gauge itself, and then re-render in cases when the size changes?

As per the offline discussion with @joepavitt I've re-rendered gauge dials on resize and considered.

As I noticed, Safari is not properly adjusting the grid row heights, causing the layout to appear cluttered. Unlike in Chrome, where the gauges fit neatly, Safari seems to mishandle the row sizing. This inconsistency affects the display and usability of the grid-based interface.

Screenshot 2024-10-08 at 10 17 25

Due to the observed issue, I applied a fix here. The main change I made was ensuring the component calculates the minimum dimension between width and height using Math.min(clientWidth, clientHeight). This allows the component to adjust its size dynamically based on the available space.

This is ready for review

gayanSandamal avatar Oct 08 '24 06:10 gayanSandamal

Font Size

The font size of the value has broken and is rendering too small.

Screenshot 2024-10-08 at 12 02 22 ### Problem Not Fixed This has also still, after my fourth review, not fixed the underlying problem reported for Safari, where the needle doesn't correctly align to the gauge Screenshot 2024-10-08 at 12 03 58

@joepavitt Seems like it's a bit strange behaviour, This is what I'm seeing when comparing on Chrome and Safari side by side

Screenshot Screenshot 2024-10-08 at 16 43 27

Screen recording https://github.com/user-attachments/assets/55c430b2-2853-45e5-86f5-d3988d1ece08

gayanSandamal avatar Oct 08 '24 11:10 gayanSandamal

Managed to establish this is a Safari version problem (I'm running v14, Gayan on newer). However, we also have an opportunity here to fix https://github.com/FlowFuse/node-red-dashboard/issues/560

The resize event should nt monitor window, but instead the gauge.

joepavitt avatar Oct 09 '24 09:10 joepavitt

Managed to establish this is a Safari version problem (I'm running v14, Gayan on newer). However, we also have an opportunity here to fix #560

The resize event should not monitor window, but instead the gauge.

@joepavitt as discussed I've applied the fix using ResizeObserver with these 2 commits https://github.com/FlowFuse/node-red-dashboard/pull/1353/commits/91ee77e914cbf19413bd5701f0458a94d8855e47 https://github.com/FlowFuse/node-red-dashboard/pull/1353/commits/8ee9ab42cfbaa713a789ec19882319de6a37ed49

Description has been updated with the solution and the screen recording of the behaviour after the fix

Also for the issue #560 I will check and verify other widgets separately as the reporter of the issue mentioned "Any widget (like ui_gauge) using window resize event"

gayanSandamal avatar Oct 10 '24 05:10 gayanSandamal

This all looks good. Thanks for the video demonstration.

I am however a little concerned about then there are many gauges on a lower powered device. The resize observer runs very fast. e.g:

chrome_GnocVeZZsn chrome_GnocVeZZsn

Perhaps a follow up issue to throttle the observer just enough to give a little breathing space - perhaps limit updates upon resize to 1 in every 100ms?

Again, happy for that to be a follow up task - so approving for now.

@Steve-Mcl A followup task has been raised as discussed https://github.com/FlowFuse/node-red-dashboard/issues/1376

gayanSandamal avatar Oct 10 '24 08:10 gayanSandamal