Added paint of footer for zoomed stack linear chart.

This commit is contained in:
23rd 2023-09-18 21:07:02 +03:00 committed by John Preston
parent 5dc078a3f8
commit c5f294a1ac
6 changed files with 130 additions and 29 deletions

View File

@ -1302,6 +1302,8 @@ PRIVATE
statistics/view/chart_view_factory.h
statistics/view/linear_chart_view.cpp
statistics/view/linear_chart_view.h
statistics/view/stack_chart_common.cpp
statistics/view/stack_chart_common.h
statistics/view/stack_chart_view.cpp
statistics/view/stack_chart_view.h
statistics/view/stack_linear_chart_view.cpp

View File

@ -0,0 +1,33 @@
/*
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/stack_chart_common.h"
#include "data/data_statistics.h"
#include "statistics/statistics_common.h"
namespace Statistic {
LeftStartAndStep ComputeLeftStartAndStep(
const Data::StatisticalChart &chartData,
const Limits &xPercentageLimits,
const QRect &rect,
float64 xIndexStart) {
const auto fullWidth = rect.width()
/ (xPercentageLimits.max - xPercentageLimits.min);
const auto offset = fullWidth * xPercentageLimits.min;
const auto p = (chartData.xPercentage.size() < 2)
? 1.
: chartData.xPercentage[1] * fullWidth;
const auto w = chartData.xPercentage[1] * (fullWidth - p);
const auto leftStart = rect.x()
+ chartData.xPercentage[xIndexStart] * (fullWidth - p)
- offset;
return { leftStart, w };
}
} // namespace Statistic

View File

@ -0,0 +1,29 @@
/*
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;
struct LeftStartAndStep final {
float64 start = 0.;
float64 step = 0.;
};
[[nodiscard]] LeftStartAndStep ComputeLeftStartAndStep(
const Data::StatisticalChart &chartData,
const Limits &xPercentageLimits,
const QRect &rect,
float64 xIndexStart);
} // namespace Statistic

View File

@ -7,8 +7,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "statistics/view/stack_chart_view.h"
#include "ui/effects/animation_value_f.h"
#include "data/data_statistics.h"
#include "statistics/view/stack_chart_common.h"
#include "ui/effects/animation_value_f.h"
#include "ui/painter.h"
namespace Statistic {
@ -16,29 +17,6 @@ namespace {
constexpr auto kAlphaDuration = float64(200);
struct LeftStartAndStep final {
float64 start = 0.;
float64 step = 0.;
};
[[nodiscard]] LeftStartAndStep ComputeLeftStartAndStep(
const Data::StatisticalChart &chartData,
const Limits &xPercentageLimits,
const QRect &rect,
float64 xIndexStart) {
const auto fullWidth = rect.width()
/ (xPercentageLimits.max - xPercentageLimits.min);
const auto offset = fullWidth * xPercentageLimits.min;
const auto p = (chartData.xPercentage.size() < 2)
? 1.
: chartData.xPercentage[1] * fullWidth;
const auto w = chartData.xPercentage[1] * (fullWidth - p);
const auto leftStart = rect.x()
+ chartData.xPercentage[xIndexStart] * (fullWidth - p)
- offset;
return { leftStart, w };
}
} // namespace
StackChartView::StackChartView() = default;

View File

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_statistics.h"
#include "statistics/point_details_widget.h"
#include "statistics/view/stack_chart_common.h"
#include "ui/effects/animation_value_f.h"
#include "ui/painter.h"
#include "ui/rect.h"
@ -151,8 +152,12 @@ void StackLinearChartView::paint(
rect,
footer
};
if (_transitionProgress == 1) {
return paintZoomed(p, context);
if (_transitionProgress == 1.) {
if (footer) {
return paintZoomedFooter(p, context);
} else {
return paintZoomed(p, context);
}
}
const auto &[localStart, localEnd] = _lastPaintedXIndices;
_skipPoints = std::vector<bool>(chartData.lines.size(), false);
@ -389,17 +394,18 @@ void StackLinearChartView::paint(
p.setClipPath(ovalPath);
}
const auto opacity = footer ? (1. - _transitionProgress) : 1.;
for (auto k = int(chartData.lines.size() - 1); k >= 0; k--) {
if (paths[k].isEmpty()) {
continue;
}
const auto &line = chartData.lines[k];
p.setOpacity(alpha(line.id));
p.setOpacity(alpha(line.id) * opacity);
p.setPen(Qt::NoPen);
p.fillPath(paths[k], line.color);
}
p.setOpacity(1.);
{
p.setOpacity(opacity);
if (!footer) {
constexpr auto kAlphaTextPart = 0.6;
const auto progress = std::clamp(
(_transitionProgress - kAlphaTextPart) / (1. - kAlphaTextPart),
@ -409,6 +415,8 @@ void StackLinearChartView::paint(
auto o = ScopedPainterOpacity(p, progress);
paintPieText(p, context);
}
} else {
paintZoomedFooter(p, context);
}
// Fix ugly outline.
@ -423,6 +431,7 @@ void StackLinearChartView::paintZoomed(QPainter &p, const PaintContext &c) {
if (c.footer) {
return;
}
p.fillRect(c.rect, st::boxBg);
const auto center = QPointF(c.rect.center());
const auto side = (c.rect.width() / 2.) * kCircleSizeRatio;
const auto rectF = QRectF(
@ -472,6 +481,55 @@ void StackLinearChartView::paintZoomed(QPainter &p, const PaintContext &c) {
}
}
void StackLinearChartView::paintZoomedFooter(
QPainter &p,
const PaintContext &c) {
if (!c.footer) {
return;
}
auto o = ScopedPainterOpacity(p, _transitionProgress);
auto hq = PainterHighQualityEnabler(p);
const auto &[localStart, localEnd] = _lastPaintedXIndices;
const auto &[leftStart, w] = ComputeLeftStartAndStep(
c.chartData,
c.xPercentageLimits,
c.rect,
localStart);
for (auto i = localStart; i <= localEnd; i++) {
auto sum = 0.;
auto lastEnabledId = int(0);
for (const auto &line : c.chartData.lines) {
if (!isEnabled(line.id)) {
continue;
}
sum += line.y[i] * alpha(line.id);
lastEnabledId = line.id;
}
auto stack = 0.;
for (auto k = int(c.chartData.lines.size() - 1); k >= 0; k--) {
const auto &line = c.chartData.lines[k];
if (!isEnabled(line.id)) {
continue;
}
const auto visibleHeight = c.rect.height() * (line.y[i] / sum);
const auto height = (line.id == lastEnabledId)
? c.rect.height()
: visibleHeight;
const auto column = QRectF(
leftStart + (i - localStart) * w,
stack,
w,
height);
p.setPen(Qt::NoPen);
p.fillRect(column, line.color);
stack += visibleHeight;
}
}
}
void StackLinearChartView::paintPieText(QPainter &p, const PaintContext &c) {
const auto center = QPointF(c.rect.center());
const auto side = (c.rect.width() / 2.) * kCircleSizeRatio;

View File

@ -86,6 +86,7 @@ private:
bool footer);
void paintZoomed(QPainter &p, const PaintContext &context);
void paintZoomedFooter(QPainter &p, const PaintContext &context);
void paintPieText(QPainter &p, const PaintContext &context);
[[nodiscard]] bool skipSelectedTranslation() const;