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