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
|
#pragma once
#include <util/string/printf.h>
#include <util/stream/str.h>
#include <util/string/vector.h>
#include <util/generic/set.h>
#include <util/generic/hash_set.h>
#include "data.h"
#include "util.h"
namespace NAnalytics {
inline TString ToJsonFlot(const TTable& in, const TString& xno, const TVector<TString>& ynos, const TString& opts = TString())
{
TStringStream ss;
ss << "[ ";
bool first = true;
TString xn;
THashSet<TString> xopts;
ParseNameAndOpts(xno, xn, xopts);
bool xstack = xopts.contains("stack");
for (const TString& yno : ynos) {
TString yn;
THashSet<TString> yopts;
ParseNameAndOpts(yno, yn, yopts);
bool ystackOpt = yopts.contains("stack");
ss << (first? "": ",\n ") << "{ " << opts << (opts? ", ": "") << "\"label\": \"" << yn << "\", \"data\": [ ";
bool first2 = true;
using TPt = std::tuple<double, double, TString>;
std::vector<TPt> pts;
for (const TRow& row : in) {
double x, y;
if (row.Get(xn, x) && row.Get(yn, y)) {
pts.emplace_back(x, y, row.Name);
}
}
if (xstack) {
std::sort(pts.begin(), pts.end(), [] (const TPt& a, const TPt& b) {
// At first sort by Name, then by x, then by y
return std::make_tuple(std::get<2>(a), std::get<0>(a), std::get<1>(a)) <
std::make_tuple(std::get<2>(b), std::get<0>(b), std::get<1>(b));
});
} else {
std::sort(pts.begin(), pts.end());
}
double x = 0.0, xsum = 0.0;
double y = 0.0, ysum = 0.0;
for (auto& pt : pts) {
if (xstack) {
x = xsum;
xsum += std::get<0>(pt);
} else {
x = std::get<0>(pt);
}
if (ystackOpt) {
y = ysum;
ysum += std::get<1>(pt);
} else {
y = std::get<1>(pt);
}
ss << (first2? "": ", ") << "["
<< Sprintf("%.6lf", Finitize(x)) << ", " // x coordinate
<< Sprintf("%.6lf", Finitize(y)) << ", " // y coordinate
<< "\"" << std::get<2>(pt) << "\", " // label
<< Sprintf("%.6lf", std::get<0>(pt)) << ", " // x label (real value)
<< Sprintf("%.6lf", std::get<1>(pt)) // y label (real value)
<< "]";
first2 = false;
}
// Add final point
if (!first2 && (xstack || ystackOpt)) {
if (xstack)
x = xsum;
if (ystackOpt)
y = ysum;
ss << (first2? "": ", ") << "["
<< Sprintf("%.6lf", Finitize(x)) << ", " // x coordinate
<< Sprintf("%.6lf", Finitize(y)) << ", " // y coordinate
<< "\"\", "
<< Sprintf("%.6lf", x) << ", " // x label (real value)
<< Sprintf("%.6lf", y) // y label (real value)
<< "]";
}
ss << " ] }";
first = false;
}
ss << "\n]";
return ss.Str();
}
}
|