graph.h
1 /***************************************************************************
2  Copyright (C) 2002-2015 Kentaro Kitagawa
3  kitagawa@phys.s.u-tokyo.ac.jp
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  You should have received a copy of the GNU Library General
11  Public License and a list of authors along with this program;
12  see the files COPYING and AUTHORS.
13 ***************************************************************************/
14 #ifndef graphH
15 #define graphH
16 
17 #include "xnode.h"
18 #include "xlistnode.h"
19 #include "xitemnode.h"
20 
21 #include <vector>
22 #include <deque>
23 
24 #include <qcolor.h>
25 #define clWhite (unsigned int)QColor(Qt::white).rgb()
26 #define clRed (unsigned int)QColor(Qt::red).rgb()
27 #define clLime (unsigned int)QColor(Qt::darkYellow).rgb()
28 #define clAqua (unsigned int)QColor(Qt::cyan).rgb()
29 #define clBlack (unsigned int)QColor(Qt::black).rgb()
30 #define clGreen (unsigned int)QColor(Qt::green).rgb()
31 #define clBlue (unsigned int)QColor(Qt::blue).rgb()
32 
33 template <typename T>
34 struct Vector4 {
35  Vector4() : x(0), y(0), z(0), w(1) {}
36  Vector4(const Vector4 &v) : x(v.x), y(v.y), z(v.z), w(v.w) {}
37  Vector4(T nx, T ny, T nz = 0, T nw = 1) : x(nx), y(ny), z(nz), w(nw) {}
38  T x, y, z, w;
39  //! operators below do not take weights into account.
40  bool operator==(const Vector4 &s1) const {return ((x == s1.x) && (y == s1.y) && (z == s1.z));}
41  Vector4 &operator+=(const Vector4<T> &s1) {
42  x += s1.x; y += s1.y; z += s1.z;
43  return *this;
44  }
45  Vector4 &operator-=(const Vector4 &s1) {
46  x -= s1.x; y -= s1.y; z -= s1.z;
47  return *this;
48  }
49  Vector4 &operator*=(T k) {
50  x *= k; y *= k; z *= k;
51  return *this;
52  }
53  //! square of distance between this and a point
54  T distance2(const Vector4 &s1) const {
55  T x1 = x - s1.x;
56  T y1 = y - s1.y;
57  T z1 = z - s1.z;
58  return x1*x1 + y1*y1 + z1*z1;
59  }
60  //! square of distance between this and a line from s1 to s2
61  T distance2(const Vector4 &s1, const Vector4 &s2) const {
62  T x1 = x - s1.x;
63  T y1 = y - s1.y;
64  T z1 = z - s1.z;
65  T x2 = s2.x - s1.x;
66  T y2 = s2.y - s1.y;
67  T z2 = s2.z - s1.z;
68  T zbab = x1*x2 + y1*y2 + z1*z2;
69  T ab2 = x2*x2 + y2*y2 + z2*z2;
70  T zb2 = x1*x1 + y1*y1 + z1*z1;
71  return (zb2*ab2 - zbab*zbab) / ab2;
72  }
73  void normalize() {
74  T ir = (T)1.0 / sqrtf(x*x + y*y + z*z);
75  x *= ir; y *= ir; z *= ir;
76  }
77  Vector4 &vectorProduct(const Vector4 &s1) {
78  Vector4 s2;
79  s2.x = y * s1.z - z * s1.y;
80  s2.y = z * s1.x - x * s1.z;
81  s2.z = x * s1.y - y * s1.x;
82  *this = s2;
83  return *this;
84  }
85  T innerProduct(const Vector4 &s1) const {
86  return x * s1.x + y * s1.y + z * s1.z;
87  }
88 };
89 
90 class XAxis;
91 class XGraph;
92 class XPlot;
93 
94 class XQGraphPainter;
95 
98 
99 //! XGraph object can have one or more plots and two or more axes.
100 //! \sa XPlot, XAxis, XQGraphPainter
101 class DECLSPEC_KAME XGraph : public XNode {
102 public:
103  XGraph(const char *name, bool runtime);
104  virtual XString getLabel() const {return ( **label())->to_str();}
105 
106  typedef float SFloat;
107  static const SFloat SFLOAT_MAX;
108  typedef float GFloat;
109  static const GFloat GFLOAT_MAX;
110  typedef double VFloat;
111  static const VFloat VFLOAT_MAX;
112  typedef Vector4<SFloat> ScrPoint;
113  typedef Vector4<GFloat> GPoint;
114  typedef Vector4<VFloat> ValPoint;
115 
116  //! Fixes axes and performs autoscaling of the axes.
117  //! Call this function before redrawal of the graph.
118  void setupRedraw(Transaction &tr, float resolution);
119 
120  void zoomAxes(Transaction &tr, float resolution, XGraph::SFloat zoomscale,
121  const XGraph::ScrPoint &zoomcenter);
122 
123  const shared_ptr<XAxisList> &axes() const {return m_axes;}
124  const shared_ptr<XPlotList> &plots() const {return m_plots;}
125 
126  const shared_ptr<XStringNode> &label() const {return m_label;}
127  const shared_ptr<XHexNode> &backGround() const {return m_backGround;}
128  const shared_ptr<XHexNode> &titleColor() const {return m_titleColor;}
129 
130  const shared_ptr<XBoolNode> &drawLegends() const {return m_drawLegends;}
131 
132  const shared_ptr<XDoubleNode> &persistence() const {return m_persistence;}
133 
134  const shared_ptr<XListener> &lsnPropertyChanged() const {return m_lsnPropertyChanged;}
135 
136  struct Payload : public XNode::Payload {
137  Talker<XGraph*> &onUpdate() {return m_tlkOnUpdate;}
138  const Talker<XGraph*> &onUpdate() const {return m_tlkOnUpdate;}
139  private:
140  TalkerSingleton<XGraph*> m_tlkOnUpdate;
141  };
142 
143 protected:
144 private:
145  void onPropertyChanged(const Snapshot &shot, XValueNodeBase *);
146 
147  const shared_ptr<XStringNode> m_label;
148  const shared_ptr<XAxisList> m_axes;
149  const shared_ptr<XPlotList> m_plots;
150  const shared_ptr<XHexNode> m_backGround;
151  const shared_ptr<XHexNode> m_titleColor;
152  const shared_ptr<XBoolNode> m_drawLegends;
153  const shared_ptr<XDoubleNode> m_persistence;
154 
155  shared_ptr<XListener> m_lsnPropertyChanged;
156 };
157 
158 class DECLSPEC_KAME XPlot : public XNode {
159 public:
160  XPlot(const char *name, bool runtime, Transaction &tr_graph, const shared_ptr<XGraph> &graph);
161  virtual XString getLabel() const {return ( **label())->to_str();}
162 
163  virtual void clearAllPoints(Transaction &tr) = 0;
164 
165  //! obtains values from screen coordinate
166  //! if \a scr_prec > 0, value will be rounded around scr_prec
167  //! \sa XAxis::AxisToVal.
168  int screenToVal(const Snapshot &shot, const XGraph::ScrPoint &scr, XGraph::ValPoint *val,
169  XGraph::SFloat scr_prec = -1);
170  void screenToGraph(const Snapshot &shot, const XGraph::ScrPoint &pt, XGraph::GPoint *g);
171  void graphToScreen(const Snapshot &shot, const XGraph::GPoint &pt, XGraph::ScrPoint *scr);
172  void graphToVal(const Snapshot &shot, const XGraph::GPoint &pt, XGraph::ValPoint *val);
173 
174  const shared_ptr<XStringNode> &label() const {return m_label;}
175 
176  const shared_ptr<XUIntNode> &maxCount() const {return m_maxCount;}
177  const shared_ptr<XBoolNode> &displayMajorGrid() const {return m_displayMajorGrid;}
178  const shared_ptr<XBoolNode> &displayMinorGrid() const {return m_displayMinorGrid;}
179  const shared_ptr<XBoolNode> &drawLines() const {return m_drawLines;}
180  const shared_ptr<XBoolNode> &drawBars() const {return m_drawBars;}
181  const shared_ptr<XBoolNode> &drawPoints() const {return m_drawPoints;}
182  const shared_ptr<XBoolNode> &colorPlot() const {return m_colorPlot;}
183  const shared_ptr<XHexNode> &majorGridColor() const {return m_majorGridColor;}
184  const shared_ptr<XHexNode> &minorGridColor() const {return m_minorGridColor;}
185  const shared_ptr<XHexNode> &pointColor() const {return m_pointColor;}
186  const shared_ptr<XHexNode> &lineColor() const {return m_lineColor;}
187  const shared_ptr<XHexNode> &barColor() const {return m_barColor;}//, BarInnerColor;
188  const shared_ptr<XHexNode> &colorPlotColorHigh() const {return m_colorPlotColorHigh;}
189  const shared_ptr<XHexNode> &colorPlotColorLow() const {return m_colorPlotColorLow;}
190  const shared_ptr<XTouchableNode> &clearPoints() const {return m_clearPoints;}
191  const shared_ptr<XItemNode<XAxisList, XAxis> > &axisX() const {return m_axisX;}
192  const shared_ptr<XItemNode<XAxisList, XAxis> > &axisY() const {return m_axisY;}
193  const shared_ptr<XItemNode<XAxisList, XAxis> > &axisZ() const {return m_axisZ;}
194  const shared_ptr<XItemNode<XAxisList, XAxis> > &axisW() const {return m_axisW;}
195  //! z value without AxisZ
196  const shared_ptr<XDoubleNode> &zwoAxisZ() const {return m_zwoAxisZ;}
197  const shared_ptr<XDoubleNode> &intensity() const {return m_intensity;}
198 
199  //! auto-scale
200  virtual int validateAutoScale(const Snapshot &shot);
201  //! Draws points from snapshot
202  int drawPlot(const Snapshot &shot, XQGraphPainter *painter);
203  //! Draws a point for legneds.
204  //! \a spt the center of the point.
205  //! \a dx,dy the size of the area.
206  int drawLegend(const Snapshot &shot, XQGraphPainter *painter, const XGraph::ScrPoint &spt, float dx, float dy);
207  void drawGrid(const Snapshot &shot, XQGraphPainter *painter, bool drawzaxis = true);
208  //! Takes a snap-shot all points for rendering
209  virtual void snapshot(const Snapshot &shot) = 0;
210 
211  //! \return found index, if not return -1
212  int findPoint(const Snapshot &shot, int start, const XGraph::GPoint &gmin, const XGraph::GPoint &gmax,
213  XGraph::GFloat width, XGraph::ValPoint *val, XGraph::GPoint *g1);
214 
215  //! \return success or not
216  bool fixScales(const Snapshot &);
217 
218  struct Payload : public XNode::Payload {
219  };
220 protected:
221  const weak_ptr<XGraph> m_graph;
222  shared_ptr<XAxis> m_curAxisX, m_curAxisY, m_curAxisZ, m_curAxisW;
223 
224  XGraph::ScrPoint m_scr0;
225  XGraph::ScrPoint m_len;
226  std::vector<XGraph::ValPoint> m_ptsSnapped;
227 
228 private:
229  struct tCanvasPoint {
230  XGraph::GPoint graph; XGraph::ScrPoint scr; bool insidecube; unsigned int color;
231  };
232 
233  const shared_ptr<XStringNode> m_label;
234 
235  const shared_ptr<XUIntNode> m_maxCount;
236  const shared_ptr<XBoolNode> m_displayMajorGrid;
237  const shared_ptr<XBoolNode> m_displayMinorGrid;
238  const shared_ptr<XBoolNode> m_drawLines;
239  const shared_ptr<XBoolNode> m_drawBars;
240  const shared_ptr<XBoolNode> m_drawPoints;
241  const shared_ptr<XBoolNode> m_colorPlot;
242  const shared_ptr<XHexNode> m_majorGridColor;
243  const shared_ptr<XHexNode> m_minorGridColor;
244  const shared_ptr<XHexNode> m_pointColor;
245  const shared_ptr<XHexNode> m_lineColor;
246  const shared_ptr<XHexNode> m_barColor;//, BarInnerColor;
247  const shared_ptr<XHexNode> m_colorPlotColorHigh;
248  const shared_ptr<XHexNode> m_colorPlotColorLow;
249  const shared_ptr<XTouchableNode> m_clearPoints;
250  const shared_ptr<XItemNode<XAxisList, XAxis> > m_axisX;
251  const shared_ptr<XItemNode<XAxisList, XAxis> > m_axisY;
252  const shared_ptr<XItemNode<XAxisList, XAxis> > m_axisZ;
253  const shared_ptr<XItemNode<XAxisList, XAxis> > m_axisW;
254  //! z value without AxisZ
255  const shared_ptr<XDoubleNode> m_zwoAxisZ;
256  const shared_ptr<XDoubleNode> m_intensity;
257 
258  shared_ptr<XListener> m_lsnClearPoints;
259 
260  void onClearPoints(const Snapshot &, XTouchableNode *);
261 
262  inline bool clipLine(const tCanvasPoint &c1, const tCanvasPoint &c2,
264  bool blendcolor, unsigned int *color1, unsigned int *color2, float *alpha1, float *alpha2);
265  inline bool isPtIncluded(const XGraph::GPoint &pt);
266 
267  void drawGrid(const Snapshot &shot,
268  XQGraphPainter *painter, shared_ptr<XAxis> &axis1, shared_ptr<XAxis> &axis2);
269 
270  std::vector<tCanvasPoint> m_canvasPtsSnapped;
271  inline void graphToScreenFast(const XGraph::GPoint &pt, XGraph::ScrPoint *scr);
272  inline void valToGraphFast(const XGraph::ValPoint &pt, XGraph::GPoint *gr);
273  inline unsigned int blendColor(unsigned int c1, unsigned int c2, float t);
274 };
275 
276 class DECLSPEC_KAME XAxis : public XNode {
277 public:
278  enum AxisDirection {DirAxisX, DirAxisY, DirAxisZ, AxisWeight};
279  enum Tic {MajorTic, MinorTic, NoTics};
280 
281  XAxis(const char *name, bool runtime,
282  AxisDirection dir, bool rightOrTop, Transaction &tr_graph, const shared_ptr<XGraph> &graph);
283  virtual ~XAxis() {}
284 
285  virtual XString getLabel() const {return ( **label())->to_str();}
286 
287  int drawAxis(const Snapshot &shot, XQGraphPainter *painter);
288  //! obtains axis pos from value
289  XGraph::GFloat valToAxis(XGraph::VFloat value);
290  //! obtains value from position on axis
291  //! \param pos normally, 0 < \a pos < 1
292  //! \param axis_prec precision on axis. if > 0, value will be rounded
293  XGraph::VFloat axisToVal(XGraph::GFloat pos, XGraph::GFloat axis_prec = -1);
294  //! obtains axis pos from screen coordinate
295  //! \return pos in axis
296  XGraph::GFloat screenToAxis(const Snapshot &shot, const XGraph::ScrPoint &scr);
297  //! obtains screen position from axis
298  void axisToScreen(const Snapshot &shot, XGraph::GFloat pos, XGraph::ScrPoint *scr);
299  void valToScreen(const Snapshot &shot, XGraph::VFloat val, XGraph::ScrPoint *scr);
300  XGraph::VFloat screenToVal(const Snapshot &shot, const XGraph::ScrPoint &scr);
301 
302  XString valToString(XGraph::VFloat val);
303 
304  const shared_ptr<XStringNode> &label() const {return m_label;}
305 
306  const shared_ptr<XDoubleNode> &x() const {return m_x;}
307  const shared_ptr<XDoubleNode> &y() const {return m_y;}
308  const shared_ptr<XDoubleNode> &z() const {return m_z;} // in screen coordinate
309  const shared_ptr<XDoubleNode> &length() const {return m_length;} // in screen coordinate
310  const shared_ptr<XDoubleNode> &majorTicScale() const {return m_majorTicScale;}
311  const shared_ptr<XDoubleNode> &minorTicScale() const {return m_minorTicScale;}
312  const shared_ptr<XBoolNode> &displayMajorTics() const {return m_displayMajorTics;}
313  const shared_ptr<XBoolNode> &displayMinorTics() const {return m_displayMinorTics;}
314  const shared_ptr<XDoubleNode> &maxValue() const {return m_max;}
315  const shared_ptr<XDoubleNode> &minValue() const {return m_min;}
316  const shared_ptr<XBoolNode> &rightOrTopSided() const {return m_rightOrTopSided;} //sit on right, top
317 
318  const shared_ptr<XStringNode> &ticLabelFormat() const {return m_ticLabelFormat;}
319  const shared_ptr<XBoolNode> &displayLabel() const {return m_displayLabel;}
320  const shared_ptr<XBoolNode> &displayTicLabels() const {return m_displayTicLabels;}
321  const shared_ptr<XHexNode> &ticColor() const {return m_ticColor;}
322  const shared_ptr<XHexNode> &labelColor() const {return m_labelColor;}
323  const shared_ptr<XHexNode> &ticLabelColor() const {return m_ticLabelColor;}
324  const shared_ptr<XBoolNode> &autoFreq() const {return m_autoFreq;}
325  const shared_ptr<XBoolNode> &autoScale() const {return m_autoScale;}
326  const shared_ptr<XBoolNode> &logScale() const {return m_logScale;}
327 
328  void zoom(bool minchange, bool maxchange, XGraph::GFloat zoomscale,
329  XGraph::GFloat center = 0.5);
330 
331  //! Obtains the type of tic and rounded value from position on axis
332  Tic queryTic(int length, int pos, XGraph::VFloat *ticnum);
333 
334  //! Call this function before drawing or autoscale.
335  void startAutoscale(const Snapshot &shot, float resolution, bool clearscale = false);
336  //! Preserves modified scale.
337  void fixScale(Transaction &tr, float resolution, bool suppressupdate = false);
338  //! fixed value
339  XGraph::VFloat fixedMin() const {return m_minFixed;}
340  XGraph::VFloat fixedMax() const {return m_maxFixed;}
341 
342  inline bool isIncluded(XGraph::VFloat x);
343  inline void tryInclude(XGraph::VFloat x);
344 
345  const AxisDirection &direction() const {return m_direction;}
346  const XGraph::ScrPoint &dirVector() const {return m_dirVector;}
347 
348  struct Payload : public XNode::Payload {
349  };
350 protected:
351 
352 private:
353  AxisDirection m_direction;
354  XGraph::ScrPoint m_dirVector;
355 
356  const weak_ptr<XGraph> m_graph;
357 
358  void startAutoscale_(const Snapshot &shot, bool clearscale);
359  void drawLabel(const Snapshot &shot, XQGraphPainter *painter);
360  void performAutoFreq(const Snapshot &shot, float resolution);
361 
362  const shared_ptr<XStringNode> m_label;
363 
364  const shared_ptr<XDoubleNode> m_x;
365  const shared_ptr<XDoubleNode> m_y;
366  const shared_ptr<XDoubleNode> m_z; // in screen coordinate
367  const shared_ptr<XDoubleNode> m_length; // in screen coordinate
368  const shared_ptr<XDoubleNode> m_majorTicScale;
369  const shared_ptr<XDoubleNode> m_minorTicScale;
370  const shared_ptr<XBoolNode> m_displayMajorTics;
371  const shared_ptr<XBoolNode> m_displayMinorTics;
372  const shared_ptr<XDoubleNode> m_max;
373  const shared_ptr<XDoubleNode> m_min;
374  const shared_ptr<XBoolNode> m_rightOrTopSided; //sit on right, top
375 
376  const shared_ptr<XStringNode> m_ticLabelFormat;
377  const shared_ptr<XBoolNode> m_displayLabel;
378  const shared_ptr<XBoolNode> m_displayTicLabels;
379  const shared_ptr<XHexNode> m_ticColor;
380  const shared_ptr<XHexNode> m_labelColor;
381  const shared_ptr<XHexNode> m_ticLabelColor;
382  const shared_ptr<XBoolNode> m_autoFreq;
383  const shared_ptr<XBoolNode> m_autoScale;
384  const shared_ptr<XBoolNode> m_logScale;
385 
386  XGraph::VFloat m_minFixed, m_maxFixed;
387  XGraph::VFloat m_majorFixed, m_minorFixed;
388  XGraph::VFloat m_invLogMaxOverMinFixed, m_invMaxMinusMinFixed;
389  bool m_bLogscaleFixed;
390  bool m_bAutoscaleFixed;
391 };
392 
393 class DECLSPEC_KAME XXYPlot : public XPlot {
394 public:
395  XXYPlot(const char *name, bool runtime, Transaction &tr_graph, const shared_ptr<XGraph> &graph) :
396  XPlot(name, runtime, tr_graph, graph) {}
397 
398  void clearAllPoints(Transaction &tr);
399  //! Adds one point and draws.
400  void addPoint(Transaction &tr,
401  XGraph::VFloat x, XGraph::VFloat y, XGraph::VFloat z = 0.0, XGraph::VFloat weight = 1.0);
402 
403  struct Payload : public XNode::Payload {
404  Payload() : XNode::Payload(), m_startPos(0) {}
405  std::vector<XGraph::ValPoint> &points() {return m_points;}
406  const std::vector<XGraph::ValPoint> &points() const {return m_points;}
407  unsigned int m_startPos;
408  private:
409  std::vector<XGraph::ValPoint> m_points;
410  };
411 protected:
412  //! Takes a snap-shot all points for rendering
413  virtual void snapshot(const Snapshot &shot);
414 };
415 
416 class DECLSPEC_KAME XFuncPlot : public XPlot {
417 public:
418  XFuncPlot(const char *name, bool runtime, Transaction &tr_graph, const shared_ptr<XGraph> &graph);
419  void clearAllPoints(Transaction &) {}
420  virtual int validateAutoScale(const Snapshot &) {return 0;}
421 
422  virtual double func(double x) const = 0;
423 
424  struct Payload : public XNode::Payload {
425  };
426 protected:
427  //! Takes a snap-shot all points for rendering
428  virtual void snapshot(const Snapshot &shot);
429 private:
430 };
431 //---------------------------------------------------------------------------
432 #endif

Generated for KAME4 by  doxygen 1.8.3