Use the Qwik binding and continue to the working diagram, hook, dashboard, and server-rendering surfaces.
The first idea is that one headless model drives every framework binding: Qwik converts your node and edge specs into the same diagram model used by the other Grafloria bindings.
Prerequisites
Use Qwik 1.x with Node.js and a strict TypeScript project. Install the Qwik binding and its peer packages:
bashnpm install @grafloria/qwik @grafloria/engine @grafloria/renderer @builder.io/qwik @grafloria/element
The binding targets @builder.io/qwik 1.5 or later. The package versions used by this guide are @grafloria/qwik 0.10.6, @grafloria/engine 0.3.18, and @grafloria/renderer 0.4.19.
1. Mount the Qwik surfaces
For the shared provider-and-hook pattern, see the Vue quick start; this Qwik version uses QRL event props and Qwik signals, so useOnSelectionChange$ takes a module-level QRL and the values from useGrafloria, useSelection, and useViewport are read through .value.
tsximport { component$, $, noSerialize, useSignal, type NoSerialize } from '@builder.io/qwik';
import type { CommentStore } from '@grafloria/engine';
import {
GrafloriaCommentPanel,
GrafloriaDashboard,
GrafloriaDiagram,
GrafloriaFlow,
GrafloriaProvider,
useGrafloria,
useOnSelectionChange$,
useSelection,
useViewport,
type DiagramInstance,
type NodeSpec,
type SelectionChange,
} from '@grafloria/qwik';
const nodes: NodeSpec[] = [
{ id: 'review', position: { x: 60, y: 60 }, size: { width: 180, height: 80 }, label: 'Review' },
{ id: 'approve', position: { x: 320, y: 60 }, size: { width: 180, height: 80 }, label: 'Approve' },
];
const logSelection = $((change: SelectionChange) => {
console.log(`Selected ${change.nodes.length} node(s)`);
});
const Toolbar = component$(() => {
const instance = useGrafloria();
const selection = useSelection();
const viewport = useViewport();
useOnSelectionChange$(logSelection);
return (
<p>
Zoom {viewport.value.zoom.toFixed(2)}; selected {selection.value.nodes.length} node(s)
<button type="button" onClick$={() => instance.value?.fitView(40)}>Fit view</button>
</p>
);
});
const FlowWithComments = component$(() => {
const store = useSignal<NoSerialize<CommentStore>>();
return (
<>
<GrafloriaFlow
defaultNodes={nodes}
defaultEdges={[{ source: 'review', target: 'approve' }]}
comments
fitView
onInit$={$((instance: DiagramInstance) => {
const commentStore = instance.getCommentStore();
if (commentStore) store.value = noSerialize(commentStore);
})}
style={{ height: '320px' }}
/>
{store.value && <GrafloriaCommentPanel store={store.value} />}
</>
);
});
export default component$(() => (
<GrafloriaProvider>
<Toolbar />
<FlowWithComments />
<GrafloriaDiagram
spec="graph\n A[Review] --> B[Approve]"
style={{ height: '240px' }}
/>
<GrafloriaDashboard
views={[{
id: 'main',
widgets: [{
id: 'revenue',
kind: 'kpi',
span: 2,
rows: 1,
x: 0,
y: 0,
data: { label: 'Revenue', value: '$6.81M', delta: 12.4 },
}],
}]}
layout="grid"
sizing="grow"
style={{ height: '240px' }}
/>
</GrafloriaProvider>
));
The mounted page gives you a flow, a comment panel after the flow creates its store, a generic text diagram, and a KPI dashboard. The flow's onInit$ callback receives the live DiagramInstance. The toolbar displays the current camera and selection and fits the flow when you click its button. Keep the canvas hosts at a real height; a host without resolved height has no pixels to draw into.
2. Follow the working surfaces
Start with the flow and toolbar to verify the instance and reactive state. Then use the generic diagram for text or kit specifications, the comment panel for a live comment store, and the dashboard for widget views. Keep live stores and instances out of serializable Qwik state; the sample wraps the comment store with noSerialize() before passing it to the panel.
For a live, clickable version, open the Grafloria Qwik demos. The toolbar-and-hooks demo exercises the provider and hooks; ssr-resumable shows the server-rendered diagram before client code runs.
Next steps
- How Grafloria works explains the model, engine, document, ports, and shared history.
- Apply auto-layout covers layout choices and results.
- Build a dashboard covers dashboard views and widgets.
- Render on the server covers SSR markup and resume details.
Was this page helpful?