Commit 3c0ef274 authored by Purves, Murray's avatar Purves, Murray
Browse files

#20 Adding vtkPlotLineErrorBars

parent deb9f883
Pipeline #15636 passed with stages
in 7 minutes and 41 seconds
......@@ -65,6 +65,7 @@ ELSE()
${SOURCES}
vtkchartwidget.cc
vtkPlotErrorBars.cc
vtkPlotLineErrorBars.cc
vtkPlotPointsErrorBars.cc
)
ENDIF()
......@@ -77,6 +78,7 @@ ELSE()
IF(TPL_ENABLE_VTK)
SET(HEADERS ${HEADERS}
vtkPlotErrorBars.hh
vtkPlotLineErrorBars.hh
vtkPlotPointsErrorBars.hh
)
ENDIF()
......
......@@ -13,6 +13,7 @@ VTK_MODULE_INIT(vtkRenderingFreeType)
#include "vtkTable.h"
#include "radixwidgets/vtkPlotErrorBars.hh"
#include "radixwidgets/vtkPlotLineErrorBars.hh"
#include "radixwidgets/vtkPlotPointsErrorBars.hh"
#include "radixwidgets/vtkchartwidget.hh"
......@@ -49,6 +50,9 @@ vtkChartMainWindow::vtkChartMainWindow(QWidget* parent)
vtkNew<vtkFloatArray> arrXErr;
arrXErr->SetName("x error");
table->AddColumn(arrXErr);
vtkNew<vtkFloatArray> arrCosErr;
arrCosErr->SetName("cos error");
table->AddColumn(arrCosErr);
vtkNew<vtkFloatArray> arrSumErr;
arrSumErr->SetName("Sum error");
table->AddColumn(arrSumErr);
......@@ -58,21 +62,24 @@ vtkChartMainWindow::vtkChartMainWindow(QWidget* parent)
for (int i = 0; i < numPoints; ++i)
{
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;
sum = std::fabs(sin) + std::fabs(cos), xErr = x / 10.0,
cosErr = cos / 5.0, sumErr = sum / 5.0;
table->SetValue(i, 0, x);
table->SetValue(i, 1, cos);
table->SetValue(i, 2, sin);
table->SetValue(i, 3, sum);
table->SetValue(i, 4, xErr);
table->SetValue(i, 5, sumErr);
table->SetValue(i, 5, cosErr);
table->SetValue(i, 6, sumErr);
}
vtkPlot* line = vtkChartWidget->chartXY()->AddPlot(vtkChart::LINE);
line->SetInputData(table, 0, 1); // x-axis and cos
line->SetColor(255, 0, 0, 255);
line->SetWidth(0.5);
vtkPlotLineErrorBars* cosLine = vtkPlotLineErrorBars::New();
vtkChartWidget->chartXY()->AddPlot(cosLine);
cosLine->SetInputData(table, 0, 1, 4, 5); // x-axis and cos with errors
cosLine->SetPlotErrorBars(1);
cosLine->SetColor(255, 0, 0, 255);
cosLine->SetWidth(0.5);
vtkPlotPointsErrorBars* sinPoints = vtkPlotPointsErrorBars::New();
vtkChartWidget->chartXY()->AddPlot(sinPoints);
......@@ -82,7 +89,7 @@ vtkChartMainWindow::vtkChartMainWindow(QWidget* parent)
vtkPlotPointsErrorBars* sumPoints = vtkPlotPointsErrorBars::New();
vtkChartWidget->chartXY()->AddPlot(sumPoints);
sumPoints->SetInputData(table, 0, 3, 4, 5); // x-axis and sum with errors
sumPoints->SetInputData(table, 0, 3, 4, 6); // x-axis and sum with errors
sumPoints->SetPlotErrorBars(1);
sumPoints->SetColor(255, 0, 255, 255);
sumPoints->SetWidth(2.0);
......
/*=========================================================================
Program: Visualization Toolkit
Module: vtkPlotLine.cxx
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.
=========================================================================*/
#include "radixwidgets/vtkPlotLineErrorBars.hh"
#include "vtkContext2D.h"
#include "vtkIdTypeArray.h"
#include "vtkPen.h"
#include "vtkPoints2D.h"
#include "vtkRect.h"
#include "vtkObjectFactory.h"
//-----------------------------------------------------------------------------
vtkStandardNewMacro(vtkPlotLineErrorBars);
//-----------------------------------------------------------------------------
vtkPlotLineErrorBars::vtkPlotLineErrorBars()
{
this->MarkerStyle = vtkPlotPointsErrorBars::NONE;
this->PolyLine = true;
}
//-----------------------------------------------------------------------------
vtkPlotLineErrorBars::~vtkPlotLineErrorBars() {}
//-----------------------------------------------------------------------------
bool vtkPlotLineErrorBars::Paint(vtkContext2D *painter)
{
// This is where everything should be drawn, or dispatched to other methods.
vtkDebugMacro(<< "Paint event called in vtkPlotLineErrorBars.");
if (!this->Visible || !this->Points)
{
return false;
}
// Draw the line between the points
painter->ApplyPen(this->Pen);
if (this->BadPoints && this->BadPoints->GetNumberOfTuples() > 0)
{
// draw lines skipping bad points
float *points = static_cast<float *>(this->Points->GetVoidPointer(0));
const int pointSize = 2;
vtkIdType lastGood = 0;
vtkIdType bpIdx = 0;
vtkIdType lineIncrement = this->PolyLine ? 1 : 2;
vtkIdType nPoints = this->Points->GetNumberOfPoints();
vtkIdType nBadPoints = this->BadPoints->GetNumberOfTuples();
while (lastGood < nPoints)
{
vtkIdType id = bpIdx < nBadPoints ? this->BadPoints->GetValue(bpIdx)
: this->Points->GetNumberOfPoints();
// With non polyline, we discard a line if any of its points are bad
if (!this->PolyLine && id % 2 == 1)
{
id--;
}
// render from last good point to one before this bad point
if (id - lastGood > 1)
{
int start = lastGood;
int numberOfPoints = id - start;
if (this->PolyLine)
{
painter->DrawPoly(points + pointSize * start, numberOfPoints);
}
else
{
painter->DrawLines(points + pointSize * start, numberOfPoints);
}
}
lastGood = id + lineIncrement;
bpIdx++;
}
}
else
{
// draw lines between all points
if (this->PolyLine)
{
painter->DrawPoly(this->Points);
}
else
{
painter->DrawLines(this->Points);
}
}
return this->vtkPlotPointsErrorBars::Paint(painter);
}
//-----------------------------------------------------------------------------
bool vtkPlotLineErrorBars::PaintLegend(vtkContext2D *painter,
const vtkRectf &rect, int)
{
painter->ApplyPen(this->Pen);
painter->DrawLine(rect[0], rect[1] + 0.5 * rect[3], rect[0] + rect[2],
rect[1] + 0.5 * rect[3]);
this->Superclass::PaintLegend(painter, rect, 0);
return true;
}
//-----------------------------------------------------------------------------
void vtkPlotLineErrorBars::PrintSelf(ostream &os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkPlotLine.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.
=========================================================================*/
/**
* @class vtkPlotLine
* @brief Class for drawing an XY line plot given two columns from
* a vtkTable.
*
*
*
*/
#ifndef RADIX_RADIXWIDGETS_VTKPLOTLINEERRORBARS_HH_
#define RADIX_RADIXWIDGETS_VTKPLOTLINEERRORBARS_HH_
#include "vtkChartsCoreModule.h" // For export macro
#include "radixwidgets/vtkPlotPointsErrorBars.hh"
class VTKCHARTSCORE_EXPORT vtkPlotLineErrorBars : public vtkPlotPointsErrorBars
{
public:
vtkTypeMacro(vtkPlotLineErrorBars, vtkPlotPointsErrorBars);
void PrintSelf(ostream &os, vtkIndent indent) override;
/**
* Creates a 2D Chart object.
*/
static vtkPlotLineErrorBars *New();
/**
* Paint event for the XY plot, called whenever the chart needs to be drawn.
*/
bool Paint(vtkContext2D *painter) override;
/**
* Paint legend event for the XY plot, called whenever the legend needs the
* plot items symbol/mark/line drawn. A rect is supplied with the lower left
* corner of the rect (elements 0 and 1) and with width x height (elements 2
* and 3). The plot can choose how to fill the space supplied.
*/
bool PaintLegend(vtkContext2D *painter, const vtkRectf &rect,
int legendIndex) override;
//@{
/**
* Turn on/off flag to control whether the points define a poly line
* (true) or multiple line segments (false).
* If true (default), a segment is drawn between each points
* (e.g. [P1P2, P2P3, P3P4...].) If false, a segment is drawn for each pair
* of points (e.g. [P1P2, P3P4,...].)
*/
vtkSetMacro(PolyLine, bool);
vtkGetMacro(PolyLine, bool);
vtkBooleanMacro(PolyLine, bool);
//@}
protected:
vtkPlotLineErrorBars();
~vtkPlotLineErrorBars() override;
/**
* Poly line (true) or line segments(false).
*/
bool PolyLine;
private:
vtkPlotLineErrorBars(const vtkPlotLineErrorBars &) = delete;
void operator=(const vtkPlotLineErrorBars &) = delete;
};
#endif // RADIX_RADIXWIDGETS_VTKPLOTLINEERRORBARS_HH_
......@@ -191,6 +191,40 @@ bool vtkPlotPointsErrorBars::Paint(vtkContext2D *painter)
}
}
// Draw error bars if required
if (this->PlotErrorBars)
{
float *points = static_cast<float *>(this->Points->GetVoidPointer(0));
if (this->BadPoints && this->BadPoints->GetNumberOfTuples() > 0)
{
vtkIdType lastGood = 0;
vtkIdType bpIdx = 0;
vtkIdType nPoints = this->Points->GetNumberOfPoints();
vtkIdType nBadPoints = this->BadPoints->GetNumberOfTuples();
while (lastGood < nPoints)
{
vtkIdType id = bpIdx < nBadPoints ? this->BadPoints->GetValue(bpIdx)
: this->Points->GetNumberOfPoints();
// render from last good point to one before this bad point
if (id - lastGood > 0)
{
// Draw lines for error bars
PaintErrorBars(painter, points + 2 * (lastGood), id - lastGood);
}
lastGood = id + 1;
bpIdx++;
}
}
else
{
// draw all of the error bars
PaintErrorBars(painter, points, this->Points->GetNumberOfPoints());
}
}
// If there is a marker style, then draw the marker for each point too
if (this->MarkerStyle != VTK_MARKER_NONE)
{
......@@ -223,13 +257,6 @@ 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)
{
PaintErrorBars(painter, points + 2 * (lastGood), id - lastGood);
}
// Draw markers for points
painter->DrawMarkers(
this->MarkerStyle, false, points + 2 * (lastGood), id - lastGood,
colors ? colors + 4 * (lastGood) : nullptr, nColorComponents);
......@@ -241,13 +268,6 @@ bool vtkPlotPointsErrorBars::Paint(vtkContext2D *painter)
else
{
// draw all of the points
// Draw lines for error bars (if needed)
if (this->PlotErrorBars)
{
PaintErrorBars(painter, points, this->Points->GetNumberOfPoints());
}
// Draw markers for points
painter->DrawMarkers(this->MarkerStyle, false, points,
this->Points->GetNumberOfPoints(), colors,
nColorComponents);
......@@ -331,12 +351,14 @@ void vtkPlotPointsErrorBars::PaintErrorBars(vtkContext2D *painter,
vtkNew<vtkPen> errorPen;
errorPen->SetColor(0.0, 0.0, 0.0);
errorPen->SetWidth(1.0);
errorPen->SetLineType(vtkPen::SOLID_LINE);
errorPen->SetOpacity(255);
painter->ApplyPen(errorPen);
for (int i = 0; i < n; ++i)
{
float thisX = points[2 * i], thisY = points[2 * i + 1];
float capLength = this->GetWidth() / 100.0;
float capLength = std::max(0.0, this->GetWidth() / 100.0);
if (XErrors && XErrors->GetNumberOfValues() > i)
{
......
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