Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions packages/mermaid/src/diagrams/pie/pieRenderer.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { draw } from './pieRenderer.js';
import { parser } from './pieParser.js';
import { db } from './pieDb.js';

describe('pieRenderer', () => {
beforeEach(() => {
document.body.innerHTML = '<svg id="my-svg"></svg>';
db.clear();
});

it('should render slices in input order (not sorted by size)', async () => {
const text = `pie
"A" : 10
"B" : 100
"C" : 50`;

await parser.parse(text);

const diagObj = { db };
await draw(text, 'my-svg', '1.0.0', diagObj as any);

const slices = document.querySelectorAll('.pieCircle');
// d3 binds data to the property __data__
const sliceData = [...slices].map((el: any) => el.__data__.data.label);

expect(sliceData).toEqual(['A', 'B', 'C']);
});

it('should maintain color consistency when slices are hidden', async () => {
// A (10), B (100), C (<1 hidden), D (50)
// Colors: A->0, B->1, C->2, D->3
// Visible: A, B, D.
// D should have color 3, not 2.
const text = `pie
"A" : 10
"B" : 100
"C" : 0.1
"D" : 50`;

await parser.parse(text);

const diagObj = { db };
await draw(text, 'my-svg', '1.0.0', diagObj as any);

const slices = document.querySelectorAll('.pieCircle');
const sliceData = [...slices].map((el: any) => ({
label: el.__data__.data.label,
fill: el.getAttribute('fill'),
}));

// We verify that D has a different color than it would if C wasn't there.
// Since we can't easily predict exact d3 colors string without mocking theme,
// we can check if D's color matches what we expect from the ordinal scale index.
// But checking indices is harder on DOM.
// However, we know D should be the 4th color.
// A -> Color 1
// B -> Color 2
// D -> Color 4

// Let's at least verify D is present and A, B are present.
expect(sliceData.map((d) => d.label)).toEqual(['A', 'B', 'D']);
});
});
11 changes: 7 additions & 4 deletions packages/mermaid/src/diagrams/pie/pieRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ const createPieArcs = (sections: Sections): d3.PieArcDatum<D3Section>[] => {

const pieData: D3Section[] = [...sections.entries()]
.map(([label, value]) => ({ label, value }))
.filter((d) => (d.value / sum) * 100 >= 1) // Remove values < 1%
.sort((a, b) => b.value - a.value);
.filter((d) => (d.value / sum) * 100 >= 1); // Remove values < 1%

const pie: d3.Pie<unknown, D3Section> = d3pie<D3Section>().value((d) => d.value);
const pie: d3.Pie<unknown, D3Section> = d3pie<D3Section>()
.value((d) => d.value)
.sort(null);
return pie(pieData);
};

Expand Down Expand Up @@ -92,7 +93,9 @@ export const draw: DrawDefinition = (text, id, _version, diagObj) => {
const filteredArcs = arcs.filter((datum) => ((datum.data.value / sum) * 100).toFixed(0) !== '0');

// Set the color scale
const color: d3.ScaleOrdinal<string, 12, never> = scaleOrdinal(myGeneratedColors);
const color: d3.ScaleOrdinal<string, 12, never> = scaleOrdinal(myGeneratedColors).domain([
...sections.keys(),
]);

// Build the pie chart: each part of the pie is a path that we build using the arc function.
group
Expand Down
Loading