1 module plot2d.chart.box;
2 
3 public import plot2d.chart.base;
4 
5 class BoxChart : BaseChart!BoxStat
6 {
7 protected:
8     override void expandViewport(ref const Elem val, ref bool[2] inited)
9     {
10         if (inited[0])
11         {
12             vp = Viewport.initial(Point(val.tm - val.dtm/2, val.min));
13             inited[0] = true;
14         }
15         else
16         {
17             vp.expand(Point(val.tm - val.dtm/2, val.min));
18             vp.expand(Point(val.tm + val.dtm/2, val.max));
19         }
20     }
21 
22 public:
23     float boxWidth = 0.8;
24     bool strokeBox = false;
25     Color fillUp, fillDown, stroke;
26 
27     this(Color stroke, Color fillUp,
28          Color fillDown, BufferFiller fd)
29     {
30         this.stroke = stroke;
31         this.fillUp = fillUp;
32         this.fillDown = fillDown;
33         super(fd);
34     }
35 
36     override void draw(Ctx cr, Trtor tr)
37     {
38         auto linewidth = style.number.get("linewidth", 1.0);
39         cr.setLineWidth(linewidth);
40 
41         if (buffer.data.length == 0) return;
42 
43         cr.clipViewport(tr.inPadding);
44 
45 
46         foreach (val; buffer.data)
47         {
48             auto bw = Point(val.dtm/2 * boxWidth, 0);
49 
50             cr.setColor(fillUp);
51             cr.lineP2P(
52                 tr.toDA(val.q1Pnt  - bw),
53                 tr.toDA(val.q1Pnt  + bw),
54                 tr.toDA(val.medPnt + bw),
55                 tr.toDA(val.medPnt - bw),
56             );
57             cr.fill();
58 
59             cr.setColor(fillDown);
60             cr.lineP2P(
61                 tr.toDA(val.medPnt - bw),
62                 tr.toDA(val.medPnt + bw),
63                 tr.toDA(val.q3Pnt  + bw),
64                 tr.toDA(val.q3Pnt  - bw),
65             );
66             cr.fill();
67 
68             cr.setColor(stroke);
69             if (strokeBox)
70             {
71                 cr.lineP2P(
72                     tr.toDA(val.q3Pnt - bw),
73                     tr.toDA(val.q1Pnt - bw),
74                     tr.toDA(val.q1Pnt + bw),
75                     tr.toDA(val.q3Pnt + bw),
76                     tr.toDA(val.q3Pnt - bw),
77                 );
78             }
79             cr.lineP2P(
80                 tr.toDA(val.medPnt - bw),
81                 tr.toDA(val.medPnt + bw),
82             );
83             cr.lineP2P(
84                 tr.toDA(val.q1Pnt),
85                 tr.toDA(val.minPnt)
86             );
87             cr.lineP2P(
88                 tr.toDA(val.q3Pnt),
89                 tr.toDA(val.maxPnt)
90             );
91             cr.stroke();
92         }
93     }
94 }