Guide
dwgtree is a bill-of-materials tree builder. You enter items — drawings and purchased parts — link them into assemblies, group assemblies into projects, and see the whole structure drawn as one tree. It is a status dashboard in the shape of an assembly tree: one look shows what each part is, where it is used, and how its review is going.
The app has two working pages: Items, where data is entered, and Tree, where it is drawn. Everything else — Projects, Types, Statuses, Display — feeds those two. A project is a name plus a top assembly; everything reachable from that assembly is in the project, computed rather than tagged, so membership can never go stale.
The three signals
The tree exists to show three things at a glance:
- Status → color. Each node's color is the item's current status, using the colors you chose on the Statuses page, rendered exactly as you picked them.
- Review age → how long it has sat there. The clock starts when an item enters its current status and moves only when the status actually changes — editing a title or any other field never resets it. Something stuck is therefore visible immediately, and the filter panel can dim everything that has not been stuck for more than a chosen number of days.
- Responsible → who owns moving it along. A name on each item, filterable in the tree, and settable in bulk on the Items page.
Items, assemblies, and sharing
An item is one drawing or one purchased part: an identifier, a title, a type, a status, a responsible. An item that contains other items is an assembly; one that does not is a part. That distinction is derived from the links — there is nothing to toggle, and an item becomes an assembly the moment something is placed inside it.
An item is a single shared record. Link the same fastener into five assemblies and there is still one fastener in the catalog: edit its title or move its status once and it updates everywhere it appears.
In the tree, a shared item is drawn in full under every assembly that contains it, marked with a second outline stacked behind the node, and the counts above the tree say how many nodes are repeats by reuse. That is deliberate, not duplication: each appearance is a real place the item is used, and its branch belongs in the context of each parent. Collapsing shared items into one out-of-context branch would hide exactly the thing a BOM exists to show. The repeats are copies of one record — there is still only one item to edit.
Types and statuses
Both are tables you manage yourself, on their own pages — not fixed lists. New accounts start with a small usable set of each.
They are independent visual channels. Status drives color and nothing else. Type drives the node's shape, its line style, and its line weight — what a thing is — and never its color. So a purchased part is recognizable by silhouette whatever state its review is in, and a stuck item is recognizable by color whatever kind of thing it is. Statuses have an order, the pipeline order, and the legend lists them in it. A type can be set to ship hidden, for hardware too routine to draw; the filter panel is where it is switched back on.
Moving around the tree
Scroll to zoom, drag the background to pan, and the Fit button frames the whole tree. The toolbar sits collapsed in the upper-left corner and expands when the pointer rests on it; the filters and the legend live in a drawer on the right edge.
- Left click an assembly to collapse or expand it one level. A collapsed node is drawn filled; an open one is hollow. Clicking a part does nothing.
- Hover over a node and, after a short pause, a tooltip appears with the fields your Display settings put there, along with three small controls on the node's corner: a ⋯ menu of structure actions, a +/− control that expands or collapses everything below the node at once, and — when the item has a PDM link — an ↗ that opens it in a new tab.
- Right click a node to focus on it: that copy becomes the temporary root, and a breadcrumb appears showing where it hangs. Each crumb climbs back out one level; "Show whole tree" clears the focus. Focusing a shared item isolates the copy you clicked, not all of them.
- Find (the toolbar field, or press /) searches identifier and title over what is drawn. Enter jumps to the match and the landing is marked with a brief pulse; picking the same item again steps to its next appearance, so a shared part is reachable everywhere it is used by pressing Enter repeatedly.
- Keyboard: / focuses find, f opens and closes the filter drawer, and Escape puts away whatever panel is open.
Restructuring by drag
The tree is edited directly, and every edit moves links — which item sits inside which. No gesture on the tree page can delete an item. That is enforced in the code, not just promised: the only thing the page ever writes is links.
- Drag a node onto an assembly — a solid ring marks the prospective parent — to move it inside. This moves the one link you dragged: if the item also appears in other assemblies, those are untouched.
- Drag a node between two siblings — an insertion line marks the slot — to place it there. Within its own parent, that is how children are reordered.
- Hold Ctrl (Cmd on a Mac) while you drag to add a link instead of moving one: the item ends up under both assemblies, one record in two places, and the assembly you dragged it out of keeps it. Nothing is duplicated — it is the same item, and both copies show the reuse marker. Dragging an assembly this way brings everything inside it. An assembly that already contains the item refuses the drop, and while Ctrl is held the trashcan refuses it too — the modifier only ever adds.
- A caption follows the drag saying exactly what the drop will do — move or add, and which assembly the item keeps. It updates the moment you press or release Ctrl, so you can change your mind without letting go of the mouse. A drop that would create a loop — an assembly containing itself through any chain — is refused with the loop spelled out.
- The trashcan appears while a drag is live. Dropping a node on it removes the link, never the item — always, even if this was the item's last use. The item stays in the catalog with everything inside it, stays in every other assembly, and if nothing contains it anymore it turns up under "Unused only" on the Items page — a staging state, not an error. For an assembly, the dialog offers two readings: the whole branch leaves together, or dissolve, where its children move up to its parent in place and only this level steps out.
- Ctrl-click (Cmd on a Mac) picks several children of one parent, Shift-click picks a range, and the bar that appears can group them under a new subassembly created on the spot. A modifier click never expands or collapses the node it lands on.
- The ⋯ menu holds the actions that are not a drag: create a new child item in place, add an existing item from the catalog (linked in as the last child, bringing its whole branch with it), dissolve, remove from this parent, and a where-used list of every assembly containing the item, with a jump to each one drawn in the current tree.
Deleting an item outright lives on the Items page and only there, behind a warning that says how many assemblies it appears in.
Filters
The filter drawer (right edge, or press f) filters by responsible, status, and days at status — "dim everything not stuck for more than N days". These dim rather than hide: non-matching nodes fade but keep their place and their status color, so the tree keeps its shape and a match deep in the structure is still seen in context. Hiding a mid-level assembly would orphan everything below it, which is why dimming is the rule.
Type is the deliberate exception: it hides. A type toggled off is removed from the tree entirely and takes up no space — that is how routine hardware is cleared out of the way. The legend notes which types are currently hidden.
Within one filter, choices add together (two names selected means either matches); across filters, they narrow (a name and a status and an age). An item whose age is unknown never matches an age threshold — unknown is not the same as stuck. The drawer's edge tab shows how many filters are active even while the panel is closed, and Clear puts everything back, type toggles included.
Getting data in
By hand, on the Items page. Create an item with the form; open any row's children editor to link items into it, creating new ones as you go. The tree page can do the same in place — the ⋯ menu's "Add a child item" and "Add an existing item".
From the old exports, on the Import page. The importer reads the previous system's one-level JSON export files and merges them into one structure. Your browser parses the files and sends the result as ordinary data — nothing you upload is ever stored or executed as a file. Importing again is safe: items match on identifier and links on their parent-child pair, so a re-import updates rather than duplicates.
Getting data out
On the tree page, the Export tab on the right edge holds Export… with four formats:
- Image — PNG, at 2× resolution so labels survive being shrunk into a slide, and Image — SVG, the same picture as vectors with its styling built in.
- CSV — one row per drawn node, deepest branch first, with a level number and the fields your display settings show. Written so it opens safely in Excel: nothing in a title can run as a formula.
- Paged — the tree sliced into sheets at the page size set on the Display page, delivered as one printable file. Each cut is marked "continued on page N", each sheet names the assembly it hangs from, and every sheet carries a legend of the statuses actually drawn.
Beside it, Sliced SVG… produces the same sheet breakdown as one SVG file per sheet in a zip, for decks that want them one at a time — of the whole tree, or of the current view.
Every export is a picture of the tree as it is drawn: the focus you are in, the branches you collapsed, the types you switched off, and the filter dimming all carry through. Your zoom and pan do not — an export frames the whole drawn tree, not the window. All of it is built in your browser from data the page already loaded; nothing is sent anywhere to make a file.