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(
43        mut self,
44        key: impl Into<SharedString>,
45        value: impl Into<SharedString>,
46    ) -> Self {
47        self.properties.push((key.into(), value.into()));
48        self
49    }
50
51    pub fn group(mut self, group: impl Into<SharedString>) -> Self {
52        self.group = Some(group.into());
53        self
54    }
55
56    pub fn color(mut self, color: impl Into<Hsla>) -> Self {
57        self.color = Some(color.into());
58        self
59    }
60
61    pub fn size(mut self, radius: f32) -> Self {
62        self.size = Some(radius);
63        self
64    }
65}
66
67/// A directed relationship between two nodes. Parallel edges and self-loops are allowed.
68#[derive(Clone, Debug)]
69#[non_exhaustive]
70pub struct Edge {
71    pub source: SharedString,
72    pub target: SharedString,
73    /// Relationship type (e.g. `ACTED_IN`), drawn at the midpoint.
74    pub label: SharedString,
75    pub properties: Vec<(SharedString, SharedString)>,
76}
77
78impl Edge {
79    pub fn new(
80        source: impl Into<SharedString>,
81        target: impl Into<SharedString>,
82        label: impl Into<SharedString>,
83    ) -> Self {
84        Self {
85            source: source.into(),
86            target: target.into(),
87            label: label.into(),
88            properties: Vec::new(),
89        }
90    }
91
92    pub fn property(
93        mut self,
94        key: impl Into<SharedString>,
95        value: impl Into<SharedString>,
96    ) -> Self {
97        self.properties.push((key.into(), value.into()));
98        self
99    }
100}
101
102/// A batch of nodes and edges, as returned by a query.
103#[derive(Clone, Debug, Default)]
104#[non_exhaustive]
105pub struct GraphData {
106    pub nodes: Vec<Node>,
107    pub edges: Vec<Edge>,
108}
109
110impl GraphData {
111    pub fn new(nodes: Vec<Node>, edges: Vec<Edge>) -> Self {
112        Self { nodes, edges }
113    }
114}