comparison include/gui/widgets/graph.h @ 258:862d0d8619f6

*: HUUUGE changes animia has been renamed to animone, so instead of thinking of a health condition, you think of a beautiful flower :) I've also edited some of the code for animone, but I have no idea if it even works or not because I don't have a mac or windows machine lying around. whoops! ... anyway, all of the changes divergent from Anisthesia are now licensed under BSD. it's possible that I could even rewrite most of the code to where I don't even have to keep the MIT license, but that's thinking too far into the future I've been slacking off on implementing the anime seasons page, mostly out of laziness. I think I'd have to create another db file specifically for the seasons anyway, this code is being pushed *primarily* because the hard drive it's on is failing! yay :)
author Paper <paper@paper.us.eu.org>
date Mon, 01 Apr 2024 02:43:44 -0400
parents 45a0967485f1
children 0362f3c4534c
comparison
equal deleted inserted replaced
257:699a20c57dc8 258:862d0d8619f6
1 #ifndef __gui__widgets__graph_h 1 #ifndef __gui__widgets__graph_h
2 #define __gui__widgets__graph_h 2 #define __gui__widgets__graph_h
3 3
4 /* This class is defined as a template, so that means everything gets defined here as well :) */ 4 /* This class is defined as a template, so that means everything gets defined here as well :) */
5 5
6 #include <QWidget>
7 #include <QDebug> 6 #include <QDebug>
8 #include <QSize>
9 #include <QPaintEvent> 7 #include <QPaintEvent>
10 #include <QSize>
11 #include <QRect>
12 #include <QPainter> 8 #include <QPainter>
13 #include <QPainterPath> 9 #include <QPainterPath>
14 #include <QPen> 10 #include <QPen>
11 #include <QRect>
12 #include <QSize>
13 #include <QWidget>
15 #include <algorithm> 14 #include <algorithm>
16 #include <unordered_map> 15 #include <unordered_map>
17 16
18 template<typename T> 17 template<typename T>
19 class Graph final : public QWidget { 18 class Graph final : public QWidget {
20 public: 19 public:
21 Graph(QWidget* parent = nullptr) : QWidget(parent) {}; 20 Graph(QWidget* parent = nullptr) : QWidget(parent){};
22 void AddItem(T key, unsigned long val) { map[key] = val; update(); updateGeometry(); }; 21 void AddItem(T key, unsigned long val) {
23 void Clear() { map.clear(); update(); updateGeometry(); }; 22 map[key] = val;
23 update();
24 updateGeometry();
25 };
26 void Clear() {
27 map.clear();
28 update();
29 updateGeometry();
30 };
24 31
25 protected: 32 protected:
26 std::unordered_map<T, unsigned long> map = {}; 33 std::unordered_map<T, unsigned long> map = {};
27 34
28 QSize minimumSizeHint() const override { 35 QSize minimumSizeHint() const override {
29 QFontMetrics metric(font()); 36 QFontMetrics metric(font());
30 /* wtf?... */ 37 /* wtf?... */
31 return QSize(100, metric.height() * map.size() + (2 * (map.size() - 2))); 38 return QSize(100, (metric.height() * map.size()) + (2 * map.size()));
39 }
40
41 /* helper functions */
42 inline unsigned long GetTotal() {
43 unsigned long count = 0;
44
45 for (const auto& item : map)
46 count += item.second;
47
48 return count;
49 }
50
51 inline unsigned long GetTextWidth() {
52 unsigned long ret = 0;
53 QFontMetrics metric(font());
54
55 for (const auto& item : map) {
56 unsigned long width = metric.horizontalAdvance(QString::number(item.first), -1);
57 if (width > ret)
58 ret = width;
32 } 59 }
33 60
34 /* helper functions */ 61 return ret;
35 inline unsigned long GetTotal() { 62 }
36 unsigned long count = 0;
37 63
38 for (const auto& item : map) 64 void paintEvent(QPaintEvent* event) override {
39 count += item.second; 65 static constexpr int HORIZ_SPACING = 5;
66 static constexpr int VERT_SPACING = 2;
40 67
41 return count; 68 /* these are retrieved from the QPaintEvent */
42 } 69 const QRect rect = event->rect();
70 const int width = event->rect().width();
71 const int x = rect.x();
72 int y = rect.y();
43 73
44 inline unsigned long GetTextWidth() { 74 /* these are calculated from font metrics and such */
45 unsigned long ret = 0; 75 const int total = GetTotal();
46 QFontMetrics metric(font()); 76 const int text_width = GetTextWidth();
77 const int each_height = QFontMetrics(font()).height();
47 78
48 for (const auto& item : map) { 79 /* now we do the actual painting */
49 unsigned long width = metric.horizontalAdvance(QString::number(item.first), -1); 80 QPainter painter(this);
50 if (width > ret) 81
51 ret = width; 82 for (const auto& [key, value] : map) {
83 painter.drawText(QRect(x, y, text_width, each_height), Qt::AlignVCenter | Qt::AlignRight,
84 QString::number(key));
85
86 /* only draw this if we actually have any data */
87 if (total) {
88 QPainterPath path;
89 path.addRect(x + text_width + HORIZ_SPACING, y,
90 (static_cast<double>(value) / total) * (width - text_width - HORIZ_SPACING), each_height);
91 painter.fillPath(path, Qt::darkBlue);
92 painter.drawPath(path);
52 } 93 }
53 94
54 return ret; 95 y += each_height + VERT_SPACING;
55 } 96 }
56 97 }
57 void paintEvent(QPaintEvent* event) override {
58 static constexpr int HORIZ_SPACING = 5;
59 static constexpr int VERT_SPACING = 2;
60
61 /* these are retrieved from the QPaintEvent */
62 const QRect rect = event->rect();
63 const int width = event->rect().width();
64 const int x = rect.x();
65 int y = rect.y();
66
67 /* these are calculated from font metrics and such */
68 const int total = GetTotal();
69 const int text_width = GetTextWidth() + 10;
70 const int each_height = QFontMetrics(font()).height();
71
72 /* now we do the actual painting */
73 QPainter painter(this);
74
75 for (const auto& [key, value] : map) {
76 painter.drawText(QRect(x, y, text_width, each_height), Qt::AlignVCenter, QString::number(key));
77
78 /* only draw this if we actually have any data */
79 if (total) {
80 QPainterPath path;
81 path.addRect(x + text_width + HORIZ_SPACING, y, (static_cast<double>(value)/total) * (width - text_width - HORIZ_SPACING), each_height);
82 painter.fillPath(path, Qt::darkBlue);
83 painter.drawPath(path);
84 }
85
86 y += each_height + VERT_SPACING;
87 }
88 }
89 }; 98 };
90 99
91 #endif // __gui__widgets__graph_h 100 #endif // __gui__widgets__graph_h