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 }