Skip to content

finding(plugin-charts): the radar mark hard-codes fillOpacity={0.6} and never consults the series — authored opacity / dashArray AND the whole variant: 'comparison' treatment are dropped on a radar chart #8157

Closed

Description

@os-justin

Measured (objectui origin/main @ c14d3a090)

AdvancedChartImpl.tsx resolves per-series presentation in one helper — comparisonStyle on main (:92), renamed seriesStyle by the objectui#7698 branch. Every cartesian mark calls it. The radar arm does not.

The radar branch (:1719) maps over series exactly like the cartesian arms do, and then renders:

<Radar
  key={s.dataKey}
  dataKey={s.dataKey}
  stroke={color}
  fill={color}
  fillOpacity={0.6}
  {...animProps}
/>

fillOpacity={0.6} is a literal (:1739). The helper is never called on this path, and no other read of s.opacity / s.dashArray / s.variant exists in the branch. Control: grep -rniE 'opacity|dasharray' packages/plugin-charts/src (tests excluded) finds the helper, the cartesian cmp?.… call sites and the two normalizeSeries reads — and this literal, which the objectui#7698 card's own census classified as "a literal constant", i.e. deliberately outside that card's measured surface.

Consequence

On chartType: 'radar', three declared things are inert at once:

  • series[].opacity — declared by @objectstack/spec as ChartSeries.opacity and by @object-ui/types' ChartDataSeriesSchema. Read by normalizeSeries, then discarded.
  • series[].dashArray — same, and recharts' Radar is a stroked mark (stroke={color} right above), so unlike a bar or scatter this is a family where a dash would actually paint.
  • variant: 'comparison' — a radar overlay gets none of the muted treatment every other family gets. The variant key is declared and documented with no family restriction.

So a radar series carrying any of the three draws identically to one carrying none.

Relationship to objectui#7698

Adjacent, not the same card, and deliberately left out of it. objectui#7698 is about the variant gate and the Bar / Scatter marks inside the helper's own call graph; the radar arm never enters that graph, and its census counted this literal as out of scope. Repairing it is also not the same edit: passing the helper's result here would newly mute existing comparison radar series (the helper's non-bar / non-area fill default is 0.5, against today's fixed 0.6), which is a visible change to already-drawn charts and wants its own decision. That is exactly why it is filed rather than folded in.

Out of scope for objectui#7698, and still open after it. This card stands on its own.

Same measurement family, all separate: objectui#7690, objectui#7694, objectui#7682, objectui#7546.

Found while implementing objectui#7698 by the Claude Code dev seat, session session_01YBWFb5YgMU5dw8p2VKj16S; filed without an assignee for triage.

Activity

  1. added theissue type on Sep 8, 2026
  2. os-zhuang commented on Sep 8, 2026

    @os-zhuang
    Contributor

    Triage routing

    Labels bug plugin package: plugin-charts finding domain:ui pm:queue priority:p3 · Type Bug

    Lane — domain:ui. packages/plugin-charts is a published library; the fix lands in the radar arm of AdvancedChartImpl.tsx.

    Re-measured on 83d4fda16 — the claim holds, and two of the card's anchors have moved because objectui#7698 has landed.

    card says (c14d3a090) actual today
    helper comparisonStyle at :92 seriesStyle at :111 — the #7698 rename is on main now, not just on its branch
    radar branch at :1719 branch at :1739
    fillOpacity={0.6} at :1739 :1759

    I read the radar branch in full. It maps over series, resolves resolveColor(config[s.dataKey]?.color || DEFAULT_CHART_COLOR), and renders <Radar stroke={color} fill={color} fillOpacity={0.6} {...animProps} />. No seriesStyle call anywhere in the branch — and the contrast is sharp, because the four cartesian arms all call it, at :1845 (scatter), :1914 (dynamic), :2057 (bar), :2068 (line), :2076 (area). Five call sites in the same file, zero on the radar path. That is a reading, not an absence.

    Admission — class (b), violation of a declared contract, three times over on one mark:

    • series[].opacity — declared by @objectstack/spec as ChartSeries.opacity and by @object-ui/types' ChartDataSeriesSchema, read by normalizeSeries, then discarded.
    • series[].dashArray — same, and the card's point here is the sharp one: Radar is a stroked mark (stroke={color} sits directly above the literal), so unlike a bar or scatter this is a family where a dash would actually paint. It is not inert for want of a place to show.
    • variant: 'comparison' — declared and documented with no family restriction, so a radar overlay silently opts out of a treatment every other family gets.

    Grade p3. Nothing renders wrongly — it renders identically whether or not the three keys are authored, which is the accepted-and-dropped shape rather than a visible defect. Bounded to one chartType. Re-grade to p2 if a radar series carrying opacity, dashArray, or variant: 'comparison' is found authored in this repo, a template, or a consuming app; that is one cheap grep and worth doing before starting.

    ⛔ The remedy is not "call the helper here" — the card says so and is right. Passing seriesStyle's result through would newly mute existing comparison radar series: the helper's non-bar / non-area fill default is 0.5 against today's fixed 0.6. That is a visible change to already-drawn charts, so a claimant must state in the claim comment what happens to a radar series that authors none of the three keys. The defensible answer is that it keeps rendering at 0.6 — honouring the declared keys is the contract repair; relayouting untouched charts is not, and would be this card widening itself.

    This is not a decision-box card: honouring already-declared keys narrows nothing and widens nothing, and it deletes no published capability. The 0.6-vs-0.5 default is an implementation choice with a stated constraint, not a maintainer ruling.

    Correctly not folded into objectui#7698. That card is the variant gate and the Bar / Scatter marks inside the helper's own call graph; the radar arm never enters that graph, and #7698's census classified this literal as "a literal constant" — i.e. deliberately outside its measured surface. Filing rather than riding was right, and this card is still open after #7698 landed. ⛔ Do not close it as covered by #7698.

    Same measurement family, all separate cards, all still their own: objectui#7690, #7694, #7682, #7546.

    Triage seat only — no claim, no dispatch, no code.


    Generated by Claude Code

  3. self-assigned this
    on Sep 18, 2026
  4. os-justin commented on Sep 18, 2026

    @os-justin
    CollaboratorAuthor

    Claim: objectui#8157 — domain:ui execution seat, session_012EpHzwH4wTy5sd7ibkD2yq, 2026-09-18T11:38Z.
    Seat: domain:ui#1
    Thread-read: 5583140952
    Branch: claude/issue-8157-radar-series-presentation
    Clause-②: no

    State written in one call: pm:queue → pm:dispatched, assignee os-justin. Read back MATCHES: bug, plugin, priority:p3, domain:ui, package: plugin-charts, pm:dispatched.

    ⛔⛔ THE ANCHORS HAVE MOVED TWICE — re-derive every one of them

    The card measured c14d3a090; triage re-measured 83d4fda16 and corrected it; I re-measured 592402ea3 and they moved again:

    card triage today
    the helper comparisonStyle :92 seriesStyle :111 re-derive it
    the radar branch :1719 :1739 <RadarChart> :1881, <Radar :1893
    the literal :1739 :1759 fillOpacity={0.6} :1898

    ⇒ three readings of one line in three days. ⛔ Trust none of the numbers above, mine included; find them by content.

    ⭐ The control is what makes the absence a reading, and it still holds: seriesStyle( has 5 call sites in this file — every cartesian arm — and zero on the radar path. That is the sharp fact, ⛔ not the line numbers.

    Scope

    Make the radar arm consult the series the way the five cartesian arms do, so three declared things stop being inert on chartType: 'radar':

    • series[].opacity — declared by @objectstack/spec as ChartSeries.opacity and by @object-ui/types' ChartDataSeriesSchema, read by normalizeSeries, then discarded;
    • series[].dashArray — ⭐ and this is the card's sharpest point: Radar is a stroked mark (stroke={color} sits right above the literal), so unlike a bar or a scatter this is a family where a dash would actually paint;
    • variant: 'comparison' — declared and documented with no family restriction, yet a radar overlay gets none of the muted treatment every other family gets.

    ⛔ Hard constraints

    • ⛔ Not objectui#7698. That card is the variant gate and the Bar / Scatter marks inside the helper's own coverage; its census classified this literal as "a literal constant", i.e. deliberately outside its measured surface. ⛔ Do not reopen or extend it.
    • ⚠️ fillOpacity={0.6} is a DEFAULT, not merely a bug. A radar fill needs some opacity or the overlay is unreadable. ⇒ the question is "what does the series say, and what is the fallback when it says nothing" — ⛔ not "delete the literal". If your reading says the helper cannot supply a sane radar default, stop and report rather than shipping a transparent radar.
    • ⛔ Do not change the cartesian arms. They are the control that shows what the radar arm is missing.
    • ⛔ objectui AGENTS.md:316: never git push --force or --force-with-lease, never push to main. Absolute, and ⛔ not tiered by seat.

    Clause-②: no — a renderer arm reading declarations it already receives. Nothing is added to any published face; the keys are already declared by the spec and by @object-ui/types. ⇒ this is conformance to a contract that already shipped, which SKILL.md puts outside clause ②: 「拉回已声明契约不触它」. ⚠️ Re-measure and return clause_2; ⛔ do not report ^\+export = 0 as if it were the answer.

    The pin

    Three reds, ⛔ not one — a radar series carrying opacity, one carrying dashArray, and one under variant: 'comparison' must each draw differently from a series carrying none, and pre-fix they draw identically. ⭐ The control that keeps it honest: a radar series carrying none of the three renders exactly what it renders today, so the default face does not move.

    ⚠️ Assert on the rendered mark's attributes, ⛔ not on the helper's return value — the helper is not on this path today, which is the entire defect.

    Serial constraints cleared

    packages/plugin-charts/src/AdvancedChartImpl.tsx. Nothing open touches it; my other in-flight card is objectui#8148 (packages/fields) and the three PRs in the queue are on types, plugin-chatbot and plugin-detail. Merge main before opening your PR.

    Return

    Three pre-fix reds with the no-declaration control green on both sides, what you chose as the radar fallback and why, the clause_2 field, and any premise of mine you falsified — ⭐ the line numbers were already wrong twice. A clean stop is a full success.


    Generated by Claude Code

  5. os-justin commented on Sep 18, 2026

    @os-justin
    CollaboratorAuthor

    os-dev-report

    {
      "issue": 8157,
      "status": "done",
      "branch": "claude/issue-8157-radar-series-presentation",
      "pr": "https://github.com/objectstack-ai/objectui/pull/9864",
      "session": "session_012EpHzwH4wTy5sd7ibkD2yq",
      "clause_2": "no — re-measured, not assumed. The diff adds no export, no new declared key and no new published face. `opacity` and `dashArray` are already declared by `@objectstack/spec` (its `dist` declares dashArray as an optional Zod string and opacity as an optional Zod number on the chart-series shape) and by `@object-ui/types`' `ChartDataSeriesSchema` in `packages/types/src/data-display.ts`; `variant` likewise. `seriesStyle` is module-local to `AdvancedChartImpl.tsx` and is not exported. This is a renderer arm being brought into conformance with a contract that already shipped.",
      "premise_still_valid": true,
      "premises_falsified": "One, and it is the class the dispatch warned about. The helper is at line 110, not the 111 the dispatch carried over from triage — a third reading of the same symbol. The dispatch's own radar anchors held on 592402ea3 (RadarChart 1881, Radar 1893, the literal 1898), so they had NOT moved a third time; the helper's had. Everything was re-derived by content, and the sharp control the dispatch named held exactly: `grep -c 'seriesStyle('` on AdvancedChartImpl.tsx = 5, all five in cartesian arms, zero on the radar path. Two other premises checked and confirmed: the `0.6` literal is a single occurrence inside the radar mark; `normalizeSeries` does read and carry all three keys onto the NormalizedSeries the radar arm maps over.",
      "summary": "The radar arm of packages/plugin-charts/src/AdvancedChartImpl.tsx now calls `seriesStyle(s, 'radar')` like the five cartesian arms do, and passes strokeOpacity and strokeDasharray to the mark alongside fillOpacity — radar is a stroked mark, so a dash actually paints there. The `0.6` literal was treated as a DEFAULT, not deleted: it became the fallback, `fillOpacity={pres.fillOpacity ?? 0.6}`, so a radar series declaring none of the three keys paints exactly what it painted before (fill-opacity 0.6, no stroke fade, no dash). The helper gained 'radar' in its `kind` union plus an `areaLike` binding; radar takes the AREA family's muted defaults because it is the other mark this renderer both strokes and fills, so no new numbers were invented. No cartesian arm changed. The doc rows in content/docs/plugins/plugin-charts.mdx that said this renderer strokes `line` and `area` marks were falsified by the change and were repaired in the same commit. A patch changeset declares it.",
      "radar_fallback_choice": "`fillOpacity={pres.fillOpacity ?? 0.6}` at the call site, and the AREA family's muted defaults (fill 0.2, stroke 0.6, dash '4 4') for a comparison radar overlay. Why: triage ruled the defensible answer is that a series authoring none of the three keeps rendering at 0.6, and that is pinned from both sides. The muted numbers were NOT invented — reusing area's is the one choice that adds no new constant, and radar is the only other mark this renderer both strokes and fills. The alternative considered and rejected was widening the `kind` union alone with no helper-body change, which would have dropped a muted radar into the generic 0.5 fill bucket with no stroke fade and no dash: it passes a pin while leaving 'the muted treatment every other family gets' as a 0.1 fill nudge on a stroked mark, which is a hollow repair of the card's sharpest point.",
      "tests": "All readings from the final head 869c3160a (after merging origin/main), each exit code captured before any pipe. THREE REDS, pre-fix and again as a post-commit ablation: `git checkout 592402ea3 -- packages/plugin-charts/src/AdvancedChartImpl.tsx` (mutation proved on disk first: `seriesStyle(s, 'radar')` count 1 to 0, mutated blob 1787741c7 differs from HEAD blob 3ef441070) gives `Tests 4 failed | 15 passed (19)` — authored `opacity` painted 0.6/absent instead of 0.25/0.25; authored `dashArray` left stroke-dasharray absent; `variant: 'comparison'` drew identically to the primary; and authored keys did not override the comparison default. CONTROL GREEN ON BOTH SIDES: the two no-declaration cases (a lone series, and the primary beside a comparison overlay) pass in the ablated run AND with the fix, both asserting exactly fill-opacity 0.6 / stroke-opacity absent / stroke-dasharray absent. The 15 green in the ablated run are those 2 plus the whole 13-case objectui#7698 cartesian pin, which is green on BOTH legs — that is the measurement, not an argument, that no cartesian arm moved. RESTORE proved by blob hash returning to 3ef441070 and an empty `git diff HEAD`, with a `trap ... EXIT INT TERM` on absolute paths. WITH THE FIX: `pnpm exec vitest run packages/plugin-charts/` (through /home/user/objectstack/scripts/pm/os-verify-lock.sh, VERDICT command-exit 0) = `Test Files 64 passed (64)` / `Tests 569 passed (569)`. `pnpm --filter @object-ui/plugin-charts type-check` exit 0 (covers src and tsconfig.test.json, so the new test file is type-checked). `pnpm --filter @object-ui/plugin-charts lint` exit 0 (358 warnings, 0 errors, all pre-existing). Gates, all exit 0: check-changeset-presence, check:control-bytes, check:new-line-citations (0 new citations), check:changeset-claims, check:doc-fences, check:doc-types, check:test-path-roots, check:vi-mock-specifiers, check:vi-mock-inherit, check:vi-mock-override-shape, check:pending-changeset-literals, and check-governed-queue-guard --test on the four paths = NOT GOVERNED. NOT MEASURED, with a proved narrowing declared in the PR body: check:doc-snippets and check:doc-examples both refuse to run until 34 packages are built (PREREQUISITE NOT MET, not a red gate); `git diff -U0` on the .mdx shows three markdown table rows changed and zero fence lines touched, so no TypeScript block in any document moved — CI owns both. Remote CI is in_progress; the report is not held for it.",
      "mcp_calls": "0 — no MCP GitHub tool was called, read or write.",
      "api_writes": "2 — POST /repos/objectstack-ai/objectui/pulls (draft), POST /repos/objectstack-ai/objectui/issues/8157/comments. No label write was made, deliberately: see open_questions. Two git pushes (empty branch as the routing probe, then the work), which are not REST writes.",
      "open_questions": [
        {
          "question": "A standing dev clause says label writing is the seat's step and not CI's, and budgets a POST to the labels endpoint. In objectui that is false and acting on it is harmful. Which text governs objectui?",
          "options": [
            "A — do not hand-apply labels on an objectui PR; .github/workflows/labeler.yml runs actions/labeler@v7 with sync-labels: true, which applies the whole computed set in ONE setLabels call on every opened/synchronize/reopened event, so any label added by hand is erased at the next push. Measured on this PR: I added none, and the workflow applied `plugin`, `plugin: charts`, `tests` on its own.",
            "B — keep hand-applying and re-add after every stomp."
          ],
          "recommendation": "A. The clause's own hazard note (a whole-set PUT erasing a correct additive write) is exactly this workflow, so A is the clause applied rather than the clause broken. Flagging it per the no-silent-side-picking rule rather than deciding it quietly. `needs:contract-review` is ABSENT on PR 9864 (read back after the labeler ran); I neither added nor removed anything."
        }
      ],
      "out_of_scope_findings": [
        "noted, not filed: packages/types/src/data-display.ts carries cross-file line-address citations into this package's AdvancedChartImpl.tsx and normalizeChartSchema.ts, and .changeset/7546-chart-series-keys-declared.md carries another into normalizeChartSchema.ts — the banned form under AGENTS.md #11. Addresses deliberately not reproduced; one of them points into a span this diff shifts. NOT filed because the rule itself rules the repair opportunistic and forbids a sweep, so a card would ask for the thing the rule refuses. Carrier: whoever next edits packages/types/src/data-display.ts, and the seat that lands the objectui#7546 changeset. This change adds none — check:new-line-citations reports 0 new citations.",
        "noted, not filed: check:changeset-claims flagged .changeset/7546-chart-series-keys-declared.md as naming a file this change edits. I read the paragraph, which says the six keys do real work in AdvancedChartImpl.tsx with opacity/dashArray setting stroke and fill. This change makes that sentence MORE true (it was silently overstated for the radar family before). No correction needed, none made. Carrier: none needed.",
        "noted, not filed: triage's re-grade probe. A grep for authored radar metadata carrying opacity, dashArray or variant: 'comparison' finds none in this repo's docs, fixtures or examples, so nothing re-grades the card to p2. Carrier: none."
      ]
    }

    Generated by Claude Code

  6. os-justin commented on Sep 18, 2026

    @os-justin
    CollaboratorAuthor

    ACCEPT — in-seat review of PR objectui#9864 at head 869c3160a

    domain:ui execution seat, session_012EpHzwH4wTy5sd7ibkD2yq, 2026-09-18T12:02Z. ⛔ Not landing on this comment: CI is running with 0 red as I write; I re-read it at the flip.

    ⛔ My anchor was wrong — a THIRD reading of the same symbol

    I told you the helper was at :111, carried over from triage. It is at :110. ⇒ the card said :92, triage said :111, the tree says :110 — three readings in three days of one symbol, which is exactly why my order said to trust none of the numbers including mine. ✅ You re-derived by content and the radar anchors I gave did hold (1881 / 1893 / 1898), so only the helper's had moved.

    ⭐ And the sharp control held exactly as named: seriesStyle( = 5 call sites, all cartesian, zero on the radar path.

    ⭐ The fallback decision is the best part, and it is argued rather than picked

    fillOpacity={pres.fillOpacity ?? 0.6} — the literal became the fallback, not a deletion, which is the boundary I set and the reason I set it: a radar fill with no opacity is unreadable, so "delete the literal" would have shipped a transparent chart.

    ⭐ And the muted numbers were not invented: radar takes the area family's defaults (fill 0.2, stroke 0.6, dash 4 4) because area is the other mark this renderer both strokes and fills, so the change adds no new constant. ✅ The rejected alternative is named with its cost — widening the kind union alone would drop a muted radar into the generic 0.5 bucket with no stroke fade and no dash, "which is a hollow repair of the card's sharpest point". That is a design judgement stated as a trade, which is what I ask for and rarely get.

    The control is a measurement, not an argument

    ✅ Four reds under ablation from the committed fix, mutation proven on disk first (seriesStyle(s, 'radar') 1 → 0; blob 1787741c7 vs HEAD 3ef441070), restore proven by blob hash and an empty git diff HEAD.
    ⭐ The 13-case objectui#7698 cartesian pin is green on BOTH legs. That is the measurement that no cartesian arm moved — ⛔ not a sentence claiming it. And the two no-declaration cases (a lone series, and the primary beside a comparison overlay) are green on both sides asserting exactly fill-opacity 0.6 / stroke-opacity absent / stroke-dasharray absent, so the default face provably does not move.

    ✅ Doc rows this change falsified were repaired in the same commit — in scope, because the change is what made them false.

    Clause-②: no ✅ — opacity, dashArray and variant are already declared by @objectstack/spec and @object-ui/types, and seriesStyle is module-local and unexported. Conformance to a contract that already shipped, ⛔ not an extension of one.

    ⛔ Your open question, ruled: A, and I verified the mechanism rather than taking the recommendation

    Do not hand-apply labels on an objectui PR. Measured:

    • .github/workflows/labeler.yml — on: pull_request types: [opened, synchronize, reopened], actions/labeler@v7, sync-labels: true ⇒ it runs on every push, not just at open;
    • the workflow's own comment at :18–:21 states the mechanism: "The action applies the whole set in ONE setLabels call";
    • .github/labeler.yml declares 0 occurrences of needs:contract-review and 0 of any pm: label.

    ⇒ the clause the standing text budgets — a seat POSTing labels — is the clause's own named hazard in this repo, so A is the clause applied, not broken. ✅ You were right to flag rather than pick silently.

    ⚠️ And this lands on me, not on you. I have been hand-hanging needs:contract-review on objectui PRs all shift — that is the clause-② carrier. If the whole set is replaced on every push, that carrier does not survive the next push, and a pair goes half-written with nobody touching it. ⛔ I am not asserting it does: actions/labeler v5+ is also documented to remove only labels its own config manages, which would leave an unmanaged label alone, and I have no natural experiment in today's history to tell the two readings apart. ⇒ filing it as an unmeasured hazard with the experiment named, because if the first reading is right, every clause-②-yes PR in this repo is one push away from a half-written pair.

    Carried out of review, correctly not filed

    The cross-file line-address citations in packages/types/src/data-display.ts and .changeset/7546-* are the AGENTS.md #11 banned form, and one points into a span this diff shifts — ✅ correctly not filed, because the rule itself calls the repair opportunistic and forbids a sweep, so a card would ask for what the rule refuses. ✅ check:changeset-claims flagged .changeset/7546-*; the paragraph was read, and this change makes its sentence more true rather than false, so no correction was made. ✅ And a re-grade probe found no authored radar metadata carrying any of the three keys anywhere in the repo, so nothing lifts this to p2.


    Generated by Claude Code

  7. os-justin commented on Sep 18, 2026

    @os-justin
    CollaboratorAuthor

    Landed

    objectstack-ai/objectui#9864 merged as 1fbf63f8df5267c155cd4baca72d084f179c2f30, 2026-09-18T12:37Z. That sha is main's head as this comment is written, so the verification below reads the landed tree directly.

    Control, and it is the same instrument the card was filed on. Every line of packages/plugin-charts/src/AdvancedChartImpl.tsx containing seriesStyle( — a CALL, excluding the const seriesStyle = definition at :118:

    1913  seriesStyle(s, 'radar')      ← new
    2053  seriesStyle(s, 'scatter')
    2122  seriesStyle(s, seriesType as any)
    2265  seriesStyle(s, 'bar')
    2276  seriesStyle(s, 'line')
    2284  seriesStyle(s, 'area')
    

    6 call sites. The card measured 5, all cartesian, 0 on radar — that asymmetry was the finding, and it is gone. :1913 sits inside the <RadarChart> region (:1895–:1927), and <Radar> at :1915–:1924 now passes strokeOpacity={pres.strokeOpacity} and strokeDasharray={pres.strokeDasharray}, which it carried neither of before.

    The default was kept, and kept deliberately. fillOpacity={pres.fillOpacity ?? 0.6} — the bare 0.6 the card found is now the FLOOR under an authored value, not the whole story. :1906–:1912 records why: a radar polygon with no fill opacity is an unreadable overlay, so a series declaring nothing must still land somewhere. Removing the literal outright would have been the wrong fix dressed as a cleaner one.

    The no-regression argument is in the code, not in the PR description. :127 reads const areaLike = kind === 'area' || kind === 'radar';, with the claim that for every cartesian kind areaLike is exactly kind === 'area' — so no cartesian arm's result moves. That is checkable by inspection over the union's other four members (line, area, bar, scatter) and it holds. Radar takes the AREA muted defaults because it is the other mark this renderer both strokes and fills.

    Docs match the code. content/docs/plugins/plugin-charts.mdx updates three series-key rows rather than adding a radar aside: variant now states that a radar overlay takes the area muted defaults, and dashArray / opacity add radar to the mark families they list. That claim is the one :127 implements, so the table and the helper now say the same thing — which is what the card was about, the renderer having quietly honoured a published declaration on four marks out of five.

    Closed by the PR's Fixes line; pm:* stripped in the same write as this record.

    Reading time: 2026-09-18T12:39Z


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpackage: plugin-chartspluginpriority:p3

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions