Skip to content

Add vectorized per-item style channels [codex]#98

Merged
Alek99 merged 6 commits into
mainfrom
set_alpha
Jul 21, 2026
Merged

Add vectorized per-item style channels [codex]#98
Alek99 merged 6 commits into
mainfrom
set_alpha

Conversation

@sselvakumaran

Copy link
Copy Markdown
Contributor

unifies style attributes so per-item attributes can vary (mainly to allow setting alpha per-item; but also adds changes to color, line-height, etc.)

@codspeed-hq

codspeed-hq Bot commented Jul 20, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 94 untouched benchmarks
⏩ 1 skipped benchmark1


Comparing set_alpha (a6b0378) with main (c2a61d8)

Open in CodSpeed

Footnotes

  1. 1 benchmark was skipped, so the baseline result was used instead. If it was deleted from the codebase, click here and archive it to remove it from the performance reports.

@Alek99 Alek99 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Review findings:

  • [P1] js/src/50_chartview.js:2330: the simple scatter path does not exclude g.styleBuf. Constant-color/size circles with vector opacity, artist alpha, symbol, or stroke width are sent to _drawSimplePoints, which binds only x/y and scalar opacity; the new channels are ignored.
  • [P1] python/xy/_raster.py:1500 / python/xy/_svg.py:2129: scalar stroke= remains in style, but the new static paths only inspect trace["stroke"] and otherwise use the face paint. bar(color="red", stroke="blue") exports a red outline. For meshes this also forces one raster command per triangle with varying fills, matching the CodSpeed regression.
  • [P1] js/src/40_gl.js:776 plus the SVG/PNG gradient branches: gradient rectangles bypass vector opacity/artist alpha; static paths also discard vector stroke/width (and PNG corner radii). Preserve the resolved instance channels in all three renderers.
  • [P2] js/src/40_gl.js:253,580,790: constant outlines use a scalar premultiplied uniform, so per-item opacity/artist alpha affects fills but not scalar strokes. The match-fill fallback also uses a trace color rather than each direct face color.
  • [P2] python/xy/_trace.py:87: style/stroke-only scatters aggregate at 200k rather than retaining direct rendering until the documented 2M per-item ceiling.
  • [P2] python/xy/marks.py:1572: histogram scalar _artist_alpha is discarded; vector alpha works.
  • [P2] js/src/50_chartview.js:3955: destruction omits the new rgba/style/stroke/radius buffers, leaking GPU allocations.
  • Required checks are currently failing: protocol was bumped to 4 while repository smoke specs remain at 3, and docs lint finds the missing _artist_alpha scatter parameter documentation.

sselvakumaran and others added 4 commits July 20, 2026 23:01
Review fixes for the per-item style channel refactor:

- Static exporters (SVG + PNG) resolved rect-family and triangle-mesh
  strokes from the trace stroke channel or the face paint only, dropping
  a scalar CSS stroke= into the face color. Restore the style['stroke']
  fallback the scatter emitters already had.
- SVG segments emitted a translucent constant color verbatim in stroke=
  while also feeding its intrinsic alpha into stroke-opacity, applying
  it twice. Gate the verbatim pass-through on an opaque color, matching
  the scatter path.
- The affine-channel raster fast path ignored a direct per-point stroke
  channel, silently dropping RGBA edgecolors when combined with a
  colormap c=. Defer to the styled painter, like the second fast path.
- WebGL uniform strokes (scalar CSS edge colors) bypassed the artist
  alpha / per-item opacity stack that direct stroke buffers and both
  static exporters apply. Ship u_stroke/u_ptStroke straight-alpha and
  premultiply in-shader through the same alpha stack for both modes.

Adds SVG and PNG regression tests for all three exporter paths.
@greptile-apps

greptile-apps Bot commented Jul 21, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds vectorized per-item styling across interactive and static chart rendering. The main changes are:

  • Adds per-item color, opacity, alpha, stroke, width, symbol, and corner-radius channels.
  • Extends WebGL shaders and buffers for the new style attributes.
  • Aligns SVG, PNG, native, widget, streaming, and static-client output.
  • Updates the wire protocol and native ABI versions.
  • Adds rendering and Matplotlib compatibility tests.

Confidence Score: 5/5

This looks safe to merge.

The gradient rectangle and bar paths now apply per-item opacity and artist alpha. The packaged browser clients include the same shader update. No blocking issue remains in the changed code.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex confirmed that the scalar reference produced near-equal point counts across all five positions, with counts around 660 each.
  • T-Rex observed that the vectorized output produced strongly varying per-item counts (114, 258, 788, 459, 834) and 551 distinct RGB values, indicating per-item alpha, color, stroke, and width variation.
  • T-Rex ran Chromium navigation and capture, which exited with code 0, and the accessibility text identified a five-item data series.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
js/src/40_gl.js Extends WebGL shaders with per-item paint and style attributes and preserves the alpha stack for gradient rectangles and bars.
js/src/50_chartview.js Builds, binds, draws, and cleans up the new per-item style buffers across supported mark types.
python/xy/_paint.py Centralizes direct-paint and alpha resolution for static exporters.
python/xy/_payload.py Encodes vectorized paint and style channels in the updated chart payload.
python/xy/_svg.py Applies per-item styles to SVG output.
python/xy/_raster.py Applies per-item styles to raster output.
python/xy/static/index.js Synchronizes the packaged browser client with the new shader and rendering behavior.
python/xy/static/standalone.js Synchronizes the standalone browser client with the new shader and rendering behavior.
tests/pyplot/test_vectorized_styles.py Covers vectorized style behavior through the Matplotlib compatibility layer.

Reviews (2): Last reviewed commit: "Preserve vector alpha for gradient recta..." | Re-trigger Greptile

Comment thread js/src/40_gl.js Outdated
@Alek99
Alek99 merged commit 09eb9f0 into main Jul 21, 2026
26 checks passed
Alek99 added a commit that referenced this pull request Jul 21, 2026
)

Semantic resolutions:
- widget.py: keep this branch's _configure_transport (callback-gated view
  transport) and adopt #98's expanded append() style-channel signature; the
  transport hook now runs on the expanded message.
- render_smoke_nonumpy.py: the probe string keeps this branch's xonly flag
  and gains #98's vstyle via baseWithStyle.
- Bundles and example assets regenerated from the merged js/src (contains
  containment + style channels + context release); the plotly comparison
  baseline stays at main's exact bytes.
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.

2 participants