Probably the right decision in the long-term, as the unit-graph data makes it redundant. This change also makes the graph easier to work with, and hopefully will better support existing and future annotations.
VMWXIDPEMIGIVB4YP4YKM2GFIO6O6J7HEYS5FNYPTUSQ3X5MWTMAC 3NPBHM5FRTNMFB6RK5H765YZEVGYA7B4YAMEYBOHYUBRM7QSXSOQC UKNTVY7Z7SSOL4KM7J26MZUTU6WP2D5346KMYCYS7WGKFBSDBJ2AC WFBF7VS6OFN23TQBQGOPUOGMIHXVBTFJ2GFLDYET6IQLY7VOS7RAC BRXHJFU7ANVWOFXBNR5EYUGDURCFCZIF66VDV6L3JBYC45CAFNJAC YA5ITLOV2UWAQZWFJND2WM45DLWG7PTECNJQOLPZAHH2GETPI3HQC XVQXXAGZ4WHBQIU3WEUKLZX6FKV5V52LSTTGMFXR42WPWJZJNENQC C43IWI7GMF6UEKGTXTK4GSQLAFD2SH6BKQRGR4ZQNITYSUK6RMXAC ZEN3WUPDVQWI7LPTEG3WQA5QSEHU74CUXVFJJFIJNSIFC7N2CMEAC UXJFRBBL7IZ2PR7ZYNFGOJ6A7EH5ZVLYVFLA3HNFCNRVL6KWJUDAC 475UXTLYE5LQTMOGOFYC5Z5Z45YJ32M4GD2WOBTXZRBXKUSWFW2AC OPTMCUTBEZQT3HETRWVBU4HYSB7NNBA4TY7QOOKCN3YLSMDKNM2QC L6QJNN62E4LA65OOTWGFK25QQNIJGLK3SJEEKAHOB5B7RXDUEZUQC 7CVIL7UJBYEZ4KHKPJ7ZYSVQ7BLQWWUSJLJR5FOXBICQTD5ETK4QC Q3Z6XMP5FFCC3PWC5FSV4C6ICNDPMKMELOV7MYQGC5A42LVHGVPAC UQJO24KBYI77E4J6LXWX2IUN7VABQKG6PGKBKWEPDCH5CKYBTC4AC LOR3KOXGQ2VYGDHXQ6MG22ZME5TMPFTUW7A5OG36IAVQANOCXBRAC T34OV3YQGRFMXYWEFLBCFMX3U2TVXF552B5B3S6HMBJZU66PDMYAC V2NPEIA6ZXW2FE24IQBPLUICWIGMW7R2K7MNXUUKMOAAQWSQ36WQC ZPFD3275NTWST7F5YCWYOOUS3QB5HE23LUOZXZIND4HBFSX62NCQC JVYWRCPTXQUCJ2BYOWAU36BM5ZKJ5FLKHIKMLSJA7XWOVIY2DMDQC let empty_vec = Vec::new();let self_times = annotations.pkg(pkg.id()).map(|node| node.timings().unwrap_or(&empty_vec)).unwrap_or(&empty_vec).iter().map(|message| TreemapData {value: message.duration,id: None,name: Some(format!("{:?} {:?}", message.mode, message.target.kind)),upper_label: None,visual_dimension: None,children: vec![],children_visible_min: None,});
for node in packages {let self_times = node.timings().iter().map(|message| TreemapData {value: message.duration,id: None,name: Some(format!("{:?} {:?}", message.mode, message.target.kind)),upper_label: None,visual_dimension: None,children: vec![],children_visible_min: None,});
let mut children = data(annotations, &direct_dependencies);
// Recursively call this function for all direct dependencieslet direct_dependencies = annotations.node_edges(node, Direction::Outgoing).collect::<Vec<_>>();let mut children = data(annotations, direct_dependencies);
for (from, to) in links {let edge_weight = annotations.variable(to, Variable::UnitDuration, Measurement::Relative).unwrap_or(0_f64);
for (source, target) in annotations.edges() {let edge_weight =annotations.variable(target, Variable::UnitDuration, Measurement::Relative);
) -> impl Iterator<Item = (&'graph PackageId, forceatlas2::Node<f64, 2>)> {let link_index: IndexMap<&PackageId, usize> = annotations.packages().enumerate().map(|(index, id)| (*id, index)).collect();
) -> impl Iterator<Item = (&'graph Node<'graph>, forceatlas2::Node<f64, 2>)> {
.links().map(|(from, to)| (link_index.get(from), link_index.get(to))).map(|(from, to)| (*from.unwrap(), *to.unwrap()))
.edges()// Get the graph index of both nodes connected to the edge (NodeIndex).map(|(source, target)| (source.index(), target.index()))// Get the integer representation of that index (usize).map(|(source, target)| (source.index(), target.index()))
let sizes = link_index.keys().map(|id| {annotations.variable(id, Variable::UnitDuration, Measurement::Exact).unwrap_or(0_f64)
let sizes = annotations.edges().map(|(source, _target)| {annotations.variable(source, Variable::UnitDuration, Measurement::Exact)
.map(|(id, node)| {let unit_time = annotations.variable(id, Variable::UnitDuration, Measurement::Exact).unwrap_or(0_f64);
.map(|(graph_node, layout_node)| {let unit_time =annotations.variable(graph_node, Variable::UnitDuration, Measurement::Exact);
id: id.repr().to_string(),name: annotations.metadata(id).unwrap().name().to_string(),x: node.pos.x(),y: node.pos.y(),
id: graph_node.id().repr.clone(),name: graph_node.name().to_string(),x: layout_node.pos.x(),y: layout_node.pos.y(),
pub fn timings(&self) -> Option<&Vec<timings::Message>> {self.timings.as_ref()
pub fn index(&self) -> NodeIndex {NodeIndex::new(self.index)}pub fn id(&self) -> &PackageId {&self.unit.pkg_id}pub fn name(&self) -> &str {self.metadata.name.as_str()}pub fn timings(&self) -> &Vec<timings::Message> {&self.timings
.map(|(index, id)| (id, index)).collect::<IndexMap<&PackageId, usize>>();// Iterate over node_indicies.keys() to preserve orderinglet nodes = node_indices.keys().map(|id| Element::Node {weight: Node {id,timings: timings.repr.remove(id),},});let package_set = package_graph.resolve_all();let edges = package_set.links(DependencyDirection::Forward).map(|link| Element::Edge {source: *node_indices.get(link.from().id()).unwrap(),target: *node_indices.get(link.to().id()).unwrap(),weight: (),
.map(|(index, unit)| Element::Node {weight: Node {index,metadata: metadata[&unit.pkg_id].clone(),unit,timings: timings.repr.remove(&unit.pkg_id).unwrap(),},
fn node_index(&self, id: &PackageId) -> Option<NodeIndex> {let node_index = *self.node_indices.get(id)?;Some(NodeIndex::new(node_index))
pub fn roots(&'graph self) -> impl Iterator<Item = &'graph Node> {self.unit_graph.roots.iter().map(|root| NodeIndex::new(*root)).map(|index| &self.graph[index])
pub fn packages(&self) -> impl Iterator<Item = &&PackageId> {self.node_indices.keys()
pub fn edges(&'graph self) -> impl Iterator<Item = (&'graph Node, &'graph Node)> {self.graph.edge_indices().map(|edge| self.graph.edge_endpoints(edge)).map(Option::unwrap).map(|(source, target)| (&self.graph[source], &self.graph[target]))
.raw_edges().iter().map(|edge| (self.graph[edge.source()].id, self.graph[edge.target()].id))
.edges_directed(node_index, direction).map(move |edge| match direction {Direction::Outgoing => edge.target(),Direction::Incoming => edge.source(),}).map(|index| &self.graph[index])
pub fn metadata(&self, id: &PackageId) -> Result<PackageMetadata, guppy::Error> {self.package_graph.metadata(id)}pub fn dependents(&self, id: &PackageId) -> Option<usize> {let node_index = self.node_index(id)?;let dependents = self.graph.edges_directed(node_index, Direction::Incoming).count();Some(dependents)}pub fn variable(&self,id: &PackageId,variable: Variable,measurement: Measurement,) -> Option<f64> {
pub fn variable(&self, node: &Node, variable: Variable, measurement: Measurement) -> f64 {
name = "ahash"version = "0.8.11"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"dependencies = ["cfg-if","getrandom","once_cell","version_check","zerocopy",][[package]]
][[package]]name = "guppy"version = "0.17.5"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "34e99a7734579b834a076ef11789783c153c6eb5fb3520ed15bc41f483f0f317"dependencies = ["ahash","camino","cargo_metadata","cfg-if","debug-ignore","fixedbitset","guppy-workspace-hack","indexmap","itertools","nested","once_cell","pathdiff","petgraph","semver","serde","serde_json","smallvec","static_assertions","target-spec",
][[package]]name = "itertools"version = "0.12.1"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"dependencies = ["either",
"unicode-ident",][[package]]name = "target-lexicon"version = "0.12.14"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f"[[package]]name = "target-spec"version = "3.1.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "36a8e795b1824524d13cdf04f73cf8b4f244ce86c96b4d2a83a6ca1a753d2752"dependencies = ["cfg-expr","guppy-workspace-hack","target-lexicon",
[[package]]name = "zerocopy"version = "0.7.32"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"dependencies = ["zerocopy-derive",][[package]]name = "zerocopy-derive"version = "0.7.32"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"dependencies = ["proc-macro2","quote","syn",]