You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
**`diagnoseConfig` catches common mistakes**: Run `diagnoseConfig("BarChart", props)` to check for empty data, bad dimensions, missing accessors, margin overflow, invisible bar padding, and more. Use `npxsemiotic-ai --doctor` from CLI.
469
469
470
+
## Performance
471
+
472
+
**Prefer string accessors over function accessors**: `xAccessor="value"` is always referentially stable. `xAccessor={d => d.value}` creates a new function on every parent render, which can trigger unnecessary scene rebuilds. The pipeline stores use `.toString()` comparison to detect functionally identical inline arrow functions and skip re-resolution, but this heuristic doesn't work for closures that capture changing variables. When you must use a function accessor, memoize it with `useCallback` or define it outside the component:
content: [{type: "text",text: `PNG output requires the 'sharp' package. Install it with: npm install sharp\n\nFalling back to SVG output:\n\n${svg}`}],
data: zod_1.z.array(zod_1.z.record(zod_1.z.string(),zod_1.z.unknown())).min(1).max(5).describe("1-5 sample data objects"),
477
503
intent: zod_1.z.enum(["comparison","trend","distribution","relationship","composition","geographic","network","hierarchy"]).optional().describe("Visualization intent to narrow suggestions"),
478
504
},suggestChartHandler);
479
-
srv.tool("renderChart",`Render a Semiotic chart to static SVG. Returns SVG string or validation errors. Optionally pass theme CSS custom properties (--semiotic-bg, --semiotic-text, etc.) to style the output. Available components: ${componentNames.join(", ")}.`,{
505
+
srv.tool("renderChart",`Render a Semiotic chart to static SVG or PNG. Returns SVG string (default) or Base64-encoded PNG image. Optionally pass theme CSS custom properties (--semiotic-bg, --semiotic-text, etc.) to style the output. PNG requires the 'sharp' package to be installed. Available components: ${componentNames.join(", ")}.`,{
480
506
component: zod_1.z.string().describe("Chart component name, e.g. 'LineChart', 'BarChart'"),
theme: zod_1.z.record(zod_1.z.string(),zod_1.z.string()).optional().describe("CSS custom properties for theming, e.g. { '--semiotic-bg': '#1a1a2e', '--semiotic-text': '#ededed' }. Only --semiotic-* variables are applied."),
509
+
format: zod_1.z.enum(["svg","png"]).optional().describe("Output format: 'svg' (default) returns SVG markup, 'png' returns a Base64-encoded PNG image. PNG requires the 'sharp' package."),
483
510
},renderChartHandler);
484
511
srv.tool("diagnoseConfig","Diagnose a Semiotic chart configuration for common problems (empty data, bad dimensions, missing accessors, wrong data shape, color contrast issues, etc). Checks WCAG color contrast ratios and suggests COLOR_BLIND_SAFE_CATEGORICAL for accessibility. Returns a human-readable diagnostic report with actionable fixes.",{
485
512
component: zod_1.z.string().describe("Chart component name, e.g. 'LineChart'"),
content: [{type: "text"asconst,text: `PNG output requires the 'sharp' package. Install it with: npm install sharp\n\nFalling back to SVG output:\n\n${svg}`}],
@@ -506,11 +532,12 @@ function createServer(): McpServer {
506
532
507
533
srv.tool(
508
534
"renderChart",
509
-
`Render a Semiotic chart to static SVG. Returns SVG string or validation errors. Optionally pass theme CSS custom properties (--semiotic-bg, --semiotic-text, etc.) to style the output. Available components: ${componentNames.join(", ")}.`,
535
+
`Render a Semiotic chart to static SVG or PNG. Returns SVG string (default) or Base64-encoded PNG image. Optionally pass theme CSS custom properties (--semiotic-bg, --semiotic-text, etc.) to style the output. PNG requires the 'sharp' package to be installed. Available components: ${componentNames.join(", ")}.`,
510
536
{
511
537
component: z.string().describe("Chart component name, e.g. 'LineChart', 'BarChart'"),
theme: z.record(z.string(),z.string()).optional().describe("CSS custom properties for theming, e.g. { '--semiotic-bg': '#1a1a2e', '--semiotic-text': '#ededed' }. Only --semiotic-* variables are applied."),
540
+
format: z.enum(["svg","png"]).optional().describe("Output format: 'svg' (default) returns SVG markup, 'png' returns a Base64-encoded PNG image. PNG requires the 'sharp' package."),
message: `Function accessor${fnAccessors.length>1 ? "s" : ""} detected: ${fnAccessors.join(", ")}. If defined inline (e.g. \`xAccessor={d => d.value}\`), every parent re-render creates a new reference which may trigger unnecessary scene rebuilds.`,
499
+
fix: `Use string accessors when possible (e.g. xAccessor="value"), or memoize with useCallback / define outside the component.`,
0 commit comments