RelationshipLayout.h header

#include <ew/app/RelationshipLayout.h>

Namespace ew::app

ForceLayoutParams struct

struct ew::app::ForceLayoutParams

Tunables for forceDirectedLayout: the number of relaxation passes and the layout area. The defaults suit a graph of up to a few hundred nodes.

Members

int ew::app::ForceLayoutParams::iterations = 300

Relaxation passes. Fixed (not until-convergence) so the result is deterministic.

double ew::app::ForceLayoutParams::width = 1200.0

Width of the layout area (scene units); node positions stay within [0, width].

double ew::app::ForceLayoutParams::height = 900.0

Height of the layout area (scene units); node positions stay within [0, height].

RadialLayoutParams struct

struct ew::app::RadialLayoutParams

Tunables for radialLayout: the centre the focus sits on and the gap between depth rings.

Members

double ew::app::RadialLayoutParams::centreX = 600.0

Scene x of the centre (where the focus node is placed).

double ew::app::RadialLayoutParams::centreY = 450.0

Scene y of the centre.

double ew::app::RadialLayoutParams::ringSpacing = 160.0

Distance between successive depth rings; a node at depth d sits d*ringSpacing from the centre.

Functions

std::map< ew::core::ContentId, QPointF > ew::app::forceDirectedLayout(const RelationshipGraph &graph, const ForceLayoutParams &params={})

Computes a force-directed (Fruchterman-Reingold) layout for graph: nodes repel one another while edges pull their endpoints together, relaxed over params.iterations passes with a cooling step size, so an arbitrary graph spreads out legibly instead of piling onto a single circle – the new default general layout. Deterministic: nodes start on an index-seeded spiral and no randomness is used, so the same graph (in the same node order) lays out identically every run, which keeps it unit-testable and stable between openings. Disconnected components drift apart under mutual repulsion. Returns a position (within the params area) for every node, keyed by id; an empty map for an empty graph.

std::map< ew::core::ContentId, QPointF > ew::app::hierarchicalLayout(const RelationshipGraph &graph)

Computes a top-down hierarchical (layered) layout for graph: each node is placed on a row given by the longest directed path of relationships leading into it, so roots sit at the top and their descendants cascade below – the shape a family tree or faction hierarchy needs. Nodes on the same row are spread evenly and centred. Nodes only reachable through a cycle fall to the top row. Returns a position (in scene coordinates) for every node, keyed by entity id.

std::map< ew::core::ContentId, QPointF > ew::app::radialLayout(const RelationshipGraph &graph, ew::core::ContentId focusId, const std::map< ew::core::ContentId, int > &depths, const RadialLayoutParams &params={})

Computes a radial (concentric-by-depth) layout for focus mode: the focus node sits at the centre, and every other node is placed on the ring for its hop distance from the focus – depth-1 on the first ring, depth-2 on the next, and so on – with the nodes on each ring spread evenly around it. This is the ego-graph shape for "who is connected to this entity, and how far". depths is the nodeDepths map for focusId (so the caller chooses the direction); only nodes of graph that appear in depths are placed. Deterministic: ring order follows the node order in graph.