vtkChartXY.h 13.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkChartXY.h

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

16 17 18 19 20 21 22 23 24 25
/**
 * @class   vtkChartXY
 * @brief   Factory class for drawing XY charts
 *
 *
 * This class implements an XY chart.
 *
 * @sa
 * vtkBarChartActor
*/
26

27 28
#ifndef vtkChartXY_h
#define vtkChartXY_h
29 30

#include "vtkChart.h"
Mathieu Westphal's avatar
Mathieu Westphal committed
31 32 33 34
#include "vtkChartsCoreModule.h" // For export macro
#include "vtkContextPolygon.h"   // For vtkContextPolygon
#include "vtkSmartPointer.h"     // For SP ivars
#include "vtkVector.h"           // For vtkVector2f in struct
35 36 37 38

class vtkPlot;
class vtkAxis;
class vtkPlotGrid;
39
class vtkChartLegend;
40
class vtkTooltipItem;
41 42
class vtkChartXYPrivate; // Private class to keep my STL vector in...

43
class VTKCHARTSCORE_EXPORT vtkChartXY : public vtkChart
44 45
{
public:
46
  vtkTypeMacro(vtkChartXY, vtkChart);
47
  void PrintSelf(ostream& os, vtkIndent indent) override;
48

49 50 51
  /**
   * Creates a 2D Chart object.
   */
Mathieu Westphal's avatar
Mathieu Westphal committed
52
  static vtkChartXY* New();
53

54 55 56 57 58
  /**
   * Perform any updates to the item that may be necessary before rendering.
   * The scene should take care of calling this on all items before their
   * Paint function is invoked.
   */
59
  void Update() override;
60

61 62 63
  /**
   * Paint event for the chart, called whenever the chart needs to be drawn
   */
64
  bool Paint(vtkContext2D* painter) override;
65

66 67 68
  /**
   * Add a plot to the chart, defaults to using the name of the y column
   */
69
  vtkPlot* AddPlot(int type) override;
70

71 72 73
  /**
   * Adds a plot to the chart
   */
74
  vtkIdType AddPlot(vtkPlot* plot) override;
75

76 77 78 79
  /**
   * Remove the plot at the specified index, returns true if successful,
   * false if the index was invalid.
   */
80
  bool RemovePlot(vtkIdType index) override;
81

82 83 84
  /**
   * Remove all plots from the chart.
   */
85
  void ClearPlots() override;
86

87 88 89
  /**
   * Get the plot at the specified index, returns null if the index is invalid.
   */
90
  vtkPlot* GetPlot(vtkIdType index) override;
91

92 93 94 95
  /**
   * Get the index of the specified plot, returns -1 if the plot does not
   * belong to the chart.
   */
96 97
  virtual vtkIdType GetPlotIndex(vtkPlot*);

98 99 100 101 102
  /**
   * Raises the \a plot to the top of the plot's stack.
   * \return The new index of the plot
   * \sa StackPlotAbove(), LowerPlot(), StackPlotUnder()
   */
103 104
  vtkIdType RaisePlot(vtkPlot* plot);

105 106 107 108 109 110
  /**
   * Raises the \a plot above the \a under plot. If \a under is null,
   * the plot is raised to the top of the plot's stack.
   * \return The new index of the plot
   * \sa RaisePlot(), LowerPlot(), StackPlotUnder()
   */
111 112
  virtual vtkIdType StackPlotAbove(vtkPlot* plot, vtkPlot* under);

113 114 115 116 117
  /**
   * Lowers the \a plot to the bottom of the plot's stack.
   * \return The new index of the plot
   * \sa StackPlotUnder(), RaisePlot(), StackPlotAbove()
   */
118 119
  vtkIdType LowerPlot(vtkPlot* plot);

120 121 122 123 124 125
  /**
   * Lowers the \a plot under the \a above plot. If \a above is null,
   * the plot is lowered to the bottom of the plot's stack
   * \return The new index of the plot
   * \sa StackPlotUnder(), RaisePlot(), StackPlotAbove()
   */
126 127
  virtual vtkIdType StackPlotUnder(vtkPlot* plot, vtkPlot* above);

128 129 130
  /**
   * Get the number of plots the chart contains.
   */
131
  vtkIdType GetNumberOfPlots() override;
132

133 134 135
  /**
   * Figure out which quadrant the plot is in.
   */
Mathieu Westphal's avatar
Mathieu Westphal committed
136
  int GetPlotCorner(vtkPlot* plot);
137

138 139 140
  /**
   * Figure out which quadrant the plot is in.
   */
Mathieu Westphal's avatar
Mathieu Westphal committed
141
  void SetPlotCorner(vtkPlot* plot, int corner);
142

143 144 145 146 147
  /**
   * Get the axis specified by axisIndex. This is specified with the vtkAxis
   * position enum, valid values are vtkAxis::LEFT, vtkAxis::BOTTOM,
   * vtkAxis::RIGHT and vtkAxis::TOP.
   */
148
  vtkAxis* GetAxis(int axisIndex) override;
149

150 151 152
  /**
   * Set whether the chart should draw a legend.
   */
153
  void SetShowLegend(bool visible) override;
154

155 156 157
  /**
   * Get the vtkChartLegend object that will be displayed by the chart.
   */
158
  vtkChartLegend* GetLegend() override;
159

160 161 162
  /**
   * Set the vtkTooltipItem object that will be displayed by the chart.
   */
Mathieu Westphal's avatar
Mathieu Westphal committed
163
  virtual void SetTooltip(vtkTooltipItem* tooltip);
164

165 166 167
  /**
   * Get the vtkTooltipItem object that will be displayed by the chart.
   */
168 169
  virtual vtkTooltipItem* GetTooltip();

170 171 172
  /**
   * Get the number of axes in the current chart.
   */
173
  vtkIdType GetNumberOfAxes() override;
174

175 176 177 178
  /**
   * Request that the chart recalculates the range of its axes. Especially
   * useful in applications after the parameters of plots have been modified.
   */
179
  void RecalculateBounds() override;
180

181 182 183 184 185 186 187
  /**
   * Set the selection method, which controls how selections are handled by the
   * chart. The default is SELECTION_ROWS which selects all points in all plots
   * in a chart that have values in the rows selected. SELECTION_PLOTS allows
   * for finer-grained selections specific to each plot, and so to each XY
   * column pair.
   */
188
  void SetSelectionMethod(int method) override;
189

190 191 192 193
  //@{
  /**
   * If true then the axes will be drawn at the origin (scientific style).
   */
194 195
  vtkSetMacro(DrawAxesAtOrigin, bool);
  vtkGetMacro(DrawAxesAtOrigin, bool);
196
  vtkBooleanMacro(DrawAxesAtOrigin, bool);
197
  //@}
198

199 200 201 202 203
  //@{
  /**
   * If true then the axes will be turned on and off depending upon whether
   * any plots are in that corner. Defaults to true.
   */
204 205
  vtkSetMacro(AutoAxes, bool);
  vtkGetMacro(AutoAxes, bool);
206
  vtkBooleanMacro(AutoAxes, bool);
207
  //@}
208

209 210 211 212
  //@{
  /**
   * Border size of the axes that are hidden (vtkAxis::GetVisible())
   */
213 214
  vtkSetMacro(HiddenAxisBorder, int);
  vtkGetMacro(HiddenAxisBorder, int);
215 216 217 218 219 220 221 222
  //@}

  //@{
  /**
   * Force the axes to have their Minimum and Maximum properties inside the
   * plot boundaries. It constrains pan and zoom interaction.
   * False by default.
   */
223 224 225
  vtkSetMacro(ForceAxesToBounds, bool);
  vtkGetMacro(ForceAxesToBounds, bool);
  vtkBooleanMacro(ForceAxesToBounds, bool);
226 227 228 229 230 231 232 233 234 235
  //@}

  //@{
  /**
   * Set the width fraction for any bar charts drawn in this chart. It is
   * assumed that all bar plots will use the same array for the X axis, and that
   * this array is regularly spaced. The delta between the first two x values is
   * used to calculated the width of the bars, and subdivided between each bar.
   * The default value is 0.8, 1.0 would lead to bars that touch.
   */
236 237
  vtkSetMacro(BarWidthFraction, float);
  vtkGetMacro(BarWidthFraction, float);
238 239 240 241 242 243 244 245 246
  //@}

  //@{
  /**
   * Set the behavior of the mouse wheel.  If true, the mouse wheel zooms in/out
   * on the chart.  Otherwise, unless MouseWheelEvent is overridden by a subclass
   * the mouse wheel does nothing.
   * The default value is true.
   */
247 248 249
  vtkSetMacro(ZoomWithMouseWheel, bool);
  vtkGetMacro(ZoomWithMouseWheel, bool);
  vtkBooleanMacro(ZoomWithMouseWheel, bool);
250 251 252 253 254 255 256 257
  //@}

  //@{
  /**
   * Adjust the minimum of a logarithmic axis to be greater than 0, regardless
   * of the minimum data value.
   * False by default.
   */
258 259 260
  vtkSetMacro(AdjustLowerBoundForLogPlot, bool);
  vtkGetMacro(AdjustLowerBoundForLogPlot, bool);
  vtkBooleanMacro(AdjustLowerBoundForLogPlot, bool);
261
  //@}
262

263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
  //@{
  /**
  * Set if the point can be dragged along X
  * by the ClickAndDrag Action
  * True by default.
  */
  vtkSetMacro(DragPointAlongX, bool);
  vtkGetMacro(DragPointAlongX, bool);
  vtkBooleanMacro(DragPointAlongX, bool);
  //@}

  //@{
  /**
  * Set if the point can be dragged along Y
  * by the ClickAndDrag Action
  * True by default.
  */
  vtkSetMacro(DragPointAlongY, bool);
  vtkGetMacro(DragPointAlongY, bool);
  vtkBooleanMacro(DragPointAlongY, bool);
  //@}

285 286 287
  /**
   * Set the information passed to the tooltip.
   */
Mathieu Westphal's avatar
Mathieu Westphal committed
288 289
  virtual void SetTooltipInfo(const vtkContextMouseEvent&, const vtkVector2d&, vtkIdType, vtkPlot*,
    vtkIdType segmentIndex = -1);
290

291 292 293
  /**
   * Return true if the supplied x, y coordinate is inside the item.
   */
294
  bool Hit(const vtkContextMouseEvent& mouse) override;
295

296 297 298
  /**
   * Mouse enter event.
   */
299
  bool MouseEnterEvent(const vtkContextMouseEvent& mouse) override;
300

301 302 303
  /**
   * Mouse move event.
   */
304
  bool MouseMoveEvent(const vtkContextMouseEvent& mouse) override;
305

306 307 308
  /**
   * Mouse leave event.
   */
309
  bool MouseLeaveEvent(const vtkContextMouseEvent& mouse) override;
310

311 312 313
  /**
   * Mouse button down event
   */
314
  bool MouseButtonPressEvent(const vtkContextMouseEvent& mouse) override;
315

316 317 318
  /**
   * Mouse button release event.
   */
319
  bool MouseButtonReleaseEvent(const vtkContextMouseEvent& mouse) override;
320

321 322 323
  /**
   * Mouse wheel event, positive delta indicates forward movement of the wheel.
   */
324
  bool MouseWheelEvent(const vtkContextMouseEvent& mouse, int delta) override;
325

326 327 328
  /**
   * Key press event.
   */
329
  bool KeyPressEvent(const vtkContextKeyEvent& key) override;
330

331 332
protected:
  vtkChartXY();
333
  ~vtkChartXY() override;
334

335 336 337
  /**
   * Recalculate the necessary transforms.
   */
338 339
  void RecalculatePlotTransforms();

340 341 342 343
  /**
   * Calculate the optimal zoom level such that all of the points to be plotted
   * will fit into the plot area.
   */
344 345
  void RecalculatePlotBounds();

346 347 348 349 350
  /**
  * Remove all the selection from Plots
  */
  void ReleasePlotSelections();

351 352 353 354 355
  /**
   * Update the layout of the chart, this may require the vtkContext2D in order
   * to get font metrics etc. Initially this was added to resize the charts
   * according in response to the size of the axes.
   */
356
  virtual bool UpdateLayout(vtkContext2D* painter);
357

358 359 360 361 362
  /**
   * Layout for the legend if it is visible. This is run after the axes layout
   * and will adjust the borders to account for the legend position.
   * \return The required space in the specified border.
   */
363 364
  virtual int GetLegendBorder(vtkContext2D* painter, int axisPosition);

365 366 367 368
  /**
   * Called after the edges of the chart are decided, set the position of the
   * legend, depends upon its alignment.
   */
369 370
  virtual void SetLegendPosition(const vtkRectf& rect);

371 372 373
  /**
   * The legend for the chart.
   */
374
  vtkSmartPointer<vtkChartLegend> Legend;
375

376 377 378
  /**
   * The tooltip item for the chart - can be used to display extra information.
   */
379
  vtkSmartPointer<vtkTooltipItem> Tooltip;
380

381 382 383
  /**
   * Does the plot area transform need to be recalculated?
   */
384 385
  bool PlotTransformValid;

386 387 388
  /**
   * The box created as the mouse is dragged around the screen.
   */
389
  vtkRectf MouseBox;
390

391 392 393
  /**
   * Should the box be drawn (could be selection, zoom etc).
   */
394 395
  bool DrawBox;

396 397 398 399
  /**
   * The polygon created as the mouse is dragged around the screen when in
   * polygonal selection mode.
   */
400 401
  vtkContextPolygon SelectionPolygon;

402 403 404
  /**
   * Should the selection polygon be drawn.
   */
405 406
  bool DrawSelectionPolygon;

407 408 409
  /**
   * Should we draw the location of the nearest point on the plot?
   */
410 411
  bool DrawNearestPoint;

412 413 414 415 416
  /**
   * Keep the axes drawn at the origin? This will attempt to keep the axes drawn
   * at the origin, i.e. 0.0, 0.0 for the chart. This is often the preferred
   * way of drawing scientific/mathematical charts.
   */
417 418
  bool DrawAxesAtOrigin;

419 420 421
  /**
   * Should axes be turned on and off automatically - defaults to on.
   */
422 423
  bool AutoAxes;

424 425 426
  /**
   * Size of the border when an axis is hidden
   */
427 428
  int HiddenAxisBorder;

429 430 431 432
  /**
   * The fraction of the interval taken up along the x axis by any bars that are
   * drawn on the chart.
   */
433 434
  float BarWidthFraction;

435 436 437 438 439
  /**
   * Property to force the axes to have their Minimum and Maximum properties
   * inside the plot boundaries. It constrains pan and zoom interaction.
   * False by default.
   */
440 441
  bool ForceAxesToBounds;

442 443 444 445
  /**
   * Property to enable zooming the chart with the mouse wheel.
   * True by default.
   */
446 447
  bool ZoomWithMouseWheel;

448 449 450 451
  /**
   * Property to adjust the minimum of a logarithmic axis to be greater than 0,
   * regardless of the minimum data value.
   */
452 453
  bool AdjustLowerBoundForLogPlot;

454 455 456 457 458 459
  /**
  * Properties to enable the drag of a point for the ClickAndDrag Action
  */
  bool DragPointAlongX;
  bool DragPointAlongY;

460
private:
461 462
  vtkChartXY(const vtkChartXY&) = delete;
  void operator=(const vtkChartXY&) = delete;
463

Mathieu Westphal's avatar
Mathieu Westphal committed
464
  vtkChartXYPrivate* ChartPrivate; // Private class where I hide my STL containers
465

466 467 468 469 470 471
  /**
   * Internal variable to handle update of drag:
   * true if a point has been selected by the user click.
   */
  bool DragPoint;

472 473 474
  /**
   * Figure out the spacing between the bar chart plots, and their offsets.
   */
475 476
  void CalculateBarPlots();

477 478 479 480 481
  /**
   * Try to locate a point within the plots to display in a tooltip.
   * If invokeEvent is greater than 0, then an event will be invoked if a point
   * is at that mouse position.
   */
Mathieu Westphal's avatar
Mathieu Westphal committed
482
  bool LocatePointInPlots(const vtkContextMouseEvent& mouse, int invokeEvent = -1);
483

Mathieu Westphal's avatar
Mathieu Westphal committed
484 485
  int LocatePointInPlot(const vtkVector2f& position, const vtkVector2f& tolerance,
    vtkVector2f& plotPos, vtkPlot* plot, vtkIdType& segmentIndex);
486

487 488 489
  /**
   * Remove the plot from the plot corners list.
   */
Mathieu Westphal's avatar
Mathieu Westphal committed
490
  bool RemovePlotFromCorners(vtkPlot* plot);
491

Mathieu Westphal's avatar
Mathieu Westphal committed
492
  void ZoomInAxes(vtkAxis* x, vtkAxis* y, float* orign, float* max);
493

494 495 496
  /**
   * Transform the selection box or polygon.
   */
Mathieu Westphal's avatar
Mathieu Westphal committed
497 498 499
  void TransformBoxOrPolygon(bool polygonMode, vtkTransform2D* transform,
    const vtkVector2f& mousePosition, vtkVector2f& min, vtkVector2f& max,
    vtkContextPolygon& polygon);
500 501
};

502 503 504 505 506 507
//@{
/**
 * Small struct used by InvokeEvent to send some information about the point
 * that was clicked on. This is an experimental part of the API, subject to
 * change.
 */
508 509 510 511
struct vtkChartPlotData
{
  vtkStdString SeriesName;
  vtkVector2f Position;
512
  vtkVector2i ScreenPosition;
513
  int Index;
514
};
515
//@}
516

Mathieu Westphal's avatar
Mathieu Westphal committed
517
#endif // vtkChartXY_h