stack_chart_common.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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/view/stack_chart_common.h"
  8. #include "data/data_statistics_chart.h"
  9. #include "statistics/statistics_common.h"
  10. #include "ui/effects/animation_value_f.h"
  11. namespace Statistic {
  12. LeftStartAndStep ComputeLeftStartAndStep(
  13. const Data::StatisticalChart &chartData,
  14. const Limits &xPercentageLimits,
  15. const QRect &rect,
  16. float64 xIndexStart) {
  17. const auto fullWidth = rect.width()
  18. / (xPercentageLimits.max - xPercentageLimits.min);
  19. const auto offset = fullWidth * xPercentageLimits.min;
  20. const auto p = (chartData.xPercentage.size() < 2)
  21. ? 1.
  22. : chartData.xPercentage[1] * fullWidth;
  23. const auto w = chartData.xPercentage[1] * (fullWidth - p);
  24. const auto leftStart = rect.x()
  25. + chartData.xPercentage[xIndexStart] * (fullWidth - p)
  26. - offset;
  27. return { leftStart, w };
  28. }
  29. Limits FindStackXIndicesFromRawXPercentages(
  30. const Data::StatisticalChart &chartData,
  31. const Limits &rawXPercentageLimits,
  32. const Limits &zoomedInLimitXIndices) {
  33. const auto zoomLimit = Limits{
  34. chartData.xPercentage[zoomedInLimitXIndices.min],
  35. chartData.xPercentage[zoomedInLimitXIndices.max],
  36. };
  37. // Due to a specificity of the stack chart plotting,
  38. // the right edge has a special offset to the left.
  39. // This reduces the number of displayed points by 1,
  40. // but allows the last point to be displayed.
  41. const auto offset = (zoomLimit.max == 1.) ? 0 : -1;
  42. const auto rightShrink = (rawXPercentageLimits.max == 1.)
  43. ? ((zoomLimit.max == 1.) ? 0 : 1)
  44. : 0;
  45. const auto n = chartData.xPercentage.size();
  46. auto minIt = -1;
  47. auto maxIt = n;
  48. const auto zoomedIn = Limits{
  49. anim::interpolateF(
  50. zoomLimit.min,
  51. zoomLimit.max,
  52. rawXPercentageLimits.min),
  53. anim::interpolateF(
  54. zoomLimit.min,
  55. zoomLimit.max,
  56. rawXPercentageLimits.max),
  57. };
  58. for (auto i = int(0); i < n; i++) {
  59. if (minIt < 0) {
  60. if (chartData.xPercentage[i] > zoomedIn.min) {
  61. minIt = i;
  62. }
  63. }
  64. if (maxIt >= n) {
  65. if (chartData.xPercentage[i] > zoomedIn.max) {
  66. maxIt = i;
  67. }
  68. }
  69. }
  70. return {
  71. .min = std::clamp(
  72. float64(minIt + offset),
  73. zoomedInLimitXIndices.min,
  74. zoomedInLimitXIndices.max - rightShrink),
  75. .max = std::clamp(
  76. float64(maxIt + offset),
  77. zoomedInLimitXIndices.min,
  78. zoomedInLimitXIndices.max - rightShrink),
  79. };
  80. }
  81. } // namespace Statistic