@unovis/mcp 1.7.0-mcp.2 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/codegen/index.js +23 -8
- package/dist/codegen/index.js.map +1 -1
- package/dist/recipes/bar.d.ts +1 -1
- package/dist/recipes/bar.js +4 -1
- package/dist/recipes/bar.js.map +1 -1
- package/dist/recipes/shared.js +1 -1
- package/dist/recipes/shared.js.map +1 -1
- package/dist/render/materialize.js +25 -8
- package/dist/render/materialize.js.map +1 -1
- package/dist/render/spec-schema.d.ts +3 -3
- package/dist/render/spec-schema.js +2 -2
- package/dist/render/spec-schema.js.map +1 -1
- package/dist/render/spec.d.ts +9 -4
- package/dist/render/spec.js +8 -3
- package/dist/render/spec.js.map +1 -1
- package/dist/server.js +12 -3
- package/dist/server.js.map +1 -1
- package/dist/tools/register.d.ts +11 -1
- package/dist/tools/register.js +70 -12
- package/dist/tools/register.js.map +1 -1
- package/dist/widget/bundle.js +423 -426
- package/dist/widget/bundle.meta.json +2 -2
- package/dist/widget/bundle.standard.js +215 -218
- package/dist/widget/entry.js +79 -2
- package/dist/widget/entry.js.map +1 -1
- package/dist/widget/events.js +3 -1
- package/dist/widget/events.js.map +1 -1
- package/dist/widget/unpack.js +1 -1
- package/dist/widget/unpack.js.map +1 -1
- package/docs/README.md +1 -1
- package/docs/architecture.md +12 -89
- package/docs/chart-spec.md +15 -12
- package/docs/interactive.md +24 -12
- package/docs/output-types.md +8 -9
- package/docs/tools.md +1 -1
- package/docs/troubleshooting.md +13 -44
- package/docs/webview.md +4 -6
- package/package.json +5 -4
- package/schema/{chart-spec.v1.baseline.json → chart-spec.v0.1.baseline.json} +5 -5
- package/schema/{chart-spec.v1.json → chart-spec.v0.1.json} +5 -5
package/dist/widget/entry.js
CHANGED
|
@@ -11,6 +11,14 @@ import { materializeChart } from '../render/materialize.js';
|
|
|
11
11
|
import { buildInteractions } from './interactions.js';
|
|
12
12
|
import { componentEvents } from './events.js';
|
|
13
13
|
import { SPEC_VERSION } from '../render/spec.js';
|
|
14
|
+
/** Error text comes from exceptions that can echo spec content, so it is
|
|
15
|
+
* rendered as a text node rather than markup */
|
|
16
|
+
function showError(root, message) {
|
|
17
|
+
const el = document.createElement('div');
|
|
18
|
+
el.className = 'uv-error';
|
|
19
|
+
el.textContent = message;
|
|
20
|
+
root.replaceChildren(el);
|
|
21
|
+
}
|
|
14
22
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
15
23
|
const BUNDLE_VERSION = typeof __UNOVIS_MCP_VERSION__ !== 'undefined' ? __UNOVIS_MCP_VERSION__ : 'dev';
|
|
16
24
|
const THEME_ATTR = 'data-theme';
|
|
@@ -84,11 +92,16 @@ export function render(spec, container, options = {}) {
|
|
|
84
92
|
},
|
|
85
93
|
};
|
|
86
94
|
}
|
|
95
|
+
/** The MCP Apps extension revision this view implements */
|
|
96
|
+
const APPS_PROTOCOL_VERSION = '2026-01-26';
|
|
97
|
+
/** Fixed request id for the view-initiated ui/initialize */
|
|
98
|
+
const APPS_INIT_ID = 'unovis-ui-init';
|
|
87
99
|
function startEmbedMode() {
|
|
88
100
|
const root = document.getElementById('uv-embed-root') ?? document.body;
|
|
89
101
|
let handle;
|
|
90
102
|
let lastSpec;
|
|
91
103
|
let lastOptions;
|
|
104
|
+
let appsAnswered = false;
|
|
92
105
|
// In a React Native WebView the host listens on its own bridge, not on
|
|
93
106
|
// window.parent — and receives strings, not structured clones
|
|
94
107
|
const post = (message) => {
|
|
@@ -101,6 +114,7 @@ function startEmbedMode() {
|
|
|
101
114
|
};
|
|
102
115
|
const postSize = () => {
|
|
103
116
|
post({ type: 'unovis:size', width: root.scrollWidth, height: root.scrollHeight });
|
|
117
|
+
post({ jsonrpc: '2.0', method: 'ui/notifications/size-changed', params: { width: root.scrollWidth, height: root.scrollHeight } });
|
|
104
118
|
};
|
|
105
119
|
const renderMessage = (spec, rawOptions) => {
|
|
106
120
|
handle?.destroy();
|
|
@@ -115,9 +129,48 @@ function startEmbedMode() {
|
|
|
115
129
|
postSize();
|
|
116
130
|
}
|
|
117
131
|
catch (e) {
|
|
118
|
-
root
|
|
132
|
+
showError(root, String(e instanceof Error ? e.message : e));
|
|
119
133
|
}
|
|
120
134
|
};
|
|
135
|
+
// MCP Apps hosts speak JSON-RPC. The view initiates the lifecycle
|
|
136
|
+
// (ui/initialize → host result → ui/notifications/initialized) — hosts MUST
|
|
137
|
+
// NOT send tool data before the initialized notification arrives, so the
|
|
138
|
+
// handshake is not optional. Returns true when the message was JSON-RPC.
|
|
139
|
+
const applyHostTheme = (theme) => {
|
|
140
|
+
if (theme !== 'dark' && theme !== 'light')
|
|
141
|
+
return;
|
|
142
|
+
if (lastSpec)
|
|
143
|
+
renderMessage({ ...lastSpec, theme }, lastOptions);
|
|
144
|
+
else
|
|
145
|
+
applyTheme(theme);
|
|
146
|
+
};
|
|
147
|
+
const onJsonRpc = (message) => {
|
|
148
|
+
if (message.jsonrpc !== '2.0')
|
|
149
|
+
return false;
|
|
150
|
+
// The host answered our ui/initialize: adopt its context, signal readiness
|
|
151
|
+
if (message.id === APPS_INIT_ID && message.result) {
|
|
152
|
+
appsAnswered = true;
|
|
153
|
+
applyHostTheme(message.result.hostContext?.theme);
|
|
154
|
+
post({ jsonrpc: '2.0', method: 'ui/notifications/initialized' });
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
if (message.method === 'ui/notifications/tool-result') {
|
|
158
|
+
const spec = message.params?.structuredContent?.spec;
|
|
159
|
+
// Results without a spec (static output types) leave the frame empty
|
|
160
|
+
if (spec)
|
|
161
|
+
renderMessage(spec, { events: true });
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
if (message.method === 'ui/notifications/host-context-changed') {
|
|
165
|
+
applyHostTheme(message.params?.hostContext?.theme);
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
if (message.method === 'ping' && message.id !== undefined) {
|
|
169
|
+
post({ jsonrpc: '2.0', id: message.id, result: {} });
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
return true; // tool-input, tool-cancelled, other ui/*: acknowledged by ignoring
|
|
173
|
+
};
|
|
121
174
|
const onMessage = (event) => {
|
|
122
175
|
// React Native posts strings; iframes post structured clones
|
|
123
176
|
const raw = event.data;
|
|
@@ -133,6 +186,8 @@ function startEmbedMode() {
|
|
|
133
186
|
else {
|
|
134
187
|
message = raw;
|
|
135
188
|
}
|
|
189
|
+
if (onJsonRpc(message))
|
|
190
|
+
return;
|
|
136
191
|
if (message?.type === 'unovis:render' && message.spec)
|
|
137
192
|
renderMessage(message.spec, message.options);
|
|
138
193
|
// Theme flips shouldn't force the host to resend the spec (or reload the
|
|
@@ -151,6 +206,28 @@ function startEmbedMode() {
|
|
|
151
206
|
// Version handshake: hosts that persist embed documents or specs assert
|
|
152
207
|
// compatibility here instead of discovering drift as a blank chart
|
|
153
208
|
post({ type: 'unovis:ready', version: BUNDLE_VERSION, specVersion: SPEC_VERSION });
|
|
209
|
+
// MCP Apps lifecycle: view initiates. Retried briefly because a host may
|
|
210
|
+
// attach its bridge after this document's scripts run; non-Apps hosts never
|
|
211
|
+
// answer, and the retries stop on their own — harmless either way
|
|
212
|
+
const postInitialize = () => post({
|
|
213
|
+
jsonrpc: '2.0',
|
|
214
|
+
id: APPS_INIT_ID,
|
|
215
|
+
method: 'ui/initialize',
|
|
216
|
+
params: {
|
|
217
|
+
protocolVersion: APPS_PROTOCOL_VERSION,
|
|
218
|
+
appInfo: { name: 'unovis-chart-widget', version: BUNDLE_VERSION },
|
|
219
|
+
appCapabilities: {},
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
postInitialize();
|
|
223
|
+
let initializeAttempts = 0;
|
|
224
|
+
const initializeRetry = setInterval(() => {
|
|
225
|
+
if (appsAnswered || ++initializeAttempts > 8) {
|
|
226
|
+
clearInterval(initializeRetry);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
postInitialize();
|
|
230
|
+
}, 500);
|
|
154
231
|
}
|
|
155
232
|
/** Render a spec embedded in the page as <script type="application/json" id="uv-spec"> */
|
|
156
233
|
function renderInlineSpec() {
|
|
@@ -164,7 +241,7 @@ function renderInlineSpec() {
|
|
|
164
241
|
render(JSON.parse(specEl.textContent), root, options);
|
|
165
242
|
}
|
|
166
243
|
catch (e) {
|
|
167
|
-
root
|
|
244
|
+
showError(root, `Failed to render chart: ${String(e instanceof Error ? e.message : e)}`);
|
|
168
245
|
}
|
|
169
246
|
}
|
|
170
247
|
window.UnovisChart = { render, startEmbed: startEmbedMode, unovis };
|
package/dist/widget/entry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../../src/widget/entry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAA;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE7C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../../src/widget/entry.ts"],"names":[],"mappings":"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"}
|
package/dist/widget/events.js
CHANGED
|
@@ -78,7 +78,9 @@ export function componentEvents(lib, component, componentIndex, onEvent) {
|
|
|
78
78
|
const selectors = clickableSelectors(lib, component.type);
|
|
79
79
|
if (!selectors.length)
|
|
80
80
|
return undefined;
|
|
81
|
-
|
|
81
|
+
// Inline own-property check, so static analysis can see the name is validated
|
|
82
|
+
const candidate = Object.prototype.hasOwnProperty.call(extractors, component.type) ? extractors[component.type] : undefined;
|
|
83
|
+
const extract = typeof candidate === 'function' ? candidate : flatRecord;
|
|
82
84
|
const events = {};
|
|
83
85
|
for (const selector of selectors) {
|
|
84
86
|
events[selector] = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/widget/events.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/widget/events.ts"],"names":[],"mappings":"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"}
|
package/dist/widget/unpack.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";(()=>{var f=Uint8Array,S=Uint16Array,xr=Int32Array,er=new f([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),ir=new f([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),zr=new f([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),ar=function(r,t){for(var n=new S(31),e=0;e<31;++e)n[e]=t+=1<<r[e-1];for(var i=new xr(n[30]),e=1;e<30;++e)for(var l=n[e];l<n[e+1];++l)i[l]=l-n[e]<<5|e;return{b:n,r:i}},or=ar(er,2),sr=or.b,Ar=or.r;sr[28]=258,Ar[258]=28;var fr=ar(ir,0),Mr=fr.b,dr=fr.r,W=new S(32768);for(o=0;o<32768;++o)g=(o&43690)>>1|(o&21845)<<1,g=(g&52428)>>2|(g&13107)<<2,g=(g&61680)>>4|(g&3855)<<4,W[o]=((g&65280)>>8|(g&255)<<8)>>1;var g,o,I=(function(r,t,n){for(var e=r.length,i=0,l=new S(t);i<e;++i)r[i]&&++l[r[i]-1];var y=new S(t);for(i=1;i<t;++i)y[i]=y[i-1]+l[i-1]<<1;var p;if(n){p=new S(1<<t);var z=15-t;for(i=0;i<e;++i)if(r[i])for(var C=i<<4|r[i],w=t-r[i],a=y[r[i]-1]++<<w,s=a|(1<<w)-1;a<=s;++a)p[W[a]>>z]=C}else for(p=new S(e),i=0;i<e;++i)r[i]&&(p[i]=W[y[r[i]-1]++]>>15-r[i]);return p}),B=new f(288);for(o=0;o<144;++o)B[o]=8;var o;for(o=144;o<256;++o)B[o]=9;var o;for(o=256;o<280;++o)B[o]=7;var o;for(o=280;o<288;++o)B[o]=8;var o,hr=new f(32);for(o=0;o<32;++o)hr[o]=5;var o;var Sr=I(B,9,1);var Cr=I(hr,5,1),R=function(r){for(var t=r[0],n=1;n<r.length;++n)r[n]>t&&(t=r[n]);return t},v=function(r,t,n){var e=t/8|0;return(r[e]|r[e+1]<<8)>>(t&7)&n},V=function(r,t){var n=t/8|0;return(r[n]|r[n+1]<<8|r[n+2]<<16)>>(t&7)},Ur=function(r){return(r+7)/8|0},ur=function(r,t,n){return(t==null||t<0)&&(t=0),(n==null||n>r.length)&&(n=r.length),new f(r.subarray(t,n))};var Fr=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],u=function(r,t,n){var e=new Error(t||Fr[r]);if(e.code=r,Error.captureStackTrace&&Error.captureStackTrace(e,u),!n)throw e;return e},
|
|
1
|
+
"use strict";(()=>{var f=Uint8Array,S=Uint16Array,xr=Int32Array,er=new f([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),ir=new f([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),zr=new f([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),ar=function(r,t){for(var n=new S(31),e=0;e<31;++e)n[e]=t+=1<<r[e-1];for(var i=new xr(n[30]),e=1;e<30;++e)for(var l=n[e];l<n[e+1];++l)i[l]=l-n[e]<<5|e;return{b:n,r:i}},or=ar(er,2),sr=or.b,Ar=or.r;sr[28]=258,Ar[258]=28;var fr=ar(ir,0),Mr=fr.b,dr=fr.r,W=new S(32768);for(o=0;o<32768;++o)g=(o&43690)>>1|(o&21845)<<1,g=(g&52428)>>2|(g&13107)<<2,g=(g&61680)>>4|(g&3855)<<4,W[o]=((g&65280)>>8|(g&255)<<8)>>1;var g,o,I=(function(r,t,n){for(var e=r.length,i=0,l=new S(t);i<e;++i)r[i]&&++l[r[i]-1];var y=new S(t);for(i=1;i<t;++i)y[i]=y[i-1]+l[i-1]<<1;var p;if(n){p=new S(1<<t);var z=15-t;for(i=0;i<e;++i)if(r[i])for(var C=i<<4|r[i],w=t-r[i],a=y[r[i]-1]++<<w,s=a|(1<<w)-1;a<=s;++a)p[W[a]>>z]=C}else for(p=new S(e),i=0;i<e;++i)r[i]&&(p[i]=W[y[r[i]-1]++]>>15-r[i]);return p}),B=new f(288);for(o=0;o<144;++o)B[o]=8;var o;for(o=144;o<256;++o)B[o]=9;var o;for(o=256;o<280;++o)B[o]=7;var o;for(o=280;o<288;++o)B[o]=8;var o,hr=new f(32);for(o=0;o<32;++o)hr[o]=5;var o;var Sr=I(B,9,1);var Cr=I(hr,5,1),R=function(r){for(var t=r[0],n=1;n<r.length;++n)r[n]>t&&(t=r[n]);return t},v=function(r,t,n){var e=t/8|0;return(r[e]|r[e+1]<<8)>>(t&7)&n},V=function(r,t){var n=t/8|0;return(r[n]|r[n+1]<<8|r[n+2]<<16)>>(t&7)},Ur=function(r){return(r+7)/8|0},ur=function(r,t,n){return(t==null||t<0)&&(t=0),(n==null||n>r.length)&&(n=r.length),new f(r.subarray(t,n))};var Fr=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],u=function(r,t,n){var e=new Error(t||Fr[r]);if(e.code=r,Error.captureStackTrace&&Error.captureStackTrace(e,u),!n)throw e;return e},Dr=function(r,t,n,e){var i=r.length,l=e?e.length:0;if(!i||t.f&&!t.l)return n||new f(0);var y=!n,p=y||t.i!=2,z=t.i;y&&(n=new f(i*3));var C=function(rr){var tr=n.length;if(rr>tr){var nr=new f(Math.max(tr*2,rr));nr.set(n),n=nr}},w=t.f||0,a=t.p||0,s=t.b||0,x=t.l,E=t.d,U=t.m,F=t.n,d=i*8;do{if(!x){w=v(r,a,1);var G=v(r,a+1,3);if(a+=3,G)if(G==1)x=Sr,E=Cr,U=9,F=5;else if(G==2){var L=v(r,a,31)+257,j=v(r,a+10,15)+4,k=L+v(r,a+5,31)+1;a+=14;for(var D=new f(k),$=new f(19),h=0;h<j;++h)$[zr[h]]=v(r,a+h*3,7);a+=j*3;for(var J=R($),pr=(1<<J)-1,gr=I($,J,1),h=0;h<k;){var K=gr[v(r,a,pr)];a+=K&15;var c=K>>4;if(c<16)D[h++]=c;else{var A=0,Z=0;for(c==16?(Z=3+v(r,a,3),a+=2,A=D[h-1]):c==17?(Z=3+v(r,a,7),a+=3):c==18&&(Z=11+v(r,a,127),a+=7);Z--;)D[h++]=A}}var Q=D.subarray(0,L),m=D.subarray(L);U=R(Q),F=R(m),x=I(Q,U,1),E=I(m,F,1)}else u(1);else{var c=Ur(a)+4,O=r[c-4]|r[c-3]<<8,q=c+O;if(q>i){z&&u(0);break}p&&C(s+O),n.set(r.subarray(c,q),s),t.b=s+=O,t.p=a=q*8,t.f=w;continue}if(a>d){z&&u(0);break}}p&&C(s+131072);for(var yr=(1<<U)-1,wr=(1<<F)-1,P=a;;P=a){var A=x[V(r,a)&yr],M=A>>4;if(a+=A&15,a>d){z&&u(0);break}if(A||u(2),M<256)n[s++]=M;else if(M==256){P=a,x=null;break}else{var X=M-254;if(M>264){var h=M-257,T=er[h];X=v(r,a,(1<<T)-1)+sr[h],a+=T}var H=E[V(r,a)&wr],N=H>>4;H||u(3),a+=H&15;var m=Mr[N];if(N>3){var T=ir[N];m+=V(r,a)&(1<<T)-1,a+=T}if(a>d){z&&u(0);break}p&&C(s+131072);var b=s+X;if(s<m){var _=l-m,mr=Math.min(m,b);for(_+s<0&&u(3);s<mr;++s)n[s]=e[_+s]}for(;s<b;++s)n[s]=n[s-m]}}t.l=x,t.p=P,t.b=s,t.f=w,x&&(w=1,t.m=U,t.d=E,t.n=F)}while(!w);return s!=n.length&&y?ur(n,0,s):n.subarray(0,s)};var Tr=new f(0);var Ir=function(r){(r[0]!=31||r[1]!=139||r[2]!=8)&&u(6,"invalid gzip data");var t=r[3],n=10;t&4&&(n+=(r[10]|r[11]<<8)+2);for(var e=(t>>3&1)+(t>>4&1);e>0;e-=!r[n++]);return n+(t&2)},Br=function(r){var t=r.length;return(r[t-4]|r[t-3]<<8|r[t-2]<<16|r[t-1]<<24)>>>0};function lr(r,t){var n=Ir(r);return n+8>r.length&&u(6,"invalid gzip data"),Dr(r.subarray(n,-8),{i:2},t&&t.out||new f(Br(r)),t&&t.dictionary)}var Y=typeof TextDecoder<"u"&&new TextDecoder,Er=0;try{Y.decode(Tr,{stream:!0}),Er=1}catch{}var Zr=function(r){for(var t="",n=0;;){var e=r[n++],i=(e>127)+(e>223)+(e>239);if(n+i>r.length)return{s:t,r:ur(r,n-1)};i?i==3?(e=((e&15)<<18|(r[n++]&63)<<12|(r[n++]&63)<<6|r[n++]&63)-65536,t+=String.fromCharCode(55296|e>>10,56320|e&1023)):i&1?t+=String.fromCharCode((e&31)<<6|r[n++]&63):t+=String.fromCharCode((e&15)<<12|(r[n++]&63)<<6|r[n++]&63):t+=String.fromCharCode(e)}};function vr(r,t){if(t){for(var n="",e=0;e<r.length;e+=16384)n+=String.fromCharCode.apply(null,r.subarray(e,e+16384));return n}else{if(Y)return Y.decode(r);var i=Zr(r),l=i.s,n=i.r;return n.length&&u(8),l}}var cr=document.getElementById("uv-bundle-gz");if(cr?.textContent)try{let r=cr.textContent.replace(/\s+/g,""),t=Uint8Array.from(atob(r),i=>i.charCodeAt(0)),n=vr(lr(t)),e=document.createElement("script");e.textContent=n,document.head.appendChild(e)}catch(r){let t=document.createElement("div");t.className="uv-error",t.textContent=`Failed to unpack the chart bundle: ${String(r instanceof Error?r.message:r)}`,document.body.replaceChildren(t)}})();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unpack.js","sourceRoot":"","sources":["../../src/widget/unpack.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAE9C,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,cAAc,CAAC,CAAA;AACvD,IAAI,OAAO,EAAE,WAAW,EAAE,CAAC;IACzB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;QACnD,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAA;QAC9D,MAAM,MAAM,GAAG,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAA;QAC3C,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;QAC/C,MAAM,CAAC,WAAW,GAAG,MAAM,CAAA;QAC3B,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;IACnC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"unpack.js","sourceRoot":"","sources":["../../src/widget/unpack.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAE9C,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,cAAc,CAAC,CAAA;AACvD,IAAI,OAAO,EAAE,WAAW,EAAE,CAAC;IACzB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;QACnD,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAA;QAC9D,MAAM,MAAM,GAAG,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAA;QAC3C,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;QAC/C,MAAM,CAAC,WAAW,GAAG,MAAM,CAAA;QAC3B,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;IACnC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;QACxC,EAAE,CAAC,SAAS,GAAG,UAAU,CAAA;QACzB,EAAE,CAAC,WAAW,GAAG,sCAAsC,MAAM,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QACnG,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,CAAA;IACnC,CAAC;AACH,CAAC"}
|
package/docs/README.md
CHANGED
|
@@ -12,7 +12,7 @@ rendered locally in Node, with no browser and no remote services.
|
|
|
12
12
|
| [Output types](./output-types.md) | `svg`, `png`, `html`, `interactive`, `config`, `code` — what each returns and when to use it |
|
|
13
13
|
| [Chart spec](./chart-spec.md) | The JSON IR behind every chart: containers, components, accessor references |
|
|
14
14
|
| [Programmatic use](./programmatic.md) | Use it as a library: `renderChart`, the `renderToSvg` SSR primitive, PNG rasterization, embedding the tools in your own MCP server |
|
|
15
|
-
| [Interactive charts](./interactive.md) | The browser widget, self-contained HTML, iframe embedding, MCP
|
|
15
|
+
| [Interactive charts](./interactive.md) | The browser widget, self-contained HTML, iframe embedding, the MCP Apps extension |
|
|
16
16
|
| [Native WebViews](./webview.md) | React Native embedding: the bridge, theme switching without reloads, version pinning |
|
|
17
17
|
| [Architecture](./architecture.md) | How headless rendering actually works, and why each piece exists |
|
|
18
18
|
| [Troubleshooting](./troubleshooting.md) | Fonts, blank charts, timeouts, large data, known limitations |
|
package/docs/architecture.md
CHANGED
|
@@ -19,23 +19,17 @@ tool call ──► recipe ──► ChartSpec ──► materializer ──►
|
|
|
19
19
|
SVG post-processing ──► standalone SVG ──► PNG (resvg)
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
The work is split across two packages:
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
| `src/tools/`, `src/server.ts`, `src/cli.ts` | The MCP surface |
|
|
34
|
-
|
|
35
|
-
The dependency arrows only point one way: [`@unovis/ssr`](https://www.npmjs.com/package/@unovis/ssr)
|
|
36
|
-
knows nothing about specs, and `render` knows nothing about MCP. `renderToSvg`
|
|
37
|
-
is the package boundary: this server consumes it exactly the way any other
|
|
38
|
-
SSR consumer would, and re-exports it unchanged.
|
|
24
|
+
- **[`@unovis/ssr`](https://www.npmjs.com/package/@unovis/ssr)** — the headless
|
|
25
|
+
browser environment, the `renderToSvg` SSR primitive, SVG post-processing and
|
|
26
|
+
SVG → PNG rasterization. It knows nothing about chart specs or MCP.
|
|
27
|
+
- **`@unovis/mcp`** — the chart spec and the recipes that build it, the code
|
|
28
|
+
generator, the browser widget, and the MCP surface itself.
|
|
29
|
+
|
|
30
|
+
The dependency arrows only point one way: `renderToSvg` is the package
|
|
31
|
+
boundary, and this server consumes it exactly the way any other SSR consumer
|
|
32
|
+
would, and re-exports it unchanged.
|
|
39
33
|
|
|
40
34
|
## The environment shims
|
|
41
35
|
|
|
@@ -99,8 +93,7 @@ The interactive outputs bundle the **same materializer** the headless renderer
|
|
|
99
93
|
uses, so one code path turns a spec into a chart on both sides. esbuild keeps
|
|
100
94
|
the bundle at ~670kB by importing components individually — the package barrel
|
|
101
95
|
statically pulls in Leaflet, MapLibre and Three — and by excluding elkjs, whose
|
|
102
|
-
1.4MB engine would dwarf everything else.
|
|
103
|
-
fails the build if the barrel creeps back in.
|
|
96
|
+
1.4MB engine would dwarf everything else.
|
|
104
97
|
|
|
105
98
|
Documents don't carry those bytes raw, twice over. Two prebuilt variants split
|
|
106
99
|
along the dependency line — `standard` (~330kB: XY and radial charts) and
|
|
@@ -110,80 +103,10 @@ that covers the spec. The chosen bundle is then inlined as a gzip+base64
|
|
|
110
103
|
payload with a ~5kB synchronous self-extracting bootstrap. Net effect: a line
|
|
111
104
|
chart document is ~140kB on disk, a graph document ~290kB, and the spec and
|
|
112
105
|
styles stay readable in both. A spec rendered against a bundle that lacks its
|
|
113
|
-
component fails with an explicit error
|
|
114
|
-
either bundle outgrows its reason to exist.
|
|
106
|
+
component fails with an explicit error instead of drawing a blank chart.
|
|
115
107
|
|
|
116
108
|
Interactions are derived from the spec: per-chart-type tooltip templates, a
|
|
117
109
|
crosshair for continuous XY charts, and the real HTML legend. Hosts that opt
|
|
118
110
|
in also receive clicks as normalized events, and native WebViews get the same
|
|
119
111
|
protocol over their own bridge ([Interactive charts](./interactive.md),
|
|
120
112
|
[Native WebViews](./webview.md)).
|
|
121
|
-
|
|
122
|
-
## Upstream changes
|
|
123
|
-
|
|
124
|
-
A handful of fixes belong in `@unovis/ts` rather than in shims, and were made
|
|
125
|
-
there:
|
|
126
|
-
|
|
127
|
-
- `ContainerCore` falls back to the configured width/height when `clientWidth`
|
|
128
|
-
is 0 (detached or non-layouting environments).
|
|
129
|
-
- `getPixelsPerInch` pre-seeds its cache before measuring — without layout,
|
|
130
|
-
`getComputedStyle` returns the specified value (`'128in'`), which recursed
|
|
131
|
-
infinitely.
|
|
132
|
-
- Root `index.js` / `maps.js` entries so `@unovis/ts` resolves in plain Node.
|
|
133
|
-
|
|
134
|
-
The trend matters: as the core becomes SSR-friendlier, `@unovis/ssr`'s shim
|
|
135
|
-
layer shrinks. Three upstream issues track the next deletions:
|
|
136
|
-
[#888](https://github.com/f5/unovis/issues/888) (text measurement via canvas
|
|
137
|
-
instead of getBBox — retires the hardest shim),
|
|
138
|
-
[#889](https://github.com/f5/unovis/issues/889) (event binding without the
|
|
139
|
-
500ms throttle window), and
|
|
140
|
-
[#890](https://github.com/f5/unovis/issues/890) (clear the diagnostics that
|
|
141
|
-
stop vite-plugin-dts emitting entry declarations — retires
|
|
142
|
-
`packages/ts/build-entry-dts.mjs`).
|
|
143
|
-
|
|
144
|
-
## Testing strategy
|
|
145
|
-
|
|
146
|
-
| Layer | What it proves |
|
|
147
|
-
|---|---|
|
|
148
|
-
| Env unit tests | Bbox math, variable resolution, frame flushing |
|
|
149
|
-
| Visual regression | Every fixture compared as pixels against a text-stored SVG baseline (both sides rasterized at test time) — attribute noise passes, visual changes fail with a reviewable diff image |
|
|
150
|
-
| Spec contract | Version gating, locale-aware formatting, derived time-axis ticks |
|
|
151
|
-
| Post-processing tests | Id rewriting, variable baking, header synthesis, theme |
|
|
152
|
-
| MCP integration | Real SDK client over an in-memory transport: schemas, every output type, error paths, tool filtering, concurrency |
|
|
153
|
-
| Tool schemas | Every advertised schema validated against the draft 2020-12 meta-schema, with no `$ref`s — the shape a client must accept before any chart can render ([why](./troubleshooting.md#the-client-rejects-the-whole-tool-list)) |
|
|
154
|
-
| Widget tests | The **real browser bundle** executed in jsdom: rendering, a simulated hover producing tooltip content, the embed protocol with its version handshake, clicks surfacing as normalized events, the React Native bridge and runtime theme switching |
|
|
155
|
-
| Widget matrix | All 15 chart types rendered interactively with a clean console |
|
|
156
|
-
| Browser smoke lane | Headless Chromium (real layout, paint and input): every family renders with a clean console, hover produces the crosshair readout, a click travels the embed protocol, the theme message re-renders — the interactions jsdom cannot exercise |
|
|
157
|
-
| Codegen | Generated TypeScript **type-checked against `@unovis/ts`** |
|
|
158
|
-
| `pnpm samples` | Every fixture rendered to SVG + PNG, light and dark, as a contact sheet for eyeball review |
|
|
159
|
-
|
|
160
|
-
Graph charts are deliberately not snapshotted — even as pixels. They keep
|
|
161
|
-
settling for a few frames after their layout reports completion — fit-view,
|
|
162
|
-
label collision passes — so exact geometry depends on machine load, and
|
|
163
|
-
`force` layouts additionally call `Math.random()`. The renderer waits out a
|
|
164
|
-
short grace period so real output doesn't lose those late frames, but a
|
|
165
|
-
snapshot would still be a false signal that fails randomly under CI load.
|
|
166
|
-
Structural assertions, the widget matrix and the async-layout probe cover
|
|
167
|
-
graphs instead.
|
|
168
|
-
|
|
169
|
-
`pnpm test` builds the widget bundle first, so a fresh clone can run the suite
|
|
170
|
-
without a manual build step.
|
|
171
|
-
|
|
172
|
-
## Continuous integration
|
|
173
|
-
|
|
174
|
-
The `mcp` job in `.github/workflows/pull_request.yml` runs on every pull
|
|
175
|
-
request: build (`@unovis/ts` then this package), type-check, lint, the full test
|
|
176
|
-
suite, and the sample gallery — which is uploaded as a build artifact so a
|
|
177
|
-
reviewer can look at the charts instead of trusting a green check.
|
|
178
|
-
|
|
179
|
-
Inter is cached at `~/.cache/unovis-ssr` (keyed on `@unovis/ssr`'s `src/env/fonts.ts`, which
|
|
180
|
-
holds the pinned version and checksum). That keeps the suite off the network and
|
|
181
|
-
keeps text metrics — and therefore the SVG snapshots — reproducible between
|
|
182
|
-
runs. Baselines are SVG text: reviewable diffs, and git stores deltas instead
|
|
183
|
-
of binary copies. Both the baseline and the fresh render rasterize through
|
|
184
|
-
the same resvg on the same machine at compare time, so platform differences
|
|
185
|
-
cancel — the tight pixel tolerance only absorbs sub-pixel jitter from
|
|
186
|
-
harmless baseline drift.
|
|
187
|
-
|
|
188
|
-
What the suite can't prove is covered in
|
|
189
|
-
[Troubleshooting](./troubleshooting.md#what-the-tests-dont-cover).
|
package/docs/chart-spec.md
CHANGED
|
@@ -18,7 +18,7 @@ reach Unovis options the tool schemas deliberately don't expose.
|
|
|
18
18
|
|
|
19
19
|
```ts
|
|
20
20
|
interface ChartSpec {
|
|
21
|
-
specVersion?:
|
|
21
|
+
specVersion?: string // contract version, e.g. "0.1" (see below)
|
|
22
22
|
container: 'xy' | 'single'
|
|
23
23
|
width: number
|
|
24
24
|
height: number
|
|
@@ -63,20 +63,23 @@ options the tools don't expose.
|
|
|
63
63
|
## Versioning
|
|
64
64
|
|
|
65
65
|
The spec is a persistence format — apps store specs and commit generated embed
|
|
66
|
-
documents — so it carries a version
|
|
67
|
-
`@unovis/mcp/spec`)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
66
|
+
documents — so it carries a version: `SPEC_VERSION` (importable from
|
|
67
|
+
`@unovis/mcp/spec`), currently **0.1**, stamped into every spec the recipes
|
|
68
|
+
produce as `major.minor`.
|
|
69
|
+
|
|
70
|
+
The 0 major is deliberate: the contract is still settling, and **while the
|
|
71
|
+
major is 0, breaking changes are allowed and bump the minor** (0.1 → 0.2).
|
|
72
|
+
Additions never require a bump. Declaring 1.0 will be the deliberate act of
|
|
73
|
+
adopting the additive-only promise — from then on, only the major breaks. A
|
|
74
|
+
renderer or widget given a newer spec refuses with an explicit error instead
|
|
75
|
+
of drawing a wrong or blank chart, and the widget reports
|
|
76
|
+
`{ version, specVersion }` in its
|
|
72
77
|
[`unovis:ready` handshake](./interactive.md#protocol) so hosts can assert
|
|
73
78
|
compatibility up front. Specs without `specVersion` are treated as current.
|
|
74
79
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
an "additive" change quietly isn't. Breaking on purpose means bumping
|
|
79
|
-
`SPEC_VERSION` and freezing a new baseline.
|
|
80
|
+
A version bump is always a deliberate act, never an accident — the published
|
|
81
|
+
schema is guarded against silent contract changes. It also resolves at its
|
|
82
|
+
`$id`: <https://unovis.dev/schema/chart-spec.v0.1.json>.
|
|
80
83
|
|
|
81
84
|
## A complete example
|
|
82
85
|
|
package/docs/interactive.md
CHANGED
|
@@ -7,7 +7,7 @@ browser bundle that shares the spec layer with the headless renderer.
|
|
|
7
7
|
```
|
|
8
8
|
ChartSpec ──┬──► headless renderer ──► SVG / PNG (works everywhere)
|
|
9
9
|
├──► widget bundle ──► .html file (any browser)
|
|
10
|
-
└──► widget bundle ──► ui:// resource (MCP
|
|
10
|
+
└──► widget bundle ──► ui:// resource (MCP Apps hosts)
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
## What you get
|
|
@@ -54,13 +54,26 @@ a repo.
|
|
|
54
54
|
{ "outputType": "interactive" }
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
-
The
|
|
58
|
-
`ui://
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
57
|
+
The server implements the **MCP Apps extension**
|
|
58
|
+
(`io.modelcontextprotocol/ui`, [SEP-1865](https://modelcontextprotocol.io/seps/1865-mcp-apps-interactive-user-interfaces-for-mcp)),
|
|
59
|
+
official since the 2026-07-28 protocol revision. Every chart tool declares its
|
|
60
|
+
template ahead of time (`_meta.ui.resourceUri: "ui://unovis/chart"`), so hosts
|
|
61
|
+
can prefetch, cache and security-review the widget before any call — and the
|
|
62
|
+
review is easy: the resource ships with **empty CSP allowlists**, because the
|
|
63
|
+
widget makes no network requests at all. The widget implements
|
|
64
|
+
the full view lifecycle — it initiates `ui/initialize`, signals
|
|
65
|
+
`ui/notifications/initialized`, renders on `ui/notifications/tool-result`,
|
|
66
|
+
adopts the host's theme (including live `host-context-changed` switches),
|
|
67
|
+
reports `size-changed`, answers `ping` — and keeps its plain-iframe protocol
|
|
68
|
+
for non-MCP hosts. Because an Apps host renders the frame for *every* call of
|
|
69
|
+
a declared tool, the server includes the chart spec in `structuredContent` on
|
|
70
|
+
every result when the client advertises the extension capability — so a plain
|
|
71
|
+
`outputType: "svg"` call still shows a live chart in Claude or ChatGPT, while
|
|
72
|
+
non-Apps clients keep lean responses.
|
|
73
|
+
|
|
74
|
+
Pre-extension hosts that understood the earlier `openai/outputTemplate`
|
|
75
|
+
convention keep working — the result still carries it. Host support for the
|
|
76
|
+
extension is still uneven; when in doubt, `html` remains the always-works path.
|
|
64
77
|
|
|
65
78
|
For React Native and other native WebViews, see
|
|
66
79
|
[Embedding in native WebViews](./webview.md).
|
|
@@ -130,10 +143,9 @@ Sankey and graph links report `{ source, target, value }`; treemap and nested
|
|
|
130
143
|
donut segments report `{ key, value }`.
|
|
131
144
|
|
|
132
145
|
Two shapes don't click: **lines and areas** have no per-datum element (the
|
|
133
|
-
crosshair is their readout), and
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
(tracked upstream as [f5/unovis#889](https://github.com/f5/unovis/issues/889)).
|
|
146
|
+
crosshair is their readout), and click handlers become active **within ~500ms
|
|
147
|
+
of the render settling** — relevant only if you automate clicks immediately
|
|
148
|
+
after rendering.
|
|
137
149
|
|
|
138
150
|
Using the widget API directly, pass a callback instead:
|
|
139
151
|
|
package/docs/output-types.md
CHANGED
|
@@ -8,7 +8,7 @@ decide separately how you want it delivered.
|
|
|
8
8
|
| `svg` (default) | Standalone SVG markup as text | Embedding in docs, READMEs, anything; works in every client |
|
|
9
9
|
| `png` | A rendered PNG image (base64) | Chat clients that display images; slides; anywhere SVG isn't accepted |
|
|
10
10
|
| `html` | Path to a self-contained interactive file | Exploration: tooltips, crosshair, hover |
|
|
11
|
-
| `interactive` | The chart spec + a widget reference |
|
|
11
|
+
| `interactive` | The chart spec + a widget reference | Hosts implementing the MCP Apps extension |
|
|
12
12
|
| `config` | The resolved chart spec as JSON | Iterating on a chart before rendering; feeding another tool |
|
|
13
13
|
| `code` | Ready-to-paste Unovis source | Putting the chart into your own app |
|
|
14
14
|
|
|
@@ -91,7 +91,7 @@ widget works.
|
|
|
91
91
|
## `interactive`
|
|
92
92
|
|
|
93
93
|
Returns the chart spec as structured content plus a reference to the
|
|
94
|
-
`ui://unovis/chart` widget resource, letting
|
|
94
|
+
`ui://unovis/chart` widget resource, letting hosts that support the MCP Apps extension
|
|
95
95
|
resources render the chart **inside the conversation**. The text content is a
|
|
96
96
|
short summary, which is what clients without widget support will show.
|
|
97
97
|
|
|
@@ -99,9 +99,9 @@ short summary, which is what clients without widget support will show.
|
|
|
99
99
|
{ "outputType": "interactive" }
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
need a guaranteed result.
|
|
102
|
+
Implements the official MCP Apps extension (`io.modelcontextprotocol/ui`,
|
|
103
|
+
protocol revision 2026-07-28). Host adoption is still spreading — prefer
|
|
104
|
+
`html` when you need a guaranteed result.
|
|
105
105
|
|
|
106
106
|
## `config`
|
|
107
107
|
|
|
@@ -146,7 +146,7 @@ export default function Chart (): JSX.Element {
|
|
|
146
146
|
return (
|
|
147
147
|
<>
|
|
148
148
|
<VisXYContainer height={480}>
|
|
149
|
-
<VisGroupedBar data={data} x={(d, i) => i} y={[d => d.rev]} orientation="vertical" roundedCorners={
|
|
149
|
+
<VisGroupedBar data={data} x={(d, i) => i} y={[d => d.rev]} orientation="vertical" roundedCorners={2} />
|
|
150
150
|
<VisAxis type="x" gridLine={false} tickFormat={(index: number | Date) => categories[Math.round(Number(index))]} tickValues={[0, 1]} />
|
|
151
151
|
<VisAxis type="y" gridLine={true} tickFormat={formatNumber} />
|
|
152
152
|
</VisXYContainer>
|
|
@@ -166,6 +166,5 @@ Notes on the generated code:
|
|
|
166
166
|
string, which wouldn't type-check.
|
|
167
167
|
- Map charts import their topojson (`import { WorldMapTopoJSON } from
|
|
168
168
|
'@unovis/ts/maps'`) instead of inlining megabytes of geometry.
|
|
169
|
-
- The
|
|
170
|
-
|
|
171
|
-
known to be real.
|
|
169
|
+
- The emitted imports, generics and prop names are verified against
|
|
170
|
+
`@unovis/ts`, so the vanilla-TypeScript output compiles as-is.
|
package/docs/tools.md
CHANGED
|
@@ -68,7 +68,7 @@ Generate a bar chart: single-series, grouped, or stacked; vertical or horizontal
|
|
|
68
68
|
| `type` | `grouped` \| `stacked` | `"grouped"` | How multiple series are arranged: side-by-side groups or stacks |
|
|
69
69
|
| `orientation` | `vertical` \| `horizontal` | `"vertical"` | Bar direction. Horizontal puts categories on the Y axis |
|
|
70
70
|
| `seriesLabels` | string[] | — | Display names for the series (legend). Defaults to field names |
|
|
71
|
-
| `roundedCorners` | boolean | `
|
|
71
|
+
| `roundedCorners` | boolean \| number | `2` | Outer bar corner radius in pixels (default 2, matching the library), or true for fully rounded pill tops |
|
|
72
72
|
| `barPadding` | number | — | Padding between bars within a group, 0..0.9 |
|
|
73
73
|
| `referenceLines` | { axis, value, label, color, lineWidth, style }[] | — | Reference lines for thresholds/targets, e.g. an SLA or goal |
|
|
74
74
|
| `referenceBands` | { axis, from, to, label, color }[] | — | Shaded ranges drawn behind the data, e.g. an acceptable range |
|