Skip to main content

gpui_graph/
model.rs

1use gpui::{Hsla, SharedString};
2
3/// A vertex in the graph. Build with [`Node::new`] and the builder methods.
4#[derive(Clone, Debug)]
5#[non_exhaustive]
6pub struct Node {
7    /// Unique id; edges refer to nodes by this.
8    pub id: SharedString,
9    /// Text drawn under the node.
10    pub label: SharedString,
11    /// Vertex type (e.g. `Person`). Nodes of one category share a palette color.
12    pub category: SharedString,
13    /// Arbitrary key/value pairs, carried along for the host app (details panels, tooltips).
14    pub properties: Vec<(SharedString, SharedString)>,
15    /// Community / cluster id, typically computed by the database (Louvain,
16    /// label propagation, ...). Members are drawn together, outlined by a hull,
17    /// and can be collapsed into one node.
18    pub group: Option<SharedString>,
19    /// Overrides the category / group color.
20    pub color: Option<Hsla>,
21    /// Overrides [`NodeSizing`](crate::NodeSizing) with a fixed radius, in world units.
22    pub size: Option<f32>,
23}
24
25impl Node {
26    pub fn new(
27        id: impl Into<SharedString>,
28        label: impl Into<SharedString>,
29        category: impl Into<SharedString>,
30    ) -> Self {
31        Self {
32            id: id.into(),
33            label: label.into(),
34            category: category.into(),
35            properties: Vec::new(),
36            group: None,
37            color: None,
38            size: None,
39        }
40    }
41
42    pub fn property(mut self, key: impl Into<SharedString>, value: impl Into<SharedString>) -> Self {
43        self.properties.push((key.into(), value.into()));
44        self
45    }
46
47    pub fn group(mut self, group: impl Into<SharedString>) -> Self {
48        self.group = Some(group.into());
49        self
50    }
51
52    pub fn color(mut self, color: impl Into<Hsla>) -> Self {
53        self.color = Some(color.into());
54        self
55    }
56
57    pub fn size(mut self, radius: f32) -> Self {
58        self.size = Some(radius);
59        self
60    }
61}
62
63/// A directed relationship between two nodes. Parallel edges and self-loops are allowed.
64#[derive(Clone, Debug)]
65#[non_exhaustive]
66pub struct Edge {
67    pub source: SharedString,
68    pub target: SharedString,
69    /// Relationship type (e.g. `ACTED_IN`), drawn at the midpoint.
70    pub label: SharedString,
71    pub properties: Vec<(SharedString, SharedString)>,
72}
73
74impl Edge {
75    pub fn new(
76        source: impl Into<SharedString>,
77        target: impl Into<SharedString>,
78        label: impl Into<SharedString>,
79    ) -> Self {
80        Self {
81            source: source.into(),
82            target: target.into(),
83            label: label.into(),
84            properties: Vec::new(),
85        }
86    }
87
88    pub fn property(mut self, key: impl Into<SharedString>, value: impl Into<SharedString>) -> Self {
89        self.properties.push((key.into(), value.into()));
90        self
91    }
92}
93
94/// A batch of nodes and edges, as returned by a query.
95#[derive(Clone, Debug, Default)]
96#[non_exhaustive]
97pub struct GraphData {
98    pub nodes: Vec<Node>,
99    pub edges: Vec<Edge>,
100}
101
102impl GraphData {
103    pub fn new(nodes: Vec<Node>, edges: Vec<Edge>) -> Self {
104        Self { nodes, edges }
105    }
106}