1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkChartBox.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15
16 #include "vtkChartBox.h"
17
18 #include "vtkAnnotationLink.h"
19 #include "vtkAxis.h"
20 #include "vtkBrush.h"
21 #include "vtkCommand.h"
22 #include "vtkContext2D.h"
23 #include "vtkContextScene.h"
24 #include "vtkContextMapper2D.h"
25 #include "vtkContextMouseEvent.h"
26 #include "vtkDataArray.h"
27 #include "vtkIdTypeArray.h"
28 #include "vtkNew.h"
29 #include "vtkObjectFactory.h"
30 #include "vtkPen.h"
31 #include "vtkPlotBox.h"
32 #include "vtkPlotGrid.h"
33 #include "vtkPoints2D.h"
34 #include "vtkSelection.h"
35 #include "vtkSelectionNode.h"
36 #include "vtkSmartPointer.h"
37 #include "vtkStringArray.h"
38 #include "vtkTable.h"
39 #include "vtkTextProperty.h"
40 #include "vtkTooltipItem.h"
41 #include "vtkTransform2D.h"
42
43 #include <algorithm>
44 #include <vector>
45
46
47 // Minimal storage class for STL containers etc.
48 class vtkChartBox::Private
49 {
50 public:
Private()51 Private()
52 {
53 this->Plot = vtkSmartPointer<vtkPlotBox>::New();
54 this->YAxis->SetPosition(vtkAxis::LEFT);
55 this->YAxis->SetPoint1(0, 0);
56 this->YAxis->SetTitle("Y");
57 }
58 ~Private() = default;
59 vtkSmartPointer<vtkPlotBox> Plot;
60 std::vector<float> XPosition;
61 vtkNew<vtkTransform2D> Transform;
62 vtkNew<vtkAxis> YAxis;
63 vtkNew<vtkPlotGrid> Grid;
64 float SelectedColumnDelta;
65 };
66
67 //-----------------------------------------------------------------------------
68
69 //-----------------------------------------------------------------------------
70 vtkStandardNewMacro(vtkChartBox);
71
72 //-----------------------------------------------------------------------------
vtkChartBox()73 vtkChartBox::vtkChartBox()
74 {
75 this->Storage = new vtkChartBox::Private;
76 this->Storage->Plot->SetParent(this);
77 this->AddItem(this->Storage->YAxis);
78 this->GeometryValid = false;
79 this->Selection = vtkIdTypeArray::New();
80 this->SelectedColumn = -1;
81 this->Storage->Plot->SetSelection(this->Selection);
82 this->VisibleColumns = vtkStringArray::New();
83
84 this->Tooltip = vtkSmartPointer<vtkTooltipItem>::New();
85 this->Tooltip->SetVisible(false);
86 this->AddItem(this->Tooltip);
87
88 // Set up default mouse button assignments for parallel coordinates.
89 this->SetActionToButton(vtkChart::PAN, vtkContextMouseEvent::RIGHT_BUTTON);
90 this->SetActionToButton(vtkChart::SELECT, vtkContextMouseEvent::LEFT_BUTTON);
91 }
92
93 //-----------------------------------------------------------------------------
~vtkChartBox()94 vtkChartBox::~vtkChartBox()
95 {
96 this->Storage->Plot->SetSelection(nullptr);
97 delete this->Storage;
98 this->Selection->Delete();
99 this->VisibleColumns->Delete();
100 }
101
102 //-----------------------------------------------------------------------------
Update()103 void vtkChartBox::Update()
104 {
105 vtkTable* table = this->Storage->Plot->GetData()->GetInput();
106 if (!table)
107 {
108 return;
109 }
110
111 if (table->GetMTime() < this->BuildTime && this->MTime < this->BuildTime)
112 {
113 return;
114 }
115
116 int nbCols = this->VisibleColumns->GetNumberOfTuples();
117
118 this->Storage->XPosition.resize(nbCols);
119
120 double grange[2] = { VTK_DOUBLE_MAX, VTK_DOUBLE_MIN };
121 // Now set up their ranges and locations
122 for (int i = 0; i < nbCols; ++i)
123 {
124 vtkDataArray* array =
125 vtkArrayDownCast<vtkDataArray>(table->GetColumnByName(
126 this->VisibleColumns->GetValue(i)));
127 if (array)
128 {
129 double range[2];
130 array->GetRange(range);
131 if (range[0] < grange[0])
132 {
133 grange[0] = range[0];
134 }
135 if (range[1] > grange[1])
136 {
137 grange[1] = range[1];
138 }
139 }
140 }
141
142 this->Storage->YAxis->SetMinimum(grange[0]);
143 this->Storage->YAxis->SetMaximum(grange[1]);
144
145 this->GeometryValid = false;
146 this->BuildTime.Modified();
147 }
148
149 //-----------------------------------------------------------------------------
Paint(vtkContext2D * painter)150 bool vtkChartBox::Paint(vtkContext2D *painter)
151 {
152 if (this->GetScene()->GetViewWidth() == 0 ||
153 this->GetScene()->GetViewHeight() == 0 ||
154 !this->Visible || !this->Storage->Plot->GetVisible() ||
155 this->VisibleColumns->GetNumberOfTuples() < 1)
156 {
157 // The geometry of the chart must be valid before anything can be drawn
158 return false;
159 }
160
161 //this->UpdateGeometry(painter);
162 this->Update();
163 this->UpdateGeometry(painter);
164
165 // Handle selections
166 vtkIdTypeArray *idArray = nullptr;
167 if (this->AnnotationLink)
168 {
169 vtkSelection *selection = this->AnnotationLink->GetCurrentSelection();
170 if (selection->GetNumberOfNodes() &&
171 this->AnnotationLink->GetMTime() > this->Storage->Plot->GetMTime())
172 {
173 vtkSelectionNode *node = selection->GetNode(0);
174 idArray = vtkArrayDownCast<vtkIdTypeArray>(node->GetSelectionList());
175 this->Storage->Plot->SetSelection(idArray);
176 }
177 }
178 else
179 {
180 vtkDebugMacro("No annotation link set.");
181 }
182
183 painter->PushMatrix();
184 painter->SetTransform(this->Storage->Transform);
185 this->Storage->Plot->Paint(painter);
186 painter->PopMatrix();
187
188 this->Storage->YAxis->Paint(painter);
189
190 if (this->Title)
191 {
192 painter->ApplyTextProp(this->TitleProperties);
193 vtkVector2f stringBounds[2];
194 painter->ComputeStringBounds(this->Title, stringBounds->GetData());
195 float height = 1.1 * stringBounds[1].GetY();
196
197 // Shift the position of the title down if it would be outside the window
198 float shift;
199 if (this->Point2[1] + height > this->Geometry[1])
200 {
201 shift = this->Point2[1] + height - this->Geometry[1];
202 }
203 else
204 {
205 shift = 0.0f;
206 }
207 vtkPoints2D *rect = vtkPoints2D::New();
208 rect->InsertNextPoint(this->Point1[0],
209 this->Point2[1]);
210 rect->InsertNextPoint(this->Point2[0]-this->Point1[0],
211 height - shift);
212 painter->DrawStringRect(rect, this->Title);
213 rect->Delete();
214 }
215
216 if (this->GetShowLegend())
217 {
218 vtkRectf rect;
219 rect.Set(0, 2, 10, 20);
220 this->Storage->Plot->PaintLegend(painter, rect, 0);
221 }
222
223 if (this->Tooltip && this->Tooltip->GetVisible())
224 {
225 this->Tooltip->Paint(painter);
226 }
227
228 return true;
229 }
230
231 //-----------------------------------------------------------------------------
SetColumnVisibility(const vtkStdString & name,bool visible)232 void vtkChartBox::SetColumnVisibility(const vtkStdString& name,
233 bool visible)
234 {
235 if (visible)
236 {
237 for (vtkIdType i = 0; i < this->VisibleColumns->GetNumberOfTuples(); ++i)
238 {
239 if (this->VisibleColumns->GetValue(i) == name)
240 {
241 // Already there, nothing more needs to be done
242 return;
243 }
244 }
245 // Add the column to the end of the list
246 this->VisibleColumns->InsertNextValue(name);
247 this->Modified();
248 this->Update();
249 }
250 else
251 {
252 // Remove the value if present
253 for (vtkIdType i = 0; i < this->VisibleColumns->GetNumberOfTuples(); ++i)
254 {
255 if (this->VisibleColumns->GetValue(i) == name)
256 {
257 // Move all the later elements down by one, and reduce the size
258 while (i < this->VisibleColumns->GetNumberOfTuples()-1)
259 {
260 this->VisibleColumns->SetValue(i, this->VisibleColumns->GetValue(i+1));
261 ++i;
262 }
263 this->VisibleColumns->SetNumberOfTuples(
264 this->VisibleColumns->GetNumberOfTuples()-1);
265 if (this->SelectedColumn >= this->VisibleColumns->GetNumberOfTuples())
266 {
267 this->SelectedColumn = -1;
268 }
269 this->Modified();
270 this->Update();
271 return;
272 }
273 }
274 }
275 }
276
277 //-----------------------------------------------------------------------------
SetColumnVisibility(vtkIdType column,bool visible)278 void vtkChartBox::SetColumnVisibility(vtkIdType column, bool visible)
279 {
280 vtkPlot *plot = this->GetPlot(0);
281 if (!plot || !plot->GetInput())
282 {
283 return;
284 }
285 vtkTable *table = plot->GetInput();
286 if (table)
287 {
288 this->SetColumnVisibility(table->GetColumnName(column), visible);
289 }
290 }
291
292 //-----------------------------------------------------------------------------
SetColumnVisibilityAll(bool visible)293 void vtkChartBox::SetColumnVisibilityAll(bool visible)
294 {
295 // We always need to clear the current visible columns.
296 this->VisibleColumns->SetNumberOfTuples(0);
297 this->SelectedColumn = -1;
298 if (visible)
299 {
300 vtkPlot *plot = this->GetPlot(0);
301 if (!plot || !plot->GetInput())
302 {
303 return;
304 }
305 vtkTable *table = plot->GetInput();
306 for (vtkIdType i = 0; i < table->GetNumberOfColumns(); ++i)
307 {
308 this->SetColumnVisibility(table->GetColumnName(i), visible);
309 }
310 }
311 }
312
313 //-----------------------------------------------------------------------------
GetColumnVisibility(const vtkStdString & name)314 bool vtkChartBox::GetColumnVisibility(const vtkStdString& name)
315 {
316 for (vtkIdType i = 0; i < this->VisibleColumns->GetNumberOfTuples(); ++i)
317 {
318 if (this->VisibleColumns->GetValue(i) == name)
319 {
320 return true;
321 }
322 }
323 return false;
324 }
325
326 //-----------------------------------------------------------------------------
GetColumnVisibility(vtkIdType column)327 bool vtkChartBox::GetColumnVisibility(vtkIdType column)
328 {
329 vtkPlot *plot = this->GetPlot(0);
330 if (!plot || !plot->GetInput())
331 {
332 return false;
333 }
334 vtkTable *table = plot->GetInput();
335 return this->GetColumnVisibility(table->GetColumnName(column));
336 }
337
338 //-----------------------------------------------------------------------------
GetNumberOfVisibleColumns()339 vtkIdType vtkChartBox::GetNumberOfVisibleColumns()
340 {
341 return this->VisibleColumns->GetNumberOfTuples();
342 }
343
344 //-----------------------------------------------------------------------------
GetColumnId(const vtkStdString & name)345 vtkIdType vtkChartBox::GetColumnId(const vtkStdString& name)
346 {
347 vtkPlot *plot = this->GetPlot(0);
348 if (!plot || !plot->GetInput())
349 {
350 return -1;
351 }
352 vtkTable *table = plot->GetInput();
353 vtkIdType nbColumn = table->GetNumberOfColumns();
354 for (vtkIdType i = 0; i < nbColumn; i++)
355 {
356 if (!strcmp(table->GetColumnName(i), name.c_str()))
357 {
358 return i;
359 }
360 }
361 return -1;
362 }
363
364 //-----------------------------------------------------------------------------
GetYAxis()365 vtkAxis* vtkChartBox::GetYAxis()
366 {
367 return this->Storage->YAxis;
368 }
369
370 //-----------------------------------------------------------------------------
SetPlot(vtkPlotBox * plot)371 void vtkChartBox::SetPlot(vtkPlotBox *plot)
372 {
373 this->Storage->Plot = plot;
374 this->Storage->Plot->SetParent(this);
375 this->Modified();
376 }
377
378 //-----------------------------------------------------------------------------
GetPlot(vtkIdType)379 vtkPlot* vtkChartBox::GetPlot(vtkIdType)
380 {
381 return this->Storage->Plot;
382 }
383
384 //-----------------------------------------------------------------------------
GetNumberOfPlots()385 vtkIdType vtkChartBox::GetNumberOfPlots()
386 {
387 return 1;
388 }
389
390 //-----------------------------------------------------------------------------
GetXPosition(int index)391 float vtkChartBox::GetXPosition(int index)
392 {
393 return (index < static_cast<int>(this->Storage->XPosition.size())) ?
394 this->Storage->XPosition[index] : 0;
395 }
396
397 //-----------------------------------------------------------------------------
UpdateGeometry(vtkContext2D * painter)398 void vtkChartBox::UpdateGeometry(vtkContext2D* painter)
399 {
400 vtkVector2i geometry(this->GetScene()->GetViewWidth(),
401 this->GetScene()->GetViewHeight());
402
403 if (geometry.GetX() != this->Geometry[0] ||
404 geometry.GetY() != this->Geometry[1] || !this->GeometryValid)
405 {
406 vtkAxis* axis = this->Storage->YAxis;
407
408 axis->SetPoint1(0, this->Point1[1]);
409 axis->SetPoint2(0, this->Point2[1]);
410 if (axis->GetBehavior() == 0)
411 {
412 axis->AutoScale();
413 }
414 axis->Update();
415
416 int leftBorder = 0;
417 if (axis->GetVisible())
418 {
419 vtkRectf bounds = axis->GetBoundingRect(painter);
420 leftBorder = int(bounds.GetWidth());
421 }
422 axis->SetPoint1(leftBorder, this->Point1[1]);
423 axis->SetPoint2(leftBorder, this->Point2[1]);
424
425 // Take up the entire window right now, this could be made configurable
426 this->SetGeometry(geometry.GetData());
427
428 vtkVector2i tileScale = this->Scene->GetLogicalTileScale();
429 this->SetBorders(leftBorder, 30 * tileScale.GetY(),
430 0, 20 * tileScale.GetY());
431
432 int nbPlots = static_cast<int>(this->Storage->XPosition.size());
433 // Iterate through the axes and set them up to span the chart area.
434 int xStep = (this->Point2[0] - this->Point1[0]) / nbPlots;
435 int x = this->Point1[0] + (xStep / 2);
436
437 for (int i = 0; i < nbPlots; ++i)
438 {
439 this->Storage->XPosition[i] = x;
440
441 x += xStep;
442 }
443 this->GeometryValid = true;
444
445 // Cause the plot transform to be recalculated if necessary
446 this->CalculatePlotTransform();
447
448 if (this->VisibleColumns->GetNumberOfValues() > 1)
449 {
450 this->Storage->Plot->SetBoxWidth(0.5f *
451 (this->GetXPosition(1) - this->GetXPosition(0)));
452 }
453
454 this->Storage->Plot->Update();
455 }
456 }
457
458 //-----------------------------------------------------------------------------
CalculatePlotTransform()459 void vtkChartBox::CalculatePlotTransform()
460 {
461 // In the case of box plots everything is plotted in a normalized
462 // system, where the range is from 0.0 to 1.0 in the y axis, and in screen
463 // coordinates along the x axis.
464 vtkAxis* axis = this->Storage->YAxis;
465 float *min = axis->GetPoint1();
466 float *max = axis->GetPoint2();
467 float yScale = 1.0f / (max[1] - min[1]);
468
469 this->Storage->Transform->Identity();
470 this->Storage->Transform->Translate(0, axis->GetPoint1()[1]);
471 // Get the scale for the plot area from the x and y axes
472 this->Storage->Transform->Scale(1.0, 1.0 / yScale);
473 }
474
475 //-----------------------------------------------------------------------------
Hit(const vtkContextMouseEvent & mouse)476 bool vtkChartBox::Hit(const vtkContextMouseEvent &mouse)
477 {
478 vtkVector2i pos(mouse.GetScreenPos());
479 float width = this->Storage->Plot->GetBoxWidth() / 2.f;
480 return
481 pos[0] > this->Point1[0] - width &&
482 pos[0] < this->Point2[0] + width &&
483 pos[1] > this->Point1[1] &&
484 pos[1] < this->Point2[1];
485 }
486
487 //-----------------------------------------------------------------------------
MouseMoveEvent(const vtkContextMouseEvent & mouse)488 bool vtkChartBox::MouseMoveEvent(const vtkContextMouseEvent &mouse)
489 {
490 if (mouse.GetButton() == this->Actions.Pan() && this->SelectedColumn >= 0)
491 {
492 if (this->Tooltip)
493 {
494 this->Tooltip->SetVisible(false);
495 }
496
497 // Move the plot in x
498 float posX = mouse.GetScenePos().GetX() + this->SelectedColumnDelta;
499 this->Storage->XPosition[this->SelectedColumn] = posX;
500
501 int nbCols = static_cast<int>(this->Storage->XPosition.size());
502 int left = this->SelectedColumn - 1;
503 int right = this->SelectedColumn + 1;
504
505 float width = this->Storage->Plot->GetBoxWidth() * 0.5f;
506
507 if (left >= 0 && (posX - width) < this->Storage->XPosition[left])
508 {
509 this->SwapAxes(this->SelectedColumn, this->SelectedColumn - 1);
510 this->SelectedColumn--;
511 }
512 else if (right < nbCols && (posX + width) > this->Storage->XPosition[right])
513 {
514 this->SwapAxes(this->SelectedColumn, this->SelectedColumn + 1);
515 this->SelectedColumn++;
516 }
517 this->Scene->SetDirty(true);
518 this->Storage->XPosition[this->SelectedColumn] = posX;
519 }
520
521 if (mouse.GetButton() == vtkContextMouseEvent::NO_BUTTON)
522 {
523 this->Scene->SetDirty(true);
524
525 if (this->Tooltip)
526 {
527 this->Tooltip->SetVisible(this->LocatePointInPlots(mouse));
528 }
529 }
530 return true;
531 }
532
533 //-----------------------------------------------------------------------------
MouseButtonPressEvent(const vtkContextMouseEvent & mouse)534 bool vtkChartBox::MouseButtonPressEvent(const vtkContextMouseEvent& mouse)
535 {
536 if (mouse.GetButton() == this->Actions.Pan())
537 {
538 // Select a plot if we are within range
539 if (mouse.GetScenePos()[1] > this->Point1[1] &&
540 mouse.GetScenePos()[1] < this->Point2[1])
541 {
542 // Iterate over the axes, see if we are within 10 pixels of an axis
543 for (size_t i = 0; i < this->Storage->XPosition.size(); ++i)
544 {
545 float selX = this->Storage->XPosition[i];
546 float width = this->Storage->Plot->GetBoxWidth() / 2.f;
547 if (selX - width < mouse.GetScenePos()[0] &&
548 selX + width > mouse.GetScenePos()[0])
549 {
550 this->SelectedColumn = static_cast<int>(i);
551 this->SelectedColumnDelta =
552 this->GetXPosition(this->SelectedColumn) - mouse.GetScenePos().GetX();
553 this->Scene->SetDirty(true);
554 return true;
555 }
556 }
557 }
558 this->SelectedColumn = -1;
559 this->Scene->SetDirty(true);
560 return true;
561 }
562
563 return false;
564 }
565
566 //-----------------------------------------------------------------------------
MouseButtonReleaseEvent(const vtkContextMouseEvent & mouse)567 bool vtkChartBox::MouseButtonReleaseEvent(const vtkContextMouseEvent& mouse)
568 {
569 this->SelectedColumn = -1;
570 if (mouse.GetButton() == this->Actions.Select())
571 {
572 if (this->SelectedColumn >= 0)
573 {
574 if (this->AnnotationLink)
575 {
576 vtkSelection* selection = vtkSelection::New();
577 vtkSelectionNode* node = vtkSelectionNode::New();
578 selection->AddNode(node);
579 node->SetContentType(vtkSelectionNode::INDICES);
580 node->SetFieldType(vtkSelectionNode::POINT);
581
582 node->SetSelectionList(this->Storage->Plot->GetSelection());
583 this->AnnotationLink->SetCurrentSelection(selection);
584 selection->Delete();
585 node->Delete();
586 }
587 this->InvokeEvent(vtkCommand::SelectionChangedEvent);
588 this->Scene->SetDirty(true);
589 }
590 return true;
591 }
592 else if (mouse.GetButton() == this->Actions.Pan())
593 {
594 this->GeometryValid = false;
595 this->SelectedColumn = -1;
596 return true;
597 }
598 this->Scene->SetDirty(true);
599 return true;
600 }
601
602 //-----------------------------------------------------------------------------
LocatePointInPlot(const vtkVector2f & position,const vtkVector2f & tolerance,vtkVector2f & plotPos,vtkPlot * plot,vtkIdType &)603 int vtkChartBox::LocatePointInPlot(const vtkVector2f &position,
604 const vtkVector2f &tolerance,
605 vtkVector2f &plotPos,
606 vtkPlot *plot,
607 vtkIdType &)
608 {
609 if (plot && plot->GetVisible())
610 {
611 vtkPlotBox* plotBar = vtkPlotBox::SafeDownCast(plot);
612 if (plotBar)
613 {
614 // If the plot is a vtkPlotBar, get the segment index too
615 return plotBar->GetNearestPoint(position, tolerance,
616 &plotPos);
617 }
618 else
619 {
620 return plot->GetNearestPoint(position, tolerance, &plotPos);
621 }
622 }
623 return -1;
624 }
625
626 //-----------------------------------------------------------------------------
LocatePointInPlots(const vtkContextMouseEvent & mouse,int invokeEvent)627 bool vtkChartBox::LocatePointInPlots(const vtkContextMouseEvent &mouse,
628 int invokeEvent)
629 {
630 vtkVector2i pos(mouse.GetScreenPos());
631 if (pos[0] > this->Point1[0] &&
632 pos[0] < this->Point2[0] &&
633 pos[1] > this->Point1[1] &&
634 pos[1] < this->Point2[1])
635 {
636 vtkVector2f plotPos, position;
637 vtkTransform2D* transform =
638 this->Storage->Transform;
639 transform->InverseTransformPoints(mouse.GetPos().GetData(),
640 position.GetData(), 1);
641 // Use a tolerance of +/- 5 pixels
642 vtkVector2f tolerance(5*(1.0/transform->GetMatrix()->GetElement(0, 0)),
643 5*(1.0/transform->GetMatrix()->GetElement(1, 1)));
644
645 vtkPlot* plot = this->Storage->Plot;
646 vtkIdType segmentIndex = -1;
647 int seriesIndex =
648 LocatePointInPlot(position, tolerance, plotPos, plot, segmentIndex);
649
650 if (seriesIndex >= 0)
651 {
652 // We found a point, set up the tooltip and return
653 vtkRectd ss(plot->GetShiftScale());
654 vtkVector2d plotPosd(plotPos[0] / ss[2] - ss[0],
655 plotPos[1] / ss[3] - ss[1]);
656 this->SetTooltipInfo(mouse, plotPosd, seriesIndex, plot,
657 segmentIndex);
658 if (invokeEvent >= 0)
659 {
660 vtkChartBoxData plotIndex;
661 plotIndex.SeriesName =
662 this->GetVisibleColumns()->GetValue(seriesIndex);
663 plotIndex.Position = plotPos;
664 plotIndex.ScreenPosition = mouse.GetScreenPos();
665 plotIndex.Index = segmentIndex;
666 // Invoke an event, with the client data supplied
667 this->InvokeEvent(invokeEvent, static_cast<void*>(&plotIndex));
668 }
669 return true;
670 }
671 }
672 return false;
673 }
674
675 //-----------------------------------------------------------------------------
SetTooltip(vtkTooltipItem * tooltip)676 void vtkChartBox::SetTooltip(vtkTooltipItem *tooltip)
677 {
678 if (tooltip == this->Tooltip)
679 {
680 // nothing to change
681 return;
682 }
683
684 if (this->Tooltip)
685 {
686 // remove current tooltip from scene
687 this->RemoveItem(this->Tooltip);
688 }
689
690 this->Tooltip = tooltip;
691
692 if (this->Tooltip)
693 {
694 // add new tooltip to scene
695 this->AddItem(this->Tooltip);
696 }
697 }
698
699 //-----------------------------------------------------------------------------
GetTooltip()700 vtkTooltipItem* vtkChartBox::GetTooltip()
701 {
702 return this->Tooltip;
703 }
704
705 //-----------------------------------------------------------------------------
SetTooltipInfo(const vtkContextMouseEvent & mouse,const vtkVector2d & plotPos,vtkIdType seriesIndex,vtkPlot * plot,vtkIdType segmentIndex)706 void vtkChartBox::SetTooltipInfo(const vtkContextMouseEvent& mouse,
707 const vtkVector2d &plotPos,
708 vtkIdType seriesIndex, vtkPlot* plot,
709 vtkIdType segmentIndex)
710 {
711 if (!this->Tooltip)
712 {
713 return;
714 }
715
716 // Have the plot generate its tooltip label
717 vtkStdString tooltipLabel = plot->GetTooltipLabel(plotPos, seriesIndex,
718 segmentIndex);
719
720 // Set the tooltip
721 this->Tooltip->SetText(tooltipLabel);
722 this->Tooltip->SetPosition(mouse.GetScreenPos()[0] + 2,
723 mouse.GetScreenPos()[1] + 2);
724 }
725
726 //-----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)727 void vtkChartBox::PrintSelf(ostream &os, vtkIndent indent)
728 {
729 this->Superclass::PrintSelf(os, indent);
730 }
731
732 //-----------------------------------------------------------------------------
SwapAxes(int a1,int a2)733 void vtkChartBox::SwapAxes(int a1, int a2)
734 {
735 vtkStdString colTmp = this->VisibleColumns->GetValue(a1);
736 this->VisibleColumns->SetValue(a1, this->VisibleColumns->GetValue(a2));
737 this->VisibleColumns->SetValue(a2, colTmp);
738
739 int xStep = (this->Point2[0] - this->Point1[0]) /
740 (static_cast<int>(this->Storage->XPosition.size()));
741 int xPos = (this->Point1[0] + (xStep / 2)) + xStep * a1;
742 this->Storage->XPosition[a1] = xPos;
743
744 this->GeometryValid = true;
745
746 this->Storage->Plot->Update();
747 }
748