plot icon indicating copy to clipboard operation
plot copied to clipboard

Rounded corners on rect, but only for some corners

Open mbostock opened this issue 1 year ago • 2 comments

As originally suggested in #1201, this is a common request, and the workaround isn’t always feasible (for example with diverging bars).

image

mbostock avatar Apr 13 '24 17:04 mbostock

Thinking about this has sent me into a rabbit hole. Two issues:

  1. how do we name this option (maybe "high-end radius—rh"—knowing that high will be bottom for negative values, right for horizontal bars and left for horizontal-negative)?
  2. instead of a svg:rect we'll now have a generic svg:path. We can do one that just implements rh (if not nullish[1]), and keep it at this.

But there might be future use cases (some we already have in mind) where the element we create is completely different: what if, for example, if we want bars that follow a radial coordinate system (#133). (Or even, marks that are rendered with the same visual logic but using canvas instead of SVG…)

So, while we can implement this with a simple test like (rh != null ? "rect" : "path") (and maybe we should, I can put up a PR for this anyway), it's also tempting to take this as an opportunity to think more globally about how we'd want to be able to pass new "visual materializers" to marks.

[1] I'd want an explicit rh: 0 to opt-in to a svg:path, in order to make it possible to transition from rh=0 to rh=5 without discontinuity.

Fil avatar Apr 15 '24 18:04 Fil

Hmm, one possibility is an ry2 option that rounds the corners corresponding to the y2 edge. Then you could have similar options ry1, rx1, rx2 for the other sides — but you’d have to define which side takes precedence since the sides would compete for the corners.

Another possibility is separate radii for each corner, like CSS does for border-radius (which also supports elliptical corners!).

Complicated!

mbostock avatar Apr 15 '24 18:04 mbostock

I'm going to give up on that one, because a clean generalization with all the possibilities is just too much work — too many "corner" cases, for a limited usage. Instead let's create examples to show how to use a render transform?

For instance: https://observablehq.com/@observablehq/dog-eared-bars (although the implementation is not optimal since it creates rects then discards them… I find it easier that way).

Fil avatar Jul 09 '24 15:07 Fil