chart_rulers_data.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #include "statistics/chart_rulers_data.h"
  8. #include "lang/lang_tag.h"
  9. namespace Statistic {
  10. namespace {
  11. constexpr auto kMinLines = ChartValue(2);
  12. constexpr auto kMaxLines = ChartValue(6);
  13. constexpr auto kStep = 5.;
  14. [[nodiscard]] ChartValue Round(ChartValue maxValue) {
  15. const auto k = ChartValue(maxValue / kStep);
  16. return (k % 10 == 0) ? maxValue : ((maxValue / 10 + 1) * 10);
  17. }
  18. [[nodiscard]] QString Format(ChartValue absoluteValue) {
  19. constexpr auto kTooMuch = ChartValue(10'000);
  20. return (absoluteValue >= kTooMuch)
  21. ? Lang::FormatCountToShort(absoluteValue).string
  22. : QString::number(absoluteValue);
  23. }
  24. } // namespace
  25. ChartRulersData::ChartRulersData(
  26. ChartValue newMaxHeight,
  27. ChartValue newMinHeight,
  28. bool useMinHeight,
  29. float64 rightRatio,
  30. Fn<QString(float64)> leftCustomCaption,
  31. Fn<QString(float64)> rightCustomCaption) {
  32. if (!useMinHeight) {
  33. const auto v = (newMaxHeight > 100)
  34. ? Round(newMaxHeight)
  35. : newMaxHeight;
  36. const auto step = std::max(
  37. ChartValue(1),
  38. ChartValue(std::ceil(v / kStep)));
  39. auto n = kMaxLines;
  40. if (v < kMaxLines) {
  41. n = std::max(2, int(v + 1));
  42. } else if (v / 2 < kMaxLines) {
  43. n = v / 2 + 1;
  44. if (v % 2 != 0) {
  45. n++;
  46. }
  47. }
  48. lines.resize(n);
  49. for (auto i = 1; i < n; i++) {
  50. auto &line = lines[i];
  51. line.absoluteValue = i * step;
  52. line.caption = Lang::FormatCountToShort(
  53. line.absoluteValue).string;
  54. }
  55. } else {
  56. auto n = int(0);
  57. const auto diff = newMaxHeight - newMinHeight;
  58. auto step = 0.;
  59. if (diff == 0) {
  60. newMinHeight--;
  61. n = kMaxLines / 2;
  62. step = 1.;
  63. } else if (diff < kMaxLines) {
  64. n = std::max(kMinLines, diff + 1);
  65. step = 1.;
  66. } else if (diff / 2 < kMaxLines) {
  67. n = diff / 2 + diff % 2 + 1;
  68. step = 2.;
  69. } else {
  70. step = (newMaxHeight - newMinHeight) / kStep;
  71. if (step <= 0) {
  72. step = 1;
  73. n = std::max(kMinLines, newMaxHeight - newMinHeight + 1);
  74. } else {
  75. n = 6;
  76. }
  77. }
  78. lines.resize(n);
  79. const auto diffAbsoluteValue = ChartValue((n - 1) * step);
  80. const auto skipFloatValues = (step / rightRatio) < 1;
  81. for (auto i = 0; i < n; i++) {
  82. auto &line = lines[i];
  83. const auto value = ChartValue(i * step);
  84. line.absoluteValue = newMinHeight + value;
  85. line.relativeValue = 1. - value / float64(diffAbsoluteValue);
  86. line.caption = leftCustomCaption
  87. ? leftCustomCaption(line.absoluteValue)
  88. : Format(line.absoluteValue);
  89. if (rightRatio > 0 || rightCustomCaption) {
  90. const auto v = (newMinHeight + i * step) / rightRatio;
  91. line.scaledLineCaption = rightCustomCaption
  92. ? rightCustomCaption(line.absoluteValue)
  93. : (!skipFloatValues)
  94. ? Format(v)
  95. : ((v - ChartValue(v)) < 0.01)
  96. ? Format(v)
  97. : QString();
  98. }
  99. }
  100. }
  101. }
  102. void ChartRulersData::computeRelative(
  103. ChartValue newMaxHeight,
  104. ChartValue newMinHeight) {
  105. for (auto &line : lines) {
  106. line.relativeValue = 1.
  107. - ((line.absoluteValue - newMinHeight)
  108. / (newMaxHeight - newMinHeight));
  109. }
  110. }
  111. ChartValue ChartRulersData::LookupHeight(ChartValue maxValue) {
  112. const auto v = (maxValue > 100) ? Round(maxValue) : maxValue;
  113. const auto step = ChartValue(std::ceil(v / kStep));
  114. return step * kStep;
  115. }
  116. } // namespace Statistic