##// END OF EJS Templates
Added callout example (Drawing on top of chart)
Marek Rosa -
r2150:128c1c36c673
parent child
Show More
@@ -0,0 +1,102
1 #include "callout.h"
2 #include <QPainter>
3 #include <QFontMetrics>
4 #include <QGraphicsSceneMouseEvent>
5 #include <QCursor>
6
7 Callout::Callout(QGraphicsItem * parent):
8 QGraphicsItem(parent)
9 {
10 }
11
12 QRectF Callout::boundingRect() const
13 {
14 QPointF anchor = mapFromParent(m_anchor);
15 QRectF rect;
16 rect.setLeft(qMin(m_textRect.left(), anchor.x()));
17 rect.setRight(qMax(m_textRect.right(), anchor.x()));
18 rect.setTop(qMin(m_textRect.top(), anchor.y()));
19 rect.setBottom(qMax(m_textRect.bottom(), anchor.y()));
20 return rect;
21 }
22
23 void Callout::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
24 {
25 Q_UNUSED(option)
26 Q_UNUSED(widget)
27 QPainterPath path;
28 path.addRoundedRect(m_textRect, 5, 5);
29
30 QPointF anchor = mapFromParent(m_anchor);
31 if (!m_textRect.contains(anchor)) {
32 QPointF point1, point2;
33
34 // establish the position of the anchor point in relation to m_textRect
35 bool above = anchor.y() <= m_textRect.top();
36 bool aboveCenter = anchor.y() > m_textRect.top() && anchor.y() <= m_textRect.center().y();
37 bool belowCenter = anchor.y() > m_textRect.center().y() && anchor.y() <= m_textRect.bottom();
38 bool below = anchor.y() > m_textRect.bottom();
39
40 bool onLeft = anchor.x() <= m_textRect.left();
41 bool leftOfCenter = anchor.x() > m_textRect.left() && anchor.x() <= m_textRect.center().x();
42 bool rightOfCenter = anchor.x() > m_textRect.center().x() && anchor.x() <= m_textRect.right();
43 bool onRight = anchor.x() > m_textRect.right();
44
45 // get the nearest m_textRect corner.
46 qreal x = (onRight + rightOfCenter) * m_textRect.width();
47 qreal y = (below + belowCenter) * m_textRect.height();
48 bool cornerCase = (above && onLeft) || (above && onRight) || (below && onLeft) || (below && onRight);
49 bool vertical = qAbs(anchor.x() - x) > qAbs(anchor.y() - y);
50
51 qreal x1 = x + leftOfCenter * 10 - rightOfCenter * 20 + cornerCase * !vertical * (onLeft * 10 - onRight * 20);
52 qreal y1 = y + aboveCenter * 10 - belowCenter * 20 + cornerCase * vertical * (above * 10 - below * 20);;
53 point1.setX(x1);
54 point1.setY(y1);
55
56 qreal x2 = x + leftOfCenter * 20 - rightOfCenter * 10 + cornerCase * !vertical * (onLeft * 20 - onRight * 10);;
57 qreal y2 = y + aboveCenter * 20 - belowCenter * 10 + cornerCase * vertical * (above * 20 - below * 10);;
58 point2.setX(x2);
59 point2.setY(y2);
60
61 path.moveTo(point1);
62 path.lineTo(mapFromParent(m_anchor));
63 path.lineTo(point2);
64 path = path.simplified();
65 }
66 painter->setBrush(QColor(255, 255, 255));
67 painter->drawPath(path);
68 painter->drawText(m_textRect.adjusted(2, 2, 0, 0), m_text);
69 }
70
71 void Callout::mousePressEvent(QGraphicsSceneMouseEvent *event)
72 {
73 if (m_textRect.contains(event->pos())) {
74 m_clickOffset = event->pos();
75 event->setAccepted(true);
76 } else {
77 event->setAccepted(false);
78 }
79 }
80
81 void Callout::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
82 {
83 if (m_textRect.contains(event->pos())){
84 setPos(mapToParent(event->pos() - m_clickOffset));
85 event->setAccepted(true);
86 } else {
87 event->setAccepted(false);
88 }
89 }
90
91 void Callout::setText(const QString &text)
92 {
93 m_text = text;
94 QFontMetrics metrics(m_font);
95 prepareGeometryChange();
96 m_textRect = metrics.boundingRect(QRect(0, 0, 150, 150), Qt::AlignLeft, m_text).adjusted(0, 0, 4, 4);
97 }
98
99 void Callout::setAnchor(QPointF point)
100 {
101 m_anchor = point;
102 }
@@ -0,0 +1,32
1 #ifndef CALLOUT_H
2 #define CALLOUT_H
3
4 #include <QGraphicsItem>
5 #include <QFont>
6
7 class QGraphicsSceneMouseEvent;
8
9 class Callout : public QGraphicsItem
10 {
11 public:
12 Callout(QGraphicsItem * parent = 0);
13
14 void setText(const QString &text);
15 void setAnchor(QPointF point);
16
17 QRectF boundingRect() const;
18 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget);
19
20 protected:
21 void mousePressEvent(QGraphicsSceneMouseEvent *event);
22 void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
23
24 private:
25 QString m_text;
26 QRectF m_textRect;
27 QPointF m_anchor;
28 QFont m_font;
29 QPointF m_clickOffset;
30 };
31
32 #endif // CALLOUT_H
@@ -0,0 +1,13
1 !include( ../examples.pri ) {
2 error( "Couldn't find the examples.pri file!" )
3 }
4
5 TARGET = callout
6 TEMPLATE = app
7
8 SOURCES += main.cpp\
9 widget.cpp \
10 callout.cpp
11
12 HEADERS += widget.h \
13 callout.h
@@ -0,0 +1,11
1 #include <QApplication>
2 #include "widget.h"
3
4 int main(int argc, char *argv[])
5 {
6 QApplication a(argc, argv);
7 Widget w;
8 w.show();
9
10 return a.exec();
11 }
@@ -0,0 +1,56
1 #include "widget.h"
2 #include <QGraphicsScene>
3 #include <QGraphicsView>
4 #include <QVBoxLayout>
5 #include <QChart>
6 #include <QLineSeries>
7 #include <QGraphicsTextItem>
8 #include <QGraphicsLineItem>
9 #include "callout.h"
10
11 QTCOMMERCIALCHART_USE_NAMESPACE
12
13 Widget::Widget(QWidget *parent)
14 : QWidget(parent),
15 m_scene(0),
16 m_chart(0),
17 m_view(0)
18 {
19 // chart
20 m_chart = new QChart;
21 m_chart->setMinimumSize(640, 480);
22 QLineSeries *series = new QLineSeries;
23 series->setName("Click the line to create a movable callout");
24 series->append(1, 3);
25 series->append(4, 5);
26 series->append(5, 4.5);
27 series->append(7, 1);
28 series->append(11, 2);
29 m_chart->addSeries(series);
30 m_chart->createDefaultAxes();
31
32 m_scene = new QGraphicsScene;
33 m_view = new QGraphicsView(m_scene);
34 m_view->setRenderHint(QPainter::Antialiasing);
35 m_scene->addItem(m_chart);
36
37 QVBoxLayout *mainLayout = new QVBoxLayout;
38 mainLayout->addWidget(m_view);
39 setLayout(mainLayout);
40
41 connect(series, SIGNAL(clicked(QPointF)), this, SLOT(addCallout(QPointF)));
42 }
43
44 Widget::~Widget()
45 {
46
47 }
48
49 void Widget::addCallout(QPointF point)
50 {
51 Callout *label = new Callout(m_chart);
52 label->setText(QString("X: %1\nY: %2").arg(point.x()).arg(point.y()));
53 label->setAnchor(m_chart->mapFromParent(m_view->mapToScene(m_view->mapFromGlobal(QCursor::pos()))));
54 label->setPos(m_chart->mapFromParent(m_view->mapToScene(m_view->mapFromGlobal(QCursor::pos() + QPoint(10, -50)))));
55 label->setZValue(11);
56 }
@@ -0,0 +1,29
1 #ifndef WIDGET_H
2 #define WIDGET_H
3
4 #include <QWidget>
5 #include <QChart>
6
7 class QGraphicsScene;
8 class QGraphicsView;
9
10 QTCOMMERCIALCHART_USE_NAMESPACE
11
12 class Widget : public QWidget
13 {
14 Q_OBJECT
15
16 public:
17 Widget(QWidget *parent = 0);
18 ~Widget();
19
20 public slots:
21 void addCallout(QPointF point);
22
23 private:
24 QGraphicsScene *m_scene;
25 QChart *m_chart;
26 QGraphicsView *m_view;
27 };
28
29 #endif // WIDGET_H
@@ -31,7 +31,8 SUBDIRS += \
31 scrollchart \
31 scrollchart \
32 temperaturerecords \
32 temperaturerecords \
33 donutchart \
33 donutchart \
34 multiaxis
34 multiaxis \
35 callout
35
36
36 !linux-arm*: {
37 !linux-arm*: {
37 SUBDIRS += \
38 SUBDIRS += \
General Comments 0
You need to be logged in to leave comments. Login now