Added details popup to selected part of pie chart.

This commit is contained in:
23rd 2023-09-15 12:41:14 +03:00 committed by John Preston
parent 42215343cf
commit 83753343cb
4 changed files with 88 additions and 6 deletions

View File

@ -32,6 +32,57 @@ namespace {
} // namespace
void PaintDetails(
QPainter &p,
const Data::StatisticalChart::Line &line,
int absoluteValue,
const QRect &rect) {
auto name = Ui::Text::String(
st::statisticsDetailsPopupStyle,
line.name);
auto value = Ui::Text::String(
st::statisticsDetailsPopupStyle,
QString("%L1").arg(absoluteValue));
const auto nameWidth = name.maxWidth();
const auto valueWidth = value.maxWidth();
const auto width = valueWidth
+ rect::m::sum::h(st::statisticsDetailsPopupMargins)
+ rect::m::sum::h(st::statisticsDetailsPopupPadding)
+ st::statisticsDetailsPopupPadding.left() // Between strings.
+ nameWidth;
const auto height = st::statisticsDetailsPopupStyle.font->height
+ rect::m::sum::v(st::statisticsDetailsPopupMargins)
+ rect::m::sum::v(st::statisticsDetailsPopupPadding);
const auto fullRect = QRect(
rect.x() + rect.width() - width,
rect.y(),
width,
height);
const auto innerRect = fullRect - st::statisticsDetailsPopupPadding;
const auto textRect = innerRect - st::statisticsDetailsPopupMargins;
Ui::Shadow::paint(p, innerRect, rect.width(), st::boxRoundShadow);
Ui::FillRoundRect(p, innerRect, st::boxBg, Ui::BoxCorners);
const auto lineY = textRect.y();
const auto valueContext = Ui::Text::PaintContext{
.position = QPoint(rect::right(textRect) - valueWidth, lineY),
};
const auto nameContext = Ui::Text::PaintContext{
.position = QPoint(textRect.x(), lineY),
.outerWidth = textRect.width() - valueWidth,
.availableWidth = textRect.width(),
};
p.setPen(st::boxTextFg);
name.draw(p, nameContext);
p.setPen(line.color);
value.draw(p, valueContext);
}
PointDetailsWidget::PointDetailsWidget(
not_null<Ui::RpWidget*> parent,
const Data::StatisticalChart &chartData,

View File

@ -12,6 +12,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Statistic {
void PaintDetails(
QPainter &p,
const Data::StatisticalChart::Line &line,
int absoluteValue,
const QRect &rect);
class PointDetailsWidget : public Ui::RippleButton {
public:
PointDetailsWidget(

View File

@ -7,8 +7,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "statistics/view/stack_linear_chart_view.h"
#include "ui/effects/animation_value_f.h"
#include "data/data_statistics.h"
#include "statistics/point_details_widget.h"
#include "ui/effects/animation_value_f.h"
#include "ui/painter.h"
#include "ui/rect.h"
#include "styles/style_statistics.h"
@ -429,27 +430,43 @@ void StackLinearChartView::paintZoomed(QPainter &p, const PaintContext &c) {
center + QPointF(side, side));
auto hq = PainterHighQualityEnabler(p);
auto selectedLineIndex = -1;
for (auto k = 0; k < c.chartData.lines.size(); k++) {
const auto previous = k
? _cachedTransition.lines[k - 1].angle
: -180;
const auto now = _cachedTransition.lines[k].angle;
p.setBrush(c.chartData.lines[k].color);
const auto &line = c.chartData.lines[k];
p.setBrush(line.color);
p.setPen(Qt::NoPen);
const auto textAngle = (previous + kPieAngleOffset)
+ (now - previous) / 2.;
const auto partOffset = _piePartController.offset(
c.chartData.lines[k].id,
textAngle);
const auto partOffset = _piePartController.offset(line.id, textAngle);
p.translate(partOffset);
p.drawPie(
rectF,
-(previous + kPieAngleOffset) * 16,
-(now - previous) * 16);
p.translate(-partOffset);
if (_piePartController.selected() == line.id) {
selectedLineIndex = k;
}
}
paintPieText(p, c);
if (selectedLineIndex >= 0) {
const auto &[localStart, localEnd] = _lastPaintedXIndices;
const auto &line = c.chartData.lines[selectedLineIndex];
auto sum = 0;
for (auto i = localStart; i <= localEnd; i++) {
sum += line.y[i];
}
sum *= alpha(line.id);
if (sum > 0) {
PaintDetails(p, line, sum, c.rect);
}
}
}
void StackLinearChartView::paintPieText(QPainter &p, const PaintContext &c) {
@ -552,6 +569,10 @@ QPointF StackLinearChartView::PiePartController::offset(
return { std::cos(radians) * offset, std::sin(radians) * offset };
}
auto StackLinearChartView::PiePartController::selected() const -> LineId {
return _selected;
}
void StackLinearChartView::handleMouseMove(
const Data::StatisticalChart &chartData,
const QPoint &center,
@ -570,7 +591,10 @@ void StackLinearChartView::handleMouseMove(
: -180;
const auto now = _cachedTransition.lines[k].angle;
if (angle > previous && angle <= now) {
if (_piePartController.set(chartData.lines[k].id)) {
const auto id = p.isNull()
? -1
: chartData.lines[k].id;
if (_piePartController.set(id)) {
if (!_piePartAnimation.animating()) {
_piePartAnimation.start();
}

View File

@ -128,6 +128,7 @@ private:
bool set(LineId id);
[[nodiscard]] float64 progress(LineId id);
[[nodiscard]] QPointF offset(LineId id, float64 angle);
[[nodiscard]] LineId selected() const;
private:
void update(LineId id);