Added initial support of static zoom for chart widget.
This commit is contained in:
		
							parent
							
								
									26b17325aa
								
							
						
					
					
						commit
						e8aa55d4d8
					
				
					 6 changed files with 75 additions and 11 deletions
				
			
		| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										17
									
								
								Telegram/SourceFiles/statistics/statistics_common.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								Telegram/SourceFiles/statistics/statistics_common.h
									
										
									
									
									
										Normal 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
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue