d3 / d3-shape

Graphical primitives for visualization, such as lines and areas.
https://d3js.org/d3-shape
ISC License
2.48k stars 310 forks source link

startPadAngle and endPadAngle #207

Open cittadhammo opened 1 year ago

cittadhammo commented 1 year ago

Dear All,

I would like to implement two optional parameters for the function arc().

At the moment arc().padAngle(x) create a symetric padding on each side of the arc sector. I have posted on d3 slack about my issue and I think it would be worth implement a solution at the source level. (notice the last comment on this stakOverflow post that bumped into the same problem).

Basically, I would like to modify the arc.js of d3-shape to be able to specify something like :

const arc = d3.arc()
    .innerRadius(0)
    .outerRadius(100)
    .startAngle(0)
    .endAngle(Math.PI / 2)
    .startPadAngle(0.03)
    .endPadAngle(0)

by default startPadAngle and endPadAngle should be equal to padAngle if not specified.

I have been giving a quick try in the source code here for exemple, but I don't understand all the mathematics... any help ?

Thanks!

cittadhammo commented 1 year ago

For anyone interested, this modif works in arc.js https://github.com/cittadhammo/d3-shape/blob/main/src/arc.js

main new code:


 // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.
      if (rp > epsilon) {
        var p0s = asin(rp / r0 * sin(aps)),
            p0e = asin(rp / r0 * sin(ape)),
            p1s = asin(rp / r1 * sin(aps)),
            p1e = asin(rp / r1 * sin(ape));
        if ((da0 -= p0s+p0e) > epsilon) p0s *= (cw ? 1 : -1), a00 += p0s, a10 -= p0e;
        else da0 = 0, a00 = a10 = (a0 + a1) / 2;
        if ((da1 -= p1s+p1e) > epsilon) p1s *= (cw ? 1 : -1), a01 += p1s, a11 -= p1e;
        else da1 = 0, a01 = a11 = (a0 + a1) / 2;
      }

compiled d3.js with the modif here and a test page here,

curran commented 1 year ago

Very nice!

cittadhammo commented 1 year ago

@curran Do you think it is worth a Pull Request ?

curran commented 1 year ago

Personally, I think so! This would make a nice addition to the library, and it seems to be a non-breaking change.

I'm not able to merge PRs as I'm not a maintainer here, but happy to review it and provide feedback.