Commit 3ecd03f5 authored by Marcus D. Hanwell's avatar Marcus D. Hanwell
Browse files

ENH: Added facility to set an indexed label array.

New API in vtkPlot to set an indexed label array, and new code in
vtkChartXY to use this if available. Modifications to vtkPlotPoints
return the actual index of the point found, so that code downstream can
look up further information on a point if necessary/desirable.

Change-Id: I7e6e57f69ca2ed469715962841d7a343477e0792
parent e537c8c8
......@@ -55,6 +55,7 @@
#include "vtksys/ios/sstream"
#include "vtkDataArray.h"
#include "vtkStringArray.h"
// My STL containers
#include <vector>
......@@ -1272,13 +1273,21 @@ void vtkChartXY::SetTooltipInfo(const vtkContextMouseEvent& mouse,
label += vtkStdString(bar->GetGroupName()) + ": ";
}
}
label += plot->GetLabel(seriesIndex);
vtkStringArray *labels = plot->GetIndexedLabels();
if (labels && seriesIndex < labels->GetNumberOfTuples())
{
label += labels->GetValue(seriesIndex) + ": ";
}
else
{
label += plot->GetLabel(0) + ": ";
}
// If axes are set to logarithmic scale we need to convert the
// axis value using 10^(axis value)
vtksys_ios::ostringstream ostr;
ostr << label;
ostr.imbue(vtkstd::locale::classic());
ostr.setf(ios::fixed, ios::floatfield);
ostr << label << ": ";
ostr.precision(ChartPrivate->axes[vtkAxis::BOTTOM]->GetPrecision());
ostr << (this->ChartPrivate->axes[vtkAxis::BOTTOM]->GetLogScale()?
pow(double(10.0), double(plotPos.X())):
......
......@@ -148,9 +148,7 @@ vtkStdString vtkPlot::GetLabel()
return this->GetLabel(0);
}
//-----------------------------------------------------------------------------
void vtkPlot::SetLabels(vtkStringArray *labels)
{
if (this->Labels == labels)
......@@ -200,6 +198,24 @@ int vtkPlot::GetNumberOfLabels()
}
}
//-----------------------------------------------------------------------------
void vtkPlot::SetIndexedLabels(vtkStringArray *labels)
{
if (this->IndexedLabels == labels)
{
return;
}
this->IndexedLabels = labels;
this->Modified();
}
//-----------------------------------------------------------------------------
vtkStringArray * vtkPlot::GetIndexedLabels()
{
return this->IndexedLabels.GetPointer();
}
//-----------------------------------------------------------------------------
vtkStdString vtkPlot::GetLabel(vtkIdType index)
{
......
......@@ -96,15 +96,15 @@ public:
// Description:
// Set a single label on this plot.
void SetLabel(const vtkStdString &label);
virtual void SetLabel(const vtkStdString &label);
// Description:
// Get the single label of this plot.
vtkStdString GetLabel();
virtual vtkStdString GetLabel();
// Description:
// Set the plot labels.
void SetLabels(vtkStringArray *labels);
virtual void SetLabels(vtkStringArray *labels);
// Description:
// Get the plot labels.
......@@ -118,6 +118,16 @@ public:
// Get the label at the specified index.
vtkStdString GetLabel(vtkIdType index);
// Description:
// Set indexed labels for the plot. If set, this array can be used to provide
// custom labels for each point in a plot. This array should be the same
// length as the points array. Default is null (no indexed labels).
void SetIndexedLabels(vtkStringArray *labels);
// Description:
// Get the indexed labels array.
virtual vtkStringArray *GetIndexedLabels();
// Description:
// Get the data object that the plot will draw.
vtkGetObjectMacro(Data, vtkContextMapper2D);
......@@ -197,6 +207,10 @@ protected:
// Holds Labels when they're auto-created
vtkSmartPointer<vtkStringArray> AutoLabels;
// Description:
// Holds Labels when they're auto-created
vtkSmartPointer<vtkStringArray> IndexedLabels;
// Description:
// Use the Y array index for the X value. If true any X column setting will be
// ignored, and the X values will simply be the index of the Y column.
......
......@@ -33,12 +33,26 @@
#include <algorithm>
// PIMPL for STL vector...
class vtkPlotPoints::VectorPIMPL : public std::vector<vtkVector2f>
struct vtkIndexedVector2f
{
size_t index;
vtkVector2f pos;
};
class vtkPlotPoints::VectorPIMPL : public std::vector<vtkIndexedVector2f>
{
public:
VectorPIMPL(vtkVector2f* startPos, vtkVector2f* finishPos)
: std::vector<vtkVector2f>(startPos, finishPos)
VectorPIMPL(vtkVector2f* array, size_t n)
: std::vector<vtkIndexedVector2f>()
{
this->reserve(n);
for (size_t i = 0; i < n; ++i)
{
vtkIndexedVector2f tmp;
tmp.index = i;
tmp.pos = array[i];
this->push_back(tmp);
}
}
};
......@@ -427,6 +441,19 @@ void vtkPlotPoints::GetBounds(double bounds[4])
namespace
{
bool compVector3fX(const vtkIndexedVector2f& v1,
const vtkIndexedVector2f& v2)
{
if (v1.pos.X() < v2.pos.X())
{
return true;
}
else
{
return false;
}
}
// Compare the two vectors, in X component only
bool compVector2fX(const vtkVector2f& v1, const vtkVector2f& v2)
{
......@@ -480,8 +507,8 @@ int vtkPlotPoints::GetNearestPoint(const vtkVector2f& point,
{
vtkVector2f* data =
static_cast<vtkVector2f*>(this->Points->GetVoidPointer(0));
this->Sorted = new VectorPIMPL(data, data+n);
std::sort(this->Sorted->begin(), this->Sorted->end(), compVector2fX);
this->Sorted = new VectorPIMPL(data, n);
std::sort(this->Sorted->begin(), this->Sorted->end(), compVector3fX);
}
// Set up our search array, use the STL lower_bound algorithm
......@@ -489,19 +516,21 @@ int vtkPlotPoints::GetNearestPoint(const vtkVector2f& point,
VectorPIMPL &v = *this->Sorted;
// Get the lowest point we might hit within the supplied tolerance
vtkVector2f lowPoint(point.X()-tol.X(), 0.0f);
low = std::lower_bound(v.begin(), v.end(), lowPoint, compVector2fX);
vtkIndexedVector2f lowPoint;
lowPoint.index = -1;
lowPoint.pos = vtkVector2f(point.X()-tol.X(), 0.0f);
low = std::lower_bound(v.begin(), v.end(), lowPoint, compVector3fX);
// Now consider the y axis
float highX = point.X() + tol.X();
while (low != v.end())
{
if (inRange(point, tol, *low))
if (inRange(point, tol, (*low).pos))
{
*location = *low;
return 0;
*location = (*low).pos;
return (*low).index;
}
else if (low->X() > highX)
else if (low->pos.X() > highX)
{
break;
}
......
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