mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Added ability to paint pie chart as zoomed stack linear chart.
This commit is contained in:
parent
13b7a07d2e
commit
788eb014d4
3 changed files with 90 additions and 1 deletions
|
@ -46,6 +46,8 @@ statisticsDetailsBottomCaptionStyle: TextStyle(defaultTextStyle) {
|
||||||
font: font(10px);
|
font: font(10px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
statisticsPieChartFont: font(20px);
|
||||||
|
|
||||||
statisticsChartHeaderHeight: 20px;
|
statisticsChartHeaderHeight: 20px;
|
||||||
statisticsHeaderTitleTextStyle: TextStyle(defaultTextStyle) {
|
statisticsHeaderTitleTextStyle: TextStyle(defaultTextStyle) {
|
||||||
font: font(12px semibold);
|
font: font(12px semibold);
|
||||||
|
|
|
@ -19,6 +19,8 @@ namespace Statistic {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr auto kAlphaDuration = float64(200);
|
constexpr auto kAlphaDuration = float64(200);
|
||||||
|
constexpr auto kCircleSizeRatio = 0.42;
|
||||||
|
constexpr auto kMinTextScaleRatio = 0.3;
|
||||||
|
|
||||||
constexpr auto kRightTop = short(0);
|
constexpr auto kRightTop = short(0);
|
||||||
constexpr auto kRightBottom = short(1);
|
constexpr auto kRightBottom = short(1);
|
||||||
|
@ -112,6 +114,7 @@ void StackLinearChartView::paint(
|
||||||
for (auto i = xIndices.min; i <= xIndices.max; i++) {
|
for (auto i = xIndices.min; i <= xIndices.max; i++) {
|
||||||
sum += line.y[i];
|
sum += line.y[i];
|
||||||
}
|
}
|
||||||
|
sum *= alpha(line.id);
|
||||||
totalSum += sum;
|
totalSum += sum;
|
||||||
sums.push_back(sum);
|
sums.push_back(sum);
|
||||||
}
|
}
|
||||||
|
@ -139,6 +142,17 @@ void StackLinearChartView::paint(
|
||||||
const Limits &heightLimits,
|
const Limits &heightLimits,
|
||||||
const QRect &rect,
|
const QRect &rect,
|
||||||
bool footer) {
|
bool footer) {
|
||||||
|
if (_transitionProgress == 1) {
|
||||||
|
return paintZoomed(
|
||||||
|
p,
|
||||||
|
{
|
||||||
|
chartData,
|
||||||
|
xPercentageLimits,
|
||||||
|
heightLimits,
|
||||||
|
rect,
|
||||||
|
footer
|
||||||
|
});
|
||||||
|
}
|
||||||
const auto &[localStart, localEnd] = _lastPaintedXIndices;
|
const auto &[localStart, localEnd] = _lastPaintedXIndices;
|
||||||
_skipPoints = std::vector<bool>(chartData.lines.size(), false);
|
_skipPoints = std::vector<bool>(chartData.lines.size(), false);
|
||||||
auto paths = std::vector<QPainterPath>(
|
auto paths = std::vector<QPainterPath>(
|
||||||
|
@ -169,7 +183,6 @@ void StackLinearChartView::paint(
|
||||||
1.);
|
1.);
|
||||||
auto rectPath = QPainterPath();
|
auto rectPath = QPainterPath();
|
||||||
rectPath.addRect(rect);
|
rectPath.addRect(rect);
|
||||||
constexpr auto kCircleSizeRatio = 0.42;
|
|
||||||
const auto r = anim::interpolateF(
|
const auto r = anim::interpolateF(
|
||||||
1.,
|
1.,
|
||||||
kCircleSizeRatio,
|
kCircleSizeRatio,
|
||||||
|
@ -394,6 +407,70 @@ void StackLinearChartView::paint(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StackLinearChartView::paintZoomed(QPainter &p, const PaintContext &c) {
|
||||||
|
if (c.footer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto &chartData = c.chartData;
|
||||||
|
const auto center = QPointF(c.rect.center());
|
||||||
|
const auto side = (c.rect.width() / 2.) * kCircleSizeRatio;
|
||||||
|
const auto rectF = QRectF(
|
||||||
|
center - QPointF(side, side),
|
||||||
|
center + QPointF(side, side));
|
||||||
|
|
||||||
|
auto hq = PainterHighQualityEnabler(p);
|
||||||
|
constexpr auto kOffset = 90;
|
||||||
|
for (auto k = 0; k < chartData.lines.size(); k++) {
|
||||||
|
const auto previous = k
|
||||||
|
? _cachedTransition.lines[k - 1].angle
|
||||||
|
: -180;
|
||||||
|
const auto now = _cachedTransition.lines[k].angle;
|
||||||
|
|
||||||
|
p.setBrush(chartData.lines[k].color);
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.drawPie(rectF, -(previous + kOffset) * 16, -(now - previous) * 16);
|
||||||
|
}
|
||||||
|
const auto &font = st::statisticsPieChartFont;
|
||||||
|
const auto maxScale = side / (font->height * 2);
|
||||||
|
const auto minScale = maxScale * kMinTextScaleRatio;
|
||||||
|
p.setBrush(Qt::NoBrush);
|
||||||
|
p.setPen(st::premiumButtonFg);
|
||||||
|
p.setFont(font);
|
||||||
|
for (auto k = 0; k < chartData.lines.size(); k++) {
|
||||||
|
const auto previous = k
|
||||||
|
? _cachedTransition.lines[k - 1].angle
|
||||||
|
: -180;
|
||||||
|
const auto now = _cachedTransition.lines[k].angle;
|
||||||
|
const auto percentage = (now - previous) / 360.;
|
||||||
|
|
||||||
|
const auto rText = side * std::sqrt(1. - percentage);
|
||||||
|
const auto textAngle = (previous + kOffset) + (now - previous) / 2.;
|
||||||
|
const auto textRadians = textAngle * M_PI / 180.;
|
||||||
|
|
||||||
|
const auto scale = (minScale) + percentage * (maxScale - minScale);
|
||||||
|
const auto text = QString::number(std::round(percentage * 100))
|
||||||
|
+ u"%"_q;
|
||||||
|
const auto textW = font->width(text);
|
||||||
|
const auto textH = font->height;
|
||||||
|
const auto textXShift = textW / 2.;
|
||||||
|
const auto textYShift = textW / 2.;
|
||||||
|
const auto textRectCenter = rectF.center() + QPointF(
|
||||||
|
(rText - textXShift * (1. - scale)) * std::cos(textRadians),
|
||||||
|
(rText - textYShift * (1. - scale)) * std::sin(textRadians));
|
||||||
|
const auto textRect = QRectF(
|
||||||
|
textRectCenter - QPointF(textXShift, textYShift),
|
||||||
|
textRectCenter + QPointF(textXShift, textYShift));
|
||||||
|
p.setOpacity(alpha(chartData.lines[k].id));
|
||||||
|
p.setTransform(
|
||||||
|
QTransform()
|
||||||
|
.translate(textRectCenter.x(), textRectCenter.y())
|
||||||
|
.scale(scale, scale)
|
||||||
|
.translate(-textRectCenter.x(), -textRectCenter.y()));
|
||||||
|
p.drawText(textRect, text, style::al_center);
|
||||||
|
}
|
||||||
|
p.resetTransform();
|
||||||
|
}
|
||||||
|
|
||||||
void StackLinearChartView::paintSelectedXIndex(
|
void StackLinearChartView::paintSelectedXIndex(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
const Data::StatisticalChart &chartData,
|
const Data::StatisticalChart &chartData,
|
||||||
|
|
|
@ -62,6 +62,14 @@ public:
|
||||||
void update(float64 dt) override;
|
void update(float64 dt) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct PaintContext final {
|
||||||
|
const Data::StatisticalChart &chartData;
|
||||||
|
const Limits &xPercentageLimits;
|
||||||
|
const Limits &heightLimits;
|
||||||
|
const QRect ▭
|
||||||
|
bool footer = false;
|
||||||
|
};
|
||||||
|
|
||||||
void paint(
|
void paint(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
const Data::StatisticalChart &chartData,
|
const Data::StatisticalChart &chartData,
|
||||||
|
@ -70,6 +78,8 @@ private:
|
||||||
const QRect &rect,
|
const QRect &rect,
|
||||||
bool footer);
|
bool footer);
|
||||||
|
|
||||||
|
void paintZoomed(QPainter &p, const PaintContext &context);
|
||||||
|
|
||||||
struct SelectedPoints final {
|
struct SelectedPoints final {
|
||||||
int lastXIndex = -1;
|
int lastXIndex = -1;
|
||||||
Limits lastHeightLimits;
|
Limits lastHeightLimits;
|
||||||
|
|
Loading…
Add table
Reference in a new issue