1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
/*
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version
2 of the License, or (at your option) any later version.
*/
#include <QFontMetrics>
#include <QPainter>
#include "graphbarwidget.h"
GraphBarWidget::GraphBarWidget(const QList<QList<QVariant> > data, QWidget *parent) : QWidget(parent), mMargin(10), mData(data) {
mBarHeight = fontMetrics().height();
}
int GraphBarWidget::maxValue() const {
int retval = -1;
foreach(QList<QVariant> l, mData){
if(l.at(1).toInt() > retval){
retval = l.at(1).toInt();
}
}
return retval;
}
QSize GraphBarWidget::maxDescr() const {
QFont f = font();
f.setBold(true);
QFontMetrics fm(f);
QSize retval(0,0);
foreach(QList<QVariant> l, mData){
QString descr = l.at(0).toString();
QSize curSize = fm.size(Qt::TextSingleLine, descr);
if(curSize.width() > retval.width()){
retval = curSize;
}
}
return retval;
}
QSize GraphBarWidget::maxCount() const {
QFontMetrics fm = fontMetrics();
QSize retval(0,0);
foreach(QList<QVariant> l, mData){
QString curCount = QString("(%1)").arg(l.at(2).toString());
QSize curSize = fm.size(Qt::TextSingleLine, curCount);
if(curSize.width() > retval.width()){
retval = curSize;
}
}
return retval;
}
QSize GraphBarWidget::sizeHint() const {
int height = mData.count() * mBarHeight;
height += mData.count() * mMargin;
height += mBarHeight + mMargin;
return QSize(400, height);
}
void GraphBarWidget::paintEvent(QPaintEvent *){
QPainter p(this);
QHash<QString, qreal> length; //int
QList<QList<QVariant> >::const_iterator it;
//draw background
QPen pen(Qt::red, 2);
p.setPen(pen);
QLinearGradient bgGradient(QPointF(0.0, height() / 2), QPointF(width(), height() / 2));
bgGradient.setColorAt(0, QColor(221, 107, 80));
bgGradient.setColorAt(1, QColor(251, 179, 150));
QBrush brush(bgGradient);
p.setBrush(brush);
p.drawRect(contentsRect());
//draw caption
QFont f = font();
f.setUnderline(true);
f.setBold(true);
p.setFont(f);
QString cap(caption());
QFontMetrics fm(f);
int captionStartx = (width() - fm.width(cap)) / 2;
int captionStarty = fm.height();
p.drawText(captionStartx, captionStarty, cap);
//prepare drawing data
int barsStarty = fm.height() + 2 * mMargin + 10;
f.setUnderline(false);
f.setBold(true);
p.setFont(f);
int maxdescr = maxDescr().width();
int maxcount = maxCount().width();
int barsStartx = maxdescr + 2 * mMargin;
int marginRight = maxcount + 2 * mMargin;
int maxWidth = width() - barsStartx - marginRight;
p.setRenderHints(QPainter::Antialiasing);
p.setPen(QPen(Qt::red, 1));
//calculate real lengths based on widget width
for(it = mData.constBegin(); it != mData.constEnd(); ++it){
qreal value = it->at(1).toDouble();
value = value / maxValue() * maxWidth;
length[it->at(0).toString()] = value;
}
//draw the bars and numbers
int ctr(0);
for(QList<QList<QVariant> >::const_iterator itr = mData.constBegin(); itr != mData.constEnd() ; ++itr, ++ctr){
int starty = barsStarty + ctr * p.fontMetrics().height() + ctr * mMargin;
p.drawText(mMargin, starty, itr->at(0).toString());
QLinearGradient barGradient(QPointF(barsStartx, starty), QPointF(width(), starty));
barGradient.setColorAt(0, QColor(0, 128, 170));
barGradient.setColorAt(1, QColor(131, 205, 214));
QBrush b(barGradient);
p.setBrush(b);
qreal len = length.value(itr->at(0).toString());
QRect bar(barsStartx, starty - p.fontMetrics().height() + p.fontMetrics().descent(), len, p.fontMetrics().height());
p.drawRect(bar);
int nStartx = barsStartx + len + mMargin;
p.drawText(nStartx, starty, QString(tr("(%1)")).arg(itr->at(2).toString()));
}
}
|