KPlotting

kplotwidget.h
1 /* -*- C++ -*-
2  This file is part of the KDE libraries
3  SPDX-FileCopyrightText: 2003 Jason Harris <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #ifndef KPLOTWIDGET_H
9 #define KPLOTWIDGET_H
10 
11 #include <kplotting_export.h>
12 
13 #include <QFrame>
14 #include <QList>
15 
16 class KPlotAxis;
17 class KPlotObject;
18 class KPlotPoint;
19 
20 /**
21  *@class KPlotWidget
22  *
23  *@short Generic data plotting widget.
24  *
25  *Widget for drawing plots. The basic idea behind KPlotWidget is that
26  *you don't have to worry about any transformation from your data's
27  *natural units to screen pixel coordinates; this is handled internally
28  *by the widget.
29  *
30  *Data to be plotted are represented by one or more instances of
31  *KPlotObject. KPlotObject contains a list of QPointFs to be plotted
32  *(again, in the data's natural units), as well as information about how
33  *the data are to be rendered in the plot (i.e., as separate points or
34  *connected by lines? With what color and point style? etc). See
35  *KPlotObject for more information.
36  *
37  *KPlotWidget automatically adds axis labels with tickmarks and tick
38  *labels. These are encapsulated in the KPlotAxis class. All you have
39  *to do is set the limits of the plotting area in data units, and
40  *KPlotWidget will figure out the optimal positions and labels for the
41  *tickmarks on the axes.
42  *
43  *Example of usage:
44  *
45  * @code
46 KPlotWidget *kpw = new KPlotWidget( parent );
47 // setting our limits for the plot
48 kpw->setLimits( 1.0, 5.0, 1.0, 25.0 );
49 
50 // creating a plot object whose points are connected by red lines ...
51 KPlotObject *kpo = new KPlotObject( Qt::red, KPlotObject::Lines );
52 // ... adding some points to it ...
53 for ( float x = 1.0; x <= 5.0; x += 0.1 )
54  kpo->addPoint( x, x*x );
55 
56 // ... and adding the object to the plot widget
57 kpw->addPlotObject( kpo );
58  * @endcode
59  *
60  *@note KPlotWidget will take ownership of the objects added to it, so when
61  *clearing the objects list (eg with removeAllPlotObjects()) any previous
62  *reference to a KPlotObject already added to a KPlotWidget will be invalid.
63  *You can disable this behavior by using setAutoDelete(false).
64  *
65  *@author Jason Harris
66  */
67 class KPLOTTING_EXPORT KPlotWidget : public QFrame
68 {
69  Q_OBJECT
70  Q_PROPERTY(int leftPadding READ leftPadding)
71  Q_PROPERTY(int rightPadding READ rightPadding)
72  Q_PROPERTY(int topPadding READ topPadding)
73  Q_PROPERTY(int bottomPadding READ bottomPadding)
74  Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor)
75  Q_PROPERTY(QColor foregroundColor READ foregroundColor WRITE setForegroundColor)
76  Q_PROPERTY(QColor gridColor READ gridColor WRITE setGridColor)
77  Q_PROPERTY(bool grid READ isGridShown WRITE setShowGrid)
78  Q_PROPERTY(bool objectToolTip READ isObjectToolTipShown WRITE setObjectToolTipShown)
79 public:
80  /**
81  *@short Constructor.
82  *@param parent the parent widget
83  */
84  explicit KPlotWidget(QWidget *parent = nullptr);
85 
86  /**
87  *@short Destructor.
88  */
89  ~KPlotWidget() override;
90 
91  /**
92  * The four types of plot axes.
93  */
94  enum Axis {
95  LeftAxis = 0, ///< the left axis
96  BottomAxis, ///< the bottom axis
97  RightAxis, ///< the right axis
98  TopAxis, ///< the top axis
99  };
100 
101  /**
102  *@return suggested minimum size for the plot widget
103  */
104  QSize minimumSizeHint() const override;
105 
106  /**
107  *@return suggested size for the plot widget
108  */
109  QSize sizeHint() const override;
110 
111  /**
112  * Set new data limits for the plot.
113  * @param x1 the minimum X value in data units
114  * @param x2 the maximum X value in data units
115  * @param y1 the minimum Y value in data units
116  * @param y2 the maximum Y value in data units
117  */
118  void setLimits(double x1, double x2, double y1, double y2);
119 
120  /**
121  * @short Reset the secondary data limits, which control the
122  * values displayed along the top and right axes.
123  *
124  * All data points are *plotted* using the coordinates
125  * defined by setLimits(), so this function is only useful for
126  * showing alternate tickmark labels along the top and right
127  * edges. For example, if you were plotting temperature on the
128  * X-axis, you could use Centigrade units for the primary
129  * (bottom) axis, using setLimits( 0.0, 100.0, 0.0, 1.0 ). If
130  * you also wanted to show Fahrenheit units along the secondary
131  * (top) axis, you would additionally use
132  * setSecondaryLimits( 32.0, 212.0, 0.0, 1.0 ). The data
133  * added to the plot would have x-coordinates in Centigrade degrees.
134  *
135  * @param x1 the minimum X value in secondary data units
136  * @param x2 the maximum X value in secondary data units
137  * @param y1 the minimum Y value in secondary data units
138  * @param y2 the maximum Y value in secondary data units
139  * @sa setLimits()
140  */
141  void setSecondaryLimits(double x1, double x2, double y1, double y2);
142 
143  /**
144  * Unset the secondary limits, so the top and right axes
145  * show the same tickmarks as the bottom and left axes (no tickmark
146  * labels will be drawn for the top and right axes in this case)
147  */
148  void clearSecondaryLimits();
149 
150  /**
151  * @return the rectangle representing the boundaries of the current plot,
152  * in natural data units.
153  * @sa setLimits()
154  */
155  QRectF dataRect() const;
156 
157  /**
158  * @return the rectangle representing the boundaries of the secondary
159  * data limits, if they have been set. Otherwise, this function
160  * behaves the same as dataRect().
161  * @sa setSecondaryLimits()
162  */
163  QRectF secondaryDataRect() const;
164 
165  /**
166  * @return the rectangle representing the boundaries of the current plot,
167  * in screen pixel units.
168  */
169  QRect pixRect() const;
170 
171  /**
172  * Add an item to the list of KPlotObjects to be plotted.
173  * The widget takes ownership of the plot object, unless auto-delete was disabled.
174  * @param object the KPlotObject to be added
175  */
176  void addPlotObject(KPlotObject *object);
177 
178  /**
179  * Add more than one KPlotObject at one time.
180  * The widget takes ownership of the plot object, unless auto-delete was disabled.
181  * @param objects the list of KPlotObjects to be added
182  */
183  void addPlotObjects(const QList<KPlotObject *> &objects);
184 
185  /**
186  * @return the current list of plot objects
187  */
188  QList<KPlotObject *> plotObjects() const;
189 
190  /**
191  * Enables auto-deletion of plot objects if autoDelete is true; otherwise auto-deletion is disabled.
192  * Auto-deletion is enabled by default.
193  * @since 5.12
194  */
195  void setAutoDeletePlotObjects(bool autoDelete);
196 
197  /**
198  * Removes all plot objects that were added to the widget.
199  * If auto-delete was not disabled, the plot objects are deleted.
200  */
201  void removeAllPlotObjects();
202 
203  /**
204  * Reset the mask used for non-overlapping labels so that all
205  * regions of the plot area are considered empty.
206  */
207  void resetPlotMask();
208 
209  /**
210  * Clear the object list, reset the data limits, and remove axis labels
211  * If auto-delete was not disabled, the plot objects are deleted.
212  */
213  void resetPlot();
214 
215  /**
216  * Replace an item in the KPlotObject list.
217  * @param i the index of the item to be replaced
218  * @param o pointer to the replacement KPlotObject
219  *
220  * @since 5.12, if auto-deletion is enabled, the previous plot object is deleted.
221  * Call setAutoDeletePlotObjects(false) if you want to swap between available plot objects
222  * and therefore you want to handle deletion externally.
223  */
224  void replacePlotObject(int i, KPlotObject *o);
225 
226  /**
227  * @return the background color of the plot.
228  *
229  * The default color is black.
230  */
231  QColor backgroundColor() const;
232 
233  /**
234  * @return the foreground color, used for axes, tickmarks and associated
235  * labels.
236  *
237  * The default color is white.
238  */
239  QColor foregroundColor() const;
240 
241  /**
242  * @return the grid color.
243  *
244  * The default color is gray.
245  */
246  QColor gridColor() const;
247 
248  /**
249  * Set the background color
250  * @param bg the new background color
251  */
252  void setBackgroundColor(const QColor &bg);
253 
254  /**
255  * Set the foreground color
256  * @param fg the new foreground color
257  */
258  void setForegroundColor(const QColor &fg);
259 
260  /**
261  * Set the grid color
262  * @param gc the new grid color
263  */
264  void setGridColor(const QColor &gc);
265 
266  /**
267  * @return whether the grid lines are shown
268  * Grid lines are not shown by default.
269  */
270  bool isGridShown() const;
271 
272  /**
273  * @return whether the tooltip for the point objects is shown.
274  * Tooltips are enabled by default.
275  */
276  bool isObjectToolTipShown() const;
277 
278  /**
279  * @return whether the antialiasing is active
280  * Antialiasing is not active by default.
281  */
282  bool antialiasing() const;
283 
284  /**
285  * Toggle antialiased drawing.
286  * @param b if true, the plot graphics will be antialiased.
287  */
288  void setAntialiasing(bool b);
289 
290  /**
291  * @return the number of pixels to the left of the plot area.
292  *
293  * Padding values are set to -1 by default; if unchanged, this
294  * function will try to guess a good value, based on whether
295  * ticklabels and/or axis labels need to be drawn.
296  */
297  int leftPadding() const;
298 
299  /**
300  * @return the number of pixels to the right of the plot area.
301  * Padding values are set to -1 by default; if unchanged, this
302  * function will try to guess a good value, based on whether
303  * ticklabels and/or axis labels are to be drawn.
304  */
305  int rightPadding() const;
306 
307  /**
308  * @return the number of pixels above the plot area.
309  * Padding values are set to -1 by default; if unchanged, this
310  * function will try to guess a good value, based on whether
311  * ticklabels and/or axis labels are to be drawn.
312  */
313  int topPadding() const;
314 
315  /**
316  * @return the number of pixels below the plot area.
317  * Padding values are set to -1 by default; if unchanged, this
318  * function will try to guess a good value, based on whether
319  * ticklabels and/or axis labels are to be drawn.
320  */
321  int bottomPadding() const;
322 
323  /**
324  * @short Set the number of pixels to the left of the plot area.
325  * Set this to -1 to revert to automatic determination of padding values.
326  */
327  void setLeftPadding(int padding);
328 
329  /**
330  * @short Set the number of pixels to the right of the plot area.
331  * Set this to -1 to revert to automatic determination of padding values.
332  */
333  void setRightPadding(int padding);
334 
335  /**
336  * @short Set the number of pixels above the plot area.
337  * Set this to -1 to revert to automatic determination of padding values.
338  */
339  void setTopPadding(int padding);
340 
341  /**
342  * @short Set the number of pixels below the plot area.
343  * Set this to -1 to revert to automatic determination of padding values.
344  */
345  void setBottomPadding(int padding);
346 
347  /**
348  * @short Revert all four padding values to -1, so that they will be
349  * automatically determined.
350  */
351  void setDefaultPaddings();
352 
353  /**
354  * @short Map a coordinate @param p from the data rect to the physical
355  * pixel rect.
356  * Used mainly when drawing.
357  * @param p the point to be converted, in natural data units
358  * @return the coordinate in the pixel coordinate system
359  */
360  QPointF mapToWidget(const QPointF &p) const;
361 
362  /**
363  * Indicate that object labels should try to avoid the given
364  * rectangle in the plot. The rectangle is in pixel coordinates.
365  *
366  * @note You should not normally call this function directly.
367  * It is called by KPlotObject when points, bars and labels are drawn.
368  * @param r the rectangle defining the region in the plot that
369  * text labels should avoid (in pixel coordinates)
370  * @param value Allows you to determine how strongly the rectangle
371  * should be avoided. Larger values are avoided more strongly.
372  */
373  void maskRect(const QRectF &r, float value = 1.0f);
374 
375  /**
376  * Indicate that object labels should try to avoid the line
377  * joining the two given points (in pixel coordinates).
378  *
379  * @note You should not normally call this function directly.
380  * It is called by KPlotObject when lines are drawn in the plot.
381  * @param p1 the starting point for the line
382  * @param p2 the ending point for the line
383  * @param value Allows you to determine how strongly the line
384  * should be avoided. Larger values are avoided more strongly.
385  */
386  void maskAlongLine(const QPointF &p1, const QPointF &p2, float value = 1.0f);
387 
388  /**
389  * Place an object label optimally in the plot. This function will
390  * attempt to place the label as close as it can to the point to which
391  * the label belongs, while avoiding overlap with regions of the plot
392  * that have been masked.
393  *
394  * @note You should not normally call this function directly.
395  * It is called internally in KPlotObject::draw().
396  *
397  * @param painter Pointer to the painter on which to draw the label
398  * @param pp pointer to the KPlotPoint whose label is to be drawn.
399  */
400  void placeLabel(QPainter *painter, KPlotPoint *pp);
401 
402  /**
403  * @return the axis of the specified @p type, or 0 if no axis has been set.
404  * @sa Axis
405  */
406  KPlotAxis *axis(Axis type);
407 
408  /**
409  * @return the axis of the specified @p type, or 0 if no axis has been set.
410  * @sa Axis
411  */
412  const KPlotAxis *axis(Axis type) const;
413 
414 public Q_SLOTS:
415  /**
416  * Toggle whether grid lines are drawn at major tickmarks.
417  * @param show if true, grid lines will be drawn.
418  * @sa isGridShown()
419  */
420  void setShowGrid(bool show);
421 
422  /**
423  * Toggle the display of a tooltip for point objects.
424  * @param show whether show the tooltip.
425  * @sa isObjectToolTipShown()
426  */
427  void setObjectToolTipShown(bool show);
428 
429 protected:
430  /**
431  * Generic event handler.
432  */
433  bool event(QEvent *) override;
434 
435  /**
436  * The paint event handler, executed when update() or repaint() is called.
437  */
438  void paintEvent(QPaintEvent *) override;
439 
440  /**
441  * The resize event handler, called when the widget is resized.
442  */
443  void resizeEvent(QResizeEvent *) override;
444 
445  /**
446  * Draws the plot axes and axis labels.
447  * @internal Internal use only; one should simply call update()
448  * to draw the widget with axes and all objects.
449  * @param p pointer to the painter on which we are drawing
450  */
451  virtual void drawAxes(QPainter *p);
452 
453  /**
454  * Synchronize the PixRect with the current widget size and
455  * padding settings.
456  */
457  void setPixRect();
458 
459  /**
460  * @return a list of points in the plot which are within 4 pixels
461  * of the screen position given as an argument.
462  * @param p The screen position from which to check for plot points.
463  */
464  QList<KPlotPoint *> pointsUnderPoint(const QPoint &p) const;
465 
466 private:
467  class Private;
468  Private *const d;
469 
471 };
472 
473 #endif
Encapsulates a point in the plot.
Definition: kplotpoint.h:27
virtual QSize minimumSizeHint() const const
virtual QSize sizeHint() const const override
Axis
The four types of plot axes.
Definition: kplotwidget.h:94
virtual void paintEvent(QPaintEvent *) override
Encapsulates a data set to be plotted in a KPlotWidget.
Definition: kplotobject.h:40
Generic data plotting widget.
Definition: kplotwidget.h:67
the top axis
Definition: kplotwidget.h:98
Q_PROPERTY(...)
Axis for KPlotWidget.
Definition: kplotaxis.h:24
Q_DISABLE_COPY(Class)
the right axis
Definition: kplotwidget.h:97
the bottom axis
Definition: kplotwidget.h:96
virtual void resizeEvent(QResizeEvent *event)
virtual bool event(QEvent *e) override
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Tue Jul 27 2021 22:45:24 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.