A data flow diagram (DFD) shows where data comes from, which processes transform it, where it is stored and where it leaves the system. This sample models a small online shop: a customer places an order, the system validates it, takes payment, ships it and emails a confirmation.
DFDs are not UML. UML covers software structure and behaviour; DFDs are one of the other standard notations used alongside it. This page uses Gane-Sarson symbols and shows both a level 1 diagram and the level 0 context diagram it refines.
Read it by following the data, not the clock. A DFD has no sequence; it only says which data can reach which process.
Notice that processes never talk to stores of another system directly, and stores never talk to each other: every flow passes through a process. That rule is the first thing a reviewer checks.
Gane-Sarson uses rounded rectangles for processes (with the number in a top band), open-ended rectangles for stores and shaded squares for external entities. The older Yourdon-DeMarco style draws processes as circles and stores as two parallel lines; the meaning is identical. Label flows with nouns ("pick list"), and processes with verb-object phrases ("Fulfil Order").
The context diagram is the same system zoomed out: one process numbered 0 and every flow that crosses the boundary. It is the best first conversation with stakeholders, because it fixes the scope. A key check when you decompose it: the level 1 diagram must have exactly the same external flows (order details, confirmation, charge request and so on). This is called balancing. If level 1 shows a new flow to an outside party, either the context diagram or the decomposition is wrong.
Graphviz has no native DFD shapes, but rounded boxes and record nodes give a close match:
// Graphviz DOT - level 1 DFD (render: dot -Tsvg dfd.dot)
digraph dfd1 {
rankdir=LR; node [fontname="Helvetica"];
Customer [shape=box, style=filled, fillcolor="#ffe9a8"];
Gateway [label="Payment Gateway", shape=box, style=filled, fillcolor="#ffe9a8"];
Warehouse[shape=box, style=filled, fillcolor="#ffe9a8"];
P1 [label="1.0\nValidate Order", shape=box, style=rounded];
P2 [label="2.0\nTake Payment", shape=box, style=rounded];
P3 [label="3.0\nFulfil Order", shape=box, style=rounded];
P4 [label="4.0\nNotify Customer",shape=box, style=rounded];
D1 [label="D1 | Customers", shape=record];
D2 [label="D2 | Orders", shape=record];
D3 [label="D3 | Inventory", shape=record];
Customer -> P1 [label="order details"];
D1 -> P1 [label="customer record"];
P1 -> P2 [label="valid order"]; P1 -> D2 [label="new order"];
P2 -> Gateway [label="charge request"]; Gateway -> P2 [label="auth result"];
P2 -> D2 [label="paid status"]; D2 -> P3 [label="order to ship"];
P3 -> Warehouse [label="pick list"]; Warehouse -> P3 [label="tracking no."];
P3 -> D3 [label="stock decrement"]; P3 -> P4 [label="shipped event"];
P4 -> Customer [label="confirmation"];
}