Makes main.rs
much less cluttered, but does not move the rendering code itself, as the goal is for that to get split into a separate module, e.g. render.rs
.
UXJFRBBL7IZ2PR7ZYNFGOJ6A7EH5ZVLYVFLA3HNFCNRVL6KWJUDAC
UQJO24KBYI77E4J6LXWX2IUN7VABQKG6PGKBKWEPDCH5CKYBTC4AC
7CVIL7UJBYEZ4KHKPJ7ZYSVQ7BLQWWUSJLJR5FOXBICQTD5ETK4QC
Q3Z6XMP5FFCC3PWC5FSV4C6ICNDPMKMELOV7MYQGC5A42LVHGVPAC
ZPFD3275NTWST7F5YCWYOOUS3QB5HE23LUOZXZIND4HBFSX62NCQC
JVYWRCPTXQUCJ2BYOWAU36BM5ZKJ5FLKHIKMLSJA7XWOVIY2DMDQC
LOR3KOXGQ2VYGDHXQ6MG22ZME5TMPFTUW7A5OG36IAVQANOCXBRAC
use forceatlas2::Layout;
use guppy::{
graph::{DependencyDirection, PackageGraph, PackageSet},
MetadataCommand, PackageId,
};
use guppy::{graph::PackageGraph, MetadataCommand};
fn graph_layout<'graph>(
package_set: &'graph PackageSet,
) -> impl Iterator<Item = (&'graph PackageId, forceatlas2::Node<f64, 2>)> {
let link_index: HashMap<&PackageId, usize> = package_set
.package_ids(DependencyDirection::Forward)
.enumerate()
.map(|(index, id)| (id, index))
.collect();
let edges = package_set
.links(DependencyDirection::Forward)
.map(|link| (link.from(), link.to()))
.map(|(from, to)| (link_index.get(from.id()), link_index.get(to.id())))
.map(|(from, to)| (*from.unwrap(), *to.unwrap()))
.map(|edge| (edge, 1.0))
.collect();
let sizes = package_set
.package_ids(DependencyDirection::Forward)
.map(|_id| 1.0);
let mut layout =
Layout::from_graph_with_degree_mass(edges, sizes, forceatlas2::Settings::default());
for _step in 0..1_000 {
layout.iteration();
}
// TODO: validate that PackageSet::package_ids() is stable; it is used twice (link_index, here)
// so need to validate ordering is consistent (or, find a cleaner solution)
layout
.nodes
.into_iter()
.zip(package_set.package_ids(DependencyDirection::Forward))
.map(|(node, id)| (id, node))
}
fn graph_data(graph: &PackageGraph) -> charming::series::GraphData {
let categories = vec![charming::series::GraphCategory {
name: String::from("default"),
}];
let package_set = graph.resolve_all();
let layout = graph_layout(&package_set);
let nodes = layout
.map(|(id, node)| charming::series::GraphNode {
id: id.repr().to_string(),
name: graph.metadata(id).unwrap().name().to_string(),
x: node.pos.x(),
y: node.pos.y(),
value: 1_f64,
category: 0,
symbol_size: 1_f64,
label: None,
})
.collect();
let links = graph
.query_forward(graph.package_ids())
.unwrap()
.resolve()
.links(DependencyDirection::Forward)
.map(|link| link.endpoints())
.map(|(source, target)| charming::series::GraphLink {
source: source.id().repr().to_string(),
target: target.id().repr().to_string(),
value: None,
})
.collect();
charming::series::GraphData {
nodes,
links,
categories,
}
}
use std::collections::HashMap;
use forceatlas2::Layout;
use guppy::{
graph::{DependencyDirection, PackageGraph, PackageSet},
PackageId,
};
fn layout<'graph>(
package_set: &'graph PackageSet,
) -> impl Iterator<Item = (&'graph PackageId, forceatlas2::Node<f64, 2>)> {
let link_index: HashMap<&PackageId, usize> = package_set
.package_ids(DependencyDirection::Forward)
.enumerate()
.map(|(index, id)| (id, index))
.collect();
let edges = package_set
.links(DependencyDirection::Forward)
.map(|link| (link.from(), link.to()))
.map(|(from, to)| (link_index.get(from.id()), link_index.get(to.id())))
.map(|(from, to)| (*from.unwrap(), *to.unwrap()))
.map(|edge| (edge, 1.0))
.collect();
let sizes = package_set
.package_ids(DependencyDirection::Forward)
.map(|_id| 1.0);
let mut layout =
Layout::from_graph_with_degree_mass(edges, sizes, forceatlas2::Settings::default());
for _step in 0..1_000 {
layout.iteration();
}
// TODO: validate that PackageSet::package_ids() is stable; it is used twice (link_index, here)
// so need to validate ordering is consistent (or, find a cleaner solution)
layout
.nodes
.into_iter()
.zip(package_set.package_ids(DependencyDirection::Forward))
.map(|(node, id)| (id, node))
}
pub fn data(graph: &PackageGraph) -> charming::series::GraphData {
let categories = vec![charming::series::GraphCategory {
name: String::from("default"),
}];
let package_set = graph.resolve_all();
let layout = layout(&package_set);
let nodes = layout
.map(|(id, node)| charming::series::GraphNode {
id: id.repr().to_string(),
name: graph.metadata(id).unwrap().name().to_string(),
x: node.pos.x(),
y: node.pos.y(),
value: 1_f64,
category: 0,
symbol_size: 1_f64,
label: None,
})
.collect();
let links = graph
.query_forward(graph.package_ids())
.unwrap()
.resolve()
.links(DependencyDirection::Forward)
.map(|link| link.endpoints())
.map(|(source, target)| charming::series::GraphLink {
source: source.id().repr().to_string(),
target: target.id().repr().to_string(),
value: None,
})
.collect();
charming::series::GraphData {
nodes,
links,
categories,
}
}