Commit cb520946 authored by Mathieu Westphal's avatar Mathieu Westphal

Adding a Resize option in ChartMatrix and Use it in ScatterPlot

vtkChartMatrix now features a SetSpecificResize allowing to move
the bottom left point of a single chart. This feature is used in
vtkScatterPlotMatrix to move the Big Chart plot a little on top right
in order to prevent overlap, using painter to compute axis bounding rect.
It also add a compare operator to vector in order to use it in the stl.
parent 2d000780
Pipeline #19785 passed with stage
c6db89e945055102d94635f6576f58dc
23f2ccb56b70deba457a9d5bfa871503
......@@ -100,15 +100,21 @@ bool vtkChartMatrix::Paint(vtkContext2D *painter)
{
y = this->Borders[vtkAxis::BOTTOM];
}
vtkVector2f resize(0., 0.);
vtkVector2i key(i, j);
if (this->SpecificResize.find(key) != this->SpecificResize.end())
{
resize = this->SpecificResize[key];
}
size_t index = j * this->Size.GetX() + i;
if (this->Private->Charts[index])
{
vtkChart *chart = this->Private->Charts[index];
vtkVector2i &span = this->Private->Spans[index];
chart->SetSize(vtkRectf(x, y,
increments.GetX() * span.GetX() +
chart->SetSize(vtkRectf(x + resize.GetX(), y + resize.GetY(),
increments.GetX() * span.GetX() - resize.GetX() +
(span.GetX() - 1) * this->Gutter.GetX(),
increments.GetY() * span.GetY() +
increments.GetY() * span.GetY() - resize.GetY() +
(span.GetY() - 1) * this->Gutter.GetY()));
}
}
......@@ -190,6 +196,18 @@ void vtkChartMatrix::SetGutterY(float value)
this->LayoutIsDirty = true;
}
void vtkChartMatrix::SetSpecificResize(const vtkVector2i& index, const vtkVector2f& resize)
{
this->SpecificResize[index] = resize;
this->LayoutIsDirty = true;
}
void vtkChartMatrix::ClearSpecificResizes()
{
this->SpecificResize.clear();
this->LayoutIsDirty = true;
}
void vtkChartMatrix::Allocate()
{
// Force allocation of all objects as vtkChartXY.
......@@ -297,16 +315,24 @@ vtkVector2i vtkChartMatrix::GetChartIndex(const vtkVector2f &position)
{
y = this->Borders[vtkAxis::BOTTOM];
}
vtkVector2f resize(0., 0.);
vtkVector2i key(i, j);
if (this->SpecificResize.find(key) != this->SpecificResize.end())
{
resize = this->SpecificResize[key];
}
size_t index = j * this->Size.GetX() + i;
if (this->Private->Charts[index])
{
vtkVector2i &span = this->Private->Spans[index];
// Check if the supplied location is within this charts area.
if (position.GetX() > x &&
position.GetX() < (x + increments.GetX() * span.GetX()
float x2 = x + resize.GetX();
float y2 = y + resize.GetY();
if (position.GetX() > x2 &&
position.GetX() < (x2 + increments.GetX() * span.GetX() - resize.GetY()
+ (span.GetX() - 1) * this->Gutter.GetX()) &&
position.GetY() > y &&
position.GetY() < (y + increments.GetY() * span.GetY()
position.GetY() > y2 &&
position.GetY() < (y2 + increments.GetY() * span.GetY() - resize.GetY()
+ (span.GetY() - 1) * this->Gutter.GetY()))
return vtkVector2i(i, j);
}
......
......@@ -27,6 +27,9 @@
#include "vtkAbstractContextItem.h"
#include "vtkVector.h" // For ivars
#include <map> // For specific gutter
#include <utility> // For specific gutter
class vtkChart;
class VTKCHARTSCORE_EXPORT vtkChartMatrix : public vtkAbstractContextItem
......@@ -78,6 +81,11 @@ public:
void SetGutterX(float value);
void SetGutterY(float value);
// Description:
// Set a specific resize that will move the bottom left point of a chart.
virtual void SetSpecificResize(const vtkVector2i& index, const vtkVector2f& resize);
virtual void ClearSpecificResizes();
// Description:
// Get the gutter that should be left between the charts in the matrix.
virtual vtkVector2f GetGutter() const { return this->Gutter; }
......@@ -127,6 +135,7 @@ protected:
// The gutter between each chart.
vtkVector2f Gutter;
std::map<vtkVector2i, vtkVector2f> SpecificResize;
int Borders[4];
bool LayoutIsDirty;
......
......@@ -15,32 +15,32 @@
#include "vtkScatterPlotMatrix.h"
#include "vtkTable.h"
#include "vtkFloatArray.h"
#include "vtkIntArray.h"
#include "vtkChartXY.h"
#include "vtkPlot.h"
#include "vtkAnnotationLink.h"
#include "vtkAxis.h"
#include "vtkBrush.h"
#include "vtkCallbackCommand.h"
#include "vtkChartXY.h"
#include "vtkChartXYZ.h"
#include "vtkCommand.h"
#include "vtkContext2D.h"
#include "vtkContextMouseEvent.h"
#include "vtkStdString.h"
#include "vtkStringArray.h"
#include "vtkNew.h"
#include "vtkPen.h"
#include "vtkContextScene.h"
#include "vtkFloatArray.h"
#include "vtkIntArray.h"
#include "vtkMathUtilities.h"
#include "vtkAnnotationLink.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkBrush.h"
#include "vtkPen.h"
#include "vtkPlot.h"
#include "vtkPlotPoints.h"
#include "vtkPlotPoints3D.h"
#include "vtkCommand.h"
#include "vtkTextProperty.h"
#include "vtkContextScene.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkCallbackCommand.h"
#include "vtkVectorOperators.h"
#include "vtkStdString.h"
#include "vtkStringArray.h"
#include "vtkTable.h"
#include "vtkTextProperty.h"
#include "vtkTooltipItem.h"
#include "vtkChartXYZ.h"
#include "vtkVectorOperators.h"
// STL includes
#include <map>
......@@ -353,7 +353,8 @@ bool MoveColumn(vtkStringArray* visCols, int fromCol, int toCol)
vtkStandardNewMacro(vtkScatterPlotMatrix)
vtkScatterPlotMatrix::vtkScatterPlotMatrix()
: NumberOfBins(10), NumberOfFrames(25)
: NumberOfBins(10), NumberOfFrames(25),
LayoutUpdatedTime(0)
{
this->Private = new PIMPL;
this->TitleProperties = vtkSmartPointer<vtkTextProperty>::New();
......@@ -379,10 +380,15 @@ void vtkScatterPlotMatrix::Update()
this->UpdateLayout();
this->Private->VisibleColumnsModified = false;
}
else if (this->GetMTime() > this->LayoutUpdatedTime)
{
this->UpdateLayout();
}
}
bool vtkScatterPlotMatrix::Paint(vtkContext2D *painter)
{
this->CurrentPainter = painter;
this->Update();
return Superclass::Paint(painter);
}
......@@ -925,8 +931,7 @@ void vtkScatterPlotMatrix::InsertVisibleColumn(const vtkStdString &name,
this->Private->VisibleColumnsModified =
MoveColumn(this->VisibleColumns.GetPointer(), currIdx, toIdx);
}
this->Update();
this->LayoutIsDirty = true;
}
bool vtkScatterPlotMatrix::GetColumnVisibility(const vtkStdString &name)
......@@ -980,7 +985,7 @@ void vtkScatterPlotMatrix::SetVisibleColumns(vtkStringArray* visColumns)
this->VisibleColumns->DeepCopy(visColumns);
}
this->Private->VisibleColumnsModified = true;
this->Update();
this->LayoutIsDirty = true;
}
void vtkScatterPlotMatrix::SetNumberOfBins(int numberOfBins)
......@@ -1369,6 +1374,8 @@ void vtkScatterPlotMatrix::UpdateLayout()
// Where the indices are those of the columns. The indices of the charts
// originate in the bottom-left. S = scatter plot, H = histogram and + is the
// big chart.
this->LayoutUpdatedTime = this->GetMTime();
this->ClearSpecificResizes();
int n = this->Size.GetX();
this->UpdateAxes();
this->Private->BigChart3D->SetAnnotationLink(this->Private->Link.GetPointer());
......@@ -1456,6 +1463,29 @@ void vtkScatterPlotMatrix::UpdateLayout()
this->SetChartSpan(pos, vtkVector2i(n - i, n - j));
this->SetActivePlot(vtkVector2i(0, n - 2));
// The big chart need to be resized only when it is
// "between" the histograms, ie. when n is even.
if (n%2 == 0)
{
vtkVector2f resize(30, 30);
if (this->CurrentPainter)
{
// Try to use painter to resize the big plot
vtkVector2i posLeft(i - 1, j);
vtkVector2i posBottom(i, j - 1);
vtkAxis* axis1 = this->GetChart(posLeft)->GetAxis(vtkAxis::RIGHT);
vtkAxis* axis2 = this->GetChart(posBottom)->GetAxis(vtkAxis::TOP);
int resizeX = std::max(axis1->GetBoundingRect(this->CurrentPainter).GetWidth()
- this->Gutter.GetX(), this->Gutter.GetX());
int resizeY = std::max(axis2->GetBoundingRect(this->CurrentPainter).GetWidth()
- this->Gutter.GetY(), this->Gutter.GetY());
resize.Set(resizeX, resizeY);
}
// Move big plot bottom left point to avoid overlap
this->SetSpecificResize(pos, resize);
}
}
// Only show bottom axis label for bottom plots
if (j > 0)
......@@ -1748,7 +1778,7 @@ void vtkScatterPlotMatrix::UpdateChartSettings(int plotType)
this->Private->ChartSettings[ACTIVEPLOT]);
this->Private->BigChart->SetSelectionMode(this->SelectionMode);
}
this->Modified();
}
//-----------------------------------------------------------------------------
void vtkScatterPlotMatrix::SetSelectionMode(int selMode)
......
......@@ -29,6 +29,7 @@
#include "vtkNew.h" // For ivars
#include "vtkColor.h" // For member function return
#include "vtkStdString.h" // For ivars
#include "vtkWeakPointer.h" // For currentPainter
class vtkStringArray;
class vtkTable;
......@@ -377,6 +378,9 @@ private:
PIMPL *Private;
friend class PIMPL;
vtkWeakPointer<vtkContext2D> CurrentPainter;
unsigned long LayoutUpdatedTime;
// Go through the process of calculating axis ranges, etc...
void UpdateAxes();
void ApplyAxisSetting(vtkChart *chart, const vtkStdString &x,
......
......@@ -168,6 +168,13 @@ public:
// Description:
// Get the y component of the vector, i.e. element 1.
const T& GetY() const { return this->Data[1]; }
// Description:
// Lexicographical comparison of two vector.
bool operator<(const vtkVector2<T> &v) const
{
return (this->Data[0] < v.Data[0]) || (this->Data[0] == v.Data[0] && this->Data[1] < v.Data[1]);
}
};
// .NAME vtkVector3 - templated base type for storage of 3D vectors.
......@@ -238,6 +245,14 @@ public:
res[2] = this->Data[0] * other.Data[1] - this->Data[1] * other.Data[0];
return res;
}
// Description:
// Lexicographical comparison of two vector.
bool operator<(const vtkVector3<T> &v) const
{
return (this->Data[0] < v.Data[0]) || (this->Data[0] == v.Data[0] && this->Data[1] < v.Data[1]) ||
(this->Data[0] == v.Data[0] && this->Data[1] == v.Data[1] && this->Data[2] < v.Data[2]);
}
};
// Description:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment