Skip to content

Data Visualizer

Schema Docs

JSON schema reference for building interactive node graphs, flowcharts, funnels, and tree diagrams.

Overview

What the data visualizer does

The data visualizer renders interactive node graphs from JSON. Paste structured JSON to create flowcharts, org charts, funnels, decision trees, and more. Any JSON that doesn't match the structured schema is rendered in inspector mode with expandable nodes.

Open the visualizer to try it out, or use the schema reference below to build your own JSON.

Schema Validated

Zod validation with inline error messages

4 Layout Types

Tree, funnel, flowchart, and left-to-right tree

Interactive Nodes

Click nodes to see metrics, fields, and details

Schema Structure

Top-level JSON shape

{
  "title": "My Visualization",
  "description": "Optional description",
  "layout": { "type": "flowchart" },
  "nodes": [
    { "id": "a", "label": "Node A", ... },
    { "id": "b", "label": "Node B", ... }
  ],
  "edges": [
    { "from": "a", "to": "b", "label": "connects to" }
  ]
}

Top-Level Properties

NameTypeRequiredDescription
titlestringYesTitle of the visualization. Displayed in metadata.
descriptionstringNoOptional description of the visualization.
layoutobjectNoLayout configuration. Defaults to tree layout when using children, flowchart when using edges. See Layout Options.
nodesTreeNode[]YesArray of node objects. At least one node is required.
edgesEdgeDef[]NoArray of edge connections between nodes. Required for flowchart/funnel layouts. Omit for tree layouts that use children.

Two connection modes (pick one, never both): Use edges for graph structures (flowchart, funnel, lr-tree), or children on each node for simple hierarchies (tree). If edges are present, children are completely ignored and discarded.

Node Properties

All properties available on each node

Node Object

NameTypeRequiredDescription
idstringNoUnique identifier (kebab-case recommended, e.g. "awareness-stage"). REQUIRED when using edges, as edge from/to fields must reference these IDs exactly. Auto-generated for tree layouts using children.
labelstringYesDisplay name shown on the node.
subtitlestringNoSecondary text displayed below the label.
iconstringNoEmoji or 1-3 character string shown as the node icon.
colorstringNoHex color code (#RRGGBB format, e.g. #5B8A8A). Sets the node accent color. Auto-assigned from an 8-color palette cycling through teal, copper, violet, ocean, emerald, and amber based on tree depth or node position.
descriptionstringNoLonger description shown in the detail panel when the node is clicked.
badgestringNoSmall label chip displayed next to the node title (e.g. "BETA", "NEW").
metricsMetric[]NoArray of key-value stats shown as cards in the detail panel.
fieldsField[]NoArray of labeled values shown as a list in the detail panel.
linkstring (URL)NoExternal URL. Renders as a button in the detail panel.
childrenTreeNode[]NoNested child nodes for tree layouts. Not used when edges are defined.
metadataRecord<string, string>NoArbitrary key-value pairs for additional data.

Metric Object

NameTypeDescription
labelstringMetric name (e.g. "Revenue", "Users").
valuestringMetric value (e.g. "$12.4K", "1,200").

Field Object

NameTypeDescription
labelstringField name (e.g. "Owner", "Status").
valuestringField value (e.g. "John Smith", "Active").
iconstringOptional emoji or short string shown beside the label.

Node types are automatic. The visualizer determines whether a node is a root, branch, or leaf based on its position in the graph. Nodes with no incoming edges are roots, nodes with both incoming and outgoing edges are branches, and nodes with no outgoing edges are leaves.

Edge Properties

Connections between nodes

Edge Object

NameTypeRequiredDescription
fromstringYesThe id of the source node.
tostringYesThe id of the target node.
labelstringNoText label displayed on the edge line.
style"solid" | "dashed" | "dotted"NoEdge line style. Defaults to solid.
colorstringNoHex color code for the edge line. Defaults to #5B8A8A.
animatedbooleanNoWhen true, the edge shows a moving dot animation.

Edges support many-to-many connections. A single node can have multiple incoming and outgoing edges. The layout algorithm handles crossing minimization automatically. For tree layouts using children, edges are not needed.

Layout Options

Control how nodes are arranged

Layout Object

NameTypeDescription
type"tree" | "funnel" | "flowchart" | "lr-tree"Layout algorithm to use. Defaults to tree when using children, flowchart when using edges.
spacing.xnumberHorizontal gap between nodes in pixels. Optional override.
spacing.ynumberVertical gap between ranks in pixels. Optional override.

tree

Hierarchical top-down layout

Uses children for structure. Do NOT use edges with this layout. Best for org charts, taxonomies, file trees, and any parent-child hierarchy.

Default when no layout is specified and nodes use children. Node IDs are auto-generated.

funnel

Vertical funnel with progressive narrowing

Uses edges for connections. Requires node IDs. Best for conversion funnels, onboarding flows, and sequential processes. Works best with a linear chain of edges (A → B → C → D).

Disconnected nodes or cycles will stack at the top. Keep edges in a single chain for clean results.

flowchart

Free-form graph with crossing minimization

Uses edges for connections. Requires node IDs. Best for workflows, customer journeys, content strategies, and complex processes with branching. The only layout that correctly handles cycles (e.g. "Review → Revisions → Review").

Default when edges are present and no layout is specified. Supports many-to-many connections and branching paths.

lr-tree

Left-to-right horizontal tree

Uses edges for connections. Requires node IDs. Best for decision trees, mind maps, timelines, and diagrams that read left to right.

Each node is only placed once. If a node has multiple incoming edges, only the first parent is used for positioning.

Which layout should I use? If your data is a hierarchy (parent with children), use tree. If it's a linear pipeline, use funnel. If it has branching, merging, or cycles, use flowchart. If it flows left to right, use lr-tree.

Important Rules

Key constraints to follow for correct rendering

Never mix edges and children

If your JSON has an edges array with at least one entry, all children on every node are completely discarded. Choose one approach: use children for tree layouts, or edges for flowchart/funnel/lr-tree layouts.

Every node needs an id when using edges

Edge from and to fields must exactly match a node's id. If a node is missing its id, it gets auto-generated as node-0, node-1, etc., and your edges won't find it. Always set explicit IDs on all nodes when using edges.

Edge references to missing IDs are silently dropped

If an edge references a node ID that doesn't exist, the edge simply won't render. There is no error message. Double-check that every from and to value matches a node's id exactly (case-sensitive).

Node types are determined automatically

You cannot set a node's visual type manually. In tree mode: depth-0 nodes are roots, nodes with children are branches, nodes without children are leaves. In edge mode: nodes with no incoming edges are roots, nodes with both incoming and outgoing edges are branches, nodes with no outgoing edges are leaves. Each type has a different visual size and style.

Structured mode vs. inspector mode detection

For JSON to render as a structured visualization (not raw inspector mode), it must be an object with a nodes array where the first element has a label property. Missing any of these conditions causes the visualizer to fall back to inspector mode, which shows raw JSON as an expandable tree.

Colors are auto-assigned if omitted

When no color is specified, nodes are assigned colors from an 8-color palette: teal, copper, dark teal, violet, ocean, dark copper, emerald, amber. In tree mode, the color is based on depth level. In edge mode, the color is based on the node's position in the array. The palette repeats after 8 levels/positions.

Labels should be concise

Keep node labels under 40 characters for best display. Longer labels will be truncated with an ellipsis in the node. Use the subtitle and description fields for additional context. The description is shown in a detail panel when the node is clicked.

Inspector Mode

Visualize any JSON structure

Any valid JSON that does not match the structured schema (i.e. does not have a nodes array containing objects with a label property) is automatically rendered in inspector mode.

Inspector mode displays JSON as an interactive tree of expandable nodes. Objects and arrays can be clicked to expand or collapse their contents. Primitive values (strings, numbers, booleans) are displayed as leaf nodes with type-colored indicators.

// Any of these will trigger inspector mode:
{ "name": "Alice", "age": 30, "hobbies": ["reading", "hiking"] }

[1, 2, 3, { "nested": true }]

{ "api_response": { "status": 200, "data": { ... } } }

Common Mistakes

Patterns that cause broken or unexpected rendering

Using edges without setting node IDs

Wrong

{
  "nodes": [
    { "label": "Start" },
    { "label": "End" }
  ],
  "edges": [
    { "from": "Start", "to": "End" }
  ]
}

Correct

{
  "nodes": [
    { "id": "start", "label": "Start" },
    { "id": "end", "label": "End" }
  ],
  "edges": [
    { "from": "start", "to": "end" }
  ]
}

Without explicit IDs, nodes get auto-generated IDs like "node-0". The edges reference "Start" which doesn't match, so no connections render.

Mixing children and edges

Wrong

{
  "nodes": [{
    "id": "root",
    "label": "Parent",
    "children": [
      { "label": "Child A" },
      { "label": "Child B" }
    ]
  }],
  "edges": [
    { "from": "root", "to": "other" }
  ]
}

Correct (pick one)

// Option A: Tree with children
{
  "nodes": [{
    "label": "Parent",
    "children": [
      { "label": "Child A" },
      { "label": "Child B" }
    ]
  }]
}

// Option B: Edges with IDs
{
  "nodes": [
    { "id": "root", "label": "Parent" },
    { "id": "a", "label": "Child A" },
    { "id": "b", "label": "Child B" }
  ],
  "edges": [
    { "from": "root", "to": "a" },
    { "from": "root", "to": "b" }
  ]
}

When edges exist, all children are discarded. Child A and Child B would never render in the "wrong" example.

Using funnel layout with non-linear edges

Funnel layout expects a roughly linear chain (A → B → C). If you have disconnected nodes, branching paths, or cycles, they will all pile up at the top of the funnel. Use flowchart layout instead for complex edge patterns.

Using flowchart or lr-tree with children

The flowchart, funnel, and lr-tree layouts only work with edges. If you set a layout type but use children instead of edges, the layout type is ignored and a default tree layout is used. Always use edges with these layout types.

Missing the first node's label

The visualizer checks whether the first node in the array has a label property to decide between structured mode and inspector mode. If the first node has no label, the entire JSON falls back to inspector mode (raw expandable tree view) even if other nodes have labels.

AI Prompting Guide

Use any AI assistant to generate visualization JSON

The fastest way to create visualizations is to let an AI assistant generate the JSON for you. Copy the prompt below, paste it into ChatGPT, Claude, Gemini, or any other AI tool, and replace the placeholder at the end with a description of what you want to visualize.

Ready-to-use prompt

You are generating structured JSON for the Valiance Media data visualizer. Before generating anything, read the full schema documentation and examples at:

https://www.valiancemedia.com/tools/data-visualizer/docs

That page contains the complete JSON schema reference, all node and edge properties, layout options, working examples, important rules, and common mistakes to avoid.

Critical rules to follow:
- Output ONLY valid JSON. No markdown, no explanation, no code fences.
- Every node MUST have a "label" property (required).
- When using edges: every node MUST have an explicit "id", and every edge "from"/"to" must exactly match a node id.
- Never mix edges and children. If edges exist, all children are completely discarded.
- Use "children" for tree layouts (hierarchies). Use "edges" for flowchart, funnel, and lr-tree layouts.
- Funnel layout expects a linear chain of edges (A to B to C). Use flowchart for branching or cycles.
- Flowchart is the only layout that handles cycles correctly.
- Colors must be hex format (#RRGGBB). Colors are auto-assigned if omitted.
- Keep labels under 40 characters. Use subtitle and description for more detail.

Generate the visualization JSON for:
[DESCRIBE YOUR VISUAL HERE]

How it works

1

Copy the prompt

Use the button above to copy the prompt to your clipboard.

2

Describe your visual

Replace [DESCRIBE YOUR VISUAL HERE] with what you want to see. Be specific about the structure, relationships, and data.

3

Paste the JSON

Copy the AI's JSON output and paste it into the visualizer editor.

Tips for better results

Specify the layout. Tell the AI which layout type you want: "use a funnel layout" or "make it a left-to-right tree." Otherwise it will pick one for you.

Include real data. Instead of "show a sales funnel," say "show our Q4 sales funnel with 2,400 leads, 840 qualified, 320 proposals, and 96 closed deals."

Ask for detail panel content. Mention that you want metrics, fields, descriptions, or links on nodes so the AI populates those properties.

Iterate. If the first result isn't quite right, ask the AI to adjust specific nodes, change colors, add edges, or switch layouts. The JSON is easy to refine.

Why does the prompt link here? By pointing the AI to this documentation page instead of embedding the full schema in the prompt, the AI always reads the latest version of the schema. This means any updates to the visualizer are automatically reflected in the AI's output.

Examples

Complete JSON examples for each layout type

Tree Layout (Org Chart)

Uses children for hierarchy. No edges needed.

{
  "title": "Engineering Team",
  "nodes": [
    {
      "label": "Engineering",
      "subtitle": "VP: Sarah Chen",
      "icon": "⚙️",
      "color": "#0369A1",
      "metrics": [{ "label": "Team Size", "value": "18" }],
      "children": [
        {
          "label": "Frontend",
          "subtitle": "8 engineers",
          "icon": "🎨",
          "fields": [{ "label": "Lead", "value": "Alex Kim", "icon": "👤" }],
          "children": [
            { "label": "React Team", "subtitle": "4 engineers", "icon": "RT" },
            { "label": "Mobile", "subtitle": "2 engineers", "icon": "📱" }
          ]
        },
        {
          "label": "Backend",
          "subtitle": "6 engineers",
          "icon": "🔧",
          "children": [
            { "label": "API Team", "subtitle": "3 engineers" },
            { "label": "Infrastructure", "subtitle": "3 engineers", "icon": "☁️" }
          ]
        }
      ]
    }
  ]
}
Try it in the visualizer

Funnel Layout (Sales Pipeline)

Linear flow with edges. Nodes narrow progressively.

{
  "title": "Sales Pipeline",
  "layout": { "type": "funnel" },
  "nodes": [
    {
      "id": "leads",
      "label": "Leads",
      "icon": "🎯",
      "color": "#5B8A8A",
      "metrics": [{ "label": "Count", "value": "2,400" }]
    },
    {
      "id": "qualified",
      "label": "Qualified",
      "icon": "✅",
      "color": "#7C3AED",
      "metrics": [{ "label": "Count", "value": "840" }]
    },
    {
      "id": "proposal",
      "label": "Proposal",
      "icon": "📄",
      "color": "#C5A68F",
      "metrics": [{ "label": "Count", "value": "320" }]
    },
    {
      "id": "closed",
      "label": "Closed Won",
      "icon": "🎉",
      "color": "#059669",
      "badge": "GOAL",
      "metrics": [{ "label": "Count", "value": "96" }, { "label": "Revenue", "value": "$480K" }]
    }
  ],
  "edges": [
    { "from": "leads", "to": "qualified", "label": "35% qualify", "animated": true },
    { "from": "qualified", "to": "proposal", "label": "38% propose", "animated": true },
    { "from": "proposal", "to": "closed", "label": "30% close", "animated": true }
  ]
}
Try it in the visualizer

Flowchart Layout (Process)

Many-to-many connections with mixed edge styles.

{
  "title": "Content Pipeline",
  "layout": { "type": "flowchart" },
  "nodes": [
    { "id": "research", "label": "Research", "icon": "🔍", "color": "#5B8A8A" },
    { "id": "write", "label": "Write", "icon": "📝", "color": "#0369A1" },
    { "id": "review", "label": "Review", "icon": "👀", "color": "#7C3AED" },
    { "id": "publish", "label": "Publish", "icon": "🚀", "color": "#059669", "badge": "DONE" },
    { "id": "promote", "label": "Promote", "icon": "📣", "color": "#D97706" }
  ],
  "edges": [
    { "from": "research", "to": "write", "animated": true },
    { "from": "write", "to": "review" },
    { "from": "review", "to": "write", "label": "Revisions", "style": "dashed" },
    { "from": "review", "to": "publish", "label": "Approved" },
    { "from": "publish", "to": "promote" }
  ]
}
Try it in the visualizer

LR-Tree Layout (Decision Tree)

Flows left to right. Good for decision logic.

{
  "title": "Support Routing",
  "layout": { "type": "lr-tree" },
  "nodes": [
    { "id": "start", "label": "New Ticket", "icon": "🎫", "color": "#5B8A8A" },
    { "id": "billing", "label": "Billing Issue?", "icon": "💰", "color": "#D97706" },
    { "id": "technical", "label": "Technical?", "icon": "🔧", "color": "#7C3AED" },
    { "id": "finance", "label": "Finance Team", "icon": "🏦", "color": "#059669" },
    { "id": "eng", "label": "Engineering", "icon": "⚙️", "color": "#0369A1" },
    { "id": "support", "label": "General Support", "icon": "💬", "color": "#C5A68F" }
  ],
  "edges": [
    { "from": "start", "to": "billing", "label": "Yes" },
    { "from": "start", "to": "technical", "label": "No" },
    { "from": "billing", "to": "finance" },
    { "from": "technical", "to": "eng", "label": "Yes" },
    { "from": "technical", "to": "support", "label": "No" }
  ]
}
Try it in the visualizer