Created abstract chart view class.

This commit is contained in:
23rd 2023-08-28 00:16:48 +03:00 committed by John Preston
parent 671e81033c
commit d50aca0d33
9 changed files with 135 additions and 34 deletions

View file

@ -1295,6 +1295,9 @@ PRIVATE
statistics/statistics_common.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
statistics/view/abstract_chart_view.h
statistics/view/chart_view_factory.cpp
statistics/view/chart_view_factory.h
statistics/view/linear_chart_view.cpp statistics/view/linear_chart_view.cpp
statistics/view/linear_chart_view.h statistics/view/linear_chart_view.h
storage/details/storage_file_utilities.cpp storage/details/storage_file_utilities.cpp

View file

@ -12,7 +12,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "statistics/chart_lines_filter_widget.h" #include "statistics/chart_lines_filter_widget.h"
#include "statistics/point_details_widget.h" #include "statistics/point_details_widget.h"
#include "statistics/view/linear_chart_view.h" #include "statistics/view/abstract_chart_view.h"
#include "statistics/view/chart_view_factory.h"
#include "ui/abstract_button.h" #include "ui/abstract_button.h"
#include "ui/effects/animation_value_f.h" #include "ui/effects/animation_value_f.h"
#include "ui/painter.h" #include "ui/painter.h"
@ -529,11 +530,11 @@ ChartWidget::ChartAnimationController::ChartAnimationController(
void ChartWidget::ChartAnimationController::setXPercentageLimits( void ChartWidget::ChartAnimationController::setXPercentageLimits(
Data::StatisticalChart &chartData, Data::StatisticalChart &chartData,
Limits xPercentageLimits, Limits xPercentageLimits,
const std::unique_ptr<LinearChartView> &linearChartView, const std::unique_ptr<AbstractChartView> &chartView,
crl::time now) { crl::time now) {
if ((_animationValueXMin.to() == xPercentageLimits.min) if ((_animationValueXMin.to() == xPercentageLimits.min)
&& (_animationValueXMax.to() == xPercentageLimits.max) && (_animationValueXMax.to() == xPercentageLimits.max)
&& linearChartView->isFinished()) { && chartView->isFinished()) {
return; return;
} }
start(); start();
@ -555,7 +556,7 @@ void ChartWidget::ChartAnimationController::setXPercentageLimits(
auto minValueFull = std::numeric_limits<int>::max(); auto minValueFull = std::numeric_limits<int>::max();
auto maxValueFull = 0; auto maxValueFull = 0;
for (auto &l : chartData.lines) { for (auto &l : chartData.lines) {
if (!linearChartView->isEnabled(l.id)) { if (!chartView->isEnabled(l.id)) {
continue; continue;
} }
const auto lineMax = l.segmentTree.rMaxQ(startXIndex, endXIndex); const auto lineMax = l.segmentTree.rMaxQ(startXIndex, endXIndex);
@ -574,7 +575,7 @@ void ChartWidget::ChartAnimationController::setXPercentageLimits(
if (!_previousFullHeightLimits.max) { if (!_previousFullHeightLimits.max) {
_previousFullHeightLimits = _finalHeightLimits; _previousFullHeightLimits = _finalHeightLimits;
} }
if (!linearChartView->isFinished()) { if (!chartView->isFinished()) {
_animationValueFooterHeightMin = anim::value( _animationValueFooterHeightMin = anim::value(
_animationValueFooterHeightMin.current(), _animationValueFooterHeightMin.current(),
minValueFull); minValueFull);
@ -618,7 +619,7 @@ void ChartWidget::ChartAnimationController::setXPercentageLimits(
_dtHeight.currentAlpha = 0.; _dtHeight.currentAlpha = 0.;
_addHorizontalLineRequests.fire({}); _addHorizontalLineRequests.fire({});
} }
_dtHeight.speed = (!linearChartView->isFinished()) _dtHeight.speed = (!chartView->isFinished())
? kDtHeightSpeedFilter ? kDtHeightSpeedFilter
: (k > kDtHeightSpeedThreshold1) : (k > kDtHeightSpeedThreshold1)
? kDtHeightSpeed1 ? kDtHeightSpeed1
@ -664,7 +665,7 @@ void ChartWidget::ChartAnimationController::tick(
crl::time now, crl::time now,
std::vector<ChartHorizontalLinesData> &horizontalLines, std::vector<ChartHorizontalLinesData> &horizontalLines,
std::vector<BottomCaptionLineData> &dateLines, std::vector<BottomCaptionLineData> &dateLines,
const std::unique_ptr<LinearChartView> &linearChartView) { const std::unique_ptr<AbstractChartView> &chartView) {
if (!_animation.animating()) { if (!_animation.animating()) {
return; return;
} }
@ -715,7 +716,7 @@ void ChartWidget::ChartAnimationController::tick(
const auto footerMinFinished = isFinished(_animationValueFooterHeightMin); const auto footerMinFinished = isFinished(_animationValueFooterHeightMin);
const auto footerMaxFinished = isFinished(_animationValueFooterHeightMax); const auto footerMaxFinished = isFinished(_animationValueFooterHeightMax);
linearChartView->tick(now); chartView->tick(now);
if (xFinished if (xFinished
&& yFinished && yFinished
@ -723,7 +724,7 @@ void ChartWidget::ChartAnimationController::tick(
&& bottomLineAlphaFinished && bottomLineAlphaFinished
&& footerMinFinished && footerMinFinished
&& footerMaxFinished && footerMaxFinished
&& linearChartView->isFinished()) { && chartView->isFinished()) {
const auto &lines = horizontalLines.back().lines; const auto &lines = horizontalLines.back().lines;
if ((_finalHeightLimits.min == _animationValueHeightMin.to()) if ((_finalHeightLimits.min == _animationValueHeightMin.to())
&& _finalHeightLimits.max == _animationValueHeightMax.to()) { && _finalHeightLimits.max == _animationValueHeightMax.to()) {
@ -875,8 +876,7 @@ ChartWidget::ChartWidget(not_null<Ui::RpWidget*> parent)
, _footer(std::make_unique<Footer>(this)) , _footer(std::make_unique<Footer>(this))
, _animationController([=] { , _animationController([=] {
_chartArea->update(); _chartArea->update();
if (_animationController.footerAnimating() if (_animationController.footerAnimating() || !_chartView->isFinished()) {
|| !_linearChartView->isFinished()) {
_footer->update(); _footer->update();
} }
}) { }) {
@ -964,7 +964,7 @@ void ChartWidget::setupChartArea() {
now, now,
_horizontalLines, _horizontalLines,
_bottomLine.dates, _bottomLine.dates,
_linearChartView); _chartView);
const auto chartRect = chartAreaRect(); const auto chartRect = chartAreaRect();
@ -998,7 +998,7 @@ void ChartWidget::setupChartArea() {
for (const auto &line : _chartData.lines) { for (const auto &line : _chartData.lines) {
_details.widget->setLineAlpha( _details.widget->setLineAlpha(
line.id, line.id,
_linearChartView->alpha(line.id)); _chartView->alpha(line.id));
} }
} }
} }
@ -1009,7 +1009,7 @@ void ChartWidget::setupChartArea() {
// !_animationController.isFPSSlow() // !_animationController.isFPSSlow()
// || !_animationController.animating()); // || !_animationController.animating());
PainterHighQualityEnabler hp(p); PainterHighQualityEnabler hp(p);
_linearChartView->paint( _chartView->paint(
p, p,
_chartData, _chartData,
_animationController.currentXIndices(), _animationController.currentXIndices(),
@ -1033,7 +1033,7 @@ void ChartWidget::setupChartArea() {
if (_details.widget && (detailsAlpha > 0.)) { if (_details.widget && (detailsAlpha > 0.)) {
auto hq = PainterHighQualityEnabler(p); auto hq = PainterHighQualityEnabler(p);
auto o = ScopedPainterOpacity(p, detailsAlpha); auto o = ScopedPainterOpacity(p, detailsAlpha);
_linearChartView->paintSelectedXIndex( _chartView->paintSelectedXIndex(
p, p,
_chartData, _chartData,
_animationController.currentXLimits(), _animationController.currentXLimits(),
@ -1148,7 +1148,7 @@ void ChartWidget::setupFooter() {
// !_animationController.isFPSSlow() // !_animationController.isFPSSlow()
// || !_animationController.animating()); // || !_animationController.animating());
PainterHighQualityEnabler hp(p); PainterHighQualityEnabler hp(p);
_linearChartView->paint( _chartView->paint(
p, p,
_chartData, _chartData,
{ 0., float64(_chartData.x.size() - 1) }, { 0., float64(_chartData.x.size() - 1) },
@ -1171,7 +1171,7 @@ void ChartWidget::setupFooter() {
_animationController.setXPercentageLimits( _animationController.setXPercentageLimits(
_chartData, _chartData,
xPercentageLimits, xPercentageLimits,
_linearChartView, _chartView,
now); now);
updateChartFullWidth(_chartArea->width()); updateChartFullWidth(_chartArea->width());
updateBottomDates(); updateBottomDates();
@ -1276,12 +1276,12 @@ void ChartWidget::setupFilterButtons() {
_filterButtons->buttonEnabledChanges( _filterButtons->buttonEnabledChanges(
) | rpl::start_with_next([=](const ChartLinesFilterWidget::Entry &e) { ) | rpl::start_with_next([=](const ChartLinesFilterWidget::Entry &e) {
const auto now = crl::now(); const auto now = crl::now();
_linearChartView->setEnabled(e.id, e.enabled, now); _chartView->setEnabled(e.id, e.enabled, now);
_animationController.setXPercentageLimits( _animationController.setXPercentageLimits(
_chartData, _chartData,
_animationController.currentXLimits(), _animationController.currentXLimits(),
_linearChartView, _chartView,
now); now);
}, _filterButtons->lifetime()); }, _filterButtons->lifetime());
} }
@ -1289,7 +1289,7 @@ void ChartWidget::setupFilterButtons() {
void ChartWidget::setChartData(Data::StatisticalChart chartData) { void ChartWidget::setChartData(Data::StatisticalChart chartData) {
_chartData = std::move(chartData); _chartData = std::move(chartData);
_linearChartView = std::make_unique<LinearChartView>(); _chartView = CreateChartView(ChartViewType::Linear);
setupDetails(); setupDetails();
setupFilterButtons(); setupFilterButtons();
@ -1297,7 +1297,7 @@ void ChartWidget::setChartData(Data::StatisticalChart chartData) {
_animationController.setXPercentageLimits( _animationController.setXPercentageLimits(
_chartData, _chartData,
{ _chartData.xPercentage.front(), _chartData.xPercentage.back() }, { _chartData.xPercentage.front(), _chartData.xPercentage.back() },
_linearChartView, _chartView,
0); 0);
updateChartFullWidth(_chartArea->width()); updateChartFullWidth(_chartArea->width());
updateHeader(); updateHeader();

View file

@ -19,7 +19,7 @@ namespace Statistic {
class RpMouseWidget; class RpMouseWidget;
class PointDetailsWidget; class PointDetailsWidget;
class ChartLinesFilterWidget; class ChartLinesFilterWidget;
class LinearChartView; class AbstractChartView;
class ChartWidget : public Ui::RpWidget { class ChartWidget : public Ui::RpWidget {
public: public:
@ -57,7 +57,7 @@ private:
void setXPercentageLimits( void setXPercentageLimits(
Data::StatisticalChart &chartData, Data::StatisticalChart &chartData,
Limits xPercentageLimits, Limits xPercentageLimits,
const std::unique_ptr<LinearChartView> &linearChartView, const std::unique_ptr<AbstractChartView> &AbstractChartView,
crl::time now); crl::time now);
void start(); void start();
void finish(); void finish();
@ -67,7 +67,7 @@ private:
crl::time now, crl::time now,
std::vector<ChartHorizontalLinesData> &horizontalLines, std::vector<ChartHorizontalLinesData> &horizontalLines,
std::vector<BottomCaptionLineData> &dateLines, std::vector<BottomCaptionLineData> &dateLines,
const std::unique_ptr<LinearChartView> &linearChartView); const std::unique_ptr<AbstractChartView> &AbstractChartView);
[[nodiscard]] Limits currentXLimits() const; [[nodiscard]] Limits currentXLimits() const;
[[nodiscard]] Limits currentXIndices() const; [[nodiscard]] Limits currentXIndices() const;
@ -142,7 +142,7 @@ private:
base::unique_qptr<ChartWidget> _zoomedChartWidget; base::unique_qptr<ChartWidget> _zoomedChartWidget;
std::unique_ptr<LinearChartView> _linearChartView; std::unique_ptr<AbstractChartView> _chartView;
struct { struct {
base::unique_qptr<PointDetailsWidget> widget; base::unique_qptr<PointDetailsWidget> widget;

View file

@ -14,4 +14,8 @@ struct Limits final {
float64 max = 0; float64 max = 0;
}; };
enum class ChartViewType {
Linear,
};
} // namespace Statistic } // namespace Statistic

View file

@ -0,0 +1,48 @@
/*
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 Data {
struct StatisticalChart;
} // namespace Data
namespace Statistic {
struct Limits;
class AbstractChartView {
public:
virtual ~AbstractChartView() = default;
virtual void paint(
QPainter &p,
const Data::StatisticalChart &chartData,
const Limits &xIndices,
const Limits &xPercentageLimits,
const Limits &heightLimits,
const QRect &rect,
bool footer) = 0;
virtual void paintSelectedXIndex(
QPainter &p,
const Data::StatisticalChart &chartData,
const Limits &xPercentageLimits,
const Limits &heightLimits,
const QRect &rect,
int selectedXIndex) = 0;
virtual void setEnabled(int id, bool enabled, crl::time now) = 0;
[[nodiscard]] virtual bool isEnabled(int id) const = 0;
[[nodiscard]] virtual bool isFinished() const = 0;
[[nodiscard]] virtual float64 alpha(int id) const = 0;
virtual void tick(crl::time now) = 0;
};
} // namespace Statistic

View file

@ -0,0 +1,24 @@
/*
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
*/
#include "statistics/view/chart_view_factory.h"
#include "statistics/statistics_common.h"
#include "statistics/view/linear_chart_view.h"
namespace Statistic {
std::unique_ptr<AbstractChartView> CreateChartView(ChartViewType type) {
switch (type) {
case ChartViewType::Linear: {
return std::make_unique<LinearChartView>();
} break;
default: Unexpected("Type in Statistic::CreateChartView.");
}
}
} // namespace Statistic

View file

@ -0,0 +1,18 @@
/*
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 {
class AbstractChartView;
enum class ChartViewType;
[[nodiscard]] std::unique_ptr<AbstractChartView> CreateChartView(
ChartViewType type);
} // namespace Statistic

View file

@ -57,6 +57,8 @@ void PaintChartLine(
LinearChartView::LinearChartView() = default; LinearChartView::LinearChartView() = default;
LinearChartView::~LinearChartView() = default;
void LinearChartView::paint( void LinearChartView::paint(
QPainter &p, QPainter &p,
const Data::StatisticalChart &chartData, const Data::StatisticalChart &chartData,

View file

@ -7,7 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#pragma once #pragma once
#include <statistics/statistics_common.h> #include "statistics/statistics_common.h"
#include "statistics/view/abstract_chart_view.h"
namespace Data { namespace Data {
struct StatisticalChart; struct StatisticalChart;
@ -17,9 +18,10 @@ namespace Statistic {
struct Limits; struct Limits;
class LinearChartView { class LinearChartView final : public AbstractChartView {
public: public:
LinearChartView(); LinearChartView();
~LinearChartView() override final;
void paint( void paint(
QPainter &p, QPainter &p,
@ -28,7 +30,7 @@ public:
const Limits &xPercentageLimits, const Limits &xPercentageLimits,
const Limits &heightLimits, const Limits &heightLimits,
const QRect &rect, const QRect &rect,
bool footer); bool footer) override;
void paintSelectedXIndex( void paintSelectedXIndex(
QPainter &p, QPainter &p,
@ -36,14 +38,14 @@ public:
const Limits &xPercentageLimits, const Limits &xPercentageLimits,
const Limits &heightLimits, const Limits &heightLimits,
const QRect &rect, const QRect &rect,
int selectedXIndex); int selectedXIndex) override;
void setEnabled(int id, bool enabled, crl::time now); void setEnabled(int id, bool enabled, crl::time now) override;
[[nodiscard]] bool isEnabled(int id) const; [[nodiscard]] bool isEnabled(int id) const override;
[[nodiscard]] bool isFinished() const; [[nodiscard]] bool isFinished() const override;
[[nodiscard]] float64 alpha(int id) const; [[nodiscard]] float64 alpha(int id) const override;
void tick(crl::time now); void tick(crl::time now) override;
private: private:
struct CacheToken final { struct CacheToken final {