Added class to calculate context state while chart lines are filtering.
This commit is contained in:
parent
13959ca36c
commit
e6559276c0
|
@ -1284,6 +1284,8 @@ PRIVATE
|
|||
settings/settings_websites.h
|
||||
statistics/chart_horizontal_lines_data.cpp
|
||||
statistics/chart_horizontal_lines_data.h
|
||||
statistics/chart_line_view_context.cpp
|
||||
statistics/chart_line_view_context.h
|
||||
statistics/chart_widget.cpp
|
||||
statistics/chart_widget.h
|
||||
statistics/linear_chart_view.cpp
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
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/chart_line_view_context.h"
|
||||
|
||||
namespace Statistic {
|
||||
namespace {
|
||||
constexpr auto kAlphaDuration = float64(200);
|
||||
} // namespace
|
||||
|
||||
void ChartLineViewContext::setEnabled(int id, bool enabled, crl::time now) {
|
||||
const auto it = _entries.find(id);
|
||||
if (it == end(_entries)) {
|
||||
_entries[id] = Entry{ .enabled = enabled, .startedAt = now };
|
||||
} else if (it->second.enabled != enabled) {
|
||||
auto &entry = it->second;
|
||||
entry.enabled = enabled;
|
||||
entry.startedAt = now
|
||||
- kAlphaDuration * (enabled ? entry.alpha : (1. - entry.alpha));
|
||||
}
|
||||
_isFinished = false;
|
||||
}
|
||||
|
||||
bool ChartLineViewContext::isFinished() const {
|
||||
return _isFinished;
|
||||
}
|
||||
|
||||
bool ChartLineViewContext::isEnabled(int id) const {
|
||||
const auto it = _entries.find(id);
|
||||
return (it == end(_entries)) ? true : it->second.enabled;
|
||||
}
|
||||
|
||||
float64 ChartLineViewContext::alpha(int id) const {
|
||||
const auto it = _entries.find(id);
|
||||
return (it == end(_entries)) ? 1. : it->second.alpha;
|
||||
}
|
||||
|
||||
void ChartLineViewContext::tick(crl::time now) {
|
||||
auto finishedCount = 0;
|
||||
auto idsToRemove = std::vector<int>();
|
||||
for (auto &[id, entry] : _entries) {
|
||||
if (!entry.startedAt) {
|
||||
continue;
|
||||
}
|
||||
const auto progress = (now - entry.startedAt) / kAlphaDuration;
|
||||
entry.alpha = std::clamp(
|
||||
entry.enabled ? progress : (1. - progress),
|
||||
0.,
|
||||
1.);
|
||||
if (entry.alpha == 1.) {
|
||||
idsToRemove.push_back(id);
|
||||
}
|
||||
if (progress >= 1.) {
|
||||
finishedCount++;
|
||||
}
|
||||
}
|
||||
_isFinished = (finishedCount == _entries.size());
|
||||
for (const auto &id : idsToRemove) {
|
||||
_entries.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace Statistic
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
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 ChartLineViewContext final {
|
||||
public:
|
||||
ChartLineViewContext() = default;
|
||||
|
||||
void setEnabled(int id, bool enabled, crl::time now);
|
||||
[[nodiscard]] bool isFinished() const;
|
||||
[[nodiscard]] bool isEnabled(int id) const;
|
||||
[[nodiscard]] float64 alpha(int id) const;
|
||||
|
||||
void tick(crl::time now);
|
||||
|
||||
private:
|
||||
struct Entry final {
|
||||
bool enabled = false;
|
||||
crl::time startedAt = 0;
|
||||
float64 alpha = 1.;
|
||||
};
|
||||
|
||||
base::flat_map<int, Entry> _entries;
|
||||
bool _isFinished = true;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Statistic
|
|
@ -529,11 +529,12 @@ ChartWidget::ChartAnimationController::ChartAnimationController(
|
|||
void ChartWidget::ChartAnimationController::setXPercentageLimits(
|
||||
Data::StatisticalChart &chartData,
|
||||
Limits xPercentageLimits,
|
||||
std::vector<ChartLineViewContext> &chartLinesViewContext,
|
||||
const ChartLineViewContext &chartLinesViewContext,
|
||||
crl::time now) {
|
||||
if ((_animationValueXMin.to() == xPercentageLimits.min)
|
||||
&& (_animationValueXMax.to() == xPercentageLimits.max)) {
|
||||
// return;
|
||||
&& (_animationValueXMax.to() == xPercentageLimits.max)
|
||||
&& chartLinesViewContext.isFinished()) {
|
||||
return;
|
||||
}
|
||||
start();
|
||||
_animationValueXMin.start(xPercentageLimits.min);
|
||||
|
@ -556,10 +557,7 @@ void ChartWidget::ChartAnimationController::setXPercentageLimits(
|
|||
auto minValue = std::numeric_limits<int>::max();
|
||||
auto maxValue = 0;
|
||||
for (auto &l : chartData.lines) {
|
||||
const auto it = ranges::find_if(chartLinesViewContext, [&](const auto &a) {
|
||||
return a.id == l.id;
|
||||
});
|
||||
if (it != end(chartLinesViewContext) && !it->enabled) {
|
||||
if (!chartLinesViewContext.isEnabled(l.id)) {
|
||||
continue;
|
||||
}
|
||||
const auto lineMax = l.segmentTree.rMaxQ(startXIndex, endXIndex);
|
||||
|
@ -633,7 +631,7 @@ void ChartWidget::ChartAnimationController::tick(
|
|||
crl::time now,
|
||||
std::vector<ChartHorizontalLinesData> &horizontalLines,
|
||||
std::vector<BottomCaptionLineData> &dateLines,
|
||||
std::vector<ChartLineViewContext> &chartLinesViewContext) {
|
||||
ChartLineViewContext &chartLinesViewContext) {
|
||||
if (!_animation.animating()) {
|
||||
return;
|
||||
}
|
||||
|
@ -690,33 +688,13 @@ void ChartWidget::ChartAnimationController::tick(
|
|||
const auto bottomLineAlphaFinished = isFinished(
|
||||
_animValueBottomLineAlpha);
|
||||
|
||||
auto chartLinesViewContextFinished = false;
|
||||
{
|
||||
auto finishedCount = 0;
|
||||
for (auto &viewLine : chartLinesViewContext) {
|
||||
if (!viewLine.startedAt) {
|
||||
continue;
|
||||
}
|
||||
const auto progress = (now - viewLine.startedAt)
|
||||
/ (kXExpandingDuration * 2);
|
||||
viewLine.alpha = std::clamp(
|
||||
viewLine.enabled ? progress : (1. - progress),
|
||||
0.,
|
||||
1.);
|
||||
if (progress >= 1.) {
|
||||
finishedCount++;
|
||||
}
|
||||
}
|
||||
chartLinesViewContextFinished =
|
||||
(finishedCount == chartLinesViewContext.size());
|
||||
}
|
||||
|
||||
chartLinesViewContext.tick(now);
|
||||
|
||||
if (xFinished
|
||||
&& yFinished
|
||||
&& alphaFinished
|
||||
&& bottomLineAlphaFinished
|
||||
&& chartLinesViewContextFinished) {
|
||||
&& chartLinesViewContext.isFinished()) {
|
||||
const auto &lines = horizontalLines.back().lines;
|
||||
if ((lines.front().absoluteValue == _animationValueHeightMin.to())
|
||||
&& lines.back().absoluteValue == _animationValueHeightMax.to()) {
|
||||
|
@ -1212,20 +1190,14 @@ void ChartWidget::setupFilterButtons() {
|
|||
|
||||
_filterButtons->buttonEnabledChanges(
|
||||
) | rpl::start_with_next([=](const ChartLinesFilterWidget::Entry &e) {
|
||||
auto data = ChartLineViewContext{
|
||||
.id = e.id,
|
||||
.enabled = e.enabled,
|
||||
.startedAt = crl::now(),
|
||||
};
|
||||
_animatedChartLines.clear();
|
||||
_animatedChartLines.push_back(data);
|
||||
const auto now = crl::now();
|
||||
_animatedChartLines.setEnabled(e.id, e.enabled, now);
|
||||
|
||||
_animationController.setXPercentageLimits(
|
||||
_chartData,
|
||||
_animationController.currentXLimits(),
|
||||
_animatedChartLines,
|
||||
data.startedAt);
|
||||
|
||||
now);
|
||||
}, _filterButtons->lifetime());
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
#include "data/data_statistics.h"
|
||||
#include "statistics/chart_horizontal_lines_data.h"
|
||||
#include "statistics/chart_line_view_context.h"
|
||||
#include "statistics/statistics_common.h"
|
||||
#include "ui/effects/animation_value.h"
|
||||
#include "ui/effects/animations.h"
|
||||
|
@ -48,7 +49,7 @@ private:
|
|||
void setXPercentageLimits(
|
||||
Data::StatisticalChart &chartData,
|
||||
Limits xPercentageLimits,
|
||||
std::vector<ChartLineViewContext> &chartLinesViewContext,
|
||||
const ChartLineViewContext &chartLinesViewContext,
|
||||
crl::time now);
|
||||
void start();
|
||||
void finish();
|
||||
|
@ -58,7 +59,7 @@ private:
|
|||
crl::time now,
|
||||
std::vector<ChartHorizontalLinesData> &horizontalLines,
|
||||
std::vector<BottomCaptionLineData> &dateLines,
|
||||
std::vector<ChartLineViewContext> &chartLinesViewContext);
|
||||
ChartLineViewContext &chartLinesViewContext);
|
||||
|
||||
[[nodiscard]] Limits currentXLimits() const;
|
||||
[[nodiscard]] Limits currentXIndices() const;
|
||||
|
@ -119,7 +120,7 @@ private:
|
|||
base::unique_qptr<ChartLinesFilterWidget> _filterButtons;
|
||||
Data::StatisticalChart _chartData;
|
||||
|
||||
std::vector<ChartLineViewContext> _animatedChartLines;
|
||||
ChartLineViewContext _animatedChartLines;
|
||||
|
||||
struct {
|
||||
base::unique_qptr<PointDetailsWidget> widget;
|
||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "statistics/linear_chart_view.h"
|
||||
|
||||
#include "data/data_statistics.h"
|
||||
#include "statistics/chart_line_view_context.h"
|
||||
#include "statistics/statistics_common.h"
|
||||
#include "ui/effects/animation_value_f.h"
|
||||
#include "ui/painter.h"
|
||||
|
@ -23,19 +24,13 @@ void PaintLinearChartView(
|
|||
const Limits &xPercentageLimits,
|
||||
const Limits &heightLimits,
|
||||
const QRect &rect,
|
||||
const std::vector<ChartLineViewContext> &linesContext,
|
||||
const ChartLineViewContext &lineViewContext,
|
||||
DetailsPaintContext &detailsPaintContext) {
|
||||
const auto currentMinHeight = rect.y(); //
|
||||
const auto currentMaxHeight = rect.height() + rect.y(); //
|
||||
|
||||
for (const auto &line : chartData.lines) {
|
||||
p.setOpacity(1.);
|
||||
for (const auto &lineContext : linesContext) {
|
||||
if (lineContext.id == line.id) {
|
||||
p.setOpacity(lineContext.alpha);
|
||||
break;
|
||||
}
|
||||
}
|
||||
p.setOpacity(lineViewContext.alpha(line.id));
|
||||
if (!p.opacity()) {
|
||||
continue;
|
||||
}
|
||||
|
@ -78,6 +73,7 @@ void PaintLinearChartView(
|
|||
p.drawPath(chartPath);
|
||||
}
|
||||
p.setPen(st::boxTextFg);
|
||||
p.setOpacity(1.);
|
||||
}
|
||||
|
||||
} // namespace Statistic
|
||||
|
|
|
@ -24,7 +24,7 @@ void PaintLinearChartView(
|
|||
const Limits &xPercentageLimits,
|
||||
const Limits &heightLimits,
|
||||
const QRect &rect,
|
||||
const std::vector<ChartLineViewContext> &linesContext,
|
||||
const ChartLineViewContext &lineViewContext,
|
||||
DetailsPaintContext &detailsPaintContext);
|
||||
|
||||
} // namespace Statistic
|
||||
|
|
|
@ -25,11 +25,4 @@ struct DetailsPaintContext final {
|
|||
std::vector<Dot> dots;
|
||||
};
|
||||
|
||||
struct ChartLineViewContext final {
|
||||
int id = 0;
|
||||
bool enabled = false;
|
||||
crl::time startedAt = 0;
|
||||
float64 alpha = 1.;
|
||||
};
|
||||
|
||||
} // namespace Statistic
|
||||
|
|
Loading…
Reference in New Issue