-
I really like the idea of this framework. I'm building a dashboard and would like to use a mix of libraries ( In particular, I can't figure out how to get the
function donut(data, { width } = {}) {
return vl.render({
spec: {
$schema: "https://vega.github.io/schema/vega-lite/v5.json",
description: "A simple donut chart with embedded data.",
width,
data: {
values: data,
},
mark: { type: "arc", innerRadius: 50 },
encoding: {
theta: { field: "value", type: "quantitative" },
color: { field: "category", type: "nominal" },
},
},
});
}
However, inside the card, it just says While on the topic of |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
The reason it says Since Vega-Lite already supports incremental re-rendering, the best way to solve this problem is to use Vega-Lite’s reactive signals and have it re-render the chart for you as shown in the Vega-Lite responsive bar chart example. (We haven’t released this example yet, but it’ll be merged soon in #1306.) This uses a import {resize} from "npm:@observablehq/stdlib";
import vl from "observablehq:stdlib/vega-lite";
export async function vlresize(
{autosize = {type: "fit", contains: "padding"}, ...spec},
{minWidth = 0, maxWidth = Infinity} = {}
) {
const chart = await vl.render({spec: {...spec, width: -1, autosize}});
return resize((width) => {
chart.value.width(Math.max(minWidth, Math.min(maxWidth, width)));
chart.value.run();
return chart;
});
} If you want to encapsulate your donut chart into a helper function, you could do something like this: import {vlresize} from "./vlresize.js";
export function Donut(data) {
return vlresize({
$schema: "https://vega.github.io/schema/vega-lite/v5.json",
description: "A simple donut chart with embedded data.",
data: {
values: data,
},
mark: { type: "arc", innerRadius: 50 },
encoding: {
theta: { field: "value", type: "quantitative" },
color: { field: "category", type: "nominal" },
},
});
} And then lastly in your Markdown: ```js
import {Donut} from "./donut.js";
```
<div class="grid grid-cols-1">
<div class="card">${Donut(donutData)}</div>
</div>
Vega-Lite’s built-in responsive width (as described in the example I linked above) is limited to listening to resize events on the window, and requires the container to be attached on initial render, so it doesn’t work very well. I filed vega/vega-lite#9349 to ask them to adopt ResizeObserver which would make it work better out of the box, but the |
Beta Was this translation helpful? Give feedback.
The reason it says
[object Promise]
is becausevl.render
is async (it returns a Promise) whereasresize
expects you to return a DOM element, not a promise to a DOM element. We could perhaps extend support toresize
to allow async render functions (please upvote #1335 if you are interested), but that might also be surprising because you could have multiple renderings happening concurrently — generally you want rendering to be synchronous, and Vega-Lite is a bit of an outlier here.Since Vega-Lite already supports incremental re-rendering, the best way to solve this problem is to use Vega-Lite’s reactive signals and have it re-render the chart for you as shown in the Vega-Lite responsive ba…