Improved style of rulers on charts in statistics.

This commit is contained in:
23rd 2023-10-03 02:07:05 +03:00 committed by John Preston
parent bdfb0ffe04
commit f081917cd0
11 changed files with 92 additions and 82 deletions

View file

@ -5,7 +5,7 @@ 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_horizontal_lines_data.h"
#include "statistics/chart_rulers_data.h"
#include "lang/lang_tag.h"
@ -22,14 +22,15 @@ constexpr auto kStep = 5.;
}
[[nodiscard]] QString Format(int absoluteValue) {
return (absoluteValue >= 10'000)
constexpr auto kTooMuch = int(10'000);
return (absoluteValue >= kTooMuch)
? Lang::FormatCountToShort(absoluteValue).string
: QString("%L1").arg(absoluteValue);
: QString::number(absoluteValue);
}
} // namespace
ChartHorizontalLinesData::ChartHorizontalLinesData(
ChartRulersData::ChartRulersData(
int newMaxHeight,
int newMinHeight,
bool useMinHeight,
@ -104,7 +105,7 @@ ChartHorizontalLinesData::ChartHorizontalLinesData(
}
}
void ChartHorizontalLinesData::computeRelative(
void ChartRulersData::computeRelative(
int newMaxHeight,
int newMinHeight) {
for (auto &line : lines) {
@ -114,7 +115,7 @@ void ChartHorizontalLinesData::computeRelative(
}
}
int ChartHorizontalLinesData::LookupHeight(int maxValue) {
int ChartRulersData::LookupHeight(int maxValue) {
const auto v = (maxValue > 100) ? Round(maxValue) : maxValue;
const auto step = int(std::ceil(v / kStep));

View file

@ -9,9 +9,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Statistic {
struct ChartHorizontalLinesData final {
struct ChartRulersData final {
public:
ChartHorizontalLinesData(
ChartRulersData(
int newMaxHeight,
int newMinHeight,
bool useMinHeight,

View file

@ -134,7 +134,7 @@ void PaintBottomLine(
xPoint - st::statisticsChartBottomCaptionMaxWidth / 2.,
y,
st::statisticsChartBottomCaptionMaxWidth,
st::statisticsChartBottomCaptionSkip);
st::statisticsChartBottomCaptionHeight);
const auto edgeAlpha = (r.x() < 0)
? std::max(
0.,
@ -601,7 +601,7 @@ void ChartWidget::ChartAnimationController::setXPercentageLimits(
(alpha.current() == alpha.to()) ? 0. : alpha.current(),
1.);
_dtHeight.currentAlpha = 0.;
_addHorizontalLineRequests.fire({});
_addRulerRequests.fire({});
}
_dtHeight.speed = (!linesFilter->isFinished())
? kDtHeightSpeedFilter
@ -616,9 +616,9 @@ void ChartWidget::ChartAnimationController::setXPercentageLimits(
}
}
auto ChartWidget::ChartAnimationController::addHorizontalLineRequests() const
auto ChartWidget::ChartAnimationController::addRulerRequests() const
-> rpl::producer<> {
return _addHorizontalLineRequests.events();
return _addRulerRequests.events();
}
void ChartWidget::ChartAnimationController::start() {
@ -647,7 +647,7 @@ void ChartWidget::ChartAnimationController::restartBottomLineAlpha() {
void ChartWidget::ChartAnimationController::tick(
crl::time now,
ChartHorizontalLinesView &horizontalLinesView,
ChartRulersView &rulersView,
std::vector<BottomCaptionLineData> &dateLines,
const std::unique_ptr<AbstractChartView> &chartView,
const std::shared_ptr<LinesFilterController> &linesFilter) {
@ -738,7 +738,7 @@ void ChartWidget::ChartAnimationController::tick(
_dtHeight.current.max,
anim::easeInCubic);
horizontalLinesView.computeRelative(
rulersView.computeRelative(
_animationValueHeightMax.current(),
_animationValueHeightMin.current());
}
@ -757,7 +757,7 @@ void ChartWidget::ChartAnimationController::tick(
_animationValueHeightAlpha.update(
_dtHeight.currentAlpha,
anim::easeInCubic);
horizontalLinesView.setAlpha(_animationValueHeightAlpha.current());
rulersView.setAlpha(_animationValueHeightAlpha.current());
}
if (!bottomLineAlphaFinished) {
@ -916,7 +916,9 @@ QRect ChartWidget::chartAreaRect() const {
st::lineWidth,
st::boxTextFont->height,
st::lineWidth,
st::lineWidth + st::statisticsChartBottomCaptionHeight);
st::lineWidth
+ st::statisticsChartBottomCaptionHeight
+ st::statisticsChartBottomCaptionSkip);
}
void ChartWidget::setupChartArea() {
@ -928,7 +930,7 @@ void ChartWidget::setupChartArea() {
_animationController.tick(
now,
_horizontalLinesView,
_rulersView,
_bottomLine.dates,
_chartView,
_linesFilterController);
@ -941,7 +943,7 @@ void ChartWidget::setupChartArea() {
return;
}
_horizontalLinesView.paintHorizontalLines(p, chartRect);
_rulersView.paintRulers(p, chartRect);
const auto context = PaintContext{
_chartData,
@ -957,14 +959,17 @@ void ChartWidget::setupChartArea() {
_chartView->paint(p, context);
}
_horizontalLinesView.paintCaptionsToHorizontalLines(p, chartRect);
_rulersView.paintCaptionsToRulers(p, chartRect);
{
[[maybe_unused]] const auto o = ScopedPainterOpacity(
p,
p.opacity() * kRulerLineAlpha);
const auto bottom = r
- QMargins{ 0, rect::bottom(chartRect), 0, 0 };
p.fillRect(bottom, st::boxBg);
p.fillRect(
QRect(bottom.x(), bottom.y(), bottom.width(), st::lineWidth),
st::windowSubTextFg);
st::boxTextFg);
}
if (_details.widget) {
const auto detailsAlpha = _details.widget->alpha();
@ -989,7 +994,7 @@ void ChartWidget::setupChartArea() {
_animationController.finalXLimits(),
_bottomLine.chartFullWidth,
_chartArea->width(),
rect::bottom(chartRect),
rect::bottom(chartRect) + st::statisticsChartBottomCaptionSkip,
_bottomLine.captionIndicesOffset);
}, _footer->lifetime());
}
@ -1093,9 +1098,9 @@ void ChartWidget::setupFooter() {
}
});
_animationController.addHorizontalLineRequests(
_animationController.addRulerRequests(
) | rpl::start_with_next([=] {
_horizontalLinesView.add(
_rulersView.add(
_animationController.finalHeightLimits(),
true);
_animationController.start();
@ -1126,7 +1131,7 @@ void ChartWidget::setupFooter() {
return;
}
_lastHeightLimitsChanged = now;
_horizontalLinesView.add(
_rulersView.add(
_animationController.finalHeightLimits(),
true);
}, _footer->lifetime());
@ -1413,7 +1418,7 @@ void ChartWidget::setChartData(
_chartView = CreateChartView(type);
_chartView->setLinesFilterController(_linesFilterController);
_horizontalLinesView.setChartData(_chartData, type);
_rulersView.setChartData(_chartData, type);
setupDetails();
setupFilterButtons();
@ -1433,7 +1438,7 @@ void ChartWidget::setChartData(
updateHeader();
updateBottomDates();
_animationController.finish();
_horizontalLinesView.add(_animationController.finalHeightLimits(), false);
_rulersView.add(_animationController.finalHeightLimits(), false);
RpWidget::showChildren();
_chartArea->update();

View file

@ -8,7 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "data/data_statistics_chart.h"
#include "statistics/view/chart_horizontal_lines_view.h"
#include "statistics/view/chart_rulers_view.h"
#include "statistics/statistics_common.h"
#include "ui/effects/animation_value.h"
#include "ui/effects/animations.h"
@ -33,7 +33,7 @@ public:
Data::StatisticalChart chartData,
float64 x,
ChartViewType type);
void addHorizontalLine(Limits newHeight, bool animated);
void addRuler(Limits newHeight, bool animated);
[[nodiscard]] rpl::producer<float64> zoomRequests();
@ -70,7 +70,7 @@ private:
void restartBottomLineAlpha();
void tick(
crl::time now,
ChartHorizontalLinesView &horizontalLinesView,
ChartRulersView &rulersView,
std::vector<BottomCaptionLineData> &dateLines,
const std::unique_ptr<AbstractChartView> &chartView,
const std::shared_ptr<LinesFilterController> &linesFilter);
@ -84,7 +84,7 @@ private:
[[nodiscard]] bool animating() const;
[[nodiscard]] bool footerAnimating() const;
[[nodiscard]] rpl::producer<> addHorizontalLineRequests() const;
[[nodiscard]] rpl::producer<> addRulerRequests() const;
private:
Ui::Animations::Basic _animation;
@ -120,7 +120,7 @@ private:
bool lastFPSSlow = false;
} _benchmark;
rpl::event_stream<> _addHorizontalLineRequests;
rpl::event_stream<> _addRulerRequests;
};
@ -169,7 +169,7 @@ private:
ChartAnimationController _animationController;
crl::time _lastHeightLimitsChanged = 0;
ChartHorizontalLinesView _horizontalLinesView;
ChartRulersView _rulersView;
bool _zoomEnabled = false;
rpl::event_stream<float64> _zoomRequests;

View file

@ -22,17 +22,17 @@ statisticsDetailsArrowStroke: 1.5;
statisticsDetailsPopupMargins: margins(8px, 8px, 8px, 8px);
statisticsDetailsPopupPadding: margins(6px, 6px, 6px, 6px);
statisticsDetailsPopupMidLineSpace: 4px;
statisticsDetailsDotRadius: 4px;
statisticsDetailsDotRadius: 5px;
statisticsChartLineWidth: 2px;
statisticsChartFooterBetweenSide: 5px;
statisticsChartFooterSideWidth: 10px;
statisticsChartFooterArrowSize: size(10px, 30px);
statisticsChartHorizontalLineCaptionSkip: 4px;
statisticsChartRulerCaptionSkip: 4px;
statisticsChartBottomCaptionHeight: 14px;
statisticsChartBottomCaptionSkip: 15px;
statisticsChartBottomCaptionHeight: 15px;
statisticsChartBottomCaptionSkip: 6px;
statisticsChartBottomCaptionMaxWidth: 44px;

View file

@ -9,6 +9,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Statistic {
constexpr auto kRulerLineAlpha = 0.06;
struct Limits final {
float64 min = 0;
float64 max = 0;

View file

@ -5,7 +5,7 @@ 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_horizontal_lines_view.h"
#include "statistics/view/chart_rulers_view.h"
#include "data/data_statistics_chart.h"
#include "statistics/statistics_common.h"
@ -14,12 +14,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Statistic {
ChartHorizontalLinesView::ChartHorizontalLinesView() = default;
ChartRulersView::ChartRulersView() = default;
void ChartHorizontalLinesView::setChartData(
void ChartRulersView::setChartData(
const Data::StatisticalChart &chartData,
ChartViewType type) {
_horizontalLines.clear();
_rulers.clear();
_isDouble = (type == ChartViewType::DoubleLinear);
if (_isDouble && (chartData.lines.size() == 2)) {
_leftPen = QPen(chartData.lines.front().color);
@ -37,33 +37,33 @@ void ChartHorizontalLinesView::setChartData(
}
}
void ChartHorizontalLinesView::paintHorizontalLines(
void ChartRulersView::paintRulers(
QPainter &p,
const QRect &r) {
const auto alpha = p.opacity();
for (auto &horizontalLine : _horizontalLines) {
p.setOpacity(alpha * horizontalLine.alpha);
for (const auto &line : horizontalLine.lines) {
for (auto &ruler : _rulers) {
p.setOpacity(alpha * ruler.alpha * kRulerLineAlpha);
for (const auto &line : ruler.lines) {
const auto lineRect = QRect(
0,
r.y() + r.height() * line.relativeValue,
r.x() + r.width(),
st::lineWidth);
p.fillRect(lineRect, st::windowSubTextFg);
p.fillRect(lineRect, st::boxTextFg);
}
}
p.setOpacity(alpha);
}
void ChartHorizontalLinesView::paintCaptionsToHorizontalLines(
void ChartRulersView::paintCaptionsToRulers(
QPainter &p,
const QRect &r) {
const auto offset = r.y() - st::statisticsChartHorizontalLineCaptionSkip;
const auto offset = r.y() - st::statisticsChartRulerCaptionSkip;
p.setFont(st::statisticsDetailsBottomCaptionStyle.font);
const auto alpha = p.opacity();
for (auto &horizontalLine : _horizontalLines) {
p.setOpacity(alpha * horizontalLine.alpha);
for (const auto &line : horizontalLine.lines) {
for (auto &ruler : _rulers) {
p.setOpacity(alpha * ruler.alpha);
for (const auto &line : ruler.lines) {
const auto y = offset + r.height() * line.relativeValue;
p.setPen(_isDouble ? _leftPen : st::windowSubTextFg);
p.drawText(
@ -88,24 +88,24 @@ void ChartHorizontalLinesView::paintCaptionsToHorizontalLines(
p.setOpacity(alpha);
}
void ChartHorizontalLinesView::computeRelative(
void ChartRulersView::computeRelative(
int newMaxHeight,
int newMinHeight) {
for (auto &horizontalLine : _horizontalLines) {
horizontalLine.computeRelative(newMaxHeight, newMinHeight);
for (auto &ruler : _rulers) {
ruler.computeRelative(newMaxHeight, newMinHeight);
}
}
void ChartHorizontalLinesView::setAlpha(float64 value) {
for (auto &horizontalLine : _horizontalLines) {
horizontalLine.alpha = horizontalLine.fixedAlpha * (1. - value);
void ChartRulersView::setAlpha(float64 value) {
for (auto &ruler : _rulers) {
ruler.alpha = ruler.fixedAlpha * (1. - value);
}
_horizontalLines.back().alpha = value;
_rulers.back().alpha = value;
if (value == 1.) {
while (_horizontalLines.size() > 1) {
const auto startIt = begin(_horizontalLines);
while (_rulers.size() > 1) {
const auto startIt = begin(_rulers);
if (!startIt->alpha) {
_horizontalLines.erase(startIt);
_rulers.erase(startIt);
} else {
break;
}
@ -113,8 +113,8 @@ void ChartHorizontalLinesView::setAlpha(float64 value) {
}
}
void ChartHorizontalLinesView::add(Limits newHeight, bool animated) {
auto newLinesData = ChartHorizontalLinesData(
void ChartRulersView::add(Limits newHeight, bool animated) {
auto newLinesData = ChartRulersData(
newHeight.max,
newHeight.min,
true,
@ -128,14 +128,14 @@ void ChartHorizontalLinesView::add(Limits newHeight, bool animated) {
}
}
if (!animated) {
_horizontalLines.clear();
_rulers.clear();
}
for (auto &horizontalLine : _horizontalLines) {
horizontalLine.fixedAlpha = horizontalLine.alpha;
for (auto &ruler : _rulers) {
ruler.fixedAlpha = ruler.alpha;
}
_horizontalLines.push_back(newLinesData);
_rulers.push_back(newLinesData);
if (!animated) {
_horizontalLines.back().alpha = 1.;
_rulers.back().alpha = 1.;
}
}

View file

@ -7,7 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "statistics/chart_horizontal_lines_data.h"
#include "statistics/chart_rulers_data.h"
namespace Data {
struct StatisticalChart;
@ -18,17 +18,17 @@ namespace Statistic {
enum class ChartViewType;
struct Limits;
struct ChartHorizontalLinesView final {
struct ChartRulersView final {
public:
ChartHorizontalLinesView();
ChartRulersView();
void setChartData(
const Data::StatisticalChart &chartData,
ChartViewType type);
void paintHorizontalLines(QPainter &p, const QRect &r);
void paintRulers(QPainter &p, const QRect &r);
void paintCaptionsToHorizontalLines(QPainter &p, const QRect &r);
void paintCaptionsToRulers(QPainter &p, const QRect &r);
void computeRelative(int newMaxHeight, int newMinHeight);
void setAlpha(float64 value);
@ -39,7 +39,7 @@ private:
QPen _leftPen;
QPen _rightPen;
std::vector<ChartHorizontalLinesData> _horizontalLines;
std::vector<ChartRulersData> _rulers;
float64 _scaledLineRatio = 0.;
bool _isLeftLineScaled = false;

View file

@ -162,14 +162,16 @@ void LinearChartView::paintSelectedXIndex(
}
if (!linePainted) {
[[maybe_unused]] const auto o = ScopedPainterOpacity(
p,
p.opacity() * progress * kRulerLineAlpha);
const auto lineRect = QRectF(
c.rect.x()
+ begin(_selectedPoints.points)->second.x()
begin(_selectedPoints.points)->second.x()
- (st::lineWidth / 2.),
c.rect.y(),
st::lineWidth,
c.rect.height());
p.fillRect(lineRect, st::windowSubTextFg);
p.fillRect(lineRect, st::boxTextFg);
linePainted = true;
}

View file

@ -874,13 +874,13 @@ void StackLinearChartView::paintSelectedXIndex(
{
[[maybe_unused]] const auto o = ScopedPainterOpacity(
p,
p.opacity() * progress);
p.opacity() * progress * kRulerLineAlpha);
const auto lineRect = QRectF(
_selectedPoints.xPoint - (st::lineWidth / 2.),
c.rect.y(),
st::lineWidth,
c.rect.height());
p.fillRect(lineRect, st::windowSubTextFg);
p.fillRect(lineRect, st::boxTextFg);
}
}
_selectedPoints.lastXIndex = selectedXIndex;

View file

@ -163,12 +163,12 @@ PRIVATE
statistics/chart_header_widget.cpp
statistics/chart_header_widget.h
statistics/chart_horizontal_lines_data.cpp
statistics/chart_horizontal_lines_data.h
statistics/chart_lines_filter_controller.cpp
statistics/chart_lines_filter_controller.h
statistics/chart_lines_filter_widget.cpp
statistics/chart_lines_filter_widget.h
statistics/chart_rulers_data.cpp
statistics/chart_rulers_data.h
statistics/chart_widget.cpp
statistics/chart_widget.h
statistics/point_details_widget.cpp
@ -179,8 +179,8 @@ PRIVATE
statistics/statistics_data_deserialize.cpp
statistics/statistics_data_deserialize.h
statistics/view/abstract_chart_view.h
statistics/view/chart_horizontal_lines_view.cpp
statistics/view/chart_horizontal_lines_view.h
statistics/view/chart_rulers_view.cpp
statistics/view/chart_rulers_view.h
statistics/view/chart_view_factory.cpp
statistics/view/chart_view_factory.h
statistics/view/linear_chart_view.cpp