#ifndef _ScatterDraw_DataSource_h_ #define _ScatterDraw_DataSource_h_ NAMESPACE_UPP class DataSource { public: typedef double (DataSource::*Getdatafun)(ptrdiff_t id); DataSource() : isParam(false) {} virtual ~DataSource() {} virtual double z(ptrdiff_t id) {return Null;} virtual double y(ptrdiff_t id) {return Null;} virtual double x(ptrdiff_t id) {return Null;} virtual ptrdiff_t GetCount() {return Null;} virtual ptrdiff_t GetCount(int series) {return Null;} bool IsParam() {return isParam;} virtual double MinX() {return Min(&DataSource::x);} virtual double MinY() {return Min(&DataSource::y);} virtual double MinZ() {return Min(&DataSource::z);} virtual double MaxX() {return Max(&DataSource::x);} virtual double MaxY() {return Max(&DataSource::y);} virtual double MaxZ() {return Max(&DataSource::z);} virtual double AvgX() {return Avg(&DataSource::x);} virtual double AvgY() {return Avg(&DataSource::y);} virtual double AvgZ() {return Avg(&DataSource::z);} protected: bool isParam; virtual double Min(Getdatafun getdata); virtual double Max(Getdatafun getdata); virtual double Avg(Getdatafun getdata); }; class CArray : public DataSource { private: double *xData, *yData, *zData; ptrdiff_t numData; double x0, deltaX; public: CArray(double *yData, int numData, double x0, double deltaX) : yData(yData), numData(numData), x0(x0), deltaX(deltaX) { xData = NULL; } CArray(double *xData, double *yData, int numData) : xData(xData), yData(yData), numData(numData) { zData = NULL; x0 = deltaX = 0; } CArray(double *xData, double *yData, double *zData, int numData) : xData(xData), yData(yData), zData(zData), numData(numData) { x0 = deltaX = 0; } virtual inline double z(ptrdiff_t id) {ASSERT(zData); return zData[id];} virtual inline double y(ptrdiff_t id) {return yData[id];} virtual inline double x(ptrdiff_t id) {return xData ? xData[id] : id*deltaX + x0;} virtual inline ptrdiff_t GetCount() {return numData;} }; template class VectorY : public DataSource { private: Vector *yData; public: VectorY(Vector &yData) : yData(&yData) {} virtual inline double y(ptrdiff_t id) {return (*yData)[id];} virtual inline double x(ptrdiff_t id) {return id;} virtual inline ptrdiff_t GetCount() {return yData->GetCount();} }; template class ArrayY : public DataSource { private: Upp::Array *yData; public: ArrayY(Upp::Array &yData) : yData(&yData) {} virtual inline double y(ptrdiff_t id) {return (*yData)[id];} virtual inline double x(ptrdiff_t id) {return id;} virtual inline ptrdiff_t GetCount() {return yData->GetCount();} }; template class VectorVectorY : public DataSource { private: Vector > *data; bool useCols; int idX, idY, idZ; int beginData; ptrdiff_t numData; public: VectorVectorY() : data(0), useCols(true), idX(0), idY(1), idZ(2), beginData(0), numData(Null) {} VectorVectorY(Vector > &data, bool useCols = true, int idX = 0, int idY = 1, int idZ = 2, int beginData = 0, int numData = Null) : data(&data), useCols(useCols), idX(idX), idY(idY), idZ(idZ), beginData(beginData), numData(numData) { Init(data, useCols, idX, idY, idZ, beginData, numData); } void Init(Vector > &_data, bool _useCols = true, int _idX = 0, int _idY = 1, int _idZ = 2, int _beginData = 0, int _numData = Null) { data = &_data; useCols = _useCols; idX = _idX; idY = _idY; idZ = _idZ; beginData = _beginData; numData = _numData; if (IsNull(_numData)) { if (!useCols) { if (data->IsEmpty()) numData = 0; else numData = (*data)[0].GetCount() - beginData; } else numData = data->GetCount() - beginData; } } virtual inline double z(int id) {return useCols ? (*data)[beginData + id][idZ] : (*data)[idZ][beginData + id];} virtual inline double y(int id) {return useCols ? (*data)[beginData + id][idY] : (*data)[idY][beginData + id];} virtual inline double x(int id) { if (IsNull(idX)) return id; else return useCols ? (*data)[beginData + id][idX] : (*data)[idX][beginData + id]; } virtual inline ptrdiff_t GetCount() {return numData;}; }; class VectorDouble : public DataSource { private: const Vector *xData, *yData; public: VectorDouble(const Vector &xData, Vector &yData) : xData(&xData), yData(&yData) {} virtual inline double y(ptrdiff_t id) {return (*yData)[int(id)];} virtual inline double x(ptrdiff_t id) {return (*xData)[int(id)];} virtual inline ptrdiff_t GetCount() {return xData->GetCount();} }; class ArrayDouble : public DataSource { private: const Upp::Array *xData, *yData; public: ArrayDouble(const Upp::Array &xData, Upp::Array &yData) : xData(&xData), yData(&yData) {} virtual inline double y(ptrdiff_t id) {return (*yData)[int(id)];} virtual inline double x(ptrdiff_t id) {return (*xData)[int(id)];} virtual inline ptrdiff_t GetCount() {return xData->GetCount();} }; class VectorPointf : public DataSource { private: const Vector *data; public: VectorPointf(const Vector &data) : data(&data) {} VectorPointf(Vector *data) : data(data) {} virtual inline double y(ptrdiff_t id) {return (*data)[int(id)].y;} virtual inline double x(ptrdiff_t id) {return (*data)[int(id)].x;} virtual inline ptrdiff_t GetCount() {return data->GetCount();} }; class ArrayPointf : public DataSource { private: Upp::Array *data; public: ArrayPointf(Upp::Array &data) : data(&data) {} virtual inline double y(ptrdiff_t id) {return (*data)[int(id)].y;} virtual inline double x(ptrdiff_t id) {return (*data)[int(id)].x;} virtual inline ptrdiff_t GetCount() {return data->GetCount();} }; template class VectorMapXY : public DataSource { private: VectorMap *data; public: VectorMapXY(VectorMap &data) : data(&data) {} virtual inline double y(ptrdiff_t id) {return (*data)[int(id)];} virtual inline double x(ptrdiff_t id) {return (*data).GetKey(int(id));} virtual inline ptrdiff_t GetCount() {return data->GetCount();} }; template class ArrayMapXY : public DataSource { private: ArrayMap *data; public: ArrayMapXY(ArrayMap &data) : data(&data) {} virtual inline double y(ptrdiff_t id) {return (*data)[id];} virtual inline double x(ptrdiff_t id) {return (*data).GetKey(id);} virtual inline ptrdiff_t GetCount() {return data->GetCount();} }; class FuncSource : public DataSource { private: double (*function)(double); public: FuncSource(double (*function)(double)) : function(function) {} virtual inline double y(ptrdiff_t t) {return function(double(t));} virtual inline double x(ptrdiff_t t) {return double(t);} virtual inline ptrdiff_t GetCount() {return Null;} }; class FuncSourcePara : public DataSource { private: Pointf (*function)(double); Pointf lastPointf; double lastT; int numPoints; double minT, maxT; public: FuncSourcePara(Pointf (*function)(double), int np, double from, double to) : function(function), numPoints(np), minT(from), maxT(to) { lastT = Null; isParam = true; } virtual inline double y(ptrdiff_t t) { if (IsNull(lastT) || t != lastT) { lastPointf = function(minT + t*(maxT-minT)/numPoints); lastT = double(t); } return lastPointf.y; } virtual inline double x(ptrdiff_t t) { if (IsNull(lastT) || t != lastT) { lastPointf = function(minT + t*(maxT-minT)/numPoints); lastT = double(t); } return lastPointf.x; } virtual inline ptrdiff_t GetCount() {return numPoints;} }; typedef Callback2 PlotFunc; typedef Callback2 PlotParamFunc; class PlotFuncSource : public DataSource { private: PlotFunc function; public: PlotFuncSource() {} PlotFuncSource(PlotFunc &function) : function(function) {} virtual inline double y(ptrdiff_t t) {double y; function(y, double(t)); return y;} virtual inline double x(ptrdiff_t t) {return double(t);} virtual inline ptrdiff_t GetCount() {return -1;} }; class PlotParamFuncSource : public DataSource { private: PlotParamFunc function; Pointf lastPointf; double lastT; int numPoints; double minT, maxT; public: PlotParamFuncSource(PlotParamFunc function, int np, double from, double to) : function(function), numPoints(np), minT(from), maxT(to) { lastT = Null; isParam = true; } inline double y(ptrdiff_t t) { if (IsNull(lastT) || t != lastT) { function(lastPointf, minT + t*(maxT-minT)/numPoints); lastT = double(t); } return lastPointf.y; } inline double x(ptrdiff_t t) { if (IsNull(lastT) || t != lastT) { function(lastPointf, minT + t*(maxT-minT)/numPoints); lastT = double(t); } return lastPointf.x; } virtual inline ptrdiff_t GetCount() {return numPoints;} }; END_UPP_NAMESPACE #endif