1 #ifndef _ScatterDraw_MarkPlot_h_ 2 #define _ScatterDraw_MarkPlot_h_ 3 4 namespace Upp { 5 6 class MarkPlot { 7 public: MarkPlot()8 MarkPlot() : multiPlot(false), type(0) {} ~MarkPlot()9 virtual ~MarkPlot() noexcept {}; 10 virtual void Paint(Draw &p, const double& , const Point& cp, const double& size, 11 const Color& markColor, const double& markBorderWidth, const Color& markBorderColor) const = 0; Paint(Draw &,const double &,int,int,const Vector<int> &,const Vector<int> &,const Vector<double> &,const double &,const Color &,const double &,const Color &)12 virtual void Paint(Draw &, const double& , int , int , const Vector<int>& , 13 const Vector<int>& , const Vector<double>& , const double& , 14 const Color& , const double& , const Color& ) const {NEVER();}; 15 virtual void Paint(Painter &p, const double& , const Point& cp, const double& size, 16 const Color& markColor, const double& markBorderWidth, const Color& markBorderColor) const = 0; Paint(Painter &,const double &,int,int,const Vector<int> &,const Vector<int> &,const Vector<double> &,const double &,const Color &,const double &,const Color &)17 virtual void Paint(Painter &, const double& , int , int , const Vector<int>& , 18 const Vector<int>& , const Vector<double>& , const double& , 19 const Color& , const double& , const Color& ) const {NEVER();}; 20 template<class T> Register(const String & name)21 static void Register(const String& name) 22 { 23 classMap().FindAdd(name, __Create<T>); 24 typeMap().FindAdd(typeid(T).name(), name); 25 T dummy; 26 typeNumber().Add(dummy.GetTypeCount()); 27 typeString().Add(dummy.TypeString()); 28 } Unregister(const String & name)29 static void Unregister(const String& name) 30 { 31 int i = TypeIndex(name); 32 ASSERT(i >= 0); 33 classMap().Remove(i); 34 typeMap().Remove(i); 35 typeNumber().Remove(i); 36 typeString().Remove(i); 37 } TypeName(int i)38 static String TypeName(int i) {return typeMap()[i];} TypeIndex(const String & name)39 static int TypeIndex(const String& name) {return classMap().Find(name);} GetCount()40 static int GetCount() {return classMap().GetCount();} Create(int i)41 static MarkPlot* Create(int i) {return classMap()[i]();} GetTypes()42 static Vector<String> GetTypes() {return clone(typeMap()).PickValues();} GetType()43 int GetType() const {return typeMap().Find(typeid(*this).name());} 44 MarkPlot* Copy()const; IsMultiPlot()45 bool IsMultiPlot() const {return multiPlot;} 46 GetTypeCount(int iM)47 static int GetTypeCount(int iM) {return typeNumber()[iM];} TypeString(int iM,int iT)48 static String TypeString(int iM, int iT) {return typeString()[iM][iT];} GetTypeCount()49 virtual int GetTypeCount() {return 0;} TypeString()50 virtual const char **TypeString() {return NULL;} 51 SetTypeType(int _type)52 void SetTypeType(int _type) {this->type = _type;} GetTypeType()53 int GetTypeType() {return type;} 54 55 protected: 56 typedef MarkPlot* (*CreateFunc)(); 57 template<class T> __Create()58 static MarkPlot* __Create() {return new T;} classMap()59 static VectorMap<String, CreateFunc>& classMap() {static VectorMap<String, CreateFunc> cMap; return cMap;} typeMap()60 static VectorMap<String, String>& typeMap() {static VectorMap<String, String> tMap; return tMap;} 61 62 bool multiPlot; 63 int type; 64 typeNumber()65 static Vector<int>& typeNumber() {static Vector<int> typeNumber; return typeNumber;} typeString()66 static Vector<const char **>& typeString() {static Vector<const char **> typeString; return typeString;} 67 }; 68 69 class CircleMarkPlot : public MarkPlot { 70 private: 71 template <class T> DoPaint(T & w,const double & scale,const Point & cp,const double & size,const Color & markColor,const double & markBorderWidth,const Color & markBorderColor)72 void DoPaint(T& w, const double& scale, const Point& cp, const double& size, const Color& markColor, 73 const double& markBorderWidth, const Color& markBorderColor) const 74 { 75 int radius = fround(scale*size); 76 int radius2 = radius/2; 77 w.DrawEllipse(cp.x - radius2, cp.y - radius2, radius, radius, markColor, fround(markBorderWidth), markBorderColor); 78 } 79 80 public: Paint(Draw & p,const double & scale,const Point & cp,const double & size,const Color & markColor,const double & markBorderWidth,const Color & markBorderColor)81 void Paint(Draw &p, const double& scale, const Point& cp, const double& size, const Color& markColor, 82 const double& markBorderWidth, const Color& markBorderColor) const 83 { 84 DoPaint(p, scale, cp, size, markColor, markBorderWidth, markBorderColor); 85 } Paint(Painter & p,const double & scale,const Point & cp,const double & size,const Color & markColor,const double & markBorderWidth,const Color & markBorderColor)86 void Paint(Painter &p, const double& scale, const Point& cp, const double& size, const Color& markColor, 87 const double& markBorderWidth, const Color& markBorderColor) const 88 { 89 DoPaint(p, scale, cp, size, markColor, markBorderWidth, markBorderColor); 90 } 91 }; 92 93 class SquareMarkPlot : public MarkPlot { 94 private: 95 template <class T> DoPaint(T & w,const double & scale,const Point & cp,const double & size,const Color & markColor,const double & markBorderWidth,const Color & markBorderColor)96 void DoPaint(T& w, const double& scale, const Point& cp, const double& size, const Color& markColor, 97 const double& markBorderWidth, const Color& markBorderColor) const 98 { 99 Vector <Point> p; 100 int side2l = int((size*scale)/2.); 101 int side2r = int(size*scale - side2l); 102 p << Point(cp.x - side2l, cp.y - side2l) << Point(cp.x + side2r, cp.y - side2l) 103 << Point(cp.x + side2r, cp.y + side2r) << Point(cp.x - side2l, cp.y + side2r) 104 << Point(cp.x - side2l, cp.y - side2l); 105 w.DrawPolygon(p, markColor, fround(markBorderWidth), markBorderColor); 106 } 107 108 public: Paint(Draw & p,const double & scale,const Point & cp,const double & size,const Color & markColor,const double & markBorderWidth,const Color & markBorderColor)109 void Paint(Draw &p, const double& scale, const Point& cp, const double& size, const Color& markColor, 110 const double& markBorderWidth, const Color& markBorderColor) const 111 { 112 DoPaint(p, scale, cp, size, markColor, markBorderWidth, markBorderColor); 113 } Paint(Painter & p,const double & scale,const Point & cp,const double & size,const Color & markColor,const double & markBorderWidth,const Color & markBorderColor)114 void Paint(Painter &p, const double& scale, const Point& cp, const double& size, const Color& markColor, 115 const double& markBorderWidth, const Color& markBorderColor) const 116 { 117 DoPaint(p, scale, cp, size, markColor, markBorderWidth, markBorderColor); 118 } 119 }; 120 121 class TriangleMarkPlot : public MarkPlot { 122 private: 123 template <class T> DoPaint(T & w,const double & scale,const Point & cp,const double & size,const Color & markColor,const double & markBorderWidth,const Color & markBorderColor)124 void DoPaint(T& w, const double& scale, const Point& cp, const double& size, const Color& markColor, 125 const double& markBorderWidth, const Color& markBorderColor) const 126 { 127 Vector <Point> p; 128 int xl = int((size*scale)/2.); 129 int xr = int(size*scale - xl); 130 int yt = int(size*scale*2/3.); 131 int yb = int(size*scale - yt); 132 p << Point(cp.x - xl, cp.y + yb) << Point(cp.x + xr, cp.y + yb) 133 << Point(cp.x, cp.y - yt) << Point(cp.x - xl, cp.y + yb); 134 w.DrawPolygon(p, markColor, fround(markBorderWidth), markBorderColor); 135 } 136 137 public: Paint(Draw & p,const double & scale,const Point & cp,const double & size,const Color & markColor,const double & markBorderWidth,const Color & markBorderColor)138 void Paint(Draw &p, const double& scale, const Point& cp, const double& size, const Color& markColor, 139 const double& markBorderWidth, const Color& markBorderColor) const 140 { 141 DoPaint(p, scale, cp, size, markColor, markBorderWidth, markBorderColor); 142 } Paint(Painter & p,const double & scale,const Point & cp,const double & size,const Color & markColor,const double & markBorderWidth,const Color & markBorderColor)143 void Paint(Painter &p, const double& scale, const Point& cp, const double& size, const Color& markColor, 144 const double& markBorderWidth, const Color& markBorderColor) const 145 { 146 DoPaint(p, scale, cp, size, markColor, markBorderWidth, markBorderColor); 147 } 148 }; 149 150 class CrossMarkPlot : public MarkPlot { 151 private: 152 template <class T> DoPaint(T & w,const double & scale,const Point & cp,const double & size,const Color & markColor)153 void DoPaint(T& w, const double& scale, const Point& cp, const double& size, const Color& markColor) const 154 { 155 int side2l = int((size*scale)/2.); 156 int side2r = int(size*scale - side2l); 157 w.DrawLine(cp.x - side2l, cp.y, cp.x + side2r, cp.y, fround(scale), markColor); 158 w.DrawLine(cp.x, cp.y - side2l, cp.x, cp.y + side2r, fround(scale), markColor); 159 } 160 161 public: Paint(Draw & p,const double & scale,const Point & cp,const double & size,const Color & markColor,const double &,const Color &)162 void Paint(Draw &p, const double& scale, const Point& cp, const double& size, const Color& markColor, 163 const double& , const Color& ) const 164 { 165 DoPaint(p, scale, cp, size, markColor); 166 } Paint(Painter & p,const double & scale,const Point & cp,const double & size,const Color & markColor,const double &,const Color &)167 void Paint(Painter &p, const double& scale, const Point& cp, const double& size, const Color& markColor, 168 const double& , const Color& ) const 169 { 170 DoPaint(p, scale, cp, size, markColor); 171 } 172 }; 173 174 class XMarkPlot : public MarkPlot { 175 private: 176 template <class T> DoPaint(T & w,const double & scale,const Point & cp,const double & size,const Color & markColor)177 void DoPaint(T& w, const double& scale, const Point& cp, const double& size, const Color& markColor) const 178 { 179 int side2l = int((size*scale)/2.); 180 int side2r = int(size*scale - side2l); 181 w.DrawLine(cp.x - side2l, cp.y - side2l, cp.x + side2r, cp.y + side2r, fround(scale), markColor); 182 w.DrawLine(cp.x + side2r, cp.y - side2l, cp.x - side2l, cp.y + side2r, fround(scale), markColor); 183 } 184 185 public: Paint(Draw & p,const double & scale,const Point & cp,const double & size,const Color & markColor,const double &,const Color &)186 void Paint(Draw &p, const double& scale, const Point& cp, const double& size, const Color& markColor, 187 const double& , const Color& ) const 188 { 189 DoPaint(p, scale, cp, size, markColor); 190 } Paint(Painter & p,const double & scale,const Point & cp,const double & size,const Color & markColor,const double &,const Color &)191 void Paint(Painter &p, const double& scale, const Point& cp, const double& size, const Color& markColor, 192 const double& , const Color& ) const 193 { 194 DoPaint(p, scale, cp, size, markColor); 195 } 196 }; 197 198 class RhombMarkPlot : public MarkPlot { 199 private: 200 template <class T> DoPaint(T & w,const double & scale,const Point & cp,const double & size,const Color & markColor)201 void DoPaint(T& w, const double& scale, const Point& cp, const double& size, const Color& markColor) const 202 { 203 Vector <Point> p; 204 int side2l = int((size*scale)/2.); 205 int side2r = int(size*scale - side2l); 206 p << Point(cp.x, cp.y - side2l) << Point(cp.x + side2r, cp.y) 207 << Point(cp.x, cp.y + side2r) << Point(cp.x - side2l, cp.y) 208 << Point(cp.x, cp.y - side2l); 209 w.DrawPolygon(p, markColor, fround(scale/2.), markColor); 210 } 211 212 public: Paint(Draw & p,const double & scale,const Point & cp,const double & size,const Color & markColor,const double &,const Color &)213 void Paint(Draw &p, const double& scale, const Point& cp, const double& size, const Color& markColor, 214 const double& , const Color& ) const 215 { 216 DoPaint(p, scale, cp, size, markColor); 217 } Paint(Painter & p,const double & scale,const Point & cp,const double & size,const Color & markColor,const double &,const Color &)218 void Paint(Painter &p, const double& scale, const Point& cp, const double& size, const Color& markColor, 219 const double& , const Color& ) const 220 { 221 DoPaint(p, scale, cp, size, markColor); 222 } 223 }; 224 225 //void debug_h(); // Dummy function used to debug .h files 226 227 class RangePlot : public MarkPlot { 228 public: 229 enum RangeType {ALL, MIN_MAX, MIN_AVG_MAX}; 230 RangePlot(RangeType rangeType = ALL) { 231 type = rangeType; 232 multiPlot = true; 233 } GetTypeCount()234 virtual int GetTypeCount() {return 3;} TypeString()235 virtual const char **TypeString() { 236 static const char *names[] = {"ALL", "MIN_MAX", "MIN_AVG_MAX"}; 237 return names; 238 } 239 240 private: 241 template <class T> DoPaint(T & w,const double & scale,int x,int y,const Vector<int> & dataX,const Vector<int> & dataY,const double & size,const Color & markColor)242 void DoPaint(T& w, const double& scale, int x, int y, const Vector<int>& dataX, 243 const Vector<int>& dataY, const double& size, const Color& markColor) const 244 { 245 int side2l = int((size*scale)/2.); 246 int side2r = int(size*scale - side2l); 247 const Vector<int> *pdata; 248 if (!dataY.IsEmpty()) 249 pdata = &dataY; 250 else 251 pdata = &dataX; 252 if (pdata->GetCount() == 0) 253 return; 254 int avg = 0; 255 int min = INT_MAX; 256 int max = INT_MIN; 257 for (int i = 0; i < pdata->GetCount(); ++i) { 258 if (min > (*pdata)[i]) 259 min = (*pdata)[i]; 260 if (max < (*pdata)[i]) 261 max = (*pdata)[i]; 262 } 263 if (type == MIN_AVG_MAX) { 264 for (int i = 0; i < pdata->GetCount(); ++i) 265 avg += (*pdata)[i]; 266 avg /= pdata->GetCount(); 267 } 268 if (!dataY.IsEmpty()) { 269 if (type == ALL) { 270 for (int i = 0; i < dataY.GetCount(); ++i) 271 w.DrawLine(x - side2l, dataY[i], x + side2r, dataY[i], fround(scale), markColor); 272 } else { 273 w.DrawLine(x - side2l, min, x + side2r, min, fround(scale), markColor); 274 w.DrawLine(x - side2l, max, x + side2r, max, fround(scale), markColor); 275 if (type == MIN_AVG_MAX) 276 w.DrawLine(x - side2l, avg, x + side2r, avg, fround(scale*4), markColor); 277 } 278 w.DrawLine(x, min, x, max, fround(scale), markColor); 279 } else { 280 if (type == ALL) { 281 for (int i = 0; i < dataX.GetCount(); ++i) 282 w.DrawLine(dataX[i], y - side2l, dataX[i], y + side2r, fround(scale), markColor); 283 } else { 284 w.DrawLine(min, y - side2l, min, y + side2r, fround(scale), markColor); 285 w.DrawLine(max, y - side2l, max, y + side2r, fround(scale), markColor); 286 if (type == MIN_AVG_MAX) 287 w.DrawLine(avg, y - side2l, avg, y + side2r, fround(scale*4), markColor); 288 } 289 w.DrawLine(min, y, max, y, fround(scale), markColor); 290 } 291 } 292 293 public: Paint(Draw & p,const double & scale,int x,int y,const Vector<int> & dataX,const Vector<int> & dataY,const Vector<double> &,const double & size,const Color & markColor,const double &,const Color &)294 virtual void Paint(Draw &p, const double& scale, int x, int y, const Vector<int>& dataX, 295 const Vector<int>& dataY, const Vector<double>& , const double& size, 296 const Color& markColor, const double& , const Color& ) const 297 { 298 DoPaint(p, scale, x, y, dataX, dataY, size, markColor); 299 } Paint(Painter & p,const double & scale,int x,int y,const Vector<int> & dataX,const Vector<int> & dataY,const Vector<double> &,const double & size,const Color & markColor,const double &,const Color &)300 virtual void Paint(Painter &p, const double& scale, int x, int y, const Vector<int>& dataX, 301 const Vector<int>& dataY, const Vector<double>& , const double& size, 302 const Color& markColor, const double& , const Color& ) const 303 { 304 DoPaint(p, scale, x, y, dataX, dataY, size, markColor); 305 } Paint(Draw &,const double &,const Point &,const double &,const Color &,const double &,const Color &)306 void Paint(Draw &, const double& , const Point& , const double& , const Color& , 307 const double& , const Color& ) const 308 {} Paint(Painter &,const double &,const Point &,const double &,const Color &,const double &,const Color &)309 void Paint(Painter &, const double& , const Point& , const double& , const Color& , 310 const double& , const Color& ) const 311 {} 312 }; 313 314 class BubblePlot : public MarkPlot { 315 private: 316 template <class T> DoPaint(T & w,const double & scale,int x,int y,const Vector<double> & dataFixed,const double &,const Color & markColor,const double & markBorderWidth,const Color & markBorderColor)317 void DoPaint(T& w, const double& scale, int x, int y, const Vector<double>& dataFixed, const double& , 318 const Color& markColor, const double& markBorderWidth, const Color& markBorderColor) const 319 { 320 if (dataFixed.IsEmpty()) 321 return; 322 int diameter = int(scale*dataFixed[0]); 323 int radius = int(scale*dataFixed[0]/2.); 324 w.DrawEllipse(x - radius, y - radius, diameter, diameter, markColor, fround(markBorderWidth), markBorderColor); 325 } 326 327 public: BubblePlot()328 BubblePlot() {multiPlot = true;} Paint(Draw & p,const double & scale,int x,int y,const Vector<int> &,const Vector<int> &,const Vector<double> & dataFixed,const double & size,const Color & markColor,const double & markBorderWidth,const Color & markBorderColor)329 virtual void Paint(Draw &p, const double& scale, int x, int y, const Vector<int>& , 330 const Vector<int>& , const Vector<double>& dataFixed, const double& size, 331 const Color& markColor, const double& markBorderWidth, const Color& markBorderColor) const 332 { 333 DoPaint(p, scale, x, y, dataFixed, size, markColor, markBorderWidth, markBorderColor); 334 } Paint(Painter & p,const double & scale,int x,int y,const Vector<int> &,const Vector<int> &,const Vector<double> & dataFixed,const double & size,const Color & markColor,const double & markBorderWidth,const Color & markBorderColor)335 virtual void Paint(Painter &p, const double& scale, int x, int y, const Vector<int>& , 336 const Vector<int>& , const Vector<double>& dataFixed, const double& size, 337 const Color& markColor, const double& markBorderWidth, const Color& markBorderColor) const 338 { 339 DoPaint(p, scale, x, y, dataFixed, size, markColor, markBorderWidth, markBorderColor); 340 } Paint(Draw &,const double &,const Point &,const double &,const Color &,const double &,const Color &)341 void Paint(Draw &, const double& , const Point& , const double& , const Color& , 342 const double& , const Color& ) const 343 {} Paint(Painter &,const double &,const Point &,const double &,const Color &,const double &,const Color &)344 void Paint(Painter &, const double& , const Point& , const double& , const Color& , 345 const double& , const Color& ) const 346 {} 347 }; 348 349 } 350 351 #endif 352