Will need a lot of tweaking as the lines overlap more than I would like, and might drop this crate entirely in favour of an algorithm that better represents the tree structure, but may also explore making this the first of many user-selectable layout options.
UQJO24KBYI77E4J6LXWX2IUN7VABQKG6PGKBKWEPDCH5CKYBTC4AC 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))}
let nodes = graph.packages().enumerate().map(|(coords, package)| charming::series::GraphNode {id: package.id().repr().to_string(),name: package.name().to_string(),x: coords as f64,y: coords as f64,
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(),
name = "crossbeam-epoch"version = "0.9.18"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"dependencies = ["crossbeam-utils",][[package]]name = "crossbeam-utils"version = "0.8.19"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"[[package]]
name = "rand"version = "0.8.5"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"dependencies = ["libc","rand_chacha","rand_core",][[package]]name = "rand_chacha"version = "0.3.1"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"dependencies = ["ppv-lite86","rand_core",][[package]]name = "rand_core"version = "0.6.4"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"dependencies = ["getrandom",][[package]]name = "rayon"version = "1.10.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"dependencies = ["either","rayon-core",][[package]]name = "rayon-core"version = "1.12.1"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"dependencies = ["crossbeam-deque","crossbeam-utils",][[package]]name = "redox_syscall"version = "0.4.1"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"dependencies = ["bitflags",][[package]]
name = "windows-targets"version = "0.48.5"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"dependencies = ["windows_aarch64_gnullvm","windows_aarch64_msvc","windows_i686_gnu","windows_i686_msvc","windows_x86_64_gnu","windows_x86_64_gnullvm","windows_x86_64_msvc",][[package]]name = "windows_aarch64_gnullvm"version = "0.48.5"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"[[package]]name = "windows_aarch64_msvc"version = "0.48.5"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"[[package]]name = "windows_i686_gnu"version = "0.48.5"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"[[package]]name = "windows_i686_msvc"version = "0.48.5"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"[[package]]name = "windows_x86_64_gnu"version = "0.48.5"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"[[package]]name = "windows_x86_64_gnullvm"version = "0.48.5"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"[[package]]name = "windows_x86_64_msvc"version = "0.48.5"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"[[package]]