Donut chart
chart.donut
Overview
Render deterministic exact Donut rings without inferred hierarchy, progress, remainder, or cross-ring normalization, while returning every resolved ring radius, exact part ratio, and optional digest-bound host behavior artifact. svg is a complete static, script-free chart. Mark highlight, the dotted guide, and the value panel are not in that SVG, and entry motion, focus, and updates stay inactive there. Pass the entire output.behavior.artifact unchanged to SquillifyChartRuntime.mount(container, artifact, options), then call the returned handle's replay() once to play the entry. A later value change uses update(nextArtifact, {intent}). Injecting svg directly leaves hover and motion off. Interaction is on by default for every host chart: after mount, pointer and keyboard focus open the value panel and the dotted guide. Set behavior.interaction.enabled to false to turn that off. motion.preset accepts only the family's entrance.
It aligns explicit shared IDs without inventing cross-ring semantics.
Reliability
Every ring closes independently and identical inputs are byte-stable.
Context footprint
For ring requests, you receive CHART_CAPACITY_EXCEEDED or CHART_OUTPUT_TOO_LARGE at bounded limits, CHART_THEME_UNKNOWN or CHART_DATA_SHAPE_INVALID for invalid data, and CHART_UNSAFE_OUTPUT or CHART_OUTPUT_TOO_COMPLEX if we cannot certify the SVG. A successful call costs 4 execution credits.
When to use it
When each ring is its own complete exact whole.
When inner rings are children, time periods, or inferred remainder.
Scope
Non-goals
- Sunburst hierarchy
- Implicit progress or remainder
- Partial radial arcs
Properties
Capabilities
Cost & billing
Flat rate per invocation
File handling
How we handle your data
What this means
This skill may receive sensitive content and may return submitted, transformed, extracted, or reformatted content.
Squillify guarantees
- Runs inside Squillify
- This skill runs inside Squillify.
- Payloads are not sent to an external service by this skill.
- Squillify does not permanently store submitted payloads.
- Telemetry records metadata only, not submitted content.
- Submitted payloads are not used for training.
- Submitted payloads are not reviewed by humans.
- This skill does not target sensitive data.
- The response may contain submitted or transformed content.
Your responsibility
Squillify does not determine whether submitted content is sensitive. Your application is responsible for deciding what data it is allowed to submit. Your application is responsible for securing the response.
Input schema
| Field | Type | Required | Description |
|---|---|---|---|
| rings | array | Yes | Required 1..4 independent rings, each with unique id, label, 2..12 positive exact parts, and optional matching exact whole. |
| ringOrder | string | No | input|totalAsc|totalDesc; outermost to innermost; default input. |
| partAlignment | string | No | independent|sharedIds; sharedIds requires the complete same ID set; defaults to independent. |
| innerRadiusRatio | string | No | Exact decimal within 0.30..0.75; default 0.55. |
| ringGap | integer | No | Gap within 0..16; default 4. |
| showPercentages | boolean | No | Show each part percentage in the ring and legend when it fits; defaults to true. |
| center | object | No | Optional object with mode none|text|total|largestPart and bounded text when mode=text; defaults to none. |
| direction | string | No | clockwise|counterclockwise; defaults to clockwise when omitted. |
| startAngle | integer | No | Angle within -360..360; default -90. |
| title | string | No | Bounded visible title; omission renders no title. |
| subtitle | string | No | Bounded visible subtitle; omission renders no subtitle. |
| behavior | object | No | Object with motion and interaction properties; defaults to disabled when omitted. svg is a complete static, script-free chart. Mark highlight, the dotted guide, and the value panel are not in that SVG, and entry motion, focus, and updates stay inactive there. Pass the entire output.behavior.artifact unchanged to SquillifyChartRuntime.mount(container, artifact, options), then call the returned handle's replay() once to play the entry. A later value change uses update(nextArtifact, {intent}). Injecting svg directly leaves hover and motion off. Interaction is on by default for every host chart: after mount, pointer and keyboard focus open the value panel and the dotted guide. Set behavior.interaction.enabled to false to turn that off. motion.preset accepts only the family's entrance. |
| width | integer | No | Canvas width in pixels, 100..1600 (optional; default 600). Outside that range the request is refused as invalid input rather than clamped. The ceiling is the size a chart is read at — a full-HD dashboard or a report page; beyond it the canvas stops being what limits how much fits, and type sized for the canvas is illegible once the export is displayed smaller. It applies per side, so a tall portrait canvas for a long horizontal ranking is allowed. |
| height | integer | No | Canvas height in pixels, 120..1600 (optional; default 440). Outside that range the request is refused as invalid input rather than clamped. The ceiling is the size a chart is read at — a full-HD dashboard or a report page; beyond it the canvas stops being what limits how much fits, and type sized for the canvas is illegible once the export is displayed smaller. It applies per side, so a tall portrait canvas for a long horizontal ranking is allowed. |
| theme | string | No | Visual language: basic, modern or squillify (optional; default squillify). An unregistered value is rejected with the registered names listed — we never substitute silently. |
| surface | string | No | Surface the theme renders on: dark or light (optional; default light). |
| density | string | No | How tightly the chrome is packed: compact, standard or spacious (optional; default standard). Density scales spacing only — it never lowers a legibility minimum. |
| visualProfile | string | No | What the SVG promises about the host font: portable or certified (optional; default portable). The default is layout-deterministic and tolerates substitution; certified refuses text the certified metrics cannot fully measure. |
| style | object | No | Optional bounded paint and typography styling; omit it to use the selected theme defaults. text.size is expressed in normalized design pixels at an 800-pixel reference width, so equivalent roles match at equal CSS width. It never changes data or accessibility. 'contract' selects the published semantics. 'tokens' sets design tokens; 'rules' applies typed properties to a role and optional series/category facets; 'palette' accepts a digest-checked palette; 'css' is a bounded post-layout stylesheet. The styleCapabilities section publishes this family's accepted roles, properties and copyable examples. For Bar, target one mark with role 'bar' plus seriesIndex and categoryIndex; categoryIndex alone targets that category across series. A minimal rule is {"target":{"role":"bar"},"set":{"paint.fill":"#2563eb"}}. Unsupported typed rules are refused; unsupported CSS is dropped and reported. Do not discover the grammar through trial calls: style validation failures are currently billable. Before calling, read this contract's styleSurface and styleCapabilities sections for the complete rule shape, accepted roles and properties, limits, and copyable examples. |
| output | object | No | Output scoping (optional). Nested key output.idNamespace ([a-z][a-z0-9-]{0,31}) is prefixed onto every generated element id when several charts share one host document; omit for a standalone chart. An invalid namespace is rejected. |
Output schema
| Field | Type | Required | Description |
|---|---|---|---|
| svg | string | Yes | Final script-free canonical SVG. svg is a complete static, script-free chart. Mark highlight, the dotted guide, and the value panel are not in that SVG, and entry motion, focus, and updates stay inactive there. Pass the entire output.behavior.artifact unchanged to SquillifyChartRuntime.mount(container, artifact, options), then call the returned handle's replay() once to play the entry. A later value change uses update(nextArtifact, {intent}). Injecting svg directly leaves hover and motion off. Interaction is on by default for every host chart: after mount, pointer and keyboard focus open the value panel and the dotted guide. Set behavior.interaction.enabled to false to turn that off. motion.preset accepts only the family's entrance. |
| width | integer | Yes | Resolved canvas width. |
| height | integer | Yes | Resolved canvas height. |
| viewBox | string | Yes | Rendered coordinate system. |
| ringResults | array | Yes | Array of 1..4 outer-to-inner objects containing ring id, label, exact total and exact part results. |
| donutResult | object | Yes | Object containing resolved alignment, center contract, inner/outer radii and ring count. |
| renderSummary | object | Yes | Object containing bounded ring, part and rendered-mark counts. |
| transformationSummary | object | Yes | Always-present bounded report of any label or layout adaptation. |
| behavior | object | No | Object containing digest-bound manifest, data index, entry plan and transitions when requested. svg is a complete static, script-free chart. Mark highlight, the dotted guide, and the value panel are not in that SVG, and entry motion, focus, and updates stay inactive there. Pass the entire output.behavior.artifact unchanged to SquillifyChartRuntime.mount(container, artifact, options), then call the returned handle's replay() once to play the entry. A later value change uses update(nextArtifact, {intent}). Injecting svg directly leaves hover and motion off. Interaction is on by default for every host chart: after mount, pointer and keyboard focus open the value panel and the dotted guide. Set behavior.interaction.enabled to false to turn that off. motion.preset accepts only the family's entrance. |
| styleReport | object | No | Always reports the resolved typographyProfile and fontMetrics contract, plus tokensApplied, rulesApplied, typedRulesApplied, typedAssignmentsApplied, rulesDropped, declarationsDropped and, when anything was dropped, a bounded list of reasons. |
| warnings | array | No | Present when the render succeeded with a known degradation. Each entry is an object with a stable code, a message and details. Every chart can emit FONT_SUBSTITUTION_POSSIBLE under visualProfile 'portable', FONT_GLYPH_UNMEASURED when a code point falls outside the certified metrics, and CHART_STYLE_PARTIALLY_APPLIED when part of your styling was dropped — styleReport then names which part and why. Codes are stable for agent routing. No ring or part is silently removed. |
API contract
POST /v1/executecurl -sS -X POST "$BASE/v1/execute" \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"skillKey":"chart.donut","input":{"rings":[{"id":"r","label":"Ring","parts":[{"id":"a","label":"A","value":"60"},{"id":"b","label":"B","value":"40"}]}]}}'import { Squillify } from "@squillify/sdk";
const sq = new Squillify({ apiKey: process.env.SQUILLIFY_API_KEY });
const { output } = await sq.execute("chart.donut", {"rings":[{"id":"r1","label":"Current","parts":[{"id":"a","label":"A","value":"60"},{"id":"b","label":"B","value":"40"}]}]});Errors
| Code | HTTP | Retryable | Description |
|---|---|---|---|
| VALIDATION_ERROR | 400 | No | The request payload failed schema validation. |
| UNAUTHORIZED | 401 | No | Missing or invalid API key. |
| SKILL_NOT_ACCESSIBLE | 403 | No | The API key is not granted access to this skill. |
| SKILL_NOT_AVAILABLE_FOR_PLAN | 403 | No | This skill is not included in your current plan. |
| PLAN_ELIGIBILITY_UNAVAILABLE | 503 | Yes | Plan eligibility could not be decided. Retry after backoff. |
| SKILL_NOT_FOUND | 404 | No | The requested skill or version does not exist. |
| TENANT_RATE_LIMITED | 429 | Yes | Request rate limit exceeded. Retry after backoff. |
| QUOTA_EXCEEDED | 429 | Yes | Plan quota exhausted. Retryable once the quota period resets. |
| EXECUTION_TIMEOUT | 504 | Yes | Execution exceeded the allowed time budget. |
| CHART_CAPACITY_EXCEEDED | 429 | No | A size, quota, rate, or time limit was exceeded. |
| CHART_OUTPUT_TOO_LARGE | 429 | No | A size, quota, rate, or time limit was exceeded. |
| CHART_THEME_UNKNOWN | 400 | No | The request payload failed this skill's input validation. |
| CHART_DATA_SHAPE_INVALID | 400 | No | The request payload failed this skill's input validation. |
| CHART_UNSAFE_OUTPUT | 500 | No | The skill encountered an unexpected execution failure. |
| CHART_OUTPUT_TOO_COMPLEX | 500 | No | The skill encountered an unexpected execution failure. |
Other limits
| Limit | Value |
|---|---|
| Recommended inline bytes | 32 KiB |
Limitations
- Sunburst hierarchy
- Implicit progress or remainder
- Partial radial arcs
- Parent-child data
- Operational attainment
- Many tiny parts
How to call
POST /v1/execute (requires authentication)
{
"skillKey": "chart.donut",
"input": {
"rings": [
{
"id": "r1",
"label": "Current",
"parts": [
{
"id": "a",
"label": "A",
"value": "60"
},
{
"id": "b",
"label": "B",
"value": "40"
}
]
}
]
}
}Examples
Independent rings
{
"rings": [
{
"id": "r1",
"label": "Current",
"parts": [
{
"id": "a",
"label": "A",
"value": "60"
},
{
"id": "b",
"label": "B",
"value": "40"
}
]
}
]
}{
"renderSummary": {
"skill": "chart.donut",
"ringCount": 1,
"sectorCount": 2
},
"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"600\" height=\"440\" viewBox=\"0 0 600 440\" role=\"img\" class=\"sq-chart sq-chart--donut sq-family--radial sq-theme--squillify sq-surface--light sq-density--standard\" data-sq-style-contract=\"CHART_STYLE@1\" data-sq-chart=\"donut\" data-sq-family=\"radial\" data-sq-theme=\"squillify\" data-sq-theme-version=\"1\" data-sq-surface=\"light\" data-sq-density=\"standard\" data-sq-a11y-detail=\"full\" aria-labelledby=\"sq-f72d263265b2-title-6 sq-f72d263265b2-desc-7\"><title id=\"sq-f72d263265b2-title-6\">Donut chart</title><desc id=\"sq-f72d263265b2-desc-7\">Donut chart with 1 independent ring. Current total 100. A 60 (60.00%). B 40 (40.00%).</desc><style>.sq-chart{--sq-chart-axis:#c9d1df;--sq-chart-font-family:'Squillify Mono', 'IBM Plex Mono', monospace;--sq-chart-grid:#d8dee9;--sq-chart-surface:#ffffff;--sq-chart-text-muted:#667085;--sq-chart-text-primary:#101828;--sq-series-1:#2563eb;--sq-series-2:#6d5ce7;--sq-series-3:#168a5b;--sq-series-4:#c45412;--sq-series-5:#d92d20;--sq-series-6:#667085;font-family:var(--sq-chart-font-family);font-weight:500;}.sq-chart .sq-background{fill:var(--sq-chart-surface);}</style><defs><linearGradient id=\"sq-f72d263265b2-gradient-0\" gradientUnits=\"objectBoundingBox\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#6f9bff\"/><stop offset=\"1\" stop-color=\"#c9d8ff\"/></linearGradient><linearGradient id=\"sq-f72d263265b2-gradient-1\" gradientUnits=\"objectBoundingBox\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#a99cf8\"/><stop offset=\"1\" stop-color=\"#ded9ff\"/></linearGradient><linearGradient id=\"sq-f72d263265b2-gradient-2\" gradientUnits=\"objectBoundingBox\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#54bc8b\"/><stop offset=\"1\" stop-color=\"#c8ebda\"/></linearGradient><linearGradient id=\"sq-f72d263265b2-gradient-3\" gradientUnits=\"objectBoundingBox\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#f09a5b\"/><stop offset=\"1\" stop-color=\"#f7d4ba\"/></linearGradient><linearGradient id=\"sq-f72d263265b2-gradient-4\" gradientUnits=\"objectBoundingBox\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#426cad\"/><stop offset=\"1\" stop-color=\"#b7c8e3\"/></linearGradient><linearGradient id=\"sq-f72d263265b2-gradient-5\" gradientUnits=\"objectBoundingBox\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#98a2b3\"/><stop offset=\"1\" stop-color=\"#e4e7ec\"/></linearGradient></defs><rect x=\"0\" y=\"0\" width=\"600\" height=\"440\" fill=\"#ffffff\" class=\"sq-background\" data-sq-role=\"background\"/><g class=\"sq-plot\" data-sq-role=\"plot\"><g class=\"sq-donut-curved-ring-label\" data-sq-role=\"annotation\"><g transform=\"translate(168.083 54.722) rotate(-8.234)\"><text x=\"0\" y=\"3\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-ring-character\" data-sq-role=\"annotation\">C</text></g><g transform=\"translate(176.024 53.766) rotate(-5.489)\"><text x=\"0\" y=\"3\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-ring-character\" data-sq-role=\"annotation\">u</text></g><g transform=\"translate(184.003 53.192) rotate(-2.745)\"><text x=\"0\" y=\"3\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-ring-character\" data-sq-role=\"annotation\">r</text></g><g transform=\"translate(192 53) rotate(0)\"><text x=\"0\" y=\"3\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-ring-character\" data-sq-role=\"annotation\">r</text></g><g transform=\"translate(199.997 53.192) rotate(2.745)\"><text x=\"0\" y=\"3\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-ring-character\" data-sq-role=\"annotation\">e</text></g><g transform=\"translate(207.976 53.766) rotate(5.489)\"><text x=\"0\" y=\"3\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-ring-character\" data-sq-role=\"annotation\">n</text></g><g transform=\"translate(215.917 54.722) rotate(8.234)\"><text x=\"0\" y=\"3\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-ring-character\" data-sq-role=\"annotation\">t</text></g></g><text x=\"408\" y=\"20\" font-size=\"10\" text-anchor=\"start\" fill=\"#101828\" class=\"sq-label sq-donut-ring-label\" data-sq-role=\"legend-label\" data-sq-row-index=\"0\">Current</text><path d=\"M 192 60 A 160 160 0 1 1 97.954 349.443 L 140.275 291.193 A 88 88 0 1 0 192 132 Z\" fill=\"url(#sq-f72d263265b2-gradient-0)\" stroke=\"#ffffff\" stroke-width=\"1\" class=\"sq-mark sq-donut-sector\" data-sq-role=\"region\" data-sq-target-key=\"t-donut-4225ca941c9087fd\" data-sq-category-index=\"0\" data-sq-row-index=\"0\" data-sq-palette-index=\"0\"/><rect x=\"408\" y=\"28\" width=\"8\" height=\"8\" rx=\"2\" fill=\"url(#sq-f72d263265b2-gradient-0)\" class=\"sq-mark sq-donut-legend-swatch\" data-sq-role=\"legend-swatch\" data-sq-category-index=\"0\" data-sq-row-index=\"0\" data-sq-palette-index=\"0\"/><text x=\"422\" y=\"36\" font-size=\"10\" text-anchor=\"start\" fill=\"#101828\" class=\"sq-label sq-donut-label\" data-sq-role=\"legend-label\" data-sq-category-index=\"0\" data-sq-row-index=\"0\">A 60.00%</text><text x=\"309.931\" y=\"261.318\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-percentage\" data-sq-role=\"value-label\" data-sq-category-index=\"0\">60.00%</text><path d=\"M 97.954 349.443 A 160 160 0 0 1 192 60 L 192 132 A 88 88 0 0 0 140.275 291.193 Z\" fill=\"url(#sq-f72d263265b2-gradient-1)\" stroke=\"#ffffff\" stroke-width=\"1\" class=\"sq-mark sq-donut-sector\" data-sq-role=\"region\" data-sq-target-key=\"t-donut-f0076f5691a66080\" data-sq-category-index=\"1\" data-sq-row-index=\"0\" data-sq-palette-index=\"1\"/><rect x=\"408\" y=\"42\" width=\"8\" height=\"8\" rx=\"2\" fill=\"url(#sq-f72d263265b2-gradient-1)\" class=\"sq-mark sq-donut-legend-swatch\" data-sq-role=\"legend-swatch\" data-sq-category-index=\"1\" data-sq-row-index=\"0\" data-sq-palette-index=\"1\"/><text x=\"422\" y=\"50\" font-size=\"10\" text-anchor=\"start\" fill=\"#101828\" class=\"sq-label sq-donut-label\" data-sq-role=\"legend-label\" data-sq-category-index=\"1\" data-sq-row-index=\"0\">B 40.00%</text><text x=\"74.069\" y=\"184.682\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-percentage\" data-sq-role=\"value-label\" data-sq-category-index=\"1\">40.00%</text></g></svg>",
"width": 600,
"height": 440,
"viewBox": "0 0 600 440",
"ringResults": [
{
"parts": [
{
"value": "60",
"ratio": "0.6",
"id": "a",
"label": "A",
"inputIndex": 0,
"resolvedIndex": 0
},
{
"value": "40",
"ratio": "0.4",
"id": "b",
"label": "B",
"inputIndex": 1,
"resolvedIndex": 1
}
],
"id": "r1",
"label": "Current",
"total": "100",
"inputIndex": 0,
"resolvedIndex": 0
}
],
"transformationSummary": {
"applied": false,
"operations": [],
"affectedCategoryCount": 0,
"affectedPointCount": 0,
"affectedLabelCount": 0
},
"donutResult": {
"outerRadius": "160.0",
"innerRadius": "88.0",
"showPercentages": true,
"ringCount": 1,
"alignment": "independent",
"ringThickness": "72.0",
"center": {
"content": "none",
"value": "",
"label": ""
}
}
}Aligned rings
{
"partAlignment": "sharedIds",
"rings": [
{
"id": "r1",
"label": "Current",
"parts": [
{
"id": "a",
"label": "A",
"value": "6"
},
{
"id": "b",
"label": "B",
"value": "4"
}
]
},
{
"id": "r2",
"label": "Prior",
"parts": [
{
"id": "a",
"label": "A",
"value": "5"
},
{
"id": "b",
"label": "B",
"value": "5"
}
]
}
]
}{
"renderSummary": {
"skill": "chart.donut",
"ringCount": 2,
"sectorCount": 4
},
"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"600\" height=\"440\" viewBox=\"0 0 600 440\" role=\"img\" class=\"sq-chart sq-chart--donut sq-family--radial sq-theme--squillify sq-surface--light sq-density--standard\" data-sq-style-contract=\"CHART_STYLE@1\" data-sq-chart=\"donut\" data-sq-family=\"radial\" data-sq-theme=\"squillify\" data-sq-theme-version=\"1\" data-sq-surface=\"light\" data-sq-density=\"standard\" data-sq-a11y-detail=\"full\" aria-labelledby=\"sq-8bddaa49d659-title-6 sq-8bddaa49d659-desc-7\"><title id=\"sq-8bddaa49d659-title-6\">Donut chart</title><desc id=\"sq-8bddaa49d659-desc-7\">Donut chart with 2 independent rings. Current total 10. A 6 (60.00%). B 4 (40.00%). Prior total 10. A 5 (50.00%). B 5 (50.00%).</desc><style>.sq-chart{--sq-chart-axis:#c9d1df;--sq-chart-font-family:'Squillify Mono', 'IBM Plex Mono', monospace;--sq-chart-grid:#d8dee9;--sq-chart-surface:#ffffff;--sq-chart-text-muted:#667085;--sq-chart-text-primary:#101828;--sq-series-1:#2563eb;--sq-series-2:#6d5ce7;--sq-series-3:#168a5b;--sq-series-4:#c45412;--sq-series-5:#d92d20;--sq-series-6:#667085;font-family:var(--sq-chart-font-family);font-weight:500;}.sq-chart .sq-background{fill:var(--sq-chart-surface);}</style><defs><linearGradient id=\"sq-8bddaa49d659-gradient-0\" gradientUnits=\"objectBoundingBox\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#6f9bff\"/><stop offset=\"1\" stop-color=\"#c9d8ff\"/></linearGradient><linearGradient id=\"sq-8bddaa49d659-gradient-1\" gradientUnits=\"objectBoundingBox\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#a99cf8\"/><stop offset=\"1\" stop-color=\"#ded9ff\"/></linearGradient><linearGradient id=\"sq-8bddaa49d659-gradient-2\" gradientUnits=\"objectBoundingBox\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#54bc8b\"/><stop offset=\"1\" stop-color=\"#c8ebda\"/></linearGradient><linearGradient id=\"sq-8bddaa49d659-gradient-3\" gradientUnits=\"objectBoundingBox\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#f09a5b\"/><stop offset=\"1\" stop-color=\"#f7d4ba\"/></linearGradient><linearGradient id=\"sq-8bddaa49d659-gradient-4\" gradientUnits=\"objectBoundingBox\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#426cad\"/><stop offset=\"1\" stop-color=\"#b7c8e3\"/></linearGradient><linearGradient id=\"sq-8bddaa49d659-gradient-5\" gradientUnits=\"objectBoundingBox\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#98a2b3\"/><stop offset=\"1\" stop-color=\"#e4e7ec\"/></linearGradient></defs><rect x=\"0\" y=\"0\" width=\"600\" height=\"440\" fill=\"#ffffff\" class=\"sq-background\" data-sq-role=\"background\"/><g class=\"sq-plot\" data-sq-role=\"plot\"><g class=\"sq-donut-curved-ring-label\" data-sq-role=\"annotation\"><g transform=\"translate(168.083 54.722) rotate(-8.234)\"><text x=\"0\" y=\"3\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-ring-character\" data-sq-role=\"annotation\">C</text></g><g transform=\"translate(176.024 53.766) rotate(-5.489)\"><text x=\"0\" y=\"3\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-ring-character\" data-sq-role=\"annotation\">u</text></g><g transform=\"translate(184.003 53.192) rotate(-2.745)\"><text x=\"0\" y=\"3\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-ring-character\" data-sq-role=\"annotation\">r</text></g><g transform=\"translate(192 53) rotate(0)\"><text x=\"0\" y=\"3\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-ring-character\" data-sq-role=\"annotation\">r</text></g><g transform=\"translate(199.997 53.192) rotate(2.745)\"><text x=\"0\" y=\"3\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-ring-character\" data-sq-role=\"annotation\">e</text></g><g transform=\"translate(207.976 53.766) rotate(5.489)\"><text x=\"0\" y=\"3\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-ring-character\" data-sq-role=\"annotation\">n</text></g><g transform=\"translate(215.917 54.722) rotate(8.234)\"><text x=\"0\" y=\"3\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-ring-character\" data-sq-role=\"annotation\">t</text></g></g><text x=\"408\" y=\"20\" font-size=\"10\" text-anchor=\"start\" fill=\"#101828\" class=\"sq-label sq-donut-ring-label\" data-sq-role=\"legend-label\" data-sq-row-index=\"0\">Current</text><path d=\"M 192 60 A 160 160 0 1 1 97.954 349.443 L 115 325.981 A 131 131 0 1 0 192 89 Z\" fill=\"url(#sq-8bddaa49d659-gradient-0)\" stroke=\"#ffffff\" stroke-width=\"1\" class=\"sq-mark sq-donut-sector\" data-sq-role=\"region\" data-sq-target-key=\"t-donut-4225ca941c9087fd\" data-sq-category-index=\"0\" data-sq-row-index=\"0\" data-sq-palette-index=\"0\"/><rect x=\"408\" y=\"28\" width=\"8\" height=\"8\" rx=\"2\" fill=\"url(#sq-8bddaa49d659-gradient-0)\" class=\"sq-mark sq-donut-legend-swatch\" data-sq-role=\"legend-swatch\" data-sq-category-index=\"0\" data-sq-row-index=\"0\" data-sq-palette-index=\"0\"/><text x=\"422\" y=\"36\" font-size=\"10\" text-anchor=\"start\" fill=\"#101828\" class=\"sq-label sq-donut-label\" data-sq-role=\"legend-label\" data-sq-category-index=\"0\" data-sq-row-index=\"0\">A 60.00%</text><text x=\"330.379\" y=\"267.962\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-percentage\" data-sq-role=\"value-label\" data-sq-category-index=\"0\">60.00%</text><path d=\"M 97.954 349.443 A 160 160 0 0 1 192 60 L 192 89 A 131 131 0 0 0 115 325.981 Z\" fill=\"url(#sq-8bddaa49d659-gradient-1)\" stroke=\"#ffffff\" stroke-width=\"1\" class=\"sq-mark sq-donut-sector\" data-sq-role=\"region\" data-sq-target-key=\"t-donut-f0076f5691a66080\" data-sq-category-index=\"1\" data-sq-row-index=\"0\" data-sq-palette-index=\"1\"/><rect x=\"408\" y=\"42\" width=\"8\" height=\"8\" rx=\"2\" fill=\"url(#sq-8bddaa49d659-gradient-1)\" class=\"sq-mark sq-donut-legend-swatch\" data-sq-role=\"legend-swatch\" data-sq-category-index=\"1\" data-sq-row-index=\"0\" data-sq-palette-index=\"1\"/><text x=\"422\" y=\"50\" font-size=\"10\" text-anchor=\"start\" fill=\"#101828\" class=\"sq-label sq-donut-label\" data-sq-role=\"legend-label\" data-sq-category-index=\"1\" data-sq-row-index=\"0\">B 40.00%</text><text x=\"53.621\" y=\"178.038\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-percentage\" data-sq-role=\"value-label\" data-sq-category-index=\"1\">40.00%</text><g class=\"sq-donut-curved-ring-label\" data-sq-role=\"annotation\"><g transform=\"translate(176.044 97.031) rotate(-7.393)\"><text x=\"0\" y=\"3\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-ring-character\" data-sq-role=\"annotation\">P</text></g><g transform=\"translate(184.006 96.258) rotate(-3.697)\"><text x=\"0\" y=\"3\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-ring-character\" data-sq-role=\"annotation\">r</text></g><g transform=\"translate(192 96) rotate(0)\"><text x=\"0\" y=\"3\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-ring-character\" data-sq-role=\"annotation\">i</text></g><g transform=\"translate(199.994 96.258) rotate(3.697)\"><text x=\"0\" y=\"3\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-ring-character\" data-sq-role=\"annotation\">o</text></g><g transform=\"translate(207.956 97.031) rotate(7.393)\"><text x=\"0\" y=\"3\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-ring-character\" data-sq-role=\"annotation\">r</text></g></g><text x=\"408\" y=\"72\" font-size=\"10\" text-anchor=\"start\" fill=\"#101828\" class=\"sq-label sq-donut-ring-label\" data-sq-role=\"legend-label\" data-sq-row-index=\"1\">Prior</text><path d=\"M 192 103 A 117 117 0 0 1 192 337 L 192 308 A 88 88 0 0 0 192 132 Z\" fill=\"url(#sq-8bddaa49d659-gradient-0)\" stroke=\"#ffffff\" stroke-width=\"1\" class=\"sq-mark sq-donut-sector\" data-sq-role=\"region\" data-sq-target-key=\"t-donut-15048d4053f5fddd\" data-sq-category-index=\"0\" data-sq-row-index=\"1\" data-sq-palette-index=\"0\"/><rect x=\"408\" y=\"80\" width=\"8\" height=\"8\" rx=\"2\" fill=\"url(#sq-8bddaa49d659-gradient-0)\" class=\"sq-mark sq-donut-legend-swatch\" data-sq-role=\"legend-swatch\" data-sq-category-index=\"0\" data-sq-row-index=\"1\" data-sq-palette-index=\"0\"/><text x=\"422\" y=\"88\" font-size=\"10\" text-anchor=\"start\" fill=\"#101828\" class=\"sq-label sq-donut-label\" data-sq-role=\"legend-label\" data-sq-category-index=\"0\" data-sq-row-index=\"1\">A 50.00%</text><text x=\"294.5\" y=\"223\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-percentage\" data-sq-role=\"value-label\" data-sq-category-index=\"0\">50.00%</text><path d=\"M 192 337 A 117 117 0 0 1 192 103 L 192 132 A 88 88 0 0 0 192 308 Z\" fill=\"url(#sq-8bddaa49d659-gradient-1)\" stroke=\"#ffffff\" stroke-width=\"1\" class=\"sq-mark sq-donut-sector\" data-sq-role=\"region\" data-sq-target-key=\"t-donut-7821663c0ebf5dc1\" data-sq-category-index=\"1\" data-sq-row-index=\"1\" data-sq-palette-index=\"1\"/><rect x=\"408\" y=\"94\" width=\"8\" height=\"8\" rx=\"2\" fill=\"url(#sq-8bddaa49d659-gradient-1)\" class=\"sq-mark sq-donut-legend-swatch\" data-sq-role=\"legend-swatch\" data-sq-category-index=\"1\" data-sq-row-index=\"1\" data-sq-palette-index=\"1\"/><text x=\"422\" y=\"102\" font-size=\"10\" text-anchor=\"start\" fill=\"#101828\" class=\"sq-label sq-donut-label\" data-sq-role=\"legend-label\" data-sq-category-index=\"1\" data-sq-row-index=\"1\">B 50.00%</text><text x=\"89.5\" y=\"223\" font-size=\"10\" text-anchor=\"middle\" fill=\"#101828\" class=\"sq-label sq-donut-percentage\" data-sq-role=\"value-label\" data-sq-category-index=\"1\">50.00%</text></g></svg>",
"width": 600,
"height": 440,
"viewBox": "0 0 600 440",
"ringResults": [
{
"parts": [
{
"value": "6",
"ratio": "0.6",
"id": "a",
"label": "A",
"inputIndex": 0,
"resolvedIndex": 0
},
{
"value": "4",
"ratio": "0.4",
"id": "b",
"label": "B",
"inputIndex": 1,
"resolvedIndex": 1
}
],
"id": "r1",
"label": "Current",
"total": "10",
"inputIndex": 0,
"resolvedIndex": 0
},
{
"parts": [
{
"value": "5",
"ratio": "0.5",
"id": "a",
"label": "A",
"inputIndex": 0,
"resolvedIndex": 0
},
{
"value": "5",
"ratio": "0.5",
"id": "b",
"label": "B",
"inputIndex": 1,
"resolvedIndex": 1
}
],
"id": "r2",
"label": "Prior",
"total": "10",
"inputIndex": 1,
"resolvedIndex": 1
}
],
"transformationSummary": {
"applied": false,
"operations": [],
"affectedCategoryCount": 0,
"affectedPointCount": 0,
"affectedLabelCount": 0
},
"donutResult": {
"outerRadius": "160.0",
"innerRadius": "88.0",
"showPercentages": true,
"ringCount": 2,
"alignment": "sharedIds",
"ringThickness": "29.0",
"center": {
"content": "none",
"value": "",
"label": ""
}
}
}Recommended use cases
- Compare a few explicitly independent categorical wholes
- Align the same explicit category IDs across complete rings
Avoid for
- Parent-child data
- Operational attainment
- Many tiny parts
Related skills
Composable with
Safety & privacy
- Runs without calling any external service.
- Your payloads are never stored permanently.
- Telemetry captures metadata only — never your payload contents.
- We never train models on your payloads.
- No human reviews your payloads.