WBS Generator - Work Breakdown Structure | Small Study Tools
📊 WBS · Project Management · PNG · PDF · CSV
Free Work Breakdown Structure (WBS) Generator Build professional WBS diagrams instantly. Add phases, tasks and sub-tasks with auto WBS codes. Download as PNG, PDF or SVG. Pro Mode adds colour themes, status tracking, templates and more.
● Pro Version is Free for now
Simple
Pro — Full WBS
✓ Themes · Status · Assignees · Effort · Templates · SVG · CSV · JSON · Share link unlocked
💻 Software Project
🏗️ Construction
📣 Marketing Campaign
🎪 Event Planning
🔬 Research Project
🎓 Academic Assignment
`;
const blob=new Blob([html],{type:'text/html'});
const a=document.createElement('a'); a.download=`wbs-${(tree.text||'project').replace(/\s+/g,'-').toLowerCase()}.html`; a.href=URL.createObjectURL(blob); a.click();
toast('PDF report downloaded — open and Print → Save as PDF');
}function dlSVG(){
doRender();
const canvas=document.getElementById('wbsCanvas');
const svgStr=`
`;
const blob=new Blob([svgStr],{type:'image/svg+xml'});
const a=document.createElement('a'); a.download='wbs-diagram.svg'; a.href=URL.createObjectURL(blob); a.click();
toast('SVG downloaded!');
}function dlCSV(){
const all=flatNodes(tree);
const header='WBS Code,Task Name,Level,Status,Assignee,Due Date,Effort (h),Notes\n';
const rows=all.map(n=>`"${n.code}","${n.text.replace(/"/g,'""')}",${n.level},"${n.status}","${n.assignee||''}","${n.due||''}",${n.effort||0},"${(n.note||'').replace(/"/g,'""')}"`).join('\n');
const blob=new Blob([header+rows],{type:'text/csv'});
const a=document.createElement('a'); a.download='wbs-data.csv'; a.href=URL.createObjectURL(blob); a.click();
toast('CSV downloaded!');
}function dlJSON(){
const data=JSON.stringify({project:tree.text,generated:new Date().toISOString(),tree},null,2);
const blob=new Blob([data],{type:'application/json'});
const a=document.createElement('a'); a.download='wbs-data.json'; a.href=URL.createObjectURL(blob); a.click();
toast('JSON downloaded!');
}function shareLink(){
try{
const data=btoa(unescape(encodeURIComponent(JSON.stringify({t:tree.text,c:tree.children}))));
const url=window.location.href.split('?')[0]+'?wbs='+data.slice(0,2000);
navigator.clipboard.writeText(url).then(()=>toast('Share link copied to clipboard!')).catch(()=>toast('Link too long — try export JSON instead'));
}catch(e){toast('Share failed — try export JSON instead');}
}function importJSON(e){
const file=e.target.files[0]; if(!file) return;
const reader=new FileReader();
reader.onload=ev=>{
try{
const data=JSON.parse(ev.target.result);
if(data.tree){ tree=data.tree; document.getElementById('projName').value=data.project||tree.text||'Project'; reCodes(); renderEditor(); schedRender(); toast('JSON imported!'); }
else toast('Invalid JSON format');
}catch(err){toast('Failed to parse JSON: '+err.message);}
};
reader.readAsText(file);
}// ─── APP MODE ─────────────────────────────────────────────────
function setAppMode(m){
isPro=m==='pro';
document.getElementById('btnSimple').classList.toggle('active',!isPro);
document.getElementById('btnPro').classList.toggle('active',isPro);
document.body.classList.toggle('pro-mode',isPro);
const pb=document.getElementById('proBar'); if(pb) pb.style.display=isPro?'flex':'none';
if(isPro){ buildThemeChips(); buildLevelColorRows(); }
renderEditor(); schedRender();
try{localStorage.setItem('sst_wbs_mode',m);}catch(e){}
}// ─── UTILS ────────────────────────────────────────────────────
function esc(s){return String(s||'').replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"');}
function toast(msg){const t=document.getElementById('toast');t.textContent=msg;t.classList.add('show');setTimeout(()=>t.classList.remove('show'),2600);}// ─── INIT ─────────────────────────────────────────────────────
// Check URL for shared WBS
try{
const params=new URLSearchParams(window.location.search);
const wbsParam=params.get('wbs');
if(wbsParam){ const data=JSON.parse(decodeURIComponent(escape(atob(wbsParam)))); tree.text=data.t||'Project'; tree.children=data.c||[]; reCodes(); document.getElementById('projName').value=tree.text; toast('Shared WBS loaded!'); }
}catch(e){}renderEditor();
schedRender();
try{const m=localStorage.getItem('sst_wbs_mode');if(m==='pro')setAppMode('pro');}catch(e){}