unovis icon indicating copy to clipboard operation
unovis copied to clipboard

Half Donut Vertical Centering

Open curran opened this issue 1 year ago • 3 comments

Work In Progress Towards https://github.com/f5/unovis/issues/441

curran avatar Sep 05 '24 20:09 curran

Current status:

image

curran avatar Sep 05 '24 20:09 curran

Current status: This PR makes the half donut centered vertically.

image

I think this is ready for review and testing. Thanks!

curran avatar Sep 11 '24 16:09 curran

Direction forward:

  • [ ] Modify the examples to showcase the responsive behavior of all pie examples when resizing the SVG both vertically and horizontally
  • [ ] Compute the bounding box that surrounds the donut
  • [ ] Use the bounding box for the scaling logic to fill the available space in the SVG

curran avatar Sep 11 '24 19:09 curran

Current status:

  • Got the resizing and scaling behavior to a point where it feels right
  • Scaffolded the scaling and translation logic for all 4 types of half-donut (but haven't tested those yet - I'm debating whether I should create a new example for each case, or maybe just spot check them in development)

https://github.com/user-attachments/assets/abe74484-43d9-4ab3-a0a3-592714463aa1

  • Problem with this: the sub-label gets cut off, because it's below the edge of the half donut
  • Proposed solution: we allow configuration of the margin (called bleed in this codebase) from the example
  • If we allow configuration of the margin, then the example could set a bottom margin to account for the space needed by the sub-label

I propose to make it configurable like this:

      <VisDonut
        ...
        bleed={{ top: 0, bottom: 0, left: 0, right: 0 }} // Current not available as a prop
      />

What do you think of this idea to expose the bleed as a prop @rokotyan ? Thanks!

curran avatar Oct 10 '24 17:10 curran

What do you think of this idea to expose the bleed as a prop @rokotyan ? Thanks!

All other Unovis components calculate the bleed value automatically, so exposing it as a prop goes a bit against the philosophy of the library. Also, we already have container properties like margin and padding, and I think adding bleed might make it more confusing for users.

Scaffolded the scaling and translation logic for all 4 types of half-donut (but haven't tested those yet - I'm debating whether I should create a new example for each case, or maybe just spot check them in development)

You can have all 4 of them on one page. This way it'll also be easier to test them with a visual testing framework.

rokotyan avatar Oct 10 '24 18:10 rokotyan

we already have container properties like margin and padding

Oh that's excellent news! I didn't think the margin was already configurable, since I didn't see it in DonutConfigInterface or its superclass ComponentConfigInterface. I did not think to look in the VisSingleContainer props, but sure enough it's there and it works like a charm:

image

Thank you for the tip!

curran avatar Oct 10 '24 21:10 curran

Current status:

  • Got a setup working where I can test all the various half-donut cases. Here's what they look like:
image image image image
  • Idea: export the angle ranges from Unovis somehow. WDYT @rokotyan ? Something like this:
export const halfDonutTopAngleRange: [number, number] = [-1.5707963267948966, 1.5707963267948966]
export const halfDonutRightAngleRange: [number, number] = [0, 3.141592653589793]
export const halfDonutBottomAngleRange: [number, number] = [1.5707963267948966, 4.71238898038469]
export const halfDonutLeftAngleRange: [number, number] = [3.141592653589793, 6.283185307179586]

Not sure the best way to do that within the Unovis setup... Attach them as properties of VisDonut maybe?

e.g.

import { VisDonut } from '@unovis/react'

...

      <VisDonut
        angleRange={VisDonut.halfDonutTopAngleRange}
      />

Another option would be:

import { halfDonutTopAngleRange } from '@unovis/ts'

...

      <VisDonut
        angleRange={halfDonutTopAngleRange}
      />

or something like that. Curious to know what the idiomatic Unovis API design would look like for something like this.

  • Working through getting the scaling right for all cases.
  • I do like the idea of a big example page with all the options, but that approach makes it more difficult to test out the responsive scaling as I go

Plan for next steps:

  • Get the scaling to work properly, each possibility in isolation
  • Make a new example page that shows all the possible half-donut configurations in one place (likely without nice responsive behavior)
  • Iterate once more on the PR based on feedback, then I think this will be ready to go!

curran avatar Oct 10 '24 21:10 curran

@curran Instead of forcing the users to use margin, I would change the text baseline and alignment and of the labels automatically to always stay visible, or make it configurable at least.

For example: image

As for exporting the constants, we can add a constants.ts file to components/donut and re-export it from index.ts. The only thing, I would like to prefix the constants with the component name and maybe use the UPPER_CASE. i.e. DONUT_HALF_ANGLE_RANGE_TOP instead of halfDonutTopAngleRange.

rokotyan avatar Oct 11 '24 01:10 rokotyan

Excellent! Thank you for this feedback. I will do it that way.

  • [ ] Donut half right: align text to start
  • [ ] Donut half left: align text to end
  • [ ] Donut half top: offset text vertically (upwards) to fit the sub-label within the bounds of the half donut rectangle
  • [ ] Donut half bottom: offset text vertically (downwards) to fit the sub-label within the bounds of the half donut rectangle

curran avatar Oct 11 '24 14:10 curran

Finally nailed the scaling for top half donut!

https://github.com/user-attachments/assets/734845dd-eb31-4bc6-934d-4560583a44bc

curran avatar Oct 11 '24 21:10 curran

Closing in favor of

  • https://github.com/f5/unovis/pull/502

curran avatar Dec 06 '24 18:12 curran