Diagram - Workspace Planner
Reconfigure a fictional creative studio with reusable symbols, transforms, layers and live capacity feedback.
#Make room for the next project
Workspace Planner is a fictional creative studio with 21 furniture and equipment items. Editing desks, a recording booth, meeting tables and a lounge share one authored floor plan. Add a desk, move it into place and watch the sample seat total change. Walls stay fixed; furniture stays free to move between zones.
- Choose Add desk. The new desk is selected and capacity increases by one.
- Drag its body in Select mode. Drag a corner rotation handle to turn it; hold Shift for 15° snapping. The floating rotation button turns it by 15° too.
- Choose Meeting 6 in Select object. Drag a resize corner, or open Object inspector and apply a width and depth. Tables resize; desks and equipment keep their authored size.
- Select two or more objects with Shift-click. In the inspector, Select desk row chooses the surviving first three desks; Align tops aligns the selected objects in one operation.
- Delete selected furniture, then use Undo and Redo. Capacity follows insertion, deletion and history. Restart studio restores the original plan, history and display choices.
The named object selector, insertion buttons, exact position/angle/size fields and 10 cm move buttons provide keyboard alternatives to dragging. Native fields retain their own keyboard behavior. The Diagram rotation and resize handles are keyboard focusable: Enter or Space turns by 15° or grows an allowed selection by 10%. Escape cancels an unfinished gesture. Accepted pointer releases add one Undo operation; previews do not save intermediate positions.
#Fixed architecture, useful editing
The studio is authored at one world unit = one centimeter. Its outer drawing is 1040 × 700 units, displayed as 10.4 × 7 m. Inspector X/Y values are the node's saved, unrotated top-left coordinates; width and depth describe its local body, including the furniture symbol's chair detail. Rotation uses the selection's world center. The coordinate scale is fixture data, not a conversion from CSS pixels or a measured building.
Architecture belongs to a locked layer. Furniture and equipment belong to a separate layer, with record constraints that permit movement and rotation. Meeting tables alone permit resizing, within 90–260 cm width and 75–220 cm depth. Zones are drawn on the fixed background rather than runtime containers, so they do not impose hidden ownership or movement boundaries. An object's center determines the zone named in the lower strip; outside the authored zones it says Open work area.
Lock equipment makes the console, camera and two racks selectable but locked. The inspector, floating actions and pointer handles use the same current public editing policy. Read-only permits selection and navigation while preventing editor writes, insertion, history replay and layer changes. Restart remains the explicit host action for restoring this local sample.
Hide furniture changes the actual furniture layer through the structural editor. Hidden objects leave selection and cannot be chosen or inserted into through this UI. Undo restores the saved visibility change. Zones, Snap, the inspector and the policy presets are local display/authoring choices rather than model edits. The inspector overlays the canvas at every width; closing it leaves the drawing area and page position unchanged.
#What Diagram supplies
Diagram supplies the Store/Session, registered symbol rendering, selection, pointer transforms, keyboard handles, snapping, navigation, structural layer edits, arrangement commands and ordinary history. Furniture artwork is defined with original inert path, rectangle and ellipse graphics. Each instance references its reusable symbol ID and retains its own saved bounds, rotation and metadata.
The host owns the studio fixture, insertion palette, policy presets, inspector,
zone names, upright labels and capacity arithmetic. Insertion uses
session.connections.execute with a public composite paste command, so it follows
the editor's constraints and history. Inspector transforms use session.edit;
layer visibility uses session.structure.execute. No raw Store write bypasses
the interactive editor policy.
The label renderer gets the Diagram Session from useDiagramContext() and reads
current world bounds from the session's geometry.snapshot(). Labels render
inside the viewport's projected world. Their text remains upright and
screen-sized during rotation, resizing, pan and zoom.
At very small overview zoom only selected-object labels remain;
named selection reveals furniture at a readable scale on narrow screens. No
private DOM geometry or alternative canvas participates in editing.
#Keep four kinds of state separate
| State | Owner | History |
|---|---|---|
| Furniture identity, bounds, rotation, title/kind/seat metadata and layer visibility | Diagram Store | One ordinary edit history |
| Selection, focus, active tool, transform preview and viewport | Diagram Session | Local session state |
| Inspector, draft fields, zone labels, snapping, read-only and equipment-lock presets | Host UI | Local choices; not model edits |
| Capacity and the selected object's zone | Derived host values | Recomputed from the saved model/public scene |
The initial 22 sample seats are 8 workstation, 10 meeting and 4 lounge seats. A desk or console contributes one, Meeting 6 contributes six, Huddle 4 four, and each sofa two. Other equipment contributes zero. Insertion copies its kind's authored seat count; resizing a table changes geometry without inventing more seats. Hidden and locked objects still count because they remain in the model. The summary is fixture arithmetic, not occupancy, booking or availability data.
Restart replaces the Store and remounts a fresh root, clears history, selects Desk 01, restores layer visibility and returns all local display/policy choices to their defaults. Undo does not recover a previous store after Restart. Destroy disposes the Store and symbol registry. The host's only animation is a short inspector reveal; reduced motion removes it. Nothing starts playing on mount.
#Adapt the example
Copy WorkspacePlannerDemo.vue and every helper in its source tabs, including the workbench, symbols, styles, and export controls. Place the helpers under your @/ alias using the paths shown on the tabs. The workbench and labels read the current model, scene and session through useDiagramContext(). Companion controls use PrimeVue Button, InputText, Select and Checkbox, plus individual PrimeIcons Vue imports. The source includes all symbol graphics. Follow First Diagram for application setup.
The lower entrance opens into the lounge, clear of the Recording partition and
Producer desk. STUDIO_WALLS and STUDIO_DOORS in studio.ts share the opening
endpoints; each door's open leaf and circular swing use the same hinge and radius.
These are authored drawing geometry, not automatic clearance checks.
Replace studioDocument() to author another layout. Keep page/layer IDs and
symbol references consistent; update both the floor drawing and ZONES when
changing architecture. Change the authored scale and its visible units together.
Register another symbol in FURNITURE and set its seat rule in studio.ts to add
a new object kind. The inspector and floating tools can be replaced with HTML
controls calling the same public Session commands in a headless or Tailwind app.
This example provides no collision or clearance engine, booking system, construction verification, building-code or accessibility certification. Objects may overlap or move outside the plan. Symbol registration and original artwork travel with the copied source; there is no model export action or portable output-fidelity claim. The plan is synthetic and in memory for this mounted page.
The inspector overlays the canvas at wide and narrow sizes. Opening and closing it preserves the page position and drawing area; its content scrolls within the panel. Keyboard focus moves without scrolling the surrounding page.