diff --git a/.changeset/add-xychart-point-labels.md b/.changeset/add-xychart-point-labels.md new file mode 100644 index 00000000000..13a9d7df6b3 --- /dev/null +++ b/.changeset/add-xychart-point-labels.md @@ -0,0 +1,5 @@ +--- +'mermaid': minor +--- + +feat: add per-point text labels for xychart line plots diff --git a/.changeset/fix-xychart-label-line-collision.md b/.changeset/fix-xychart-label-line-collision.md new file mode 100644 index 00000000000..3c055290665 --- /dev/null +++ b/.changeset/fix-xychart-label-line-collision.md @@ -0,0 +1,5 @@ +--- +'mermaid': patch +--- + +fix: auto-flip xychart point labels to avoid collision with line on steep slopes diff --git a/.cspell/misc-terms.txt b/.cspell/misc-terms.txt index 2906a02fa25..5def7b7ccab 100644 --- a/.cspell/misc-terms.txt +++ b/.cspell/misc-terms.txt @@ -3,6 +3,7 @@ Buzan circo handDrawn KOEPF +MMLU neato newbranch validify diff --git a/cypress/integration/rendering/xyChart.spec.js b/cypress/integration/rendering/xyChart.spec.js index 32a4f34984a..54936cf88ff 100644 --- a/cypress/integration/rendering/xyChart.spec.js +++ b/cypress/integration/rendering/xyChart.spec.js @@ -879,4 +879,107 @@ describe('XY Chart', () => { }); }); }); + + it('should render a line chart with point labels', () => { + imgSnapshotTest( + ` + xychart + title "Smallest AI models scoring above 60% on MMLU" + x-axis "Date" ["Apr 2022", "Feb 2023", "Jul 2023", "Sep 2023", "Apr 2024"] + y-axis "Parameters (B)" 0 --> 600 + line [540 "PaLM", 65 "LLaMA-65B", 34 "Llama 2 34B", 7 "Mistral 7B", 3.8 "Phi-3-mini"] + `, + {} + ); + }); + + it('should render a line chart with mixed labels (some points labeled, some not)', () => { + imgSnapshotTest( + ` + xychart + title "Quarterly Performance" + x-axis [Q1, Q2, Q3, Q4] + y-axis "Revenue ($M)" 0 --> 100 + line [25 "Launch", 45, 72, 90 "Target Hit"] + `, + {} + ); + }); + + it('should render a horizontal line chart with point labels', () => { + imgSnapshotTest( + ` + xychart horizontal + title "Model Sizes" + x-axis ["Model A", "Model B", "Model C"] + y-axis "Parameters" 0 --> 100 + line [20 "Small", 50 "Medium", 90 "Large"] + `, + {} + ); + }); + + it('should render multiple lines where only one has labels', () => { + imgSnapshotTest( + ` + xychart + title "Comparison" + x-axis [Q1, Q2, Q3, Q4] + y-axis "Value" 0 --> 100 + line [20, 40, 60, 80] + line [30 "Start", 50, 70, 95 "Peak"] + `, + {} + ); + }); + + it('should render reviewer example: label at 80 "target hit" does not collide with line', () => { + imgSnapshotTest( + ` + xychart + title "Quarterly Performance" + x-axis [Q1, Q2, Q3, Q4] + y-axis "Revenue ($M)" 0 --> 100 + line [25, 45, 80 "target hit", 90] + `, + {} + ); + }); + + describe('Point label collision avoidance', () => { + it('should flip labels below line when steep descent causes collision', () => { + imgSnapshotTest( + ` + xychart + title "Smallest AI models scoring above 60% on MMLU" + x-axis "Date" ["Apr 2022", "Feb 2023", "Jul 2023", "Sep 2023", "Apr 2024"] + y-axis "Parameters (B)" 0 --> 600 + line [540 "PaLM", 65 "LLaMA-65B", 34 "Llama 2 34B", 7 "Mistral 7B", 3.8 "Phi-3-mini"] + `, + {} + ); + }); + it('should keep labels above line when no collision on gentle slope', () => { + imgSnapshotTest( + ` + xychart + x-axis ["A", "B", "C"] + y-axis 0 --> 100 + line [40 "Start", 50 "Mid", 45 "End"] + `, + {} + ); + }); + it('should handle mixed collision: some labels above, some below', () => { + imgSnapshotTest( + ` + xychart + x-axis ["P1", "P2", "P3", "P4"] + y-axis 0 --> 500 + line [400 "High", 50 "Low", 450 "Peak", 30 "Bottom"] + `, + {} + ); + }); + }); }); diff --git a/demos/xychart.html b/demos/xychart.html index 570c8114b3c..da5c1fb27cf 100644 --- a/demos/xychart.html +++ b/demos/xychart.html @@ -316,6 +316,55 @@

XY Charts demos with all theme config


+
+

Line chart with point labels

+
+    xychart
+      title "Smallest AI models scoring above 60% on MMLU"
+      x-axis "Date" ["Apr 2022", "Feb 2023", "Jul 2023", "Sep 2023", "Apr 2024"]
+      y-axis "Parameters (B)" 0 --> 600
+      line [540 "PaLM", 65 "LLaMA-65B", 34 "Llama 2 34B", 7 "Mistral 7B", 3.8 "Phi-3-mini"]
+    
+ +
+

Line chart with mixed labels (some points labeled, some not)

+
+    xychart
+      title "Quarterly Performance"
+      x-axis [Q1, Q2, Q3, Q4]
+      y-axis "Revenue ($M)" 0 --> 100
+      line [25 "Launch", 45, 72, 90 "Target Hit"]
+    
+ +
+

Reviewer's failing example: label at 80 "target hit"

+
+    xychart
+        title "Quarterly Performance"
+        x-axis [Q1, Q2, Q3, Q4]
+        y-axis "Revenue ($M)" 0 --> 100
+        line [25, 45, 80 "target hit", 90]
+    
+ +
+

Label collision avoidance: steep descent

+
+    xychart
+      title "Smallest AI models scoring above 60% on MMLU"
+      x-axis "Date" ["Apr 2022", "Feb 2023", "Jul 2023", "Sep 2023", "Apr 2024"]
+      y-axis "Parameters (B)" 0 --> 600
+      line [540 "PaLM", 65 "LLaMA-65B", 34 "Llama 2 34B", 7 "Mistral 7B", 3.8 "Phi-3-mini"]
+    
+ +
+

Label collision avoidance: zigzag pattern

+
+    xychart
+      x-axis ["P1", "P2", "P3", "P4"]
+      y-axis 0 --> 500
+      line [400 "High", 50 "Low", 450 "Peak", 30 "Bottom"]
+    
+