source: orange/source/orangeqt/curve.h @ 9361:2a7fa63580e2

Revision 9361:2a7fa63580e2, 8.6 KB checked in by miha <miha.stajdohar@…>, 2 years ago (diff)

Fixed selections to marked only.

Line 
1/*
2    This file is part of the plot module for Orange
3    Copyright (C) 2011  Miha Čančula <miha@noughmad.eu>
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation, either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.
17*/
18
19#ifndef CURVE_H
20#define CURVE_H
21
22#include "plotitem.h"
23#include "point.h"
24
25#include <QtGui/QPen>
26#include <QtGui/QBrush>
27#include <QtCore/QtConcurrentMap>
28#include <QtCore/QFutureWatcher>
29#include <QtCore/QParallelAnimationGroup>
30#include <QtCore/QtConcurrentRun>
31
32struct PointPosMapper{
33  PointPosMapper(const QTransform& t) : t(t) {}
34  typedef QPointF result_type;
35  result_type operator()(Point* p)
36  {
37    return t.map(p->coordinates());
38  }
39 
40private:
41    QTransform t;
42};
43
44struct PointUpdater
45{
46    PointUpdater(int symbol, QColor color, int size, Point::DisplayMode mode)
47    {
48        m_symbol = symbol;
49        m_color = color;
50        m_size = size;
51        m_mode = mode;
52    }
53   
54    void operator()(Point* point)
55    {
56        point->set_symbol(m_symbol);
57        point->set_color(m_color);
58        point->set_size(m_size);
59        point->set_display_mode(m_mode);
60    }
61   
62    private:
63     int m_symbol;
64     QColor m_color;
65     int m_size;
66     Point::DisplayMode m_mode;
67     QTransform m_scale;
68};
69
70struct Updater
71{
72    Updater(double scale, const QPen& pen, const QBrush& brush, const QPainterPath& path)
73    {
74        m_scale = scale;
75        m_pen = pen;
76        m_brush = brush;
77        m_path = path;
78    }
79   
80    void operator()(QGraphicsPathItem* item)
81    {
82        item->setBrush(m_brush);
83        item->setPen(m_pen);
84        item->setScale(m_scale);
85        item->setPath(m_path);
86    }
87   
88    double m_scale;
89    QPen m_pen;
90    QBrush m_brush;
91    QPainterPath m_path;
92};
93 
94typedef QList< DataPoint > Data;
95
96class Curve : public PlotItem
97{
98    Q_OBJECT
99 
100public:
101  enum Style {
102    Points = Qt::NoPen,
103    Lines = Qt::SolidLine,
104    Dots = Qt::DotLine,
105    Sticks = 20,
106    Steps,
107    LinesPoints,
108    UserCurve = 100
109  };
110 
111  /**
112   * @brief Default constructor
113   *
114   * Constructs a Curve from a series of data points
115   *
116   * @param x_data A list of x coordinates of data points
117   * @param y_data A list of y coordinates of data points
118   * @param parent parent item
119   **/
120  Curve(const QList< double >& x_data, const QList< double >& y_data, QGraphicsItem* parent = 0);
121  explicit Curve(QGraphicsItem* parent = 0);
122  /**
123   * Default destructor
124   *
125   **/
126  virtual ~Curve();
127   
128  /**
129   * @brief Update the curve
130   *
131   * Moves all the points to their current locations, and changes their color, shape and size.
132   * Subclasses should reimplement this method to update their specific properties.
133   *
134   **/
135   virtual void update_properties();
136 
137  Point* point_item(double x, double y, int size = 0, QGraphicsItem* parent = 0);
138 
139  QColor color() const;
140  void set_color(const QColor& color);
141 
142  QPen pen() const;
143  void set_pen(QPen pen);
144 
145  QBrush brush() const;
146  void set_brush(QBrush brush);
147 
148  int point_size() const;
149  void set_point_size(int size);
150 
151  int symbol() const;
152  void set_symbol(int symbol);
153 
154  bool is_continuous() const;
155  void set_continuous(bool continuous);
156
157  Data data() const;
158  void set_data(const QList<double> x_data, const QList<double> y_data);
159 
160  virtual QTransform graph_transform() const;
161  virtual void set_graph_transform(const QTransform& transform);
162  virtual void register_points();
163 
164  QRectF graphArea() const;
165  void setGraphArea(const QRectF& area);
166 
167  int style() const;
168  void set_style(int style);
169 
170  bool auto_update() const;
171  void set_auto_update(bool auto_update);
172 
173  QTransform zoom_transform();
174  virtual void set_zoom_transform(const QTransform& transform);
175 
176  QPainterPath continuous_path();
177
178  enum UpdateFlag
179  {
180    UpdateNumberOfItems = 0x01,
181    UpdatePosition = 0x02,
182    UpdateSymbol = 0x04,
183    UpdateSize = 0x08,
184    UpdatePen = 0x10,
185    UpdateBrush = 0x20,
186    UpdateContinuous = 0x40,
187    UpdateZoom = 0x80,
188    UpdateAll = 0xFF
189  };
190 
191  Q_DECLARE_FLAGS(UpdateFlags, UpdateFlag)
192 
193  void set_dirty(UpdateFlags flags = UpdateAll);
194 
195  template <class Sequence, class Updater>
196  void update_items(const Sequence& sequence, Updater updater, Curve::UpdateFlag flag);
197   
198  template <class T>
199  void update_point_properties(const QByteArray& property, const QList< T >& values, bool animate = true);
200
201  template <class T>
202  void update_point_properties_threaded(const QByteArray& property, const QList<T>& values);
203 
204  void update_point_properties_same(const QByteArray& property, const QVariant& value, bool animate);
205 
206  template <class T>
207  void resize_item_list(QList< T* >& list, int size);
208
209  void set_points(const QList<Point*>& points);
210  QList<Point*> points();
211 
212  bool labels_on_marked();
213  void set_labels_on_marked(bool value);
214
215protected:
216  Curve::UpdateFlags needs_update();
217  void set_updated(Curve::UpdateFlags flags);
218 
219  void cancel_all_updates();
220  void update_number_of_items();
221 
222  void checkForUpdate();
223  void changeContinuous();
224 
225  bool use_animations();
226 
227public slots:
228    void update_point_coordinates();
229    void update_point_positions();
230 
231private slots:
232    void pointMapFinished();
233
234private:
235  QColor m_color;
236  int m_pointSize;
237  int m_symbol;
238  int m_style;
239  bool m_continuous;
240  Data m_data;
241  QTransform m_graphTransform;
242  QList<Point*> m_pointItems;
243  UpdateFlags m_needsUpdate;
244  bool m_autoUpdate;
245  QGraphicsPathItem* m_lineItem;
246  bool m_labels_on_marked;
247
248  QPen m_pen;
249  QBrush m_brush;
250  QTransform m_zoom_transform;
251  QMap<UpdateFlag, QFuture<void> > m_currentUpdate;
252  QMap<QByteArray, QFuture<void> > m_property_updates;
253  QFutureWatcher<QPointF> m_pos_watcher;
254  QFutureWatcher<void> m_coords_watcher;
255 
256};
257
258template <class Sequence, class Updater>
259void Curve::update_items(const Sequence& sequence, Updater updater, Curve::UpdateFlag flag)
260{
261    if (m_currentUpdate.contains(flag) && m_currentUpdate[flag].isRunning())
262    {
263        m_currentUpdate[flag].cancel();
264        m_currentUpdate[flag].waitForFinished();
265    }
266    if (!sequence.isEmpty())
267    {
268        m_currentUpdate[flag] = QtConcurrent::map(sequence, updater);
269    }
270}
271
272template < class T >
273void Curve::update_point_properties(const QByteArray& property, const QList< T >& values, bool animate)
274{
275    if (m_property_updates.contains(property))
276    {
277        m_property_updates[property].cancel();
278        m_property_updates[property].waitForFinished();
279    }
280   
281    update_number_of_items();
282   
283    int n = m_pointItems.size();
284    if (n != values.size())
285    {
286        if (values.isEmpty())
287        {
288            update_point_properties_same(property, T(), animate);
289        }
290        else
291        {
292            update_point_properties_same(property, values.first(), animate);
293        }
294       
295        return;
296    }
297   
298    if (animate && use_animations())
299    {
300        QParallelAnimationGroup* group = new QParallelAnimationGroup(this);
301        for (int i = 0; i < n; ++i)
302        {
303            QPropertyAnimation* a = new QPropertyAnimation(m_pointItems[i], property, m_pointItems[i]);
304            a->setEndValue(values[i]);
305            group->addAnimation(a);
306        }
307        group->start(QAbstractAnimation::DeleteWhenStopped);
308    }
309    else
310    {
311        m_property_updates[property] = QtConcurrent::run(this, &Curve::update_point_properties_threaded<T>, property, values);
312    }
313}
314
315template < class T >
316void Curve::update_point_properties_threaded(const QByteArray& property, const QList< T >& values)
317{
318    const int n = values.size();
319    if (n != m_pointItems.size())
320    {
321    return;
322    }
323    for (int i = 0; i < n; ++i)
324    {
325        m_pointItems[i]->setProperty(property, QVariant::fromValue<T>(values[i]));
326    }
327}
328
329template <class T>
330void Curve::resize_item_list(QList< T* >& list, int size)
331{
332    int n = list.size(); 
333    if (n > size)
334  {
335    qDeleteAll(list.constBegin() + size, list.constEnd());
336    list.erase(list.begin() + size, list.end());
337  }
338  else if (n < size)
339  { 
340#if QT_VERSION >= 0x040700
341    list.reserve(size);
342#endif
343    for (int i = 0; i < (size-n); ++i)
344    {
345      list << new T(this);
346    }
347  }
348}
349
350
351Q_DECLARE_OPERATORS_FOR_FLAGS(Curve::UpdateFlags)
352
353
354#endif // CURVE_H
Note: See TracBrowser for help on using the repository browser.