adic_shape/svg_doc/
clock_svg_doc.rs

1use svg::node::element as svg_el;
2use crate::ClockShape;
3use super::SvgDocDisplay;
4
5
6/// SVG for an adic clock
7///
8/// ```
9/// # use adic::radic;
10/// # use adic_shape::{ClockShape, ClockShapeOptions, SvgDocDisplay};
11/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
12/// let neg_one_fourth = radic!(5, [], [1]);
13/// let num_digits = 6;
14/// let adic_clock = ClockShape::new(&neg_one_fourth, num_digits, ClockShapeOptions::default())?;
15/// let clock_svg = adic_clock.create_svg_doc();
16/// # Ok(()) }
17/// ```
18impl SvgDocDisplay for ClockShape {
19
20    fn shape_style_els(
21        &self,
22    ) -> impl Iterator<Item=svg_el::Element> {
23        clock_style_instructions()
24    }
25
26}
27
28
29fn clock_style_instructions() -> impl Iterator<Item=svg_el::Element> {
30    let style_el = svg_el::Style::new("
31svg {
32    background: var(--clock-svg-background, white);
33}
34svg .clock-circle {
35    fill: transparent;
36    stroke: var(--clock-svg-circle-color, black);
37    stroke-width: 0.2;
38}
39svg .clock-sub-circle {
40    fill: transparent;
41    stroke: var(--clock-svg-sub-circle-color, black);
42    stroke-width: 0.2;
43    stroke-dasharray: 1, 4;
44}
45svg .clock-hand-path {
46    fill: transparent;
47    stroke: var(--clock-svg-hand-color, black);
48    stroke-width: 0.2;
49}
50svg .clock-head-circle {
51    fill: var(--clock-svg-hand-color, black);
52    stroke: var(--clock-svg-hand-color, black);
53    stroke-width: 0.2;
54}
55svg .tick-label {
56    fill: var(--clock-svg-tick-color, black);
57    text-anchor: middle;
58    dominant-baseline: middle;
59}
60"
61    );
62    std::iter::once(svg_el::Element::from(style_el))
63}
64
65
66
67#[cfg(test)]
68mod test {
69
70    use adic::zadic_approx;
71    use crate::{ClockMovement, ClockShape, ClockShapeOptions, SvgDocDisplay};
72
73    #[test]
74    fn basic_clock() {
75
76        let adic_data = zadic_approx!(5, 5, [0, 1, 2, 3, 4]);
77        let shape_options = ClockShapeOptions {
78            clock_movement: ClockMovement::Ticking,
79            show_hand_radii: true,
80            viewbox_width: 100,
81            viewbox_height: 100,
82        };
83
84        // Create the clock
85        let clock_shape = ClockShape::new(&adic_data, 5, shape_options).unwrap();
86
87        let clock = clock_shape.create_svg_doc();
88
89        let expected = [
90            "<svg class=\"adic-clock\" viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\">",
91               "<style>",
92                    "svg {",
93                    "    background: var(--clock-svg-background, white);",
94                    "}",
95                    "svg .clock-circle {",
96                    "    fill: transparent;",
97                    "    stroke: var(--clock-svg-circle-color, black);",
98                    "    stroke-width: 0.2;",
99                    "}",
100                    "svg .clock-sub-circle {",
101                    "    fill: transparent;",
102                    "    stroke: var(--clock-svg-sub-circle-color, black);",
103                    "    stroke-width: 0.2;",
104                    "    stroke-dasharray: 1, 4;",
105                    "}",
106                    "svg .clock-hand-path {",
107                    "    fill: transparent;",
108                    "    stroke: var(--clock-svg-hand-color, black);",
109                    "    stroke-width: 0.2;",
110                    "}",
111                    "svg .clock-head-circle {",
112                    "    fill: var(--clock-svg-hand-color, black);",
113                    "    stroke: var(--clock-svg-hand-color, black);",
114                    "    stroke-width: 0.2;",
115                    "}",
116                    "svg .tick-label {",
117                    "    fill: var(--clock-svg-tick-color, black);",
118                    "    text-anchor: middle;",
119                    "    dominant-baseline: middle;",
120                    "}",
121                "</style>",
122                "<circle class=\"clock-circle\" cx=\"50\" cy=\"50\" r=\"40\"/>",
123                "<circle class=\"clock-sub-circle\" cx=\"50\" cy=\"50\" r=\"6.666666666666666\"/>",
124                "<circle class=\"clock-sub-circle\" cx=\"50\" cy=\"50\" r=\"13.333333333333332\"/>",
125                "<circle class=\"clock-sub-circle\" cx=\"50\" cy=\"50\" r=\"20\"/>",
126                "<circle class=\"clock-sub-circle\" cx=\"50\" cy=\"50\" r=\"26.666666666666664\"/>",
127                "<circle class=\"clock-sub-circle\" cx=\"50\" cy=\"50\" r=\"33.333333333333336\"/>",
128                "<path class=\"clock-hand-path\" d=\"M 50 50 L 50 43.333333333333336\"/>",
129                "<circle class=\"clock-head-circle\" cx=\"50\" cy=\"43.333333333333336\" r=\"0.5\"/>",
130                "<path class=\"clock-hand-path\" d=\"M 50 50 L 62.68075355060205 45.87977340833403\"/>",
131                "<circle class=\"clock-head-circle\" cx=\"62.68075355060205\" cy=\"45.87977340833403\" r=\"0.5\"/>",
132                "<path class=\"clock-hand-path\" d=\"M 50 50 L 61.75570504584947 66.18033988749895\"/>",
133                "<circle class=\"clock-head-circle\" cx=\"61.75570504584947\" cy=\"66.18033988749895\" r=\"0.5\"/>",
134                "<path class=\"clock-hand-path\" d=\"M 50 50 L 34.32572660553406 71.57378651666527\"/>",
135                "<circle class=\"clock-head-circle\" cx=\"34.32572660553406\" cy=\"71.57378651666527\" r=\"0.5\"/>",
136                "<path class=\"clock-hand-path\" d=\"M 50 50 L 18.298116123494875 39.69943352083509\"/>",
137                "<circle class=\"clock-head-circle\" cx=\"18.298116123494875\" cy=\"39.69943352083509\" r=\"0.5\"/>",
138                "<path class=\"clock-hand-path\" d=\"M 50 12 L 50 10\"/>",
139                "<path class=\"clock-hand-path\" d=\"M 86.14014761921584 38.257354213751995 L 88.04226065180615 37.6393202250021\"/>",
140                "<path class=\"clock-hand-path\" d=\"M 72.33583958711398 80.74264578624799 L 73.51141009169893 82.36067977499789\"/>",
141                "<path class=\"clock-hand-path\" d=\"M 27.664160412886027 80.742645786248 L 26.48858990830108 82.3606797749979\"/>",
142                "<path class=\"clock-hand-path\" d=\"M 13.859852380784162 38.257354213752 L 11.957739348193854 37.63932022500211\"/>",
143                "<text class=\"tick-label\" dx=\"0\" dy=\"-4\" style=\"position: fixed; font-size: 4pt;\" x=\"50\" y=\"10\">0</text>",
144                "<text class=\"tick-label\" dx=\"3.8042260651806146\" dy=\"-1.2360679774997898\" style=\"position: fixed; font-size: 4pt;\" x=\"88.04226065180615\" y=\"37.6393202250021\">1</text>",
145                "<text class=\"tick-label\" dx=\"2.3511410091698934\" dy=\"3.2360679774997894\" style=\"position: fixed; font-size: 4pt;\" x=\"73.51141009169893\" y=\"82.36067977499789\">2</text>",
146                "<text class=\"tick-label\" dx=\"-2.351141009169892\" dy=\"3.2360679774997907\" style=\"position: fixed; font-size: 4pt;\" x=\"26.48858990830108\" y=\"82.3606797749979\">3</text>",
147                "<text class=\"tick-label\" dx=\"-3.8042260651806146\" dy=\"-1.2360679774997891\" style=\"position: fixed; font-size: 4pt;\" x=\"11.957739348193854\" y=\"37.63932022500211\">4</text>",
148            "</svg>",
149        ].join("\n");
150
151        for (e, c) in expected.split('\n').zip(clock.to_string().split('\n')) {
152            assert_eq!(e, c);
153        }
154        assert_eq!(expected, clock.to_string());
155
156    }
157
158}