CODAP-1509: draw and hit test point shapes in the PIXI renderer - #2697
CODAP-1509: draw and hit test point shapes in the PIXI renderer#2697kswenson wants to merge 3 commits into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## CODAP-1504-point-shapes-canvas #2697 +/- ##
==================================================================
+ Coverage 87.89% 87.91% +0.01%
==================================================================
Files 821 821
Lines 47486 47527 +41
Branches 12135 12039 -96
==================================================================
+ Hits 41738 41782 +44
+ Misses 5732 5729 -3
Partials 16 16
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
codap-v3
|
||||||||||||||||||||||||||||
| Project |
codap-v3
|
| Branch Review |
CODAP-1509-point-shapes-pixi
|
| Run status |
|
| Run duration | 09m 10s |
| Commit |
|
| Committer | null |
| View all properties for this run ↗︎ | |
| Test results | |
|---|---|
|
|
0
|
|
|
1
|
|
|
82
|
|
|
0
|
|
|
384
|
| View all changes introduced in this branch ↗︎ | |
There was a problem hiding this comment.
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Reviewing this stack — five PRs, each based on the one below it, merging bottom-up into
CODAP-1506 is split across #2691 and #2693, so approving #2691 does not complete that story — it should not leave code review until #2693 is approved too. The other three map one-to-one. Nothing here is superseded — this is the top of the stack. Worth your attention:
Out of scope by design, each with a ticket: legend keys carrying the shape (CODAP-1507), the residual plot (CODAP-1526). |
7a50b2d to
cf96a45
Compare
3f399a2 to
7c1af50
Compare
The smallest box centered on the point that contains the drawn shape, which is not the box that hugs the ink: a triangle sits on its center of area, so its outline reaches further above the point than below. A renderer that positions a shape by the middle of a box needs this rather than the drawn extent. Drawing into a texture and anchoring it at its center is exactly that, which is what the PIXI renderer does. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Textures are built from the shared geometry rather than an arc, so the WebGL renderer draws what the canvas renderer draws. The texture cache needed no change: its key is the whole style, which now carries the shape, so two shapes can never collide on one texture. A sprite's texture is drawn around its anchor, which for points is the middle of the texture. Left to size itself a texture takes the bounds of the ink, and for a triangle that box is not centered on the point -- the ink sits above the center of area, so the triangle would be drawn low by about a third of its radius, reinstating in WebGL the bias the canvas renderer was fixed for. The texture is given an explicit frame centered on the point instead. Circles keep the path they have always had, including sizing their own texture. Sprites get a hit area testing the drawn shape. PIXI hands it the pointer in the sprite's own coordinates, where the origin is the point's position, so it can defer to the same containment the canvas renderer uses and the two agree on what counts as a hit. Note this also tightens picking for circles, which until now were hit tested against the rectangle of their texture -- a click well outside a circular point could select it. Bars keep the rectangular test, which is what a bar is. The hit area holds the shape and radius rather than looking them up, since it runs per point per pointer event. It is kept in step with the texture at all three places a sprite's texture is assigned: creation, a style change, and the end of a points/bars transition. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Why a texture has to be centered on the point rather than on the ink was explained at the helper that computes the frame and again where it is called. It lives at the helper, which exists for no other reason; the call site says only that circles keep sizing their own. The symmetric extent restated why a triangle's box is off center, which the triangle's own geometry already explains. It now says what it is and who needs it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
cf96a45 to
e8f1e90
Compare
Draws the seven point shapes in the PIXI/WebGL renderer and hit tests against them. Fifth in the LEADS Point Shapes stack, on top of #2696.
Fixes CODAP-1509.
What was actually needed
Very little plumbing. Nothing in the style path branches on renderer type, so the work done for the canvas renderer already carries shapes to PIXI through the same
setPointStyleandmatchPointsToDatacalls — andpoint-shapes.tsis consumed unchanged, which is what it was built for. The texture cache needed no change either: its key is the whole style, which now carries the shape, so two shapes cannot collide on one texture.Two things did need care.
Centering
A sprite draws its texture around its anchor, which for points is the middle of the texture. Left to size itself, a texture takes the bounds of the ink — and a triangle's ink is not centered on the point, because the shape sits on its center of area. Anchoring the middle of that box would draw a triangle low by about a third of its radius, reinstating in WebGL exactly the positional bias the canvas renderer was fixed for. At r=8 the offset is 2.9px for a triangle and 1.1px for a star; every other shape is symmetric and unaffected.
The texture is given an explicit frame centered on the point instead, sized by a new
pointShapeSymmetricExtent. Circles keep the path they have always had, including sizing their own texture.Hit testing, and a behavior change worth noticing
Sprites now carry a
hitAreathat tests the drawn shape, deferring to the same containment the canvas renderer uses so the two renderers agree on what counts as a hit. That matters because graphics acceleration is a user setting — the same document should not pick differently depending on it.This also tightens picking for circles. Sprites previously had no
hitAreaat all, so they hit tested against the rectangle of their texture: a click up to about 1.4 radii from a point's center would select it. That stops. It is a fix rather than a regression, but it reaches every existing document, so it is worth a reviewer's attention rather than being buried.Bars keep the rectangular test, which is what a bar is.
Scope
Behind the
pointShapesfeature flag, which gates the controls. Verified manually with graphics acceleration on, and with it toggled off and on to confirm the two renderers agree.Not measured: texture churn with many shapes in play. The count stays bounded — shape and color are both functions of the same legend category — but
cleanupUnusedTextures()still has its single call site in the ticker's idle branch.🤖 Generated with Claude Code