# HG changeset patch # User Paper # Date 1698861154 14400 # Node ID d5efb81540b31b8cdb1a32e31d38803a03de0264 # Parent 2c27582a177c744909ea2607235b481896e0546b statistics: add graph! also now we have a VERY VERY simple graph widget that probably sucks and doesn't work half the time :) diff -r 2c27582a177c -r d5efb81540b3 include/gui/pages/statistics.h --- a/include/gui/pages/statistics.h Wed Nov 01 00:00:56 2023 -0400 +++ b/include/gui/pages/statistics.h Wed Nov 01 13:52:34 2023 -0400 @@ -3,9 +3,10 @@ #include #include +#include "gui/widgets/graph.h" namespace TextWidgets { -class Paragraph; +class LabelledSection; } class StatisticsPage : public QFrame { @@ -22,16 +23,11 @@ std::string MinutesToDateString(int minutes); std::string SecondsToDateString(int seconds); - TextWidgets::Paragraph* anime_list_data; + std::shared_ptr _anime_list; - // QPlainTextEdit* score_distribution_title; - // QPlainTextEdit* score_distribution_labels; - // wxStaticText* score_distribution_graph; // how am I gonna do this + std::shared_ptr> _score_distribution_graph; - /* we don't HAVE a local database (yet ;)) */ - // QPlainTextEdit* local_database_data; - - TextWidgets::Paragraph* application_data; + std::shared_ptr _application; }; #endif // __gui__pages__statistics_h \ No newline at end of file diff -r 2c27582a177c -r d5efb81540b3 include/gui/widgets/graph.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/gui/widgets/graph.h Wed Nov 01 13:52:34 2023 -0400 @@ -0,0 +1,60 @@ +#ifndef __gui__widgets__graph_h +#define __gui__widgets__graph_h +#include +#include +#include +#include +#include +#include +#include +#include + +template /* does this even work?? */ +class Graph final : public QWidget { +public: + Graph(QWidget* parent = nullptr) : QWidget(parent) {}; + void AddItem(T key, int val) { map[key] = val; update(); updateGeometry(); }; + void Clear() { map.clear(); update(); updateGeometry(); }; + +protected: + static constexpr int ITEM_HEIGHT = 20; + static constexpr int TEXT_WIDTH = 30; + inline int GetTotal() { + int count = 0; + for (const auto& item : map) + count += item.second; + return count; + } + QSize minimumSizeHint() const override { return QSize(100, ITEM_HEIGHT * map.size()); }; + void paintEvent(QPaintEvent* event) override { + const QRect rect = event->rect(); + const int height_of_each = rect.height() / map.size(); + const int size = GetTotal(); + + /* now we do the actual painting */ + QPainter painter(this); + + int i = 0; + for (const auto& item : map) { + painter.drawText(QRect(0, i*ITEM_HEIGHT, TEXT_WIDTH, ITEM_HEIGHT), Qt::AlignRight | Qt::AlignVCenter, QString::number(item.first)); + + if (size) { + painter.save(); + + QPen pen(Qt::transparent, 0); + painter.setPen(pen); + + QPainterPath path; + path.addRect(rect.x()+35, rect.y()+(i*ITEM_HEIGHT), (static_cast(item.second)/size)*(rect.width()-35), ITEM_HEIGHT); + painter.fillPath(path, Qt::blue); + painter.drawPath(path); + + painter.restore(); + } + i++; + } + }; + std::unordered_map map = {}; +}; + +#endif // __gui__widgets__graph_h \ No newline at end of file diff -r 2c27582a177c -r d5efb81540b3 src/gui/pages/statistics.cc --- a/src/gui/pages/statistics.cc Wed Nov 01 00:00:56 2023 -0400 +++ b/src/gui/pages/statistics.cc Wed Nov 01 13:52:34 2023 -0400 @@ -3,6 +3,7 @@ #include "core/session.h" #include "gui/pages/anime_list.h" #include "gui/widgets/text.h" +#include "gui/widgets/graph.h" #include #include #include @@ -22,18 +23,31 @@ setPalette(pal); setAutoFillBackground(true); - TextWidgets::LabelledSection* anime_list_paragraph = new TextWidgets::LabelledSection( + _anime_list.reset(new TextWidgets::LabelledSection( tr("Anime list"), tr("Anime count:\nEpisode count:\nTime spent watching:\nTime to complete:\nAverage score:\nScore deviation:"), - "", this); - anime_list_data = anime_list_paragraph->GetParagraph(); + "", this)); + + /* spaghetti incoming */ + QWidget* score_dist_widget = new QWidget(this); + QVBoxLayout* score_dist_layout = new QVBoxLayout(score_dist_widget); - TextWidgets::LabelledSection* application_paragraph = - new TextWidgets::LabelledSection(tr("Minori"), tr("Uptime:\nRequests made:"), "\n\n", this); - application_data = application_paragraph->GetParagraph(); + QWidget* content = new QWidget(score_dist_widget); + QVBoxLayout* content_layout = new QVBoxLayout(content); + score_dist_layout->addWidget(new TextWidgets::Header(tr("Score distribution"), content)); + _score_distribution_graph.reset(new Graph(content)); + content_layout->addWidget(_score_distribution_graph.get()); + content_layout->setContentsMargins(0, 0, 0, 0); + content->setContentsMargins(12, 0, 0, 0); - layout->addWidget(anime_list_paragraph); - layout->addWidget(application_paragraph); + score_dist_layout->addWidget(content); + score_dist_layout->setContentsMargins(0, 0, 0, 0); + + _application.reset(new TextWidgets::LabelledSection(tr("Minori"), tr("Uptime:\nRequests made:"), "\n\n", this)); + + layout->addWidget(_anime_list.get()); + layout->addWidget(score_dist_widget); + layout->addWidget(_application.get()); layout->addStretch(); QTimer* timer = new QTimer(this); @@ -90,6 +104,14 @@ } #undef ADD_TIME_SEGMENT +inline int GetTotalWithScore(int score) { + int count = 0; + for (const auto& item : Anime::db.items) + if (item.second.IsInUserList() && item.second.GetUserScore() == score) + count++; + return count; +} + void StatisticsPage::UpdateStatistics() { /* Anime list */ QString string = ""; @@ -100,14 +122,18 @@ ts << MinutesToDateString(Anime::db.GetTotalPlannedAmount()).c_str() << '\n'; ts << Anime::db.GetAverageScore() << '\n'; ts << Anime::db.GetScoreDeviation(); - anime_list_data->SetText(string); + _anime_list->GetParagraph()->SetText(string); + + _score_distribution_graph->Clear(); + for (int i = 10; i <= 100; i += 10) + _score_distribution_graph->AddItem(i, GetTotalWithScore(i)); string = ""; ts << QString::fromUtf8(SecondsToDateString(session.uptime() / 1000).c_str()) << '\n'; ts << session.GetRequests(); /* Application */ // UiUtils::SetPlainTextEditData(application_data, QString::number(session.uptime() / 1000)); - application_data->SetText(string); + _application->GetParagraph()->SetText(string); } #include "gui/pages/moc_statistics.cpp"