VTK/Charts
Goals
- Render 2D charts using OpenGL/VTK
- Scalable to large data sets
- Simple, flexible API
- Enable server side rendering of charts with VTK compositing
- Proper handling of IEEE Not-A-Number (NaN) values in plots of both experimental and simulation data.
Open Questions
- Alternate backend to produce publication quality output?
- Possibility to extend the API to 3D charts in the future?
- Maybe real-time charting? (just-in-time visualization of data sets)
Unlimited Options
Supported Parameter Types
- Basic types (double, int, string, vtkVariant)
<source lang="cpp"> vtkDotMark* m = vtkDotMark::New(); m->SetParameter("size", 10); </source>
- Data object
<source lang="cpp"> vtkDirectedGraph* g = vtkDirectedGraph::New(); //... vtkDotMark* m = vtkDotMark::New(); m->SetParameter("data", g); </source>
- Pipeline output port
<source lang="cpp"> vtkRandomGraphSource* s = vtkRandomGraphSource::New(); //... vtkDotMark* m = vtkDotMark::New(); m->SetParameter("data", s->GetOutputPort()); </source>
- vtkArray
<source lang="cpp"> vtkDenseArray<double>* a = vtkDenseArray<double>::New(); //... vtkDotMark* m = vtkDotMark::New(); m->SetParameter("size", a); </source>
- vtkAbstractArray
<source lang="cpp"> vtkDoubleArray* a = vtkDoubleArray::New(); //... vtkDotMark* m = vtkDotMark::New(); m->SetParameter("size", a); </source>
- Data object + field type + array name
<source lang="cpp"> vtkTable* t = vtkTable::New(); //... vtkDotMark* m = vtkDotMark::New(); m->SetParameter("size", t, vtkDataObject::ROW, "columnName"); </source>
- Data object + field type + array name + component index
<source lang="cpp"> vtkTable* t = vtkTable::New(); vtkDoubleArray* loc = vtkDoubleArray::New(); loc->SetNumberOfComponents(2); //... vtkDotMark* m = vtkDotMark::New(); m->SetParameter("left", t, vtkDataObject::ROW, "location", 0); m->SetParameter("bottom", t, vtkDataObject::ROW, "location", 1); </source>
- Function pointer
<source lang="cpp"> double MySize(vtkMark* m, int i) { return 10*i; } //... vtkDotMark* m = vtkDotMark::New(); m->SetParameter("size", &MySize); </source>
- Functor (i.e. struct type with operator()) - requires SetParameter to be templated.
<source lang="cpp"> struct MySize {
double operator()(vtkMark* m, int i) { return 10*i; }
} //... vtkDotMark* m = vtkDotMark::New(); m->SetParameter("size", MySize()); </source>
- Lambda function (boost::lambda)
- Parameter strategies
<source lang="cpp"> class vtkDoubleParameter {
virtual double Get(vtkMark* m, int i) = 0;
}
class MySize : public vtkDoubleParameter { protected:
double Get(vtkMark* m, int i) { return 10*i; }
} //... vtkDotMark* m = vtkDotMark::New(); m->SetParameter("size", MySize()); </source>
- Override virtual methods in mark
<source lang="cpp"> class vtkDotMark : public vtkMark { protected:
virtual double GetSize(int i) { return 10; }
}
class MyMark : public vtkDotMark { protected:
double GetSize(int i) { return 10*i; }
} //... MyMark* m = MyMark::New(); </source>
- Inherit from parent mark
<source lang="cpp"> vtkDotMark* parent = vtkDotMark::New(); parent->SetParameter("size", 10); vtkDotMark* child = vtkDotMark::New(); parent->Add(child); // Child has size 10 </source>
Parameter Storage and Access
- Named member variables
<source lang="cpp"> class vtkDotMark { public:
ParamType GetSize() { return this->Size; } void SetSize(ParamType p) { this->Size = p; }
private:
ParamType Size;
} </source>
- Named member variables with import/export to name/value map
<source lang="cpp"> class vtkMark { public:
ParamType GetParameter(string key) { this->ExportSettings()->GetParameter(key); } void SetParameter(string key, ParamType p) { this->ImportSettings(this->ExportSettings()->SetParameter(key, p)); } virtual void ImportSettings(vtkSettings* s) { } virtual vtkSettings* ExportSettings() { return vtkSettings::New(); }
}
class vtkDotMark { public:
ParamType GetSize() { return this->Size; } void SetSize(ParamType p) { this->Size = p; } virtual vtkSettings* ExportSettings() { return this->Parent->ExportSettings()->SetParameter("size", this->Size); } virutal void ImportSettings(vtkSettings* s) { this->Size = s->GetParameter("size"); }
private:
ParamType Size;
} </source>
- Generic name/value map
<source lang="cpp"> class vtkMark { public:
ParamType GetParameter(string key) { return this->Parameters[key].Valid ? this->Parameters[key] : this->Parent->GetParameter(key); } void SetParameter(string key, ParamType p) { this->Parameters[key] = p; }
private:
map<string, ParamType> Parameters;
} </source>
- Generic name/value map with setter/getter syntactic sugar for discoverability
<source lang="cpp"> class vtkDotMark { public:
ParamType GetSize() { return this->GetParameter("size"); } void SetSize(ParamType p) { this->SetParameter("size", p); }
} </source>
Other Features
- Declarative API
- Iterator support
Further Details on API
Please see VTK/Charts/API for a discussion about the API. There is also more detail about the VTK/Charts/2DAPI and the VTK/Charts/ChartAPI along with proposed class relationships.
Chart Types
- XY plot
- Scatter
- Bar chart
- Histogram
- Stack chart
- Pie chart
- Parallel axes
- Tree map
- Bubble chart
Existing Applications/Libraries
Below is a summary of different libraries or applications that produce 2D charts and plots. Those listed either provide both screen and publication quality rendering, or just screen rendering.
Optimized for Screen Rendering
- prefuse
- tableau
- Many Eyes
- Google Chart
- Qwt
- QwtPlot3D
- QPlotter
- ggobi
- ZedGraph
- TeeChart
- Iocomp
- Scientific charting control
- ChartDirector
- Dundas
- Visifire
- core-plot
- Protoviz