comparison include/gui/widgets/graph.h @ 172:45a0967485f1

graph, statistics: make my code a little less messy
author Paper <mrpapersonic@gmail.com>
date Tue, 28 Nov 2023 13:22:35 -0500
parents 03b444cbe55f
children 862d0d8619f6
comparison
equal deleted inserted replaced
171:03b444cbe55f 172:45a0967485f1
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;
27
28 std::unordered_map<T, unsigned long> map = {}; 26 std::unordered_map<T, unsigned long> map = {};
29 27
30 QSize minimumSizeHint() const override { 28 QSize minimumSizeHint() const override {
31 QFontMetrics metric(font()); 29 QFontMetrics metric(font());
32 /* wtf?... */ 30 /* wtf?... */
46 inline unsigned long GetTextWidth() { 44 inline unsigned long GetTextWidth() {
47 unsigned long ret = 0; 45 unsigned long ret = 0;
48 QFontMetrics metric(font()); 46 QFontMetrics metric(font());
49 47
50 for (const auto& item : map) { 48 for (const auto& item : map) {
51 unsigned long width = metric.boundingRect(QString::number(item.first)).width(); 49 unsigned long width = metric.horizontalAdvance(QString::number(item.first), -1);
52 if (width > ret) 50 if (width > ret)
53 ret = width; 51 ret = width;
54 } 52 }
55 53
56 return ret; 54 return ret;
57 } 55 }
58 56
59 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 */
60 const QRect rect = event->rect(); 62 const QRect rect = event->rect();
61 const int height_of_each = QFontMetrics(font()).height(); 63 const int width = event->rect().width();
62 const int size = GetTotal();
63 const int text_width = GetTextWidth();
64 const int x = rect.x(); 64 const int x = rect.x();
65 int y = rect.y(); 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();
66 71
67 /* now we do the actual painting */ 72 /* now we do the actual painting */
68 QPainter painter(this); 73 QPainter painter(this);
69 74
70 for (const auto& item : map) { 75 for (const auto& [key, value] : map) {
71 painter.drawText(QRect(x + 2, y, text_width - 2, 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));
72 77
73 if (size) { 78 /* only draw this if we actually have any data */
74 painter.save(); 79 if (total) {
75
76 QPen pen(Qt::transparent, 0);
77 painter.setPen(pen);
78
79 QPainterPath path; 80 QPainterPath path;
80 path.addRect(x + text_width + 2 + SPACING, y, (static_cast<double>(item.second)/size) * (rect.width() - text_width + 2 - 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);
81 painter.fillPath(path, Qt::darkBlue); 82 painter.fillPath(path, Qt::darkBlue);
82 painter.drawPath(path); 83 painter.drawPath(path);
83
84 painter.restore();
85 } 84 }
86 85
87 y += height_of_each + 2; 86 y += each_height + VERT_SPACING;
88 } 87 }
89 } 88 }
90 }; 89 };
91 90
92 #endif // __gui__widgets__graph_h 91 #endif // __gui__widgets__graph_h