Added initial support of static zoom for chart widget.

This commit is contained in:
23rd 2023-05-26 16:04:33 +03:00 committed by John Preston
parent 26b17325aa
commit e8aa55d4d8
6 changed files with 75 additions and 11 deletions

View File

@ -1292,6 +1292,7 @@ PRIVATE
statistics/segment_tree.h statistics/segment_tree.h
statistics/statistics_box.cpp statistics/statistics_box.cpp
statistics/statistics_box.h statistics/statistics_box.h
statistics/statistics_common.h
statistics/statistics_data_deserialize.cpp statistics/statistics_data_deserialize.cpp
statistics/statistics_data_deserialize.h statistics/statistics_data_deserialize.h
storage/details/storage_file_utilities.cpp storage/details/storage_file_utilities.cpp

View File

@ -73,10 +73,14 @@ class ChartWidget::Footer final : public Ui::AbstractButton {
public: public:
Footer(not_null<Ui::RpWidget*> parent); Footer(not_null<Ui::RpWidget*> parent);
[[nodiscard]] rpl::producer<Limits> xPercentageLimitsChange() const;
private: private:
not_null<Ui::AbstractButton*> _left; not_null<Ui::AbstractButton*> _left;
not_null<Ui::AbstractButton*> _right; not_null<Ui::AbstractButton*> _right;
rpl::event_stream<Limits> _xPercentageLimitsChange;
struct { struct {
int x = 0; int x = 0;
int leftLimit = 0; int leftLimit = 0;
@ -135,6 +139,10 @@ ChartWidget::Footer::Footer(not_null<Ui::RpWidget*> parent)
_start.rightLimit = rightLimit(); _start.rightLimit = rightLimit();
} break; } break;
case QEvent::MouseButtonRelease: { case QEvent::MouseButtonRelease: {
_xPercentageLimitsChange.fire({
.min = _left->x() / float64(width()),
.max = rect::right(_right) / float64(width()),
});
_start = {}; _start = {};
} break; } break;
} }
@ -150,6 +158,10 @@ ChartWidget::Footer::Footer(not_null<Ui::RpWidget*> parent)
[=] { return width() - _right->width(); }); [=] { return width() - _right->width(); });
} }
rpl::producer<Limits> ChartWidget::Footer::xPercentageLimitsChange() const {
return _xPercentageLimitsChange.events();
}
ChartWidget::ChartWidget(not_null<Ui::RpWidget*> parent) ChartWidget::ChartWidget(not_null<Ui::RpWidget*> parent)
: Ui::RpWidget(parent) : Ui::RpWidget(parent)
, _footer(std::make_unique<Footer>(this)) { , _footer(std::make_unique<Footer>(this)) {
@ -162,16 +174,40 @@ ChartWidget::ChartWidget(not_null<Ui::RpWidget*> parent)
st::countryRowHeight); st::countryRowHeight);
}, _footer->lifetime()); }, _footer->lifetime());
_footer->paintRequest( _footer->paintRequest(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=, limits = Limits{ 0., 1. }] {
auto p = QPainter(_footer.get()); auto p = QPainter(_footer.get());
if (_chartData) { if (_chartData) {
Statistic::PaintLinearChartView( Statistic::PaintLinearChartView(
p, p,
_chartData, _chartData,
limits,
_footer->rect()); _footer->rect());
} }
}, _footer->lifetime()); }, _footer->lifetime());
_footer->xPercentageLimitsChange(
) | rpl::start_with_next([=](Limits xPercentageLimits) {
_xPercentageLimits = {
.min = *ranges::lower_bound(
_chartData.xPercentage,
xPercentageLimits.min),
.max = *ranges::lower_bound(
_chartData.xPercentage,
xPercentageLimits.max),
};
const auto startXIndex = _chartData.findStartIndex(
_xPercentageLimits.min);
const auto endXIndex = _chartData.findEndIndex(
startXIndex,
_xPercentageLimits.max);
setHeightLimits(
{
float64(FindMinValue(_chartData, startXIndex, endXIndex)),
float64(FindMaxValue(_chartData, startXIndex, endXIndex)),
},
false);
update();
}, _footer->lifetime());
resize(width(), st::confirmMaxHeight + st::countryRowHeight * 2); resize(width(), st::confirmMaxHeight + st::countryRowHeight * 2);
} }
@ -179,17 +215,21 @@ void ChartWidget::setChartData(Data::StatisticalChart chartData) {
_chartData = chartData; _chartData = chartData;
{ {
_xPercentageLimits = {
.min = _chartData.xPercentage.front(),
.max = _chartData.xPercentage.back(),
};
const auto startXIndex = _chartData.findStartIndex( const auto startXIndex = _chartData.findStartIndex(
_chartData.xPercentage.front()); _xPercentageLimits.min);
const auto endXIndex = _chartData.findEndIndex( const auto endXIndex = _chartData.findEndIndex(
startXIndex, startXIndex,
_chartData.xPercentage.back()); _xPercentageLimits.max);
setHeightLimits( setHeightLimits(
{ {
float64(FindMinValue(_chartData, startXIndex, endXIndex)), float64(FindMinValue(_chartData, startXIndex, endXIndex)),
float64(FindMaxValue(_chartData, startXIndex, endXIndex)), float64(FindMaxValue(_chartData, startXIndex, endXIndex)),
}, },
true); false);
update(); update();
} }
} }
@ -205,6 +245,8 @@ void ChartWidget::paintEvent(QPaintEvent *e) {
const auto chartRect = r const auto chartRect = r
- QMargins{ 0, st::boxTextFont->height, 0, chartRectBottom }; - QMargins{ 0, st::boxTextFont->height, 0, chartRectBottom };
p.fillRect(r, st::boxBg);
for (const auto &horizontalLine : _horizontalLines) { for (const auto &horizontalLine : _horizontalLines) {
PaintHorizontalLines(p, horizontalLine, chartRect); PaintHorizontalLines(p, horizontalLine, chartRect);
} }
@ -213,6 +255,7 @@ void ChartWidget::paintEvent(QPaintEvent *e) {
Statistic::PaintLinearChartView( Statistic::PaintLinearChartView(
p, p,
_chartData, _chartData,
_xPercentageLimits,
chartRect); chartRect);
} }

