Repository: milliams/plotlib (language: rust)

Issue:
Better line style, e.g. rounded corners
In this plot with quite noisy data, you can see a lot of corners of line segments. I think it would be best to draw line segments with rounded corners.

![ss](https://i.imgur.com/BcPFAe7.png)


Discussion / hints:
I tried to add `.set("stroke-linecap", "round")` here: https://github.com/milliams/plotlib/blob/master/src/svg_render.rs#L315

But it doesn't seem to have any effect.
I think this should be a option in the style. I'll have a look into the right SVG commands to make this work.

Fix patch:
diff --git a/CHANGELOG b/CHANGELOG
index b924b71..11d6568 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,6 +4,7 @@
 ### Changed
 - Remove style traits and replace all style structs with 3 common ones in `style`
 - Group all representations under a `repr` module.
+- Add `linejoin` option to line style.
 
 ## 0.4.0 - 2019-03-02
 ### Added
diff --git a/examples/line_svg.rs b/examples/line_svg.rs
index a7007c4..985b39d 100644
--- a/examples/line_svg.rs
+++ b/examples/line_svg.rs
@@ -1,11 +1,14 @@
-use plotlib::repr::Line;
 use plotlib::page::Page;
-use plotlib::style::LineStyle;
+use plotlib::repr::Line;
+use plotlib::style::{LineJoin, LineStyle};
 use plotlib::view::ContinuousView;
 
 fn main() {
-    let l1 = Line::new(&[(0., 1.), (2., 1.5), (3., 1.2), (4., 1.1)])
-        .style(LineStyle::new().colour("burlywood"));
+    let l1 = Line::new(&[(0., 1.), (2., 1.5), (3., 1.2), (4., 1.1)]).style(
+        LineStyle::new()
+            .colour("burlywood")
+            .linejoin(LineJoin::Round),
+    );
     let v = ContinuousView::new().add(&l1);
     Page::single(&v).save("line.svg").expect("saving svg");
 }
diff --git a/src/style.rs b/src/style.rs
index 34b3051..2658dcc 100644
--- a/src/style.rs
+++ b/src/style.rs
@@ -6,16 +6,27 @@
 //! can be overlaid with another one to set many at once.
 //! Settings will be cloned in and out of it.
 
+/**
+The style that line corners should use
+*/
+#[derive(Debug, Clone)]
+pub enum LineJoin {
+    Miter,
+    Round,
+}
+
 #[derive(Debug, Default)]
 pub struct LineStyle {
     colour: Option<String>,
     width: Option<f32>,
+    linejoin: Option<LineJoin>,
 }
 impl LineStyle {
     pub fn new() -> Self {
         LineStyle {
             colour: None,
             width: None,
+            linejoin: None,
         }
     }
 
@@ -27,6 +38,10 @@ impl LineStyle {
         if let Some(ref v) = other.width {
             self.width = Some(*v)
         }
+
+        if let Some(ref v) = other.linejoin {
+            self.linejoin = Some(v.clone())
+        }
     }
     pub fn colour<T>(&mut self, value: T) -> &mut Self
     where
@@ -51,6 +66,18 @@ impl LineStyle {
     pub fn get_width(&self) -> &Option<f32> {
         &self.width
     }
+
+    pub fn linejoin<T>(&mut self, value: T) -> &mut Self
+    where
+        T: Into<LineJoin>,
+    {
+        self.linejoin = Some(value.into());
+        self
+    }
+
+    pub fn get_linejoin(&self) -> &Option<LineJoin> {
+        &self.linejoin
+    }
 }
 
 /**
@@ -157,3 +184,31 @@ impl BoxStyle {
         &self.fill
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_linestyle_simple() {
+        let s = LineStyle::new();
+        assert_eq!(*s.get_colour(), None);
+        assert_eq!(*s.get_width(), None);
+        assert!(match s.get_linejoin() {
+            None => true,
+            _ => false,
+        });
+    }
+
+    #[test]
+    fn test_linestyle_plain_overlay() {
+        let mut p = LineStyle::new();
+        p.overlay(LineStyle::new().colour("red").linejoin(LineJoin::Miter).width(1.));
+        assert_eq!(*p.get_colour(), Some("red".into()));
+        assert_eq!(*p.get_width(), Some(1.));
+        assert!(match p.get_linejoin() {
+            Some(LineJoin::Miter) => true,
+            _ => false,
+        });
+    }
+}
diff --git a/src/svg_render.rs b/src/svg_render.rs
index 2bb18ac..bc2122b 100644
--- a/src/svg_render.rs
+++ b/src/svg_render.rs
@@ -312,6 +312,10 @@ pub fn draw_face_line(
                 style.get_colour().clone().unwrap_or_else(|| "".into()),
             )
             .set("stroke-width", style.get_width().clone().unwrap_or(2.))
+            .set("stroke-linejoin", match style.get_linejoin().clone().unwrap_or(style::LineJoin::Round) {
+                style::LineJoin::Miter => "miter",
+                style::LineJoin::Round => "round",
+            })
             .set("d", path),
     );
 


Test patch: