A connected process
This is the JavaScript used by the first playground preset. Edit and run it in the interactive playground, including its HTML and CSS.
import {DiagramEngine,DrawingControl,createDocument,createShape} from '@wieslawsoltes/drawingweb';
const engine=new DiagramEngine(createDocument('An idea, in motion'));
const pageId=engine.document.pages[0].id;
const labels=['An idea','Make it real','Ship with care'];
labels.forEach((text,i)=>engine.add(pageId,createShape('roundRect',{
id:'step'+i,text,x:50+i*245,y:140,width:180,height:80,
style:{fill:['#282e42','#2c3d39','#413a2c'][i],stroke:['#91acff','#78e4b2','#f4ce8e'][i],color:'#f1f3f7',fontSize:17}
})));
for(let i=0;i<2;i++)engine.add(pageId,createShape('connector',{
source:{shapeId:'step'+i},target:{shapeId:'step'+(i+1)},style:{fill:'none',stroke:'#8c98ab',endArrow:true}
}));
const control=new DrawingControl(document.querySelector('#diagram'),{engine,grid:true,snap:true,background:document.documentElement.dataset.theme==='dark'?'#14171c':'#f6f7f9'});
let n=3;
document.querySelector('#add').onclick=()=>{engine.add(pageId,createShape('roundRect',{text:'Next step '+n,x:90+(n++%3)*215,y:285,width:170,height:70,style:{fill:'#30364c',stroke:'#91acff',color:'#fff'}}));control.fit();};
document.querySelector('#undo').onclick=()=>engine.undo();document.querySelector('#redo').onclick=()=>engine.redo();
document.querySelector('#fit').onclick=()=>control.fit();control.fit();
engine.changed.subscribe(e=>console.log('Revision',e.revision,e.label));
window.addEventListener('pagehide',()=>{control.dispose();engine.dispose();});
console.log('Actual DrawingControl attached. Drag a process step.');Show the HTML host
<div class="toolbar"><button id="add">Add a step</button><button id="undo">Undo</button><button id="redo">Redo</button><button id="fit">Fit diagram</button></div><div id="diagram" class="stage" style="border:1px solid var(--line);border-radius:8px;overflow:hidden"></div><p class="hint">Select, drag and resize shapes. Double-click text to edit. Every action uses the same diagram engine.</p>How it works
One model, every interaction
Canvas edits, property changes and bound data work against the same engine. Move a shape and the data can follow it back.
Create a DiagramEngine and a measurable host, then attach a DrawingControl. Bind records with ObservableTable and DiagramBinding when needed.
Own the lifetime
Dispose bindings, controls, tables and owned engines. A control does not dispose an engine that it borrowed.
The playground replaces its entire isolated frame on each run. In your application, use the framework’s unmount or disposal hook instead. Do not dispose a shared model while another view still owns it.
Read the lifecycle guide →Know the contract
Source repositories can contain work newer than the published package. The showcase uses @wieslawsoltes/drawingweb@0.1.0-alpha.1.