Yes/No Logic · Interactive Test Mode · Auto-Layout
Decision Tree Tool Build a Yes/No question tree to map out decision logic, troubleshooting steps or eligibility rules — then test it interactively by clicking through your own questions. Pro Mode adds custom branch labels, probabilities, icons, themes and SVG/PDF export.
● Pro Version is Free for now
Simple
(All Base Features)
Pro
(Unlock All Features)
Pro Mode active — custom branch labels, probabilities, icons, themes & SVG/PDF export unlocked
Select a node, then add Yes/No branches or mark it as an outcome Colour Themes
Default
Ocean
Sunset
Royal Quick-Start Templates
🎓
Should I Take This Class?
Academic decision guide
🐛
Bug Troubleshooting
Technical diagnostic tree
✅
Eligibility Checker
Qualification logic tree
❓ Questions: 0
🏁 Outcomes: 0
📏 Max Depth: 0
Your decision tree is empty
−
100%
+
Export your decision tree
Outline (TXT)
PNG
SVG
PDF
`;
const blob = new Blob([html],{type:'text/html'});
const a=document.createElement('a'); a.download='smallstudytools-decision-tree-print.html'; a.href=URL.createObjectURL(blob); a.click();
toast('Print-ready file downloaded — open it to save as PDF');
}function downloadOutlineTXT() {
if (!nodes.length) { toast('Build a tree first'); return; }
function buildOutline(parentId, indent) {
const children = nodes.filter(n=>n.parentId===parentId);
let lines = [];
children.forEach(c => {
const branchTxt = c.branchLabel ? `[${c.branchLabel}] ` : '';
const typeTxt = c.type === 'outcome' ? ' (OUTCOME)' : '';
lines.push(' '.repeat(indent) + '- ' + branchTxt + c.label + typeTxt);
lines = lines.concat(buildOutline(c.id, indent+1));
});
return lines;
}
const root = nodes.find(n=>n.id===0);
const lines = ['=== DECISION TREE — SmallStudyTools.com ===','', root.label, ...buildOutline(0,1), '', 'Generated by SmallStudyTools.com'];
const blob = new Blob([lines.join('\n')],{type:'text/plain'});
const a=document.createElement('a'); a.download='smallstudytools-decision-tree-outline.txt'; a.href=URL.createObjectURL(blob); a.click();
toast('Downloaded outline as TXT!');
}// ── MODE ──────────────────────────────────────────────────────
function setMode(mode) {
isPro = mode==='pro';
document.getElementById('btnSimple').classList.toggle('active',!isPro);
document.getElementById('btnPro').classList.toggle('active',isPro);
document.body.classList.toggle('pro-mode',isPro);
document.getElementById('proModeBar').style.display=isPro?'flex':'none';
document.getElementById('modeHint').textContent=isPro
?'Custom branch labels, probabilities, icons, themes and auto-layout'
:'Select a node, then add Yes/No branches or mark it as an outcome';
if (!isPro) document.getElementById('branchPanel').classList.remove('show');
else showBranchPanelIfNeeded();
render();
try{localStorage.setItem(SK+'_mode',mode);}catch(e){}
}function toast(msg){const t=document.getElementById('toast');t.textContent=msg;t.classList.add('show');setTimeout(()=>t.classList.remove('show'),2400);}
function save(){try{localStorage.setItem(SK,JSON.stringify({nodes,nextId}));}catch(e){}}// ── INIT ──────────────────────────────────────────────────────
function scrollToRoot() {
const root = nodes.find(n=>n.id===0);
if (!root) return;
const canvas = document.getElementById('canvasArea');
canvas.scrollLeft = Math.max(0, (root.x + root.w/2) - canvas.clientWidth/2);
canvas.scrollTop = 0;
}try{
const saved=JSON.parse(localStorage.getItem(SK)||'{}');
if(saved.nodes && saved.nodes.length){ nodes=saved.nodes; nextId=saved.nextId||1; }
else initRoot();
const savedMode=localStorage.getItem(SK+'_mode');
if(savedMode==='pro') setMode('pro'); else render();
scrollToRoot();
}catch(e){ initRoot(); render(); scrollToRoot(); }