json_output.h 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #pragma once
  2. #include <util/string/printf.h>
  3. #include <util/stream/str.h>
  4. #include <util/string/vector.h>
  5. #include <util/generic/set.h>
  6. #include <util/generic/hash_set.h>
  7. #include "data.h"
  8. #include "util.h"
  9. namespace NAnalytics {
  10. inline TString ToJsonFlot(const TTable& in, const TString& xno, const TVector<TString>& ynos, const TString& opts = TString())
  11. {
  12. TStringStream ss;
  13. ss << "[ ";
  14. bool first = true;
  15. TString xn;
  16. THashSet<TString> xopts;
  17. ParseNameAndOpts(xno, xn, xopts);
  18. bool xstack = xopts.contains("stack");
  19. for (const TString& yno : ynos) {
  20. TString yn;
  21. THashSet<TString> yopts;
  22. ParseNameAndOpts(yno, yn, yopts);
  23. bool ystackOpt = yopts.contains("stack");
  24. ss << (first? "": ",\n ") << "{ " << opts << (opts? ", ": "") << "\"label\": \"" << yn << "\", \"data\": [ ";
  25. bool first2 = true;
  26. using TPt = std::tuple<double, double, TString>;
  27. std::vector<TPt> pts;
  28. for (const TRow& row : in) {
  29. double x, y;
  30. if (row.Get(xn, x) && row.Get(yn, y)) {
  31. pts.emplace_back(x, y, row.Name);
  32. }
  33. }
  34. if (xstack) {
  35. std::sort(pts.begin(), pts.end(), [] (const TPt& a, const TPt& b) {
  36. // At first sort by Name, then by x, then by y
  37. return std::make_tuple(std::get<2>(a), std::get<0>(a), std::get<1>(a)) <
  38. std::make_tuple(std::get<2>(b), std::get<0>(b), std::get<1>(b));
  39. });
  40. } else {
  41. std::sort(pts.begin(), pts.end());
  42. }
  43. double x = 0.0, xsum = 0.0;
  44. double y = 0.0, ysum = 0.0;
  45. for (auto& pt : pts) {
  46. if (xstack) {
  47. x = xsum;
  48. xsum += std::get<0>(pt);
  49. } else {
  50. x = std::get<0>(pt);
  51. }
  52. if (ystackOpt) {
  53. y = ysum;
  54. ysum += std::get<1>(pt);
  55. } else {
  56. y = std::get<1>(pt);
  57. }
  58. ss << (first2? "": ", ") << "["
  59. << Sprintf("%.6lf", Finitize(x)) << ", " // x coordinate
  60. << Sprintf("%.6lf", Finitize(y)) << ", " // y coordinate
  61. << "\"" << std::get<2>(pt) << "\", " // label
  62. << Sprintf("%.6lf", std::get<0>(pt)) << ", " // x label (real value)
  63. << Sprintf("%.6lf", std::get<1>(pt)) // y label (real value)
  64. << "]";
  65. first2 = false;
  66. }
  67. // Add final point
  68. if (!first2 && (xstack || ystackOpt)) {
  69. if (xstack)
  70. x = xsum;
  71. if (ystackOpt)
  72. y = ysum;
  73. ss << (first2? "": ", ") << "["
  74. << Sprintf("%.6lf", Finitize(x)) << ", " // x coordinate
  75. << Sprintf("%.6lf", Finitize(y)) << ", " // y coordinate
  76. << "\"\", "
  77. << Sprintf("%.6lf", x) << ", " // x label (real value)
  78. << Sprintf("%.6lf", y) // y label (real value)
  79. << "]";
  80. }
  81. ss << " ] }";
  82. first = false;
  83. }
  84. ss << "\n]";
  85. return ss.Str();
  86. }
  87. }