From 31229b11608ecf6c3762f38d8454f6a3f9f5c8db Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Sat, 12 Oct 2024 13:20:09 +1300 Subject: [PATCH 1/8] Add `impl From for AnyIdOrDefaults`. --- crate/model/src/theme/any_id_or_defaults.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crate/model/src/theme/any_id_or_defaults.rs b/crate/model/src/theme/any_id_or_defaults.rs index 12d399f..43ee0c1 100644 --- a/crate/model/src/theme/any_id_or_defaults.rs +++ b/crate/model/src/theme/any_id_or_defaults.rs @@ -27,6 +27,12 @@ impl AnyIdOrDefaults { } } +impl From for AnyIdOrDefaults { + fn from(any_id: AnyId) -> Self { + Self::AnyId(any_id) + } +} + impl Serialize for AnyIdOrDefaults { fn serialize(&self, serializer: S) -> Result where From 128b70e0646e24653861b13d0705b551694e2c49 Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Sat, 12 Oct 2024 13:33:15 +1300 Subject: [PATCH 2/8] Add `node_width_default` and `node_height_default` to `GraphvizAttrs`. --- crate/model/src/common/graphviz_attrs.rs | 58 +++++++++++++++++++ crate/model/src/common/graphviz_dot_theme.rs | 24 -------- .../src/into_graphviz_dot_src/info_graph.rs | 13 +++-- 3 files changed, 67 insertions(+), 28 deletions(-) diff --git a/crate/model/src/common/graphviz_attrs.rs b/crate/model/src/common/graphviz_attrs.rs index a3c62ce..59b8bab 100644 --- a/crate/model/src/common/graphviz_attrs.rs +++ b/crate/model/src/common/graphviz_attrs.rs @@ -65,6 +65,20 @@ pub struct GraphvizAttrs { /// /// [`minlen`]: https://graphviz.org/docs/attrs/minlen/ pub edge_minlens: EdgeMinlens, + /// Minimum / initial [`width`] for nodes, defaults to `0.3`. + /// + /// If `fixedsize` is true, this will be the exact / maximum width for + /// nodes. + /// + /// [`width`]: https://graphviz.org/docs/attrs/width/ + pub node_width_default: f64, + /// Minimum / initial [`height`] for nodes, defaults to `0.1`. + /// + /// If `fixedsize` is true, this will be the exact / maximum height for + /// nodes. + /// + /// [`height`]: https://graphviz.org/docs/attrs/height/ + pub node_height_default: f64, /// How closely to pack together graph components. pub pack_mode: PackMode, } @@ -159,6 +173,28 @@ impl GraphvizAttrs { self } + /// Sets the minimum / initial [`width`] for nodes, defaults to `0.3`. + /// + /// If `fixedsize` is true, this will be the exact / maximum width for + /// nodes. + /// + /// [`width`]: https://graphviz.org/docs/attrs/width/ + pub fn with_node_width_default(mut self, node_width_default: f64) -> Self { + self.node_width_default = node_width_default; + self + } + + /// Sets the minimum / initial [`height`] for nodes, defaults to `0.1`. + /// + /// If `fixedsize` is true, this will be the exact / maximum height for + /// nodes. + /// + /// [`height`]: https://graphviz.org/docs/attrs/height/ + pub fn with_node_height_default(mut self, node_height_default: f64) -> Self { + self.node_height_default = node_height_default; + self + } + /// Returns the minimum space between two adjacent nodes in the same rank, /// in inches. Also controls the spacing between multiple edges between /// the same pair of nodes. @@ -230,6 +266,26 @@ impl GraphvizAttrs { pub fn edge_minlens(&self) -> &EdgeMinlens { &self.edge_minlens } + + /// Returns the minimum / initial [`width`] for nodes. + /// + /// If `fixedsize` is true, this will be the exact / maximum width for + /// nodes. + /// + /// [`width`]: https://graphviz.org/docs/attrs/width/ + pub fn node_width_default(&self) -> f64 { + self.node_width_default + } + + /// Returns the minimum / initial [`height`] for nodes. + /// + /// If `fixedsize` is true, this will be the exact / maximum height for + /// nodes. + /// + /// [`height`]: https://graphviz.org/docs/attrs/height/ + pub fn node_height_default(&self) -> f64 { + self.node_height_default + } } impl Default for GraphvizAttrs { @@ -244,6 +300,8 @@ impl Default for GraphvizAttrs { edge_dirs: EdgeDirs::default(), edge_minlen_default: 2, edge_minlens: EdgeMinlens::default(), + node_width_default: 0.3, + node_height_default: 0.1, pack_mode: PackMode::default(), } } diff --git a/crate/model/src/common/graphviz_dot_theme.rs b/crate/model/src/common/graphviz_dot_theme.rs index 0705359..c2321fc 100644 --- a/crate/model/src/common/graphviz_dot_theme.rs +++ b/crate/model/src/common/graphviz_dot_theme.rs @@ -7,10 +7,6 @@ pub struct GraphvizDotTheme { // // pub node_text_color: &'static str, - /// Width of a node, but it is allowed to expand. - pub node_width: f64, - /// Height of a node, but it is allowed to expand. - pub node_height: f64, /// Left and right margin in inches. /// /// Default: `0.04`. @@ -62,16 +58,6 @@ impl GraphvizDotTheme { self } - pub fn with_node_width(mut self, node_width: f64) -> Self { - self.node_width = node_width; - self - } - - pub fn with_node_height(mut self, node_height: f64) -> Self { - self.node_height = node_height; - self - } - pub fn with_node_margin_x(mut self, node_margin_x: f64) -> Self { self.node_margin_x = node_margin_x; self @@ -140,14 +126,6 @@ impl GraphvizDotTheme { self.node_text_color } - pub fn node_width(&self) -> f64 { - self.node_width - } - - pub fn node_height(&self) -> f64 { - self.node_height - } - pub fn node_margin_x(&self) -> f64 { self.node_margin_x } @@ -202,8 +180,6 @@ impl Default for GraphvizDotTheme { Self { edge_color: "#333333", node_text_color: "#111111", - node_width: 0.3, - node_height: 0.1, node_margin_x: 0.04, node_margin_y: 0.04, plain_text_color: "#222222", diff --git a/crate/rt/src/into_graphviz_dot_src/info_graph.rs b/crate/rt/src/into_graphviz_dot_src/info_graph.rs index cf49486..ddae416 100644 --- a/crate/rt/src/into_graphviz_dot_src/info_graph.rs +++ b/crate/rt/src/into_graphviz_dot_src/info_graph.rs @@ -98,7 +98,7 @@ impl IntoGraphvizDotSrc for &InfoGraph { let graph_style = self.graph_style(); let graphviz_attrs = self.graphviz_attrs(); let graph_attrs = graph_attrs(theme, self.direction(), graphviz_attrs); - let node_attrs = node_attrs(graph_style, theme); + let node_attrs = node_attrs(graph_style, graphviz_attrs, theme); let edge_attrs = edge_attrs(graphviz_attrs, theme); let diagram_theme = self.theme(); @@ -266,7 +266,11 @@ fn graph_attrs( ) } -fn node_attrs(graph_style: GraphStyle, theme: &GraphvizDotTheme) -> String { +fn node_attrs( + graph_style: GraphStyle, + graphviz_attrs: &GraphvizAttrs, + theme: &GraphvizDotTheme, +) -> String { let node_style_and_shape = match graph_style { GraphStyle::Box => { "shape = \"rect\" @@ -279,11 +283,12 @@ fn node_attrs(graph_style: GraphStyle, theme: &GraphvizDotTheme) -> String { }; let node_text_color = theme.node_text_color(); let node_point_size = theme.node_point_size(); - let node_width = theme.node_width(); - let node_height = theme.node_height(); let node_margin_x = theme.node_margin_x(); let node_margin_y = theme.node_margin_y(); + let node_width = graphviz_attrs.node_width_default(); + let node_height = graphviz_attrs.node_height_default(); + formatdoc!( r#" node [ From 378860427bf6777519b9fc3a8d98f1f2899ec53a Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Sat, 12 Oct 2024 13:46:08 +1300 Subject: [PATCH 3/8] Add `fixed_size` to `GraphvizAttrs`. --- crate/model/src/common/graphviz_attrs.rs | 30 ++++++++++++++++++- .../src/common/graphviz_attrs/fixed_size.rs | 30 +++++++++++++++++++ .../src/into_graphviz_dot_src/info_graph.rs | 8 ++++- 3 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 crate/model/src/common/graphviz_attrs/fixed_size.rs diff --git a/crate/model/src/common/graphviz_attrs.rs b/crate/model/src/common/graphviz_attrs.rs index 59b8bab..19da71b 100644 --- a/crate/model/src/common/graphviz_attrs.rs +++ b/crate/model/src/common/graphviz_attrs.rs @@ -2,13 +2,15 @@ use serde::{Deserialize, Serialize}; pub use self::{ edge_constraints::EdgeConstraints, edge_dir::EdgeDir, edge_dirs::EdgeDirs, - edge_minlens::EdgeMinlens, pack_mode::PackMode, pack_mode_flag::PackModeFlag, splines::Splines, + edge_minlens::EdgeMinlens, fixed_size::FixedSize, pack_mode::PackMode, + pack_mode_flag::PackModeFlag, splines::Splines, }; mod edge_constraints; mod edge_dir; mod edge_dirs; mod edge_minlens; +mod fixed_size; mod pack_mode; mod pack_mode_flag; mod splines; @@ -79,6 +81,12 @@ pub struct GraphvizAttrs { /// /// [`height`]: https://graphviz.org/docs/attrs/height/ pub node_height_default: f64, + /// Whether a node's `width` and `height` are fixed dimensions. + /// + /// See [`fixedsize`]. + /// + /// [`fixedsize`]: https://graphviz.org/docs/attrs/fixedsize/ + pub fixed_size: FixedSize, /// How closely to pack together graph components. pub pack_mode: PackMode, } @@ -195,6 +203,16 @@ impl GraphvizAttrs { self } + /// Sets whether a node's `width` and `height` are fixed dimensions. + /// + /// See [`fixedsize`]. + /// + /// [`fixedsize`]: https://graphviz.org/docs/attrs/fixedsize/ + pub fn with_fixed_size(mut self, fixed_size: FixedSize) -> Self { + self.fixed_size = fixed_size; + self + } + /// Returns the minimum space between two adjacent nodes in the same rank, /// in inches. Also controls the spacing between multiple edges between /// the same pair of nodes. @@ -286,6 +304,15 @@ impl GraphvizAttrs { pub fn node_height_default(&self) -> f64 { self.node_height_default } + + /// Returns whether a node's `width` and `height` are fixed dimensions. + /// + /// See [`fixedsize`]. + /// + /// [`fixedsize`]: https://graphviz.org/docs/attrs/fixedsize/ + pub fn fixed_size(&self) -> FixedSize { + self.fixed_size + } } impl Default for GraphvizAttrs { @@ -302,6 +329,7 @@ impl Default for GraphvizAttrs { edge_minlens: EdgeMinlens::default(), node_width_default: 0.3, node_height_default: 0.1, + fixed_size: FixedSize::default(), pack_mode: PackMode::default(), } } diff --git a/crate/model/src/common/graphviz_attrs/fixed_size.rs b/crate/model/src/common/graphviz_attrs/fixed_size.rs new file mode 100644 index 0000000..086ee1a --- /dev/null +++ b/crate/model/src/common/graphviz_attrs/fixed_size.rs @@ -0,0 +1,30 @@ +use std::fmt; + +use serde::{Deserialize, Serialize}; + +/// Whether a node's `width` and `height` are fixed dimensions. +/// +/// See [`fixedsize`]. +/// +/// [`fixedsize`]: https://graphviz.org/docs/attrs/fixedsize/ +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "snake_case")] +pub enum FixedSize { + /// Nodes are not fixed size, and `width`/`height` indicate their minimum dimensions. + #[default] + False, + /// Nodes are fixed size, and `width`/`height` indicate their maximum dimensions. + True, + /// `width` and `height` determine the dimensions of the node's shape, but not its label. + Shape, +} + +impl fmt::Display for FixedSize { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + FixedSize::False => write!(f, "false"), + FixedSize::True => write!(f, "true"), + FixedSize::Shape => write!(f, "shape"), + } + } +} diff --git a/crate/rt/src/into_graphviz_dot_src/info_graph.rs b/crate/rt/src/into_graphviz_dot_src/info_graph.rs index ddae416..2d85a12 100644 --- a/crate/rt/src/into_graphviz_dot_src/info_graph.rs +++ b/crate/rt/src/into_graphviz_dot_src/info_graph.rs @@ -6,7 +6,7 @@ use std::{ use dot_ix_model::{ common::{ dot_src_and_styles::{GraphvizImage, GraphvizOpts}, - graphviz_attrs::{EdgeDir, Splines}, + graphviz_attrs::{EdgeDir, FixedSize, Splines}, AnyId, DotSrcAndStyles, EdgeId, GraphvizAttrs, GraphvizDotTheme, ImageId, Images, NodeHierarchy, NodeId, TagId, TagNames, }, @@ -288,6 +288,11 @@ fn node_attrs( let node_width = graphviz_attrs.node_width_default(); let node_height = graphviz_attrs.node_height_default(); + let fixed_size = graphviz_attrs.fixed_size(); + let fixed_size = match fixed_size { + FixedSize::False => Cow::Borrowed(""), + FixedSize::True | FixedSize::Shape => Cow::Owned(format!(r#"fixedsize = {fixed_size}"#)), + }; formatdoc!( r#" @@ -299,6 +304,7 @@ fn node_attrs( width = {node_width} height = {node_height} margin = "{node_margin_x:.3},{node_margin_y:.3}" + {fixed_size} ] "# ) From 147de886b1cde2635c826a0142ebf54f0e492333 Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Sat, 12 Oct 2024 13:58:29 +1300 Subject: [PATCH 4/8] Add `NodeWidths` and `NodeHeights` to `GraphvizAttrs`. --- crate/model/src/common/graphviz_attrs.rs | 64 ++++++++++++++++++- .../src/common/graphviz_attrs/node_heights.rs | 59 +++++++++++++++++ .../src/common/graphviz_attrs/node_widths.rs | 59 +++++++++++++++++ .../src/into_graphviz_dot_src/info_graph.rs | 29 ++++++++- 4 files changed, 208 insertions(+), 3 deletions(-) create mode 100644 crate/model/src/common/graphviz_attrs/node_heights.rs create mode 100644 crate/model/src/common/graphviz_attrs/node_widths.rs diff --git a/crate/model/src/common/graphviz_attrs.rs b/crate/model/src/common/graphviz_attrs.rs index 19da71b..98f6df6 100644 --- a/crate/model/src/common/graphviz_attrs.rs +++ b/crate/model/src/common/graphviz_attrs.rs @@ -2,8 +2,8 @@ use serde::{Deserialize, Serialize}; pub use self::{ edge_constraints::EdgeConstraints, edge_dir::EdgeDir, edge_dirs::EdgeDirs, - edge_minlens::EdgeMinlens, fixed_size::FixedSize, pack_mode::PackMode, - pack_mode_flag::PackModeFlag, splines::Splines, + edge_minlens::EdgeMinlens, fixed_size::FixedSize, node_heights::NodeHeights, + node_widths::NodeWidths, pack_mode::PackMode, pack_mode_flag::PackModeFlag, splines::Splines, }; mod edge_constraints; @@ -11,6 +11,8 @@ mod edge_dir; mod edge_dirs; mod edge_minlens; mod fixed_size; +mod node_heights; +mod node_widths; mod pack_mode; mod pack_mode_flag; mod splines; @@ -74,6 +76,13 @@ pub struct GraphvizAttrs { /// /// [`width`]: https://graphviz.org/docs/attrs/width/ pub node_width_default: f64, + /// Each node's [`width`]. + /// + /// If `fixedsize` is true, this will be the exact / maximum width for + /// nodes. + /// + /// [`width`]: https://graphviz.org/docs/attrs/width/ + pub node_widths: NodeWidths, /// Minimum / initial [`height`] for nodes, defaults to `0.1`. /// /// If `fixedsize` is true, this will be the exact / maximum height for @@ -81,6 +90,13 @@ pub struct GraphvizAttrs { /// /// [`height`]: https://graphviz.org/docs/attrs/height/ pub node_height_default: f64, + /// Each node's [`height`]. + /// + /// If `fixedsize` is true, this will be the exact / maximum height for + /// nodes. + /// + /// [`height`]: https://graphviz.org/docs/attrs/height/ + pub node_heights: NodeHeights, /// Whether a node's `width` and `height` are fixed dimensions. /// /// See [`fixedsize`]. @@ -192,6 +208,17 @@ impl GraphvizAttrs { self } + /// Sets each node's [`width`]. + /// + /// If `fixedsize` is true, this will be the exact / maximum width for + /// nodes. + /// + /// [`width`]: https://graphviz.org/docs/attrs/width/ + pub fn with_node_widths(mut self, node_widths: NodeWidths) -> Self { + self.node_widths = node_widths; + self + } + /// Sets the minimum / initial [`height`] for nodes, defaults to `0.1`. /// /// If `fixedsize` is true, this will be the exact / maximum height for @@ -203,6 +230,17 @@ impl GraphvizAttrs { self } + /// Sets each node's [`height`]. + /// + /// If `fixedsize` is true, this will be the exact / maximum height for + /// nodes. + /// + /// [`height`]: https://graphviz.org/docs/attrs/height/ + pub fn with_node_heights(mut self, node_heights: NodeHeights) -> Self { + self.node_heights = node_heights; + self + } + /// Sets whether a node's `width` and `height` are fixed dimensions. /// /// See [`fixedsize`]. @@ -295,6 +333,16 @@ impl GraphvizAttrs { self.node_width_default } + /// Returns each node's [`width`]. + /// + /// If `fixedsize` is true, this will be the exact / maximum width for + /// nodes. + /// + /// [`width`]: https://graphviz.org/docs/attrs/width/ + pub fn node_widths(&self) -> &NodeWidths { + &self.node_widths + } + /// Returns the minimum / initial [`height`] for nodes. /// /// If `fixedsize` is true, this will be the exact / maximum height for @@ -305,6 +353,16 @@ impl GraphvizAttrs { self.node_height_default } + /// Returns each node's [`height`]. + /// + /// If `fixedsize` is true, this will be the exact / maximum height for + /// nodes. + /// + /// [`height`]: https://graphviz.org/docs/attrs/height/ + pub fn node_heights(&self) -> &NodeHeights { + &self.node_heights + } + /// Returns whether a node's `width` and `height` are fixed dimensions. /// /// See [`fixedsize`]. @@ -328,7 +386,9 @@ impl Default for GraphvizAttrs { edge_minlen_default: 2, edge_minlens: EdgeMinlens::default(), node_width_default: 0.3, + node_widths: NodeWidths::default(), node_height_default: 0.1, + node_heights: NodeHeights::default(), fixed_size: FixedSize::default(), pack_mode: PackMode::default(), } diff --git a/crate/model/src/common/graphviz_attrs/node_heights.rs b/crate/model/src/common/graphviz_attrs/node_heights.rs new file mode 100644 index 0000000..8db5d70 --- /dev/null +++ b/crate/model/src/common/graphviz_attrs/node_heights.rs @@ -0,0 +1,59 @@ +use std::ops::{Deref, DerefMut}; + +use indexmap::IndexMap; +use serde::{Deserialize, Serialize}; + +use crate::common::NodeId; + +/// GraphViz node height. `IndexMap` newtype. +/// +/// This is only used for GraphViz dot graphs, which sets the [`height`] +/// attribute for the node. +/// +/// [`height`]: https://graphviz.org/docs/attrs/height/ +#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)] +pub struct NodeHeights(IndexMap); + +impl NodeHeights { + /// Returns a new `NodeHeights` map. + pub fn new() -> Self { + Self::default() + } + + /// Returns a new `NodeHeights` map with the given preallocated + /// capacity. + pub fn with_capacity(capacity: usize) -> Self { + Self(IndexMap::with_capacity(capacity)) + } + + /// Returns the underlying map. + pub fn into_inner(self) -> IndexMap { + self.0 + } +} + +impl Deref for NodeHeights { + type Target = IndexMap; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for NodeHeights { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl From> for NodeHeights { + fn from(inner: IndexMap) -> Self { + Self(inner) + } +} + +impl FromIterator<(NodeId, f64)> for NodeHeights { + fn from_iter>(iter: I) -> Self { + Self(IndexMap::from_iter(iter)) + } +} diff --git a/crate/model/src/common/graphviz_attrs/node_widths.rs b/crate/model/src/common/graphviz_attrs/node_widths.rs new file mode 100644 index 0000000..3f8fcd2 --- /dev/null +++ b/crate/model/src/common/graphviz_attrs/node_widths.rs @@ -0,0 +1,59 @@ +use std::ops::{Deref, DerefMut}; + +use indexmap::IndexMap; +use serde::{Deserialize, Serialize}; + +use crate::common::NodeId; + +/// GraphViz node width. `IndexMap` newtype. +/// +/// This is only used for GraphViz dot graphs, which sets the [`width`] +/// attribute for the node. +/// +/// [`width`]: https://graphviz.org/docs/attrs/width/ +#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)] +pub struct NodeWidths(IndexMap); + +impl NodeWidths { + /// Returns a new `NodeWidths` map. + pub fn new() -> Self { + Self::default() + } + + /// Returns a new `NodeWidths` map with the given preallocated + /// capacity. + pub fn with_capacity(capacity: usize) -> Self { + Self(IndexMap::with_capacity(capacity)) + } + + /// Returns the underlying map. + pub fn into_inner(self) -> IndexMap { + self.0 + } +} + +impl Deref for NodeWidths { + type Target = IndexMap; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for NodeWidths { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl From> for NodeWidths { + fn from(inner: IndexMap) -> Self { + Self(inner) + } +} + +impl FromIterator<(NodeId, f64)> for NodeWidths { + fn from_iter>(iter: I) -> Self { + Self(IndexMap::from_iter(iter)) + } +} diff --git a/crate/rt/src/into_graphviz_dot_src/info_graph.rs b/crate/rt/src/into_graphviz_dot_src/info_graph.rs index 2d85a12..3f6e2c4 100644 --- a/crate/rt/src/into_graphviz_dot_src/info_graph.rs +++ b/crate/rt/src/into_graphviz_dot_src/info_graph.rs @@ -6,7 +6,7 @@ use std::{ use dot_ix_model::{ common::{ dot_src_and_styles::{GraphvizImage, GraphvizOpts}, - graphviz_attrs::{EdgeDir, FixedSize, Splines}, + graphviz_attrs::{EdgeDir, FixedSize, NodeHeights, NodeWidths, Splines}, AnyId, DotSrcAndStyles, EdgeId, GraphvizAttrs, GraphvizDotTheme, ImageId, Images, NodeHierarchy, NodeId, TagId, TagNames, }, @@ -141,6 +141,8 @@ impl IntoGraphvizDotSrc for &InfoGraph { ); let tag_el_css_classes_map = &tag_el_css_classes_map; + let node_widths = graphviz_attrs.node_widths(); + let node_heights = graphviz_attrs.node_heights(); let node_clusters = self .hierarchy() .iter() @@ -152,6 +154,8 @@ impl IntoGraphvizDotSrc for &InfoGraph { theme, node_id, node_hierarchy, + node_widths, + node_heights, }; node_cluster(node_cluster_args) @@ -354,6 +358,8 @@ fn node_cluster_internal( theme, node_id, node_hierarchy, + node_widths, + node_heights, } = node_cluster_args; let graph_style = info_graph.graph_style(); @@ -404,6 +410,15 @@ fn node_cluster_internal( }) .unwrap_or_default(); + let node_width = node_widths + .get(node_id) + .map(|node_width| Cow::::Owned(format!("width = {node_width}"))) + .unwrap_or_default(); + let node_height = node_heights + .get(node_id) + .map(|node_height| Cow::::Owned(format!("height = {node_height}"))) + .unwrap_or_default(); + // Note: There's no space between `{node_tailwind_classes}{node_tag_classes}` // because for some reason spaces before `{node_tag_classes}` are translated // into the `0xa0` byte. @@ -427,6 +442,8 @@ fn node_cluster_internal( {node_desc} > class = "{OUTLINE_NONE} {node_tailwind_classes}{node_tag_classes}" + {node_width} + {node_height} ] "# )?, @@ -449,6 +466,8 @@ fn node_cluster_internal( label = <> margin = 0.0 class = "{OUTLINE_NONE}" + {node_width} + {node_height} {node_id} [ label = "" @@ -495,6 +514,8 @@ fn node_cluster_internal( > style = "filled,rounded" class = "{OUTLINE_NONE} {node_tailwind_classes}{node_tag_classes}" + {node_width} + {node_height} "# )?; @@ -512,6 +533,8 @@ fn node_cluster_internal( theme, node_id: child_node_id, node_hierarchy: child_node_hierarchy, + node_widths, + node_heights, }; node_cluster_internal(node_cluster_args, buffer) @@ -527,6 +550,8 @@ fn node_cluster_internal( theme, node_id: child_node_id, node_hierarchy: child_node_hierarchy, + node_widths, + node_heights, }; node_cluster_internal(node_cluster_args, buffer) @@ -645,6 +670,8 @@ struct NodeClusterArgs<'args> { theme: &'args GraphvizDotTheme, node_id: &'args NodeId, node_hierarchy: &'args NodeHierarchy, + node_widths: &'args NodeWidths, + node_heights: &'args NodeHeights, } struct EdgeArgs<'args> { From c381fba53fbeba8a1d27dc81e758245d8e9fd4b8 Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Sat, 12 Oct 2024 13:59:19 +1300 Subject: [PATCH 5/8] Update `CHANGELOG.md`. --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f551bbe..830d53f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## unreleased + +* Support `node_width_default` in `GraphvizAttrs`. +* Support `node_widths` in `GraphvizAttrs`. +* Support `node_height_default` in `GraphvizAttrs`. +* Support `node_heights` in `GraphvizAttrs`. +* Support `fixed_size` in `GraphvizAttrs`. + + ## 0.8.1 (2024-09-27) * Support inline images ([#33]). From f6e0ef4c7c8b6d2d5cff4c2ed7898977b7edacd0 Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Sat, 12 Oct 2024 14:00:47 +1300 Subject: [PATCH 6/8] Address clippy lints. --- crate/model/src/theme/any_id_or_defaults.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crate/model/src/theme/any_id_or_defaults.rs b/crate/model/src/theme/any_id_or_defaults.rs index 43ee0c1..b2aeba3 100644 --- a/crate/model/src/theme/any_id_or_defaults.rs +++ b/crate/model/src/theme/any_id_or_defaults.rs @@ -57,7 +57,7 @@ impl<'de> Deserialize<'de> for AnyIdOrDefaults { struct AnyIdOrDefaultsVisitor; -impl<'de> Visitor<'de> for AnyIdOrDefaultsVisitor { +impl Visitor<'_> for AnyIdOrDefaultsVisitor { type Value = AnyIdOrDefaults; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { From 8eef141209ae7dcf00d55a16316c2062a05fefa1 Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Sat, 12 Oct 2024 14:01:22 +1300 Subject: [PATCH 7/8] Run `cargo fmt --all`. --- crate/model/src/common/graphviz_attrs/fixed_size.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/crate/model/src/common/graphviz_attrs/fixed_size.rs b/crate/model/src/common/graphviz_attrs/fixed_size.rs index 086ee1a..ba3cc21 100644 --- a/crate/model/src/common/graphviz_attrs/fixed_size.rs +++ b/crate/model/src/common/graphviz_attrs/fixed_size.rs @@ -10,12 +10,15 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub enum FixedSize { - /// Nodes are not fixed size, and `width`/`height` indicate their minimum dimensions. + /// Nodes are not fixed size, and `width`/`height` indicate their minimum + /// dimensions. #[default] False, - /// Nodes are fixed size, and `width`/`height` indicate their maximum dimensions. + /// Nodes are fixed size, and `width`/`height` indicate their maximum + /// dimensions. True, - /// `width` and `height` determine the dimensions of the node's shape, but not its label. + /// `width` and `height` determine the dimensions of the node's shape, but + /// not its label. Shape, } From 6564699fc3cf45bda9770acb897b626dc89a5228 Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Sat, 12 Oct 2024 14:12:49 +1300 Subject: [PATCH 8/8] Address clippy lints. --- crate/rt/src/info_graph_dot.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crate/rt/src/info_graph_dot.rs b/crate/rt/src/info_graph_dot.rs index 62ebc98..f0e0a61 100644 --- a/crate/rt/src/info_graph_dot.rs +++ b/crate/rt/src/info_graph_dot.rs @@ -14,7 +14,7 @@ pub struct InfoGraphDot<'graph> { pub edge_ids: Vec<&'graph EdgeId>, } -impl<'graph> InfoGraphDot<'graph> { +impl InfoGraphDot<'_> { fn el_prefix(&self, node_id: &AnyId) -> &str { let is_cluster = self .node_id_to_hierarchy