Graph Visualization
Status: Implemented
Purpose: define the public behavior and evidence contract for FluxGraph graph-diagram generation.
1. Scope
FluxGraph provides an optional graph-diagram toolchain that:
- accepts FluxGraph graph definitions (JSON/YAML via existing loaders, or direct
GraphSpecin C++), - emits deterministic DOT as the canonical artifact,
- optionally renders DOT to image formats using external Graphviz CLI tooling.
2. Current Non-Goals
- Live runtime graph tracing or time-series overlays.
- Interactive web UI or editor.
- Round-trip authoring (diagram back to schema).
- Core runtime dependency on Graphviz libraries.
3. Build and Dependency Contract
- Feature flag:
FLUXGRAPH_BUILD_DIAGRAM_TOOL(defaultOFF). - No new vcpkg feature is required for the current CLI-renderer path.
- Rendering uses external
dotprocess when image output is requested. - Core
fluxgraphlibrary dependency contract remains unchanged.
4. Architecture Contract
viz-core: pure C++ emitter (GraphSpec -> DOT), no third-party dependencies.fluxgraph-diagramCLI: input parsing/validation, file I/O, optional renderer invocation.
viz-core depends on FluxGraph public graph spec types (GraphSpec, ModelSpec, EdgeSpec, RuleSpec) and does not depend on runtime engine internals.
5. C++ API Sketch (Direct Integrator Use)
#include <fluxgraph/graph/spec.hpp>
#include <string>
namespace fluxgraph::viz {
struct DotEmitOptions {
bool include_models = true;
bool include_rules = true;
};
std::string emit_dot(const GraphSpec& spec, const DotEmitOptions& options = {});
} // namespace fluxgraph::viz
Guarantees:
emit_dotis deterministic for the sameGraphSpecand options.- Resulting DOT is syntactically valid for Graphviz
dot.
6. DOT Emission Policy
6.1 Identifier and Label Escaping
- Emitter always writes node IDs and edge labels as quoted DOT strings.
- Escape rules:
\->\\"->\"- newline ->
\n
- Signal paths containing
/,., spaces, or other punctuation are preserved via quoting.
6.2 Ordering Rules
- Node emission order: lexicographic by canonical node ID.
- Edge emission order: lexicographic by tuple
(source_id, target_id, transform_type, transform_label). - Attribute key ordering: lexicographic by key name.
No reliance on container insertion order is allowed for canonical DOT output.
6.3 Unknown and Extension Types
- Unknown transform types are rendered (not dropped) using raw
typetext in edge annotation. - Unknown transform types do not fail DOT generation unless required fields are structurally invalid.
- CLI emits a non-fatal warning for unknown transform types.
7. CLI Contract
Supported flags:
--in <path>: required graph input (.json,.yaml,.yml)--out <path>: required output artifact path--format dot|svg|png: output format (defaultdot)--dot-bin <path>: optional Graphvizdotbinary override (defaultdot)--dot-out <path>: optional DOT path to persist canonical DOT when rendering image output
Behavior:
--format dotwrites canonical DOT to--out.--format svg|pngfirst emits DOT, then invokes Graphviz CLI for image output.- Graphviz invocation failures are explicit and include command context.
- For image outputs,
--dot-out(if provided) must differ from--out.
Exit codes:
0: success1: input/load/validation failure2: unsupported option/format3: renderer invocation failure
8. Evidence Mapping
- Deterministic DOT output:
tests/unit/viz_dot_emitter_test.cpptests/unit/viz_dot_golden_test.cpp
- CLI DOT determinism end-to-end:
tests/integration/diagram_cli_e2e.cmake(registered asintegration.diagram_cli_json_dot)
- Core isolation:
- default presets keep
FLUXGRAPH_BUILD_DIAGRAM_TOOL=OFF
- default presets keep
- Renderer coverage in CI:
linux-matrixlanediagram-dotdiagram-render-smokejob in.github/workflows/ci.yml