summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/attributes/mod.rs14
-rw-r--r--src/attributes/viewport.rs108
2 files changed, 119 insertions, 3 deletions
diff --git a/src/attributes/mod.rs b/src/attributes/mod.rs
index 7f4fb0d..8f50c56 100644
--- a/src/attributes/mod.rs
+++ b/src/attributes/mod.rs
@@ -20,6 +20,7 @@ mod shape;
mod spline_type;
mod splines;
mod style;
+mod viewport;
pub use crate::attributes::arrow_type::ArrowType;
pub use crate::attributes::cluster_mode::ClusterMode;
@@ -49,6 +50,7 @@ use indexmap::map::IndexMap;
use std::borrow::Cow;
use std::collections::HashMap;
use Cow::Borrowed;
+use crate::attributes::viewport::ViewPort;
/// The text for a graphviz label on a node or edge.
#[derive(Clone, PartialEq, Eq, Debug)]
@@ -310,6 +312,13 @@ impl<'a> From<Styles> for AttributeText<'a> {
}
}
+impl<'a> From<ViewPort> for AttributeText<'a> {
+ fn from(viewport: ViewPort) -> Self {
+ AttributeText::quoted(viewport.dot_string())
+ }
+}
+
+
impl<'a> From<u32> for AttributeText<'a> {
fn from(v: u32) -> Self {
AttributeText::attr(v.to_string())
@@ -853,7 +862,6 @@ pub trait GraphAttributes<'a> {
self
}
- // TODO: add a ViewPort Struct?
/// Clipping window on final drawing.
/// viewport supersedes any size attribute.
/// The width and height of the viewport specify precisely the final size of the output.
@@ -865,8 +873,8 @@ pub trait GraphAttributes<'a> {
/// of the graph,
/// in points, of the center of the viewport, or the name N of a node whose center should used
/// as the focus.
- fn viewport(&mut self, viewport: String) -> &mut Self {
- self.add_attribute("viewport", AttributeText::attr(viewport))
+ fn viewport(&mut self, viewport: ViewPort) -> &mut Self {
+ self.add_attribute("viewport", AttributeText::from(viewport))
}
/// Add an attribute to the node.
diff --git a/src/attributes/viewport.rs b/src/attributes/viewport.rs
new file mode 100644
index 0000000..f5bfe92
--- /dev/null
+++ b/src/attributes/viewport.rs
@@ -0,0 +1,108 @@
+use crate::attributes::Point;
+use crate::DotString;
+use std::borrow::Cow;
+
+pub struct ViewPort {
+ pub width: f32,
+ pub height: f32,
+ pub zoom: f32,
+ pub focus: Option<FocusType>
+}
+
+impl ViewPort {
+ pub fn new(width: f32, height: f32, zoom: Option<f32>, focus: Option<FocusType>) -> Self {
+ Self {
+ width,
+ height,
+ zoom: zoom.unwrap_or(1 as f32),
+ focus
+ }
+ }
+
+ pub fn new_point(width: f32, height: f32, zoom: Option<f32>, x: f32, y: f32) -> Self {
+ Self {
+ width,
+ height,
+ zoom: zoom.unwrap_or(1 as f32),
+ focus: Some(FocusType::Point(Point::new_2d(x, y)))
+ }
+ }
+
+ pub fn new_node(width: f32, height: f32, zoom: Option<f32>, node: String) -> Self {
+ Self {
+ width,
+ height,
+ zoom: zoom.unwrap_or(1 as f32),
+ focus: Some(FocusType::Node(node))
+ }
+ }
+}
+
+impl<'a> DotString<'a> for ViewPort {
+ fn dot_string(&self) -> Cow<'a, str> {
+ let mut dot_string = String::from("");
+ dot_string.push_str(
+ format!("{:.1},{:.1},{:.1}",
+ self.width, self.height, self.zoom
+ ).as_str());
+
+ if let Some(focus) = &self.focus {
+ match focus {
+ FocusType::Point(p) => {
+ dot_string.push_str(format!(",{}", p.dot_string()).as_str());
+ },
+ FocusType::Node(n) => {
+ dot_string.push_str(format!(",'{}'", n).as_str());
+ },
+ }
+ }
+
+ dot_string.into()
+ }
+}
+
+pub enum FocusType {
+ Point(Point),
+ Node(String)
+}
+
+
+#[cfg(test)]
+mod test {
+ use crate::attributes::{ViewPort};
+ use crate::DotString;
+
+ #[test]
+ fn viewport_dot_string() {
+ assert_eq!(
+ "1.0,2.0,1.0",
+ ViewPort::new(1.0, 2.0, None, None).dot_string()
+ );
+ }
+
+ #[test]
+ fn viewport_zoom_dot_string() {
+ assert_eq!(
+ "1.0,2.0,3.0",
+ ViewPort::new(1.0, 2.0, Some(3.0), None).dot_string()
+ );
+ }
+
+ #[test]
+ fn viewport_point_focus_dot_string() {
+ assert_eq!(
+ "1.0,2.0,3.0,5.0,10.0",
+ ViewPort::new_point(1.0, 2.0, Some(3.0), 5.0, 10.0).dot_string()
+ );
+ }
+
+ #[test]
+ fn viewport_node_focus_dot_string() {
+ assert_eq!(
+ "1.0,2.0,3.0,'2.8 BSD'",
+ ViewPort::new_node(
+ 1.0, 2.0, Some(3.0), String::from("2.8 BSD")
+ ).dot_string()
+ );
+ }
+} \ No newline at end of file