Commit 0a7432f3 authored by Purves, Murray's avatar Purves, Murray
Browse files

#20 WIP Initial capability - needs prettifying

parent 6e260204
Pipeline #15626 passed with stages
in 9 minutes and 58 seconds
......@@ -57,9 +57,9 @@ vtkChartMainWindow::vtkChartMainWindow(QWidget* parent)
table->SetNumberOfRows(numPoints);
for (int i = 0; i < numPoints; ++i)
{
double x = double(i * inc), sin = std::sin(x), cos = std::cos(x),
sum = std::fabs(sin) + std::fabs(cos), sumErr = sum / 5.0,
xErr = x / 5.0;
float x = i * inc, sin = std::sin(x), cos = std::cos(x),
sum = std::fabs(sin) + std::fabs(cos), sumErr = sum / 5.0,
xErr = x / 5.0;
table->SetValue(i, 0, x);
table->SetValue(i, 1, cos);
......@@ -73,16 +73,19 @@ vtkChartMainWindow::vtkChartMainWindow(QWidget* parent)
line->SetInputData(table, 0, 1); // x-axis and cos
line->SetColor(255, 0, 0, 255);
line->SetWidth(0.5);
line = vtkChartWidget->chartXY()->AddPlot(vtkChart::LINE);
line->SetInputData(table, 0, 2); // x-axis and sin
line->SetColor(0, 255, 0, 255);
line->SetWidth(5.0);
vtkPlotPointsErrorBars* points = vtkPlotPointsErrorBars::New();
vtkChartWidget->chartXY()->AddPlot(points);
points->SetInputData(table, 0, 3, 4, 5); // x-axis and sum with errors
points->SetColor(255, 0, 255, 255);
points->SetWidth(2.0);
vtkPlotPointsErrorBars* sinPoints = vtkPlotPointsErrorBars::New();
vtkChartWidget->chartXY()->AddPlot(sinPoints);
sinPoints->SetInputData(table, 0, 2); // x-axis and sin
sinPoints->SetColor(0, 255, 0, 255);
sinPoints->SetWidth(5.0);
vtkPlotPointsErrorBars* sumPoints = vtkPlotPointsErrorBars::New();
vtkChartWidget->chartXY()->AddPlot(sumPoints);
sumPoints->SetInputData(table, 0, 3, 4, 5); // x-axis and sum with errors
sumPoints->SetPlotErrorBars(1);
sumPoints->SetColor(255, 0, 255, 255);
sumPoints->SetWidth(2.0);
}
vtkChartMainWindow::~vtkChartMainWindow() {}
......
......@@ -69,6 +69,8 @@ vtkStandardNewMacro(vtkPlotPointsErrorBars)
vtkPlotPointsErrorBars::vtkPlotPointsErrorBars()
{
this->Points = nullptr;
this->XErrors = nullptr;
this->YErrors = nullptr;
this->Sorted = nullptr;
this->BadPoints = nullptr;
this->ValidPointMask = nullptr;
......@@ -80,6 +82,7 @@ vtkStandardNewMacro(vtkPlotPointsErrorBars)
this->LookupTable = nullptr;
this->Colors = nullptr;
this->ScalarVisibility = 0;
this->PlotErrorBars = 0;
this->UnscaledInputBounds[0] = this->UnscaledInputBounds[2] = vtkMath::Inf();
this->UnscaledInputBounds[1] = this->UnscaledInputBounds[3] = -vtkMath::Inf();
......@@ -93,6 +96,16 @@ vtkPlotPointsErrorBars::~vtkPlotPointsErrorBars()
this->Points->Delete();
this->Points = nullptr;
}
if (this->XErrors)
{
this->XErrors->Delete();
this->XErrors = nullptr;
}
if (this->YErrors)
{
this->YErrors->Delete();
this->YErrors = nullptr;
}
delete this->Sorted;
if (this->BadPoints)
{
......@@ -210,6 +223,31 @@ bool vtkPlotPointsErrorBars::Paint(vtkContext2D *painter)
// render from last good point to one before this bad point
if (id - lastGood > 0)
{
// Draw lines for error bars (if needed)
if (this->PlotErrorBars)
{
float *data = static_cast<float *>(this->Points->GetVoidPointer(0));
for (int i = 0; i < this->Points->GetNumberOfPoints(); ++i)
{
float thisX = data[2 * i], thisY = data[2 * i + 1];
if (XErrors && XErrors->GetNumberOfValues() > i)
{
painter->DrawLine(thisX, thisY, thisX - XErrors->GetValue(i),
thisY);
painter->DrawLine(thisX, thisY, thisX + XErrors->GetValue(i),
thisY);
}
if (YErrors && YErrors->GetNumberOfValues() > i)
{
painter->DrawLine(thisX, thisY, thisX,
thisY - YErrors->GetValue(i));
painter->DrawLine(thisX, thisY, thisX,
thisY + YErrors->GetValue(i));
}
}
}
// Draw markers for points
painter->DrawMarkers(
this->MarkerStyle, false, points + 2 * (lastGood), id - lastGood,
colors ? colors + 4 * (lastGood) : nullptr, nColorComponents);
......@@ -221,6 +259,31 @@ bool vtkPlotPointsErrorBars::Paint(vtkContext2D *painter)
else
{
// draw all of the points
// Draw lines for error bars (if needed)
if (this->PlotErrorBars)
{
float *data = static_cast<float *>(this->Points->GetVoidPointer(0));
for (int i = 0; i < this->Points->GetNumberOfPoints(); ++i)
{
float thisX = data[2 * i], thisY = data[2 * i + 1];
if (XErrors && XErrors->GetNumberOfValues() > i)
{
painter->DrawLine(thisX, thisY, thisX - XErrors->GetValue(i),
thisY);
painter->DrawLine(thisX, thisY, thisX + XErrors->GetValue(i),
thisY);
}
if (YErrors && YErrors->GetNumberOfValues() > i)
{
painter->DrawLine(thisX, thisY, thisX,
thisY - YErrors->GetValue(i));
painter->DrawLine(thisX, thisY, thisX,
thisY + YErrors->GetValue(i));
}
}
}
// Draw markers for points
painter->DrawMarkers(this->MarkerStyle, false, points,
this->Points->GetNumberOfPoints(), colors,
nColorComponents);
......@@ -642,11 +705,39 @@ void CopyToPointsSwitch(vtkPoints2D *points, A *a, vtkDataArray *b, int n,
}
}
// Copy the data array into the X error array
template <typename A>
void CopyToXErrors(vtkFloatArray *xErrors, A *a, int n, const vtkRectd &ss)
{
xErrors->Initialize();
// xErrors->SetNumberOfComponents(n);
// float *data = static_cast<float *>(xErrors->GetVoidPointer(0));
for (int i = 0; i < n; ++i)
{
xErrors->InsertNextValue(static_cast<float>((a[i] + ss[0]) * ss[2]));
// data[i] = static_cast<float>((a[i] + ss[0]) * ss[2]);
}
}
// Copy the data array into the Y error array
template <typename A>
void CopyToYErrors(vtkFloatArray *yErrors, A *a, int n, const vtkRectd &ss)
{
yErrors->Initialize();
// yErrors->SetNumberOfComponents(n);
// float *data = static_cast<float *>(yErrors->GetVoidPointer(0));
for (int i = 0; i < n; ++i)
{
yErrors->InsertNextValue(static_cast<float>((a[i] + ss[1]) * ss[3]));
// data[i] = static_cast<float>((a[i] + ss[1]) * ss[3]);
}
}
} // namespace
//-----------------------------------------------------------------------------
bool vtkPlotPointsErrorBars::GetDataArrays(vtkTable *table,
vtkDataArray *array[2])
vtkDataArray *array[4])
{
if (!table)
{
......@@ -658,6 +749,10 @@ bool vtkPlotPointsErrorBars::GetDataArrays(vtkTable *table,
? nullptr
: this->Data->GetInputArrayToProcess(0, table);
array[1] = this->Data->GetInputArrayToProcess(1, table);
array[2] = this->PlotErrorBars ? this->Data->GetInputArrayToProcess(2, table)
: nullptr;
array[3] = this->PlotErrorBars ? this->Data->GetInputArrayToProcess(3, table)
: nullptr;
if (!array[0] && !this->UseIndexForXSeries)
{
......@@ -677,13 +772,15 @@ bool vtkPlotPointsErrorBars::GetDataArrays(vtkTable *table,
<< array[1]->GetNumberOfTuples());
return false;
}
// TODO: Could add check/errors if PlotErrorBars is true but no error data
// present
return true;
}
//-----------------------------------------------------------------------------
bool vtkPlotPointsErrorBars::UpdateTableCache(vtkTable *table)
{
vtkDataArray *array[2] = {nullptr, nullptr};
vtkDataArray *array[4] = {nullptr, nullptr, nullptr, nullptr};
if (!this->GetDataArrays(table, array))
{
this->BuildTime.Modified();
......@@ -716,6 +813,35 @@ bool vtkPlotPointsErrorBars::UpdateTableCache(vtkTable *table)
x->GetNumberOfTuples(), this->ShiftScale));
}
}
// Copy the error data into the relevant structures
if (this->PlotErrorBars)
{
if (!this->XErrors)
{
this->XErrors = vtkFloatArray::New();
}
if (!this->YErrors)
{
this->YErrors = vtkFloatArray::New();
}
vtkDataArray *xErr = array[2];
switch (xErr->GetDataType())
{
vtkTemplateMacro(CopyToXErrors(
this->XErrors, static_cast<VTK_TT *>(xErr->GetVoidPointer(0)),
xErr->GetNumberOfTuples(), this->ShiftScale));
}
vtkDataArray *yErr = array[3];
switch (yErr->GetDataType())
{
vtkTemplateMacro(CopyToYErrors(
this->YErrors, static_cast<VTK_TT *>(yErr->GetVoidPointer(0)),
yErr->GetNumberOfTuples(), this->ShiftScale));
}
}
this->CalculateLogSeries();
this->FindBadPoints();
this->Points->Modified();
......@@ -760,7 +886,7 @@ bool vtkPlotPointsErrorBars::UpdateTableCache(vtkTable *table)
void vtkPlotPointsErrorBars::CalculateUnscaledInputBounds()
{
vtkTable *table = this->Data->GetInput();
vtkDataArray *array[2] = {nullptr, nullptr};
vtkDataArray *array[4] = {nullptr, nullptr, nullptr, nullptr};
if (!this->GetDataArrays(table, array))
{
return;
......@@ -845,7 +971,7 @@ void vtkPlotPointsErrorBars::FindBadPoints()
// Scan through and find any bad points.
vtkTable *table = this->Data->GetInput();
vtkDataArray *array[2] = {nullptr, nullptr};
vtkDataArray *array[4] = {nullptr, nullptr, nullptr, nullptr};
if (!this->GetDataArrays(table, array))
{
return;
......
......@@ -204,7 +204,7 @@ class VTKCHARTSCORE_EXPORT vtkPlotPointsErrorBars : public vtkPlotErrorBars
/**
* Populate the data arrays ready to operate on input data.
*/
bool GetDataArrays(vtkTable *table, vtkDataArray *array[2]);
bool GetDataArrays(vtkTable *table, vtkDataArray *array[4]);
/**
* Update the table cache.
......@@ -247,6 +247,14 @@ class VTKCHARTSCORE_EXPORT vtkPlotPointsErrorBars : public vtkPlotErrorBars
vtkNew<vtkFloatArray> SelectedPoints;
//@}
//@{
/**
* Store two arrays of error data for this data series.
*/
vtkFloatArray *XErrors;
vtkFloatArray *YErrors;
//@}
//@{
/**
* Sorted points, used when searching for the nearest point.
......
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