Enum fdg_sim::force::Value

source ·
pub enum Value {
    Number(f32RangeInclusive<f32>),
    Bool(bool),
}
Expand description

A value that you can change in a Force’s dictionary.

Variants§

§

Number(f32RangeInclusive<f32>)

§

Bool(bool)

Implementations§

Retrieves the bool from a value.

Examples found in repository?
src/force/mod.rs (line 166)
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
    fn update<N, E, Ty: EdgeType>(
        dict: &LinkedHashMap<String, Value>,
        graph: &mut ForceGraph<N, E, Ty>,
        _dt: f32,
    ) {
        let distance = dict.get("Distance").unwrap().number().unwrap();

        for node in graph.node_weights_mut() {
            if dict.get("Up").unwrap().bool().unwrap() {
                node.location.y -= distance;
            }

            if dict.get("Down").unwrap().bool().unwrap() {
                node.location.y += distance;
            }

            if dict.get("Left").unwrap().bool().unwrap() {
                node.location.x -= distance;
            }

            if dict.get("Right").unwrap().bool().unwrap() {
                node.location.x += distance;
            }
        }
    }
More examples
Hide additional examples
src/force/handy.rs (line 28)
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
    fn update<N, E, Ty: EdgeType>(
        dict: &LinkedHashMap<String, Value>,
        graph: &mut ForceGraph<N, E, Ty>,
        dt: f32,
    ) {
        // establish current variables from the force's dictionary
        let repulsion = dict.get("Repulsive Force").unwrap().bool().unwrap();
        let attraction = dict.get("Attractive Force").unwrap().bool().unwrap();
        let scale = dict.get("Scale").unwrap().number().unwrap();
        let cooloff_factor = dict.get("Cooloff Factor").unwrap().number().unwrap();
        let gravity_factor = dict.get("Gravity Factor").unwrap().number().unwrap();
        let centering = dict.get("Centering").unwrap().bool().unwrap();
        let gravity = dict.get("Gravity").unwrap().bool().unwrap();

        // sum of all locations (for centering)
        let mut loc_sum = Vec3::ZERO;

        // reset all old locations
        graph
            .node_weights_mut()
            .for_each(|n| n.old_location = n.location);

        // loop through all nodes
        for idx in graph.node_indices().collect::<Vec<NodeIndex>>() {
            if centering {
                loc_sum += graph[idx].old_location
            }

            // force that will be applied to the node
            let mut force = Vec3::ZERO;

            if repulsion {
                force += fr_get_repulsion(idx, scale, &graph);
            }

            if attraction {
                force += fr_get_attraction(idx, scale, &graph);
            }

            if gravity {
                let node = &graph[idx];

                force += -node.old_location / (1.0 / gravity_factor);
            }

            // apply new location
            let node = &mut graph[idx];

            node.velocity += force * dt;
            node.velocity *= cooloff_factor;

            node.location += node.velocity * dt;
        }

        if centering {
            let avg_vec = loc_sum / graph.node_count() as f32;

            for idx in graph.node_indices().collect::<Vec<NodeIndex>>() {
                let node = &mut graph[idx];

                node.location -= avg_vec;
            }
        }
    }

Same as bool but returns a mutable version.

Retrieves the number from a value. If you mess up and call it on a bool it will return 0.0.

Examples found in repository?
src/force/mod.rs (line 128)
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
    fn update<N, E, Ty: EdgeType>(
        dict: &LinkedHashMap<String, Value>,
        graph: &mut ForceGraph<N, E, Ty>,
        _dt: f32,
    ) {
        let scale = dict.get("Scale Factor").unwrap().number().unwrap();

        let center = Iterator::sum::<Vec3>(
            graph
                .node_weights()
                .map(|x| x.location)
                .collect::<Vec<Vec3>>()
                .iter(),
        ) / graph.node_count() as f32;

        for node in graph.node_weights_mut() {
            node.location = ((node.location - center) * scale) + center;
        }
    }

    let mut dict = LinkedHashMap::new();
    dict.insert("Scale Factor".to_string(), Value::Number(1.5, 0.1..=2.0));

    Force {
        dict: dict.clone(),
        dict_default: dict,
        name: "Scale",
        continuous: false,
        info: Some("Scales the graph around its center."),
        update,
    }
}

/// A force for translating the graph in any direction.
pub fn translate<N, E, Ty: EdgeType>() -> Force<N, E, Ty> {
    fn update<N, E, Ty: EdgeType>(
        dict: &LinkedHashMap<String, Value>,
        graph: &mut ForceGraph<N, E, Ty>,
        _dt: f32,
    ) {
        let distance = dict.get("Distance").unwrap().number().unwrap();

        for node in graph.node_weights_mut() {
            if dict.get("Up").unwrap().bool().unwrap() {
                node.location.y -= distance;
            }

            if dict.get("Down").unwrap().bool().unwrap() {
                node.location.y += distance;
            }

            if dict.get("Left").unwrap().bool().unwrap() {
                node.location.x -= distance;
            }

            if dict.get("Right").unwrap().bool().unwrap() {
                node.location.x += distance;
            }
        }
    }
More examples
Hide additional examples
src/force/fruchterman_reingold.rs (line 20)
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
    fn update<N, E, Ty: EdgeType>(
        dict: &LinkedHashMap<String, Value>,
        graph: &mut ForceGraph<N, E, Ty>,
        dt: f32,
    ) {
        // establish current variables from the force's dictionary
        let scale = dict.get("Scale").unwrap().number().unwrap();
        let cooloff_factor = dict.get("Cooloff Factor").unwrap().number().unwrap();

        // reset all old locations
        graph
            .node_weights_mut()
            .for_each(|n| n.old_location = n.location);

        // loop through all nodes
        for idx in graph.node_indices().collect::<Vec<NodeIndex>>() {
            // force that will be applied to the node
            let mut force = Vec3::ZERO;

            force += fr_get_repulsion(idx, scale, &graph);
            force += fr_get_attraction(idx, scale, &graph);

            // apply new location
            let node = &mut graph[idx];

            node.velocity += force * dt;
            node.velocity *= cooloff_factor;

            node.location += node.velocity * dt;
        }
    }

    let mut dict = LinkedHashMap::new();
    dict.insert("Scale".to_string(), Value::Number(scale, 1.0..=200.0));
    dict.insert(
        "Cooloff Factor".to_string(),
        Value::Number(cooloff_factor, 0.0..=1.0),
    );

    Force {
        dict: dict.clone(),
        dict_default: dict,
        name: "Fruchterman-Reingold (1991)",
        continuous: true,
        info: Some("The force-directed graph drawing algorithm by Fruchterman-Reingold (1991)."),
        update,
    }
}

/// A force directed graph drawing algorithm based on Fruchterman-Reingold (1991), though it multiplies attractions by edge weights.
pub fn fruchterman_reingold_weighted<N, E: Clone + Into<f32>, Ty: EdgeType>(
    scale: f32,
    cooloff_factor: f32,
) -> Force<N, E, Ty> {
    fn update<N, E: Clone + Into<f32>, Ty: EdgeType>(
        dict: &LinkedHashMap<String, Value>,
        graph: &mut ForceGraph<N, E, Ty>,
        dt: f32,
    ) {
        // establish current variables from the force's dictionary
        let scale = dict.get("Scale").unwrap().number().unwrap();
        let cooloff_factor = dict.get("Cooloff Factor").unwrap().number().unwrap();

        // reset all old locations
        graph
            .node_weights_mut()
            .for_each(|n| n.old_location = n.location);

        // loop through all nodes
        for idx in graph.node_indices().collect::<Vec<NodeIndex>>() {
            // force that will be applied to the node
            let mut force = Vec3::ZERO;

            force += fr_get_repulsion(idx, scale, &graph);
            force += fr_get_attraction_weighted(idx, scale, &graph);

            // apply new location
            let node = &mut graph[idx];

            node.velocity += force * dt;
            node.velocity *= cooloff_factor;

            node.location += node.velocity * dt;
        }
    }
src/force/handy.rs (line 30)
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
    fn update<N, E, Ty: EdgeType>(
        dict: &LinkedHashMap<String, Value>,
        graph: &mut ForceGraph<N, E, Ty>,
        dt: f32,
    ) {
        // establish current variables from the force's dictionary
        let repulsion = dict.get("Repulsive Force").unwrap().bool().unwrap();
        let attraction = dict.get("Attractive Force").unwrap().bool().unwrap();
        let scale = dict.get("Scale").unwrap().number().unwrap();
        let cooloff_factor = dict.get("Cooloff Factor").unwrap().number().unwrap();
        let gravity_factor = dict.get("Gravity Factor").unwrap().number().unwrap();
        let centering = dict.get("Centering").unwrap().bool().unwrap();
        let gravity = dict.get("Gravity").unwrap().bool().unwrap();

        // sum of all locations (for centering)
        let mut loc_sum = Vec3::ZERO;

        // reset all old locations
        graph
            .node_weights_mut()
            .for_each(|n| n.old_location = n.location);

        // loop through all nodes
        for idx in graph.node_indices().collect::<Vec<NodeIndex>>() {
            if centering {
                loc_sum += graph[idx].old_location
            }

            // force that will be applied to the node
            let mut force = Vec3::ZERO;

            if repulsion {
                force += fr_get_repulsion(idx, scale, &graph);
            }

            if attraction {
                force += fr_get_attraction(idx, scale, &graph);
            }

            if gravity {
                let node = &graph[idx];

                force += -node.old_location / (1.0 / gravity_factor);
            }

            // apply new location
            let node = &mut graph[idx];

            node.velocity += force * dt;
            node.velocity *= cooloff_factor;

            node.location += node.velocity * dt;
        }

        if centering {
            let avg_vec = loc_sum / graph.node_count() as f32;

            for idx in graph.node_indices().collect::<Vec<NodeIndex>>() {
                let node = &mut graph[idx];

                node.location -= avg_vec;
            }
        }
    }

Same as number but returns a mutable version.

Trait Implementations§

Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more
This method tests for self and other values to be equal, and is used by ==. Read more
This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason. Read more

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.