Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dashboard gauge item #215

Merged
merged 24 commits into from
May 18, 2024
Merged

Dashboard gauge item #215

merged 24 commits into from
May 18, 2024

Conversation

patrick-gu
Copy link
Member

@patrick-gu patrick-gu commented Mar 20, 2024

Description

This implements a simple gauge using PyQt. Custom QPainter code is used to render the gauge. The value, ticks, and bounds on the gauge are configurable. Data is fetched similar to in the plot item.

This PR closes #198.

Developer Testing

Here's what I did to test my changes:

  • Ran dashboard and added a gauge item
    • python -m omnibus, python ./sources/parsley/main.py --fake, python ./sinks/dashboard/main.py
  • Tested with the series ACTUATOR_INJ/SENSOR_ANALOG/SENSOR_BATTERY_VOLT/value
  • Compared with a plot of the same data to ensure it makes sense
  • Changed the configuration to make sure it produces a reasonable result in each case
    • Including changing the width and height
  • Not sure if there is a way to do automated testing

Reviewer Testing

Here's what you should do to quickly validate my changes:

  • Run the dashboard and add a gauge, check visually that it works

This change is Reviewable

@patrick-gu
Copy link
Member Author

This is what I have so far:

image

@patrick-gu
Copy link
Member Author

image
What it looks like now

@patrick-gu patrick-gu marked this pull request as ready for review March 20, 2024 03:45
@patrick-gu
Copy link
Member Author

image
Update

@patrick-gu
Copy link
Member Author

Larger text
image

@patrick-gu
Copy link
Member Author

Label updates
image

@patrick-gu
Copy link
Member Author

image
Size comparison

Copy link
Contributor

@Darth-Raazi Darth-Raazi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haven't reviewed the code yet, but I'm not seeing the same thing as you. Here's what I see after resizing:

image.png

Not sure what's going on but maybe you can take a look?

Reviewed 1 of 2 files at r1, all commit messages.
Reviewable status: 1 of 2 files reviewed, all discussions resolved (waiting on @BluCodeGH and @KavinSatheeskumar)

@patrick-gu
Copy link
Member Author

image
I hate to say it, but works on my machine. I am using fakeni with seemingly the same settings. Are you seeing any logs in the console? Also, can you just check that you are on the latest commit, since I think I disabled rendering in certain cases in previous commits?

@patrick-gu
Copy link
Member Author

I just realized I think the problem is with the stroke colour - since you are on dark mode, it is drawing everything in white. I will update it to draw in black, but I don't know how to actually use dark mode to test it - my system settings don't seem to affect it

Copy link
Contributor

@Darth-Raazi Darth-Raazi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That fixed it!

image.png

Couple things:

  • I think the text label should be a bit bigger
  • Same with the tick numbers
  • The big numeric readout should be rounded to about 6 digits total so the actual value can be seen and not 30 decimals flying by lol
  • The default also seems a bit too small, maybe 250x250 or 300x300?

Reviewable status: 1 of 2 files reviewed, all discussions resolved (waiting on @BluCodeGH and @KavinSatheeskumar)

@patrick-gu
Copy link
Member Author

  • The text was designed to be readable at 150x150, as Jack suggested. I'll try to make the text scale dynamically with the size of the circle.
  • Will round the number if it is a float and not an int (which I was working with before), plus make the box bigger
  • I think Jack thought 400x400 was way too big so I'll take 250x250 as a medium default

@patrick-gu
Copy link
Member Author

image
Now at 250x250

@patrick-gu
Copy link
Member Author

@BluCodeGH or @KavinSatheeskumar if you have time, would appreciate a review since you're the code owners

Copy link
Contributor

@Darth-Raazi Darth-Raazi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Can we move the label down a bit for better spacing?
image.png
Also, I think I crashed it by entering a decimal max value, can support for that be added?

Reviewed 1 of 1 files at r8, all commit messages.
Reviewable status: all files reviewed, 6 unresolved discussions (waiting on @BluCodeGH, @KavinSatheeskumar, and @patrick-gu)


sinks/dashboard/items/gauge_item.py line 35 at r8 (raw file):

        self.min_value: int = 0
        self.max_value: int = 10

Decimal support please! E.g. if the data is only between 0 and 0.5


sinks/dashboard/items/gauge_item.py line 68 at r8 (raw file):

        self.widget.update()

    def on_label_change(self, param, value):

Would it be easier to have all these ..._change methods just be one thing that grab the new value for every field?


sinks/dashboard/items/gauge_item.py line 85 at r8 (raw file):

        width = self.width()
        height = self.height()
        if width < 100 or height < 100:

Why these restrictions on the size?


sinks/dashboard/items/gauge_item.py line 96 at r8 (raw file):

            # Tick marks and text

Extra blank line not needed


sinks/dashboard/items/gauge_item.py line 111 at r8 (raw file):

            # Invalid conditions
            if max_value < min_value:

This check should be in the ..._change method and it should reject the invalid value (replace it with whatever the previous value was)


sinks/dashboard/items/gauge_item.py line 189 at r8 (raw file):

            painter.setFont(font)
            painter.drawText(0, height - side / 8, width, side / 8, Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignTop, label)
            

Newline please

Copy link
Member Author

@patrick-gu patrick-gu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the label, I believe there's some padding around the box which will cut off text if it's too low, especially if you have something like a "y". So having more space would come at the cost of making the circle smaller.

Decimal support has been added.

Reviewable status: 1 of 2 files reviewed, 6 unresolved discussions (waiting on @BluCodeGH, @Darth-Raazi, and @KavinSatheeskumar)


sinks/dashboard/items/gauge_item.py line 35 at r8 (raw file):

Previously, Darth-Raazi (Ozayr Raazi) wrote…

Decimal support please! E.g. if the data is only between 0 and 0.5

Added. It was only integers before because floating point error is weird, but it should work OK now.


sinks/dashboard/items/gauge_item.py line 68 at r8 (raw file):

Previously, Darth-Raazi (Ozayr Raazi) wrote…

Would it be easier to have all these ..._change methods just be one thing that grab the new value for every field?

This is what is done in plot_dash_item.py. Don't want to have too much abstraction


sinks/dashboard/items/gauge_item.py line 85 at r8 (raw file):

Previously, Darth-Raazi (Ozayr Raazi) wrote…

Why these restrictions on the size?

The thickness of the lines and needle don't scale with the size, which makes it look really goofy when you make it small. I could make them also dynamically scale like the text, which I think would allow it to scale arbitrarily and look the same at any size. If this is important, I can change it. Just didn't account for too many cases to begin with because I was thinking about our typical use cases.


sinks/dashboard/items/gauge_item.py line 96 at r8 (raw file):

Previously, Darth-Raazi (Ozayr Raazi) wrote…

Extra blank line not needed

Done.


sinks/dashboard/items/gauge_item.py line 111 at r8 (raw file):

Previously, Darth-Raazi (Ozayr Raazi) wrote…

This check should be in the ..._change method and it should reject the invalid value (replace it with whatever the previous value was)

I'm not sure how I could go about doing this. pyqtgraph does have setLimits but I can't find any documentation on where this is applicable to a simple parameter, if at all.

https://pyqtgraph.readthedocs.io/en/latest/api_reference/parametertree/parameter.html#pyqtgraph.parametertree.Parameter.setLimits
https://pyqtgraph.readthedocs.io/en/latest/api_reference/parametertree/parametertypes.html#pyqtgraph.parametertree.parameterTypes.SimpleParameter


sinks/dashboard/items/gauge_item.py line 189 at r8 (raw file):

Previously, Darth-Raazi (Ozayr Raazi) wrote…

Newline please

Done.

@patrick-gu
Copy link
Member Author

patrick-gu commented May 12, 2024

I had to do a bit of rounding because numbers like 0.1 cannot be represented exactly in floats. I round them and convert to Python's exact decimals before working with them. There are certainly cases where this will not work perfectly, but I think this is fine for any reasonable use case.

Copy link
Contributor

@Darth-Raazi Darth-Raazi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decimals are working great. For the label, can we make the widget not square then? Default size could be 200x250 or 250x300.
Also, deleting the widget causes this error:
image.png

Reviewed 1 of 1 files at r9, all commit messages.
Reviewable status: all files reviewed, 3 unresolved discussions (waiting on @BluCodeGH, @KavinSatheeskumar, and @patrick-gu)


sinks/dashboard/items/gauge_item.py line 68 at r8 (raw file):

Previously, patrick-gu (Patrick Gu) wrote…

This is what is done in plot_dash_item.py. Don't want to have too much abstraction

Ah makes sense


sinks/dashboard/items/gauge_item.py line 85 at r8 (raw file):

Previously, patrick-gu (Patrick Gu) wrote…

The thickness of the lines and needle don't scale with the size, which makes it look really goofy when you make it small. I could make them also dynamically scale like the text, which I think would allow it to scale arbitrarily and look the same at any size. If this is important, I can change it. Just didn't account for too many cases to begin with because I was thinking about our typical use cases.

This is fine for now, but let's create an issue to address this in the future


sinks/dashboard/items/gauge_item.py line 111 at r8 (raw file):

Previously, patrick-gu (Patrick Gu) wrote…

I'm not sure how I could go about doing this. pyqtgraph does have setLimits but I can't find any documentation on where this is applicable to a simple parameter, if at all.

https://pyqtgraph.readthedocs.io/en/latest/api_reference/parametertree/parameter.html#pyqtgraph.parametertree.Parameter.setLimits
https://pyqtgraph.readthedocs.io/en/latest/api_reference/parametertree/parametertypes.html#pyqtgraph.parametertree.parameterTypes.SimpleParameter

What about just checking self.max_value < self.min_value in the change method and not updating the widget if that's true? Could also save the previous value and then restore it

@patrick-gu patrick-gu changed the title Basic QPainter gauge rendering Dashboard gauge item May 16, 2024
Copy link
Member Author

@patrick-gu patrick-gu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated default size and fixed the error (good catch, I didn't even notice it)

Reviewable status: 1 of 2 files reviewed, 3 unresolved discussions (waiting on @BluCodeGH, @Darth-Raazi, and @KavinSatheeskumar)


sinks/dashboard/items/gauge_item.py line 68 at r8 (raw file):

Previously, Darth-Raazi (Ozayr Raazi) wrote…

Ah makes sense

Done.


sinks/dashboard/items/gauge_item.py line 85 at r8 (raw file):

Previously, Darth-Raazi (Ozayr Raazi) wrote…

This is fine for now, but let's create an issue to address this in the future

Done, see #218


sinks/dashboard/items/gauge_item.py line 111 at r8 (raw file):

Previously, Darth-Raazi (Ozayr Raazi) wrote…

What about just checking self.max_value < self.min_value in the change method and not updating the widget if that's true? Could also save the previous value and then restore it

Done. It now goes back to whatever value it was before. Implementation was indeed quite straightforward.

Copy link
Contributor

@Darth-Raazi Darth-Raazi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

Great work!

Reviewable status: 1 of 2 files reviewed, all discussions resolved (waiting on @BluCodeGH and @KavinSatheeskumar)

@patrick-gu patrick-gu merged commit 623a710 into master May 18, 2024
1 of 2 checks passed
@patrick-gu patrick-gu deleted the p22gu/198-gauge-item branch May 18, 2024 23:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Gauge Item
2 participants