Repository navigation
Add legends to XY charts - #7724
Conversation
Preserve named line and bar series as legend entries so multi-series XY charts can identify their plotted data. Co-authored-by: Cursor <cursoragent@cursor.com>
Follow Mermaid contribution guidance by marking the new docs section with the release token and adding a changeset. Co-authored-by: Cursor <cursoragent@cursor.com>
✅ Deploy Preview for mermaid-js ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
🦋 Changeset detectedLatest commit: 0872879 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
@mermaid-js/examples
mermaid
@mermaid-js/layout-elk
@mermaid-js/layout-tidy-tree
@mermaid-js/mermaid-zenuml
@mermaid-js/parser
@mermaid-js/tiny
commit: |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #7724 +/- ##
==========================================
- Coverage 2.83% 2.81% -0.02%
==========================================
Files 667 670 +3
Lines 72262 72876 +614
Branches 989 992 +3
==========================================
+ Hits 2047 2051 +4
- Misses 70215 70825 +610
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
The latest updates on your projects. Learn more about Argos notifications ↗︎
|
Add focused unit coverage for legend rendering, builder layout integration, plot title persistence, and theme defaults. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Hi @xdumaine. Thanks for this PR. [sisyphus-bot] What's working well 🎉 Comprehensive test coverage for a first-time contributor. Four new test files covering legend unit tests, chart builder integration, DB title persistence, and all 11 themes. 79/79 unit tests + 🎉 Clean architectural fit. ChartLegend implements the existing ChartComponent interface without any deviation. Reserving space before expanding the plot to fill remaining width is exactly the right 🎉 Elegant backwards-compatible syntax. Reusing line "name" [...] (already parseable; title was previously ignored) means zero new grammar and existing unnamed charts are completely unaffected. 🎉 Correct sanitization. title: textSanitizer(title.text) in both setLineData and setBarData matches the established pattern for every other user-supplied text field in this diagram. No XSS path — 🎉 Config schema first. Schema additions drive config.type.ts regeneration; PR body includes pnpm types:build-config in the test plan. The regenerated file matches the schema additions exactly. Things to address 🟡 [important] showLegend: true by default changes rendering for existing documents config.schema.yaml: Any existing diagram that already uses line "name" [...] or bar "name" [...] syntax — including documents on GitHub, GitLab, Obsidian — will now automatically render a legend box, changing their CLAUDE.md is explicit: "Mermaid is rendered server-side by GitHub/GitLab — rendering changes affect millions of existing documents. Treat visual output changes as potentially breaking." The counter-argument (acknowledged in the PR description) is that users who wrote line "avg" [...] expected the name to mean something — they were already opting in to the feature by using the I would like some additional input from other maintainers if we should go for showLegend: true as default or flip to false. @aloisklink , @knsv ? The existing Cypress imgSnapshotTest cases don't use named series, so no baseline failures are expected regardless. 🟢 [nit] Cypress legend test uses screenshot: false only cypress/integration/rendering/xychart/xyChart.spec.js: The test correctly verifies DOM structure (element counts and text content). But without an imgSnapshotTest call, visual regressions — wrong marker size, misaligned text, wrong color — won't be Security No XSS or injection issues. Full trace:
getPlotColorFromPalette() supplies fill/strokeFill values set as D3 .attr('fill', ...) / .attr('stroke', ...) — the existing risk surface, no new exposure. Other checks
|
|
Great call out re: defaulting the legend to true. However, based on the end of that block (quoted below) I'm going to wait for feedback before flipping that. I'm happy to go either way and glad to make that change once there's consensus. Thank you for the review!
|
|
@aloisklink @knsv any preference? I'm glad to update it per your guidance. Would love to get this landed. |
aloisklink
left a comment
There was a problem hiding this comment.
Great work on this, @xdumaine! I'm really like this!
I think keeping showLegend: true by default is fine. Most people would probably be happy to see this, and it's not going to significantly negatively affect this XY charts for other users.
But on the off chance someone doesn't like it, could you maybe add a short instruction on how to disable this in the changeset?
I've done a quick review of your code as well, and I think the main blocking issue I spotted was the lack of visual regression E2E tests (the current @argos-ci changes are all flakiness that should be gone the next time you push), but please see my comments for more information!
I'm going to ping @subhash-halder, the original author of XY charts, in case they want to review this (and also so they can see how awesome this feature is!).
Add visual regression coverage for line and bar legend markers, simplify legend layout helpers, and trim hard-coded test fixtures per reviewer guidance. Co-authored-by: Cursor <cursoragent@cursor.com>
Resolve the xychartDb spec conflict by keeping upstream data length validation coverage and the legend title preservation test. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@aloisklink polite bump please and thank you |
aloisklink
left a comment
There was a problem hiding this comment.
Looks good to me! Thanks for the reminder.
I've got one nitpick (useless type cast, very common with LLM-generated code), but I'll apply that myself so we can merge the PR now!
As a heads up, we've already cut off the release/11.16.0 branch, so this probably won't land in the next release, but only the release after that.
cd749ff
|
@xdumaine, Thank you for the contribution! |
Upstream release: https://github.com/mermaid-js/mermaid/releases/tag/mermaid%4011.17.0 Release notes: ### Minor Changes - [#7842](mermaid-js/mermaid#7842) [`3670b4e`](mermaid-js/mermaid@3670b4e) Thanks [@filipsajdak](https://github.com/filipsajdak)! - feat(c4): render C4 elements through the unified shape system, using the new person shape - [#7812](mermaid-js/mermaid#7812) [`cdfc0ea`](mermaid-js/mermaid@cdfc0ea) Thanks [@knsv-bot](https://github.com/knsv-bot)! - feat(class): route `classDiagram` to the unified (v2) renderer by default Set `class: { defaultRenderer: 'dagre-d3' }` in the config to restore the legacy renderer. - [#7785](mermaid-js/mermaid#7785) [`c45cde9`](mermaid-js/mermaid@c45cde9) Thanks [@knsv-bot](https://github.com/knsv-bot)! - feat(flowchart): add collapsible flowchart subgraphs via `subgraphId@{ view: collapsed }` - [#7828](mermaid-js/mermaid#7828) [`8eb3afc`](mermaid-js/mermaid@8eb3afc) Thanks [@knsv-bot](https://github.com/knsv-bot)! - feat(elk): add `elk.keepEntryNodeOnTop` config option to keep a recursive flow's entry node on top - [#7803](mermaid-js/mermaid#7803) [`74e44eb`](mermaid-js/mermaid@74e44eb) Thanks [@knsv-bot](https://github.com/knsv-bot)! - feat(elk): add `elk.nodePlacementAlignment` config option - [#7792](mermaid-js/mermaid#7792) [`ea55b31`](mermaid-js/mermaid@ea55b31) Thanks [@RodrigojndSantos](https://github.com/RodrigojndSantos)! - feat(er): add subgraph support to ER diagrams. - [#7970](mermaid-js/mermaid#7970) [`a2c0fb6`](mermaid-js/mermaid@a2c0fb6) Thanks [@filipsajdak](https://github.com/filipsajdak)! - feat(flowchart): add `folder`, `bucket`, `console` (terminal window) and `browser` shapes - [#7842](mermaid-js/mermaid#7842) [`ae3e115`](mermaid-js/mermaid@ae3e115) Thanks [@filipsajdak](https://github.com/filipsajdak)! - feat(flowchart): add `person` shape (circular head above a rounded body), usable in flowcharts via `A@{ shape: person }` - [#7724](mermaid-js/mermaid#7724) [`0fd7a9f`](mermaid-js/mermaid@0fd7a9f) Thanks [@xdumaine](https://github.com/xdumaine)! - feat(xyChart): add legends for named line and bar series ### Patch Changes - [#7847](mermaid-js/mermaid#7847) [`215fe89`](mermaid-js/mermaid@215fe89) Thanks [@filipsajdak](https://github.com/filipsajdak)! - fix(c4): named attributes such as `$tags`, `$link` and `$sprite` are no longer clobbered to undefined when they arrive in an earlier positional slot of Person/System/Container/Component/Boundary/Rel statements. - [#7871](mermaid-js/mermaid#7871) [`8d874c4`](mermaid-js/mermaid@8d874c4) Thanks [@knsv-bot](https://github.com/knsv-bot)! - fix(flowchart): stop dagre layout from spamming `warn`-level logs on every node/edge/cluster - [#8071](mermaid-js/mermaid#8071) [`b3d1f63`](mermaid-js/mermaid@b3d1f63) Thanks [@pbrolin47](https://github.com/pbrolin47)! - fix(block): sibling blocks overlapping in block diagrams when one has a label wider than 200px - [#7870](mermaid-js/mermaid#7870) [`71b8843`](mermaid-js/mermaid@71b8843) Thanks [@knsv-bot](https://github.com/knsv-bot)! - fix: a `RangeError: Invalid array length` crash when rendering certain edges. - [#7924](mermaid-js/mermaid#7924) [`9cbef5d`](mermaid-js/mermaid@9cbef5d) Thanks [@nightt5879](https://github.com/nightt5879)! - fix(treeView): icons disappearing after strict security sanitization. - [#7850](mermaid-js/mermaid#7850) [`a34cbf0`](mermaid-js/mermaid@a34cbf0) Thanks [@aloisklink](https://github.com/aloisklink)! - fix(block): allow classdefs to update text color - [#7937](mermaid-js/mermaid#7937) [`f9cbe1e`](mermaid-js/mermaid@f9cbe1e) Thanks [@filipsajdak](https://github.com/filipsajdak)! - fix(dagre): let a diagram's own nodeSpacing/rankSpacing take effect in the unified dagre layout - [#8005](mermaid-js/mermaid#8005) [`90eeece`](mermaid-js/mermaid@90eeece) Thanks [@pbrolin47](https://github.com/pbrolin47)! - fix(flowchart): reverts the behavior change from #7672 (fix/4648-directions), since arrows between subgraphs are broken - [#7951](mermaid-js/mermaid#7951) [`afa2f80`](mermaid-js/mermaid@afa2f80) Thanks [@aloisklink](https://github.com/aloisklink)! - perf: use `fastdom` to batch DOM measurements (up to 25% speedup) - Updated dependencies \[[`e848423`](mermaid-js/mermaid@e848423)]: - @mermaid-js/parser@1.2.1 Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: give me a 98K <240642031+inhuman-0@users.noreply.github.com>
📑 Summary
Adds legends for named XY chart line and bar series. Authors can already write labels like
line "avg" [...]; this change preserves those labels and renders them in a right-side legend whenshowLegendis enabled.Fixes #5292.
Motivation
XY charts support multiple line and bar plots, but readers currently have no built-in way to map each plotted color to a series name. That makes examples like average, p50, and p95 latency lines hard to interpret without surrounding text or manually faked legends.
This PR makes the existing named-series syntax useful in rendered output while keeping unnamed plots unchanged.
📏 Design Decisions
line "name" [...]andbar "name" [...]; no new diagram syntax is required.ChartLegendlayout component that reserves right-side space before the plot expands into remaining width.xyChart.showLegend,legendFontSize,legendPadding, andthemeVariables.xyChart.legendTextColorfor configuration/theming.(v<MERMAID_RELEASE_VERSION>+)marker and includes a minor changeset.Screenshots
Full chart with legend:
Legend detail:
Disclaimer / Methods
I used Cursor's AI coding agent with GPT 5.5. to help inspect Mermaid's XY chart and pie legend implementations, draft the implementation, update docs/config/types, and run verification. I reviewed the generated changes, corrected the implementation where needed, checked the contribution guidelines and PR template, and validated behavior locally with parser, TypeScript, lint, and focused Cypress rendering tests.
Test plan
pnpm --filter mermaid types:build-configpnpm exec prettier --write "packages/mermaid/src/diagrams/xychart/**/*.{ts,js}" "packages/mermaid/src/themes/*.js" "packages/mermaid/src/docs/syntax/xyChart.md" "docs/syntax/xyChart.md" "cypress/integration/rendering/xychart/xyChart.spec.js" "packages/mermaid/src/schemas/config.schema.yaml" "packages/mermaid/src/config.type.ts"pnpm exec vitest run packages/mermaid/src/diagrams/xychart/parser/xychart.jison.spec.tspnpm exec vitest run packages/mermaid/src/diagrams/xychart/chartBuilder/components/legend.spec.ts packages/mermaid/src/diagrams/xychart/xychartDb.spec.ts packages/mermaid/src/diagrams/xychart/parser/xychart.jison.spec.ts packages/mermaid/src/themes/theme-xychart.spec.js(67/67 passing)pnpm exec vitest run --coverage packages/mermaid/src/diagrams/xychart/chartBuilder/components/legend.spec.ts packages/mermaid/src/diagrams/xychart/xychartDb.spec.ts packages/mermaid/src/themes/theme-xychart.spec.jspnpm test:check:tscpnpm exec eslint --quiet packages/mermaid/src/diagrams/xychart/chartBuilder/components/legend.ts packages/mermaid/src/diagrams/xychart/chartBuilder/components/legend.spec.ts packages/mermaid/src/diagrams/xychart/chartBuilder/interfaces.ts packages/mermaid/src/diagrams/xychart/xychartDb.spec.ts packages/mermaid/src/themes/theme-xychart.spec.js cypress/integration/rendering/xychart/xyChart.spec.jsMERMAID_PORT=9000 pnpm run load:env -- start-server-and-test dev http://localhost:9000/ "cypress run --spec cypress/integration/rendering/xychart/xyChart.spec.js"(38/38 passing)📋 Tasks
MERMAID_RELEASE_VERSIONis used for all new features.pnpm changesetand following the prompts. Changesets that add features should beminorand those that fix bugs should bepatch. Please prefix changeset messages withfeat:,fix:, orchore:.Made with Cursor