forked from anastasia-trg/Qt_Ploats
/
arefilling.h
129 lines (107 loc) · 3.57 KB
/
arefilling.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#ifndef AREFILLING_H
#define AREFILLING_H
#include <deque>
#include <string>
#include <sstream>
#include "curve.h"
template <class ConcreteDerived>
class AreFilling : public ConcreteDerived
{
public:
AreFilling() {}
void parseStrLine(const std::string &line);
private:
std::deque<std::string> split(const std::string &str) const;
void setAxisNames(const std::string &xAxisName, const std::string &yAxisName);
void createCurves(const std::deque<std::string> &names);
void addValuesSlice(const std::deque<float> &values);
void addValuesSlice(const std::string &line);
void pushXValue(float value);
void pushYValue(Curve *curve, float value);
};
template <class ConcreteDerived>
void AreFilling<ConcreteDerived>::parseStrLine(const std::string &line) {
if (line.length() == 0) return;
static int callingCounter = 0;
if (callingCounter == 0) {
std::deque<std::string> axisNames = split(line);
auto name = axisNames.cbegin();
setAxisNames(*name, *(++name));
} else if (callingCounter == 1) {
std::deque<std::string> names = split(line);
auto createCurvesLambda = [this, &names]() {
names.pop_front();
this->createCurves(names);
};
auto firstColumn = names.cbegin();
if (*firstColumn == "#") {
createCurvesLambda();
} else {
std::deque<float> values;
for (std::string &name : names) {
values.push_back(atof(name.c_str()));
name = "";
}
createCurvesLambda();
this->addValuesSlice(values);
}
} else {
this->addValuesSlice(line);
}
++callingCounter;
}
template <class ConcreteDerived>
std::deque<std::string> AreFilling<ConcreteDerived>::split(const std::string &str) const {
std::stringstream strStream(str);
std::string item;
std::deque<std::string> values;
while (std::getline(strStream, item, '\t')) {
if (item.length() == 0) continue;
values.push_back(item);
}
return values;
}
template <class ConcreteDerived>
void AreFilling<ConcreteDerived>::setAxisNames(const std::string &xAxisName, const std::string &yAxisName) {
this->_axisX.setName(xAxisName);
this->_axisY.setName(yAxisName);
}
template <class ConcreteDerived>
void AreFilling<ConcreteDerived>::createCurves(const std::deque<std::string> &names) {
for (const std::string &name : names) {
this->_curves.push_back(name);
}
}
template <class ConcreteDerived>
void AreFilling<ConcreteDerived>::addValuesSlice(const std::deque<float> &values) {
auto valuesIter = values.cbegin();
pushXValue(*valuesIter);
int curveIndex = 0;
for (; valuesIter != values.cend(); valuesIter++) {
pushYValue(&this->_curves[curveIndex++], *valuesIter);
}
}
template <class ConcreteDerived>
void AreFilling<ConcreteDerived>::addValuesSlice(const std::string &line) {
std::stringstream strStream(line);
auto readValue = [&strStream]() {
float value;
strStream >> value;
return value;
};
pushXValue(readValue());
for (size_t i = 0; i < this->_curves.size(); i++) {
pushYValue(&this->_curves[i], readValue());
}
}
template <class ConcreteDerived>
void AreFilling<ConcreteDerived>::pushXValue(float value) {
this->_xValues.push_back(value);
this->_axisX.tryUpdate(value);
}
template <class ConcreteDerived>
void AreFilling<ConcreteDerived>::pushYValue(Curve *curve, float value) {
curve->addValue(value);
this->_axisY.tryUpdate(value);
}
#endif // AREFILLING_H