View File

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_statistics.h" #include "data/data_statistics.h"
#include "statistics/chart_horizontal_lines_data.h" #include "statistics/chart_horizontal_lines_data.h"
#include "statistics/statistics_common.h"
#include "ui/effects/animations.h" #include "ui/effects/animations.h"
#include "ui/rp_widget.h" #include "ui/rp_widget.h"
@ -18,11 +19,6 @@ class ChartWidget : public Ui::RpWidget {
public: public:
ChartWidget(not_null<Ui::RpWidget*> parent); ChartWidget(not_null<Ui::RpWidget*> parent);
struct Limits final {
float64 min = 0;
float64 max = 0;
};
void setChartData(Data::StatisticalChart chartData); void setChartData(Data::StatisticalChart chartData);
void setHeightLimits(Limits newHeight, bool animated); void setHeightLimits(Limits newHeight, bool animated);
@ -44,6 +40,8 @@ private:
Limits _startFrom; Limits _startFrom;
Limits _startFromH; Limits _startFromH;
Limits _xPercentageLimits;
float64 _minMaxUpdateStep = 0.; float64 _minMaxUpdateStep = 0.;
crl::time _lastHeightLimitsChanged = 0; crl::time _lastHeightLimitsChanged = 0;

View File

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "statistics/linear_chart_view.h" #include "statistics/linear_chart_view.h"
#include "data/data_statistics.h" #include "data/data_statistics.h"
#include "statistics/statistics_common.h"
#include "styles/style_boxes.h" #include "styles/style_boxes.h"
namespace Statistic { namespace Statistic {
@ -15,6 +16,7 @@ namespace Statistic {
void PaintLinearChartView( void PaintLinearChartView(
QPainter &p, QPainter &p,
const Data::StatisticalChart &chartData, const Data::StatisticalChart &chartData,
const Limits &xPercentageLimits,
const QRect &rect) { const QRect &rect) {
const auto offset = 0; const auto offset = 0;
const auto currentMinHeight = rect.y(); // const auto currentMinHeight = rect.y(); //
@ -30,10 +32,10 @@ void PaintLinearChartView(
auto chartPath = QPainterPath(); auto chartPath = QPainterPath();
const auto startXIndex = chartData.findStartIndex( const auto startXIndex = chartData.findStartIndex(
chartData.xPercentage.front()); xPercentageLimits.min);
const auto endXIndex = chartData.findEndIndex( const auto endXIndex = chartData.findEndIndex(
startXIndex, startXIndex,
chartData.xPercentage.back()); xPercentageLimits.max);
const auto localStart = std::max(0, startXIndex - additionalPoints); const auto localStart = std::max(0, startXIndex - additionalPoints);
const auto localEnd = std::min( const auto localEnd = std::min(

View File

@ -13,9 +13,12 @@ struct StatisticalChart;
namespace Statistic { namespace Statistic {
struct Limits;
void PaintLinearChartView( void PaintLinearChartView(
QPainter &p, QPainter &p,
const Data::StatisticalChart &chartData, const Data::StatisticalChart &chartData,
const Limits &xPercentageLimits,
const QRect &rect); const QRect &rect);
} // namespace Statistic } // namespace Statistic

View File

@ -0,0 +1,17 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
namespace Statistic {
struct Limits final {
float64 min = 0;
float64 max = 0;
};
} // namespace Statistic