comparison include/gui/widgets/graph.h @ 202:71832ffe425a

animia: re-add kvm fd source this is all being merged from my wildly out-of-date laptop. SORRY! in other news, I edited the CI file to install the wayland client as well, so the linux CI build might finally get wayland stuff.
author Paper <paper@paper.us.eu.org>
date Tue, 02 Jan 2024 06:05:06 -0500
parents 45a0967485f1
children 862d0d8619f6
comparison
equal deleted inserted replaced
201:8f6f8dd2eb23 202:71832ffe425a
13 #include <QPainterPath> 13 #include <QPainterPath>
14 #include <QPen> 14 #include <QPen>
15 #include <algorithm> 15 #include <algorithm>
16 #include <unordered_map> 16 #include <unordered_map>
17 17
18 template <typename T> 18 template<typename T>
19 class Graph final : public QWidget { 19 class Graph final : public QWidget {
20 public: 20 public:
21 Graph(QWidget* parent = nullptr) : QWidget(parent) {}; 21 Graph(QWidget* parent = nullptr) : QWidget(parent) {};
22 void AddItem(T key, unsigned long val) { map[key] = val; update(); updateGeometry(); }; 22 void AddItem(T key, unsigned long val) { map[key] = val; update(); updateGeometry(); };
23 void Clear() { map.clear(); update(); updateGeometry(); }; 23 void Clear() { map.clear(); update(); updateGeometry(); };
24 24
25 protected: 25 protected:
26 static constexpr int SPACING = 5; 26 std::unordered_map<T, unsigned long> map = {};
27
28 QSize minimumSizeHint() const override {
29 QFontMetrics metric(font());
30 /* wtf?... */
31 return QSize(100, metric.height() * map.size() + (2 * (map.size() - 2)));
32 }
33
34 /* helper functions */
27 inline unsigned long GetTotal() { 35 inline unsigned long GetTotal() {
28 unsigned long count = 0; 36 unsigned long count = 0;
37
29 for (const auto& item : map) 38 for (const auto& item : map)
30 count += item.second; 39 count += item.second;
40
31 return count; 41 return count;
32 } 42 }
33 QSize minimumSizeHint() const override { 43
34 QFontMetrics metric(font());
35 return QSize(100, metric.height() * map.size() + 2 * (map.size() - 2));
36 };
37 inline unsigned long GetTextWidth() { 44 inline unsigned long GetTextWidth() {
38 unsigned long ret = 0; 45 unsigned long ret = 0;
39 QFontMetrics metric(font()); 46 QFontMetrics metric(font());
47
40 for (const auto& item : map) { 48 for (const auto& item : map) {
41 unsigned long width = metric.boundingRect(QString::number(item.first)).width(); 49 unsigned long width = metric.horizontalAdvance(QString::number(item.first), -1);
42 if (width > ret) 50 if (width > ret)
43 ret = width; 51 ret = width;
44 } 52 }
53
45 return ret; 54 return ret;
46 } 55 }
56
47 void paintEvent(QPaintEvent* event) override { 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 */
48 const QRect rect = event->rect(); 62 const QRect rect = event->rect();
49 const int height_of_each = QFontMetrics(font()).height(); 63 const int width = event->rect().width();
50 const int size = GetTotal(); 64 const int x = rect.x();
51 const int text_width = GetTextWidth(); 65 int y = rect.y();
52 int current_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();
53 71
54 /* now we do the actual painting */ 72 /* now we do the actual painting */
55 QPainter painter(this); 73 QPainter painter(this);
56 74
57 for (const auto& item : map) { 75 for (const auto& [key, value] : map) {
58 painter.drawText(QRect(rect.x(), current_y, text_width, height_of_each), Qt::AlignRight | Qt::AlignVCenter, QString::number(item.first)); 76 painter.drawText(QRect(x, y, text_width, each_height), Qt::AlignVCenter, QString::number(key));
59 77
60 if (size) { 78 /* only draw this if we actually have any data */
61 painter.save(); 79 if (total) {
62
63 QPen pen(Qt::transparent, 0);
64 painter.setPen(pen);
65
66 QPainterPath path; 80 QPainterPath path;
67 path.addRect(rect.x() + text_width + SPACING, current_y, (static_cast<double>(item.second)/size)*(rect.width() - text_width - SPACING), height_of_each); 81 path.addRect(x + text_width + HORIZ_SPACING, y, (static_cast<double>(value)/total) * (width - text_width - HORIZ_SPACING), each_height);
68 painter.fillPath(path, Qt::darkBlue); 82 painter.fillPath(path, Qt::darkBlue);
69 painter.drawPath(path); 83 painter.drawPath(path);
84 }
70 85
71 painter.restore(); 86 y += each_height + VERT_SPACING;
72 }
73 current_y += height_of_each + 2;
74 } 87 }
75 }; 88 }
76 std::unordered_map<T, unsigned long> map = {};
77 }; 89 };
78 90
79 #endif // __gui__widgets__graph_h 91 #endif // __gui__widgets__graph_h