use super::*; use treemap::{ Rect, Mappable, TreemapLayout }; use data::{FsInfo, INodeInfoGraph, INodeInfoGraphEntry}; /// A treemap of all **files** in the graph. #[derive(Debug, Clone, PartialEq)] pub struct Treemap { //layout: TreemapLayout, nodes: Vec, } impl Treemap { /// All nodes of the map. #[inline] pub fn nodes(&self) -> &[MapNode] { &self.nodes[..] } } #[derive(Debug, Clone, PartialEq)] pub struct MapNode { name: String, vw_size: f64, // Should be halved each iteration vw_bounds: Rect, // should be Rect::new() before aligntment } impl MapNode { /// The calculated bounds of the node #[inline] pub fn bounds(&self) -> &Rect { &self.vw_bounds } /// The name of the node #[inline] pub fn name(&self) -> &str { &self.name[..] } #[inline] fn size(&self) -> f64 //Is this useful for consumer? { self.vw_size } #[inline] fn new(name: String) -> Self { Self { vw_size: 1.0, vw_bounds: Rect::new(), name, } } } /// Create a treemap from this graph. pub fn treemap(_cfg: &Config, graph: &INodeInfoGraph, (w, h): (f64, f64)) -> Treemap { let layout = TreemapLayout::new(); let mut nodes = Vec::with_capacity(graph.len()); //TODO: Recursively walk the graph, halving size with each iteration. (Maybe we need `INodeInfoGraph` here, not `Hierarchicalinodegraph`?) let total_size = graph.total_size(); let size = 1.0; fn calc_path<'a, I: IntoIterator>>(insert: &'a mut Vec, from: I, total_size: u64, size: f64, scale: f64) { for top in from { let path = top.path(); match top.info() { FsInfo::Directory(_) => { //TODO: Do we add dir itself? I think not? // Add children let size = size * 0.5; calc_path(insert, top.level().unwrap(), total_size, size, scale); }, &FsInfo::File(sz, _) => { let fract = (sz as f64) / (total_size as f64); insert.push(MapNode { name: path.to_string_lossy().into_owned(), vw_size: fract * scale, vw_bounds: Rect::new(), }) }, } } } calc_path(&mut nodes, graph.top_level(), total_size, size, 1.0); layout.layout_items(&mut nodes[..], Rect { x: 0.0, y: 0.0, w, h, }); Treemap { //layout, nodes } } impl Mappable for MapNode { fn size(&self) -> f64 { self.vw_size } fn bounds(&self) -> &Rect { &self.vw_bounds } fn set_bounds(&mut self, bounds: Rect) { self.vw_bounds = bounds; } }