1 module plot2d.chart.tre; 2 3 public import plot2d.chart.base; 4 5 /// 6 class TreChart : BaseChart!TreStat 7 { 8 protected: 9 override void expandViewport(ref const Elem val, ref bool[2] inited) 10 { 11 if (val.tm == val.tm) 12 { 13 if (inited[0]) 14 { 15 vp.w.min.set!min(val.tm); 16 vp.w.max.set!max(val.tm); 17 } 18 else 19 { 20 vp.w.min = val.tm; 21 vp.w.max = val.tm; 22 inited[0] = true; 23 } 24 } 25 if (val.min == val.min && val.max == val.max) 26 { 27 if (inited[1]) 28 { 29 vp.h.min.set!min(val.min); 30 vp.h.max.set!max(val.max); 31 } 32 else 33 { 34 vp.h.min = val.min; 35 vp.h.max = val.max; 36 inited[1] = true; 37 } 38 } 39 } 40 41 public: 42 43 Color fillUp, fillDown, stroke, strokeLimUp, strokeLimDown; 44 45 bool skipNaN = true; 46 bool verticalCap = true; 47 48 double disaster; 49 double disasterCoef = 3; // must be > 1 50 51 this(Color stroke, 52 Color strokeLimUp, Color fillUp, 53 Color strokeLimDown, Color fillDown, 54 BufferFiller fd) 55 { 56 this.stroke = stroke; 57 this.fillUp = fillUp; 58 this.fillDown = fillDown; 59 this.strokeLimUp = strokeLimUp; 60 this.strokeLimDown = strokeLimDown; 61 super(fd); 62 } 63 64 override 65 { 66 void update() 67 { 68 super.update(); 69 if (buffer.data.length == 0) return; 70 71 auto avg_diff = 0.0; 72 foreach (a, b; lockstep(buffer.data[0..$-1], buffer.data[1..$])) 73 avg_diff += b.tm - a.tm; 74 avg_diff /= buffer.data.length; 75 disaster = avg_diff * disasterCoef; 76 } 77 78 void draw(Ctx cr, Trtor tr) 79 { 80 auto limlinewidth = style.number.get("limlinewidth", 1); 81 auto linewidth = style.number.get("linewidth", 2); 82 83 auto buf = buffer.data.filter!(a=>skipNaN?a.check:true); 84 85 if (buf.empty) return; 86 87 cr.clipViewport(tr.inPadding); 88 89 auto lst = buf.front; 90 buf.popFront; 91 92 void vcap(typeof(lst) p) 93 { 94 cr.setLineWidth(limlinewidth); 95 cr.setColor(strokeLimUp); 96 cr.lineP2P(tr.toDA(p.valPnt), tr.toDA(p.maxPnt)); 97 cr.stroke(); 98 99 cr.setColor(strokeLimDown); 100 cr.lineP2P(tr.toDA(p.valPnt), tr.toDA(p.minPnt)); 101 cr.stroke(); 102 103 cr.setLineWidth(linewidth); 104 cr.setColor(stroke); 105 cr.lineP2P(tr.toDA(p.valPnt)-Point(1,0), 106 tr.toDA(p.valPnt)+Point(1,0)); 107 cr.stroke(); 108 } 109 110 foreach (val; buf) 111 { 112 if (verticalCap) 113 { 114 if (!lst.check && val.check) vcap(val); 115 else 116 if (lst.check && !val.check) vcap(lst); 117 } 118 119 if (!skipNaN && !(val.check && lst.check)) 120 { 121 lst = val; 122 continue; 123 } 124 //if (val.tm - lst.tm > disaster) 125 //{ lst = val; continue; } 126 127 cr.setColor(fillUp); 128 cr.lineP2P(tr.toDA(lst.maxPnt), 129 tr.toDA(lst.valPnt), 130 tr.toDA(val.maxPnt)); 131 cr.fill(); 132 cr.lineP2P(tr.toDA(lst.valPnt), 133 tr.toDA(val.maxPnt), 134 tr.toDA(val.valPnt)); 135 cr.fill(); 136 137 cr.setColor(fillDown); 138 cr.lineP2P(tr.toDA(lst.valPnt), 139 tr.toDA(lst.minPnt), 140 tr.toDA(val.valPnt)); 141 cr.fill(); 142 cr.lineP2P(tr.toDA(lst.minPnt), 143 tr.toDA(val.valPnt), 144 tr.toDA(val.minPnt)); 145 cr.fill(); 146 147 cr.setLineWidth(limlinewidth); 148 149 cr.setColor(strokeLimUp); 150 cr.lineP2P(tr.toDA(lst.maxPnt), tr.toDA(val.maxPnt)); 151 cr.stroke(); 152 153 cr.setColor(strokeLimDown); 154 cr.lineP2P(tr.toDA(lst.minPnt), tr.toDA(val.minPnt)); 155 cr.stroke(); 156 157 cr.setLineWidth(linewidth); 158 cr.setColor(stroke); 159 cr.lineP2P(tr.toDA(lst.valPnt), tr.toDA(val.valPnt)); 160 cr.stroke(); 161 162 lst = val; 163 } 164 } 165 } 166 }