##// END OF EJS Templates
Fixes mouse handling in base class of chartseries
Michal Klocek -
r1747:19ac79b0cec7
parent child
Show More
@@ -1,150 +1,151
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "areachartitem_p.h"
21 #include "areachartitem_p.h"
22 #include "qareaseries.h"
22 #include "qareaseries.h"
23 #include "qareaseries_p.h"
23 #include "qareaseries_p.h"
24 #include "qlineseries.h"
24 #include "qlineseries.h"
25 #include "chartpresenter_p.h"
25 #include "chartpresenter_p.h"
26 #include "domain_p.h"
26 #include "domain_p.h"
27 #include <QPainter>
27 #include <QPainter>
28 #include <QGraphicsSceneMouseEvent>
28 #include <QGraphicsSceneMouseEvent>
29 #include <QDebug>
29 #include <QDebug>
30
30
31
31
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33
33
34 //TODO: optimize : remove points which are not visible
34 //TODO: optimize : remove points which are not visible
35
35
36 AreaChartItem::AreaChartItem(QAreaSeries *areaSeries, ChartPresenter *presenter)
36 AreaChartItem::AreaChartItem(QAreaSeries *areaSeries, ChartPresenter *presenter)
37 : ChartItem(presenter),
37 : ChartItem(presenter),
38 m_series(areaSeries),
38 m_series(areaSeries),
39 m_upper(0),
39 m_upper(0),
40 m_lower(0),
40 m_lower(0),
41 m_pointsVisible(false)
41 m_pointsVisible(false)
42 {
42 {
43 setZValue(ChartPresenter::LineChartZValue);
43 setZValue(ChartPresenter::LineChartZValue);
44 m_upper = new AreaBoundItem(this,m_series->upperSeries(),presenter);
44 m_upper = new AreaBoundItem(this,m_series->upperSeries(),presenter);
45 if (m_series->lowerSeries()){
45 if (m_series->lowerSeries()){
46 m_lower = new AreaBoundItem(this,m_series->lowerSeries(),presenter);
46 m_lower = new AreaBoundItem(this,m_series->lowerSeries(),presenter);
47 }
47 }
48
48
49 QObject::connect(m_series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
49 QObject::connect(m_series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
50 QObject::connect(m_series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
50 QObject::connect(m_series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
51 QObject::connect(this,SIGNAL(clicked(QPointF)),areaSeries,SIGNAL(clicked(QPointF)));
51 QObject::connect(this,SIGNAL(clicked(QPointF)),areaSeries,SIGNAL(clicked(QPointF)));
52
52
53 handleUpdated();
53 handleUpdated();
54 }
54 }
55
55
56 AreaChartItem::~AreaChartItem()
56 AreaChartItem::~AreaChartItem()
57 {
57 {
58 delete m_upper;
58 delete m_upper;
59 delete m_lower;
59 delete m_lower;
60 }
60 }
61
61
62 QRectF AreaChartItem::boundingRect() const
62 QRectF AreaChartItem::boundingRect() const
63 {
63 {
64 return m_rect;
64 return m_rect;
65 }
65 }
66
66
67 QPainterPath AreaChartItem::shape() const
67 QPainterPath AreaChartItem::shape() const
68 {
68 {
69 return m_path;
69 return m_path;
70 }
70 }
71
71
72 void AreaChartItem::updatePath()
72 void AreaChartItem::updatePath()
73 {
73 {
74 QPainterPath path;
74 QPainterPath path;
75
75
76 path = m_upper->shape();
76 path = m_upper->shape();
77
77
78 if (m_lower) {
78 if (m_lower) {
79 path.connectPath(m_lower->shape().toReversed());
79 path.connectPath(m_lower->shape().toReversed());
80 } else {
80 } else {
81 QPointF first = path.pointAtPercent(0);
81 QPointF first = path.pointAtPercent(0);
82 QPointF last = path.pointAtPercent(1);
82 QPointF last = path.pointAtPercent(1);
83 path.lineTo(last.x(),m_clipRect.bottom());
83 path.lineTo(last.x(),m_clipRect.bottom());
84 path.lineTo(first.x(),m_clipRect.bottom());
84 path.lineTo(first.x(),m_clipRect.bottom());
85 }
85 }
86 path.closeSubpath();
86 path.closeSubpath();
87 prepareGeometryChange();
87 prepareGeometryChange();
88 m_path = path;
88 m_path = path;
89 m_rect = path.boundingRect();
89 m_rect = path.boundingRect();
90 update();
90 update();
91 }
91 }
92
92
93 void AreaChartItem::handleUpdated()
93 void AreaChartItem::handleUpdated()
94 {
94 {
95 setVisible(m_series->isVisible());
95 setVisible(m_series->isVisible());
96 m_pointsVisible = m_series->pointsVisible();
96 m_pointsVisible = m_series->pointsVisible();
97 m_linePen = m_series->pen();
97 m_linePen = m_series->pen();
98 m_brush = m_series->brush();
98 m_brush = m_series->brush();
99 m_pointPen = m_series->pen();
99 m_pointPen = m_series->pen();
100 m_pointPen.setWidthF(2 * m_pointPen.width());
100 m_pointPen.setWidthF(2 * m_pointPen.width());
101
101
102 update();
102 update();
103 }
103 }
104
104
105 void AreaChartItem::handleDomainUpdated()
105 void AreaChartItem::handleDomainUpdated()
106 {
106 {
107 m_upper->setDomain(domain());
107 m_upper->setDomain(domain());
108 m_upper->handleDomainUpdated();
108 m_upper->handleDomainUpdated();
109 if (m_lower){
109 if (m_lower){
110 m_lower->setDomain(domain());
110 m_lower->setDomain(domain());
111 m_lower->handleDomainUpdated();
111 m_lower->handleDomainUpdated();
112 }
112 }
113 }
113 }
114
114
115 void AreaChartItem::handleGeometryChanged(const QRectF &rect)
115 void AreaChartItem::handleGeometryChanged(const QRectF &rect)
116 {
116 {
117 m_clipRect=rect.translated(-rect.topLeft());
117 m_clipRect=rect.translated(-rect.topLeft());
118 setPos(rect.topLeft());
118 setPos(rect.topLeft());
119 m_upper->handleGeometryChanged(rect);
119 m_upper->handleGeometryChanged(rect);
120 if (m_lower)
120 if (m_lower)
121 m_lower->handleGeometryChanged(rect);
121 m_lower->handleGeometryChanged(rect);
122 }
122 }
123
123
124 void AreaChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
124 void AreaChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
125 {
125 {
126 Q_UNUSED(widget)
126 Q_UNUSED(widget)
127 Q_UNUSED(option)
127 Q_UNUSED(option)
128
128
129 painter->save();
129 painter->save();
130 painter->setPen(m_linePen);
130 painter->setPen(m_linePen);
131 painter->setBrush(m_brush);
131 painter->setBrush(m_brush);
132 painter->setClipRect(m_clipRect);
132 painter->setClipRect(m_clipRect);
133 painter->drawPath(m_path);
133 painter->drawPath(m_path);
134 if (m_pointsVisible) {
134 if (m_pointsVisible) {
135 painter->setPen(m_pointPen);
135 painter->setPen(m_pointPen);
136 painter->drawPoints(m_upper->geometryPoints());
136 painter->drawPoints(m_upper->geometryPoints());
137 if (m_lower)
137 if (m_lower)
138 painter->drawPoints(m_lower->geometryPoints());
138 painter->drawPoints(m_lower->geometryPoints());
139 }
139 }
140 painter->restore();
140 painter->restore();
141 }
141 }
142
142
143 void AreaChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
143 void AreaChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
144 {
144 {
145 emit clicked(m_upper->calculateDomainPoint(event->pos()));
145 emit clicked(m_upper->calculateDomainPoint(event->pos()));
146 ChartItem::mousePressEvent(event);
146 }
147 }
147
148
148 #include "moc_areachartitem_p.cpp"
149 #include "moc_areachartitem_p.cpp"
149
150
150 QTCOMMERCIALCHART_END_NAMESPACE
151 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,66 +1,68
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "bar_p.h"
21 #include "bar_p.h"
22 #include <QPainter>
22 #include <QPainter>
23 #include <QGraphicsSceneEvent>
23 #include <QGraphicsSceneEvent>
24
24
25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26
26
27 Bar::Bar(QBarSet *barset, int index, QGraphicsItem *parent) : QGraphicsRectItem(parent),
27 Bar::Bar(QBarSet *barset, int index, QGraphicsItem *parent) : QGraphicsRectItem(parent),
28 m_index(index),
28 m_index(index),
29 m_barset(barset),
29 m_barset(barset),
30 m_hovering(false)
30 m_hovering(false)
31 {
31 {
32 setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton);
32 setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton);
33 setAcceptHoverEvents(true);
33 setAcceptHoverEvents(true);
34 }
34 }
35
35
36 Bar::~Bar()
36 Bar::~Bar()
37 {
37 {
38 // End hover event, if bar is deleted during it
38 // End hover event, if bar is deleted during it
39 if (m_hovering) {
39 if (m_hovering) {
40 emit hovered(false, m_barset);
40 emit hovered(false, m_barset);
41 }
41 }
42 }
42 }
43
43
44 void Bar::mousePressEvent(QGraphicsSceneMouseEvent *event)
44 void Bar::mousePressEvent(QGraphicsSceneMouseEvent *event)
45 {
45 {
46 Q_UNUSED(event)
46 Q_UNUSED(event)
47 emit clicked(m_index, m_barset);
47 emit clicked(m_index, m_barset);
48 QGraphicsItem::mousePressEvent(event);
48 }
49 }
49
50
50 void Bar::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
51 void Bar::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
51 {
52 {
52 Q_UNUSED(event)
53 Q_UNUSED(event)
53 m_hovering = true;
54 m_hovering = true;
54 emit hovered(true, m_barset);
55 emit hovered(true, m_barset);
56
55 }
57 }
56
58
57 void Bar::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
59 void Bar::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
58 {
60 {
59 Q_UNUSED(event)
61 Q_UNUSED(event)
60 m_hovering = false;
62 m_hovering = false;
61 emit hovered(false, m_barset);
63 emit hovered(false, m_barset);
62 }
64 }
63
65
64 #include "moc_bar_p.cpp"
66 #include "moc_bar_p.cpp"
65
67
66 QTCOMMERCIALCHART_END_NAMESPACE
68 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,174 +1,176
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef CHARTPRESENTER_H
30 #ifndef CHARTPRESENTER_H
31 #define CHARTPRESENTER_H
31 #define CHARTPRESENTER_H
32
32
33 #include "qchartglobal.h"
33 #include "qchartglobal.h"
34 #include "qchart.h" //becouse of QChart::ChartThemeId //TODO
34 #include "qchart.h" //becouse of QChart::ChartThemeId //TODO
35 #include <QRectF>
35 #include <QRectF>
36
36
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38
38
39 class ChartElement;
39 class ChartElement;
40 class QAbstractSeries;
40 class QAbstractSeries;
41 class ChartDataSet;
41 class ChartDataSet;
42 class Domain;
42 class Domain;
43 class ChartAxis;
43 class ChartAxis;
44 class ChartTheme;
44 class ChartTheme;
45 class ChartAnimator;
45 class ChartAnimator;
46 class ChartBackground;
46 class ChartBackground;
47 class ChartAnimation;
47 class ChartAnimation;
48 class ChartLayout;
48 class ChartLayout;
49
49
50 class ChartPresenter: public QObject
50 class ChartPresenter: public QObject
51 {
51 {
52 Q_OBJECT
52 Q_OBJECT
53 public:
53 public:
54 enum ZValues {
54 enum ZValues {
55 BackgroundZValue = -1,
55 BackgroundZValue = -1,
56 ShadesZValue,
56 ShadesZValue ,
57 GridZValue,
57 GridZValue,
58 SeriesZValue,
58 SeriesZValue,
59 LineChartZValue = SeriesZValue,
59 LineChartZValue = SeriesZValue,
60 SplineChartZValue = SeriesZValue,
60 BarSeriesZValue = SeriesZValue,
61 BarSeriesZValue = SeriesZValue,
61 ScatterSeriesZValue = SeriesZValue,
62 ScatterSeriesZValue = SeriesZValue,
62 PieSeriesZValue = SeriesZValue,
63 PieSeriesZValue = SeriesZValue,
63 AxisZValue,
64 AxisZValue,
64 LegendZValue
65 LegendZValue,
66 TopMostZValue
65 };
67 };
66
68
67 enum State {
69 enum State {
68 ShowState,
70 ShowState,
69 ScrollUpState,
71 ScrollUpState,
70 ScrollDownState,
72 ScrollDownState,
71 ScrollLeftState,
73 ScrollLeftState,
72 ScrollRightState,
74 ScrollRightState,
73 ZoomInState,
75 ZoomInState,
74 ZoomOutState
76 ZoomOutState
75 };
77 };
76
78
77 ChartPresenter(QChart* chart,ChartDataSet *dataset);
79 ChartPresenter(QChart* chart,ChartDataSet *dataset);
78 virtual ~ChartPresenter();
80 virtual ~ChartPresenter();
79
81
80 ChartTheme *chartTheme() const { return m_chartTheme; }
82 ChartTheme *chartTheme() const { return m_chartTheme; }
81 ChartDataSet *dataSet() const { return m_dataset; }
83 ChartDataSet *dataSet() const { return m_dataset; }
82 QGraphicsItem* rootItem() const { return m_chart; }
84 QGraphicsItem* rootItem() const { return m_chart; }
83 QGraphicsRectItem* backgroundItem();
85 QGraphicsRectItem* backgroundItem();
84 QGraphicsItem* titleItem();
86 QGraphicsItem* titleItem();
85 QList<ChartAxis*> axisItems() const;
87 QList<ChartAxis*> axisItems() const;
86
88
87 QLegend* legend();
89 QLegend* legend();
88
90
89 void setBackgroundBrush(const QBrush& brush);
91 void setBackgroundBrush(const QBrush& brush);
90 QBrush backgroundBrush() const;
92 QBrush backgroundBrush() const;
91
93
92 void setBackgroundPen(const QPen& pen);
94 void setBackgroundPen(const QPen& pen);
93 QPen backgroundPen() const;
95 QPen backgroundPen() const;
94
96
95 void setTitle(const QString& title);
97 void setTitle(const QString& title);
96 QString title() const;
98 QString title() const;
97
99
98 void setTitleFont(const QFont& font);
100 void setTitleFont(const QFont& font);
99 QFont titleFont() const;
101 QFont titleFont() const;
100
102
101 void setTitleBrush(const QBrush &brush);
103 void setTitleBrush(const QBrush &brush);
102 QBrush titleBrush() const;
104 QBrush titleBrush() const;
103
105
104 void setBackgroundVisible(bool visible);
106 void setBackgroundVisible(bool visible);
105 bool isBackgroundVisible() const;
107 bool isBackgroundVisible() const;
106
108
107 void setBackgroundDropShadowEnabled(bool enabled);
109 void setBackgroundDropShadowEnabled(bool enabled);
108 bool isBackgroundDropShadowEnabled() const;
110 bool isBackgroundDropShadowEnabled() const;
109
111
110 void setVisible(bool visible);
112 void setVisible(bool visible);
111
113
112 void setTheme(QChart::ChartTheme theme,bool force = true);
114 void setTheme(QChart::ChartTheme theme,bool force = true);
113 QChart::ChartTheme theme();
115 QChart::ChartTheme theme();
114
116
115 void setAnimationOptions(QChart::AnimationOptions options);
117 void setAnimationOptions(QChart::AnimationOptions options);
116 QChart::AnimationOptions animationOptions() const;
118 QChart::AnimationOptions animationOptions() const;
117
119
118 void zoomIn(qreal factor);
120 void zoomIn(qreal factor);
119 void zoomIn(const QRectF& rect);
121 void zoomIn(const QRectF& rect);
120 void zoomOut(qreal factor);
122 void zoomOut(qreal factor);
121 void scroll(qreal dx,qreal dy);
123 void scroll(qreal dx,qreal dy);
122
124
123 void setGeometry(const QRectF& rect);
125 void setGeometry(const QRectF& rect);
124 QRectF geometry() { return m_rect; }
126 QRectF geometry() { return m_rect; }
125
127
126 void startAnimation(ChartAnimation* animation);
128 void startAnimation(ChartAnimation* animation);
127 State state() const { return m_state; }
129 State state() const { return m_state; }
128 QPointF statePoint() const { return m_statePoint; }
130 QPointF statePoint() const { return m_statePoint; }
129
131
130 void resetAllElements();
132 void resetAllElements();
131
133
132 void setMarginsMinimum(const QRectF& margins);
134 void setMarginsMinimum(const QRectF& margins);
133 QRectF margins() const;
135 QRectF margins() const;
134 QGraphicsLayout* layout();
136 QGraphicsLayout* layout();
135
137
136 private:
138 private:
137 void createBackgroundItem();
139 void createBackgroundItem();
138 void createTitleItem();
140 void createTitleItem();
139 void selectVisibleAxis();
141 void selectVisibleAxis();
140
142
141 public Q_SLOTS:
143 public Q_SLOTS:
142 void handleSeriesAdded(QAbstractSeries* series,Domain* domain);
144 void handleSeriesAdded(QAbstractSeries* series,Domain* domain);
143 void handleSeriesRemoved(QAbstractSeries* series);
145 void handleSeriesRemoved(QAbstractSeries* series);
144 void handleAxisAdded(QAbstractAxis* axis,Domain* domain);
146 void handleAxisAdded(QAbstractAxis* axis,Domain* domain);
145 void handleAxisRemoved(QAbstractAxis* axis);
147 void handleAxisRemoved(QAbstractAxis* axis);
146 void handleAxisVisibleChanged(bool visible);
148 void handleAxisVisibleChanged(bool visible);
147
149
148 private Q_SLOTS:
150 private Q_SLOTS:
149 void handleAnimationFinished();
151 void handleAnimationFinished();
150
152
151 Q_SIGNALS:
153 Q_SIGNALS:
152 void geometryChanged(const QRectF& rect);
154 void geometryChanged(const QRectF& rect);
153 void animationsFinished();
155 void animationsFinished();
154 void marginsChanged(QRectF margins);
156 void marginsChanged(QRectF margins);
155
157
156 private:
158 private:
157 QChart* m_chart;
159 QChart* m_chart;
158 ChartDataSet* m_dataset;
160 ChartDataSet* m_dataset;
159 ChartTheme *m_chartTheme;
161 ChartTheme *m_chartTheme;
160 QMap<QAbstractSeries*, ChartElement*> m_chartItems;
162 QMap<QAbstractSeries*, ChartElement*> m_chartItems;
161 QMap<QAbstractAxis*, ChartAxis*> m_axisItems;
163 QMap<QAbstractAxis*, ChartAxis*> m_axisItems;
162 QRectF m_rect;
164 QRectF m_rect;
163 QChart::AnimationOptions m_options;
165 QChart::AnimationOptions m_options;
164 State m_state;
166 State m_state;
165 QPointF m_statePoint;
167 QPointF m_statePoint;
166 QList<ChartAnimation*> m_animations;
168 QList<ChartAnimation*> m_animations;
167 ChartLayout* m_layout;
169 ChartLayout* m_layout;
168 ChartBackground* m_backgroundItem;
170 ChartBackground* m_backgroundItem;
169 QGraphicsSimpleTextItem* m_titleItem;
171 QGraphicsSimpleTextItem* m_titleItem;
170 };
172 };
171
173
172 QTCOMMERCIALCHART_END_NAMESPACE
174 QTCOMMERCIALCHART_END_NAMESPACE
173
175
174 #endif /* CHARTPRESENTER_H_ */
176 #endif /* CHARTPRESENTER_H_ */
@@ -1,114 +1,115
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "linechartitem_p.h"
21 #include "linechartitem_p.h"
22 #include "qlineseries.h"
22 #include "qlineseries.h"
23 #include "qlineseries_p.h"
23 #include "qlineseries_p.h"
24 #include "chartpresenter_p.h"
24 #include "chartpresenter_p.h"
25 #include <QPainter>
25 #include <QPainter>
26 #include <QGraphicsSceneMouseEvent>
26 #include <QGraphicsSceneMouseEvent>
27
27
28
28
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30
30
31 //TODO: optimize : remove points which are not visible
31 //TODO: optimize : remove points which are not visible
32
32
33 LineChartItem::LineChartItem(QLineSeries* series,ChartPresenter *presenter):
33 LineChartItem::LineChartItem(QLineSeries* series,ChartPresenter *presenter):
34 XYChart(series, presenter),
34 XYChart(series, presenter),
35 QGraphicsItem(presenter ? presenter->rootItem() : 0),
35 QGraphicsItem(presenter ? presenter->rootItem() : 0),
36 m_series(series),
36 m_series(series),
37 m_pointsVisible(false)
37 m_pointsVisible(false)
38 {
38 {
39 setZValue(ChartPresenter::LineChartZValue);
39 setZValue(ChartPresenter::LineChartZValue);
40 QObject::connect(series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
40 QObject::connect(series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
41 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
41 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
42 handleUpdated();
42 handleUpdated();
43 }
43 }
44
44
45 QRectF LineChartItem::boundingRect() const
45 QRectF LineChartItem::boundingRect() const
46 {
46 {
47 return m_rect;
47 return m_rect;
48 }
48 }
49
49
50 QPainterPath LineChartItem::shape() const
50 QPainterPath LineChartItem::shape() const
51 {
51 {
52 return m_path;
52 return m_path;
53 }
53 }
54
54
55 void LineChartItem::updateGeometry()
55 void LineChartItem::updateGeometry()
56 {
56 {
57 const QVector<QPointF>& points = geometryPoints();
57 const QVector<QPointF>& points = geometryPoints();
58
58
59 if(points.size()==0)
59 if(points.size()==0)
60 {
60 {
61 prepareGeometryChange();
61 prepareGeometryChange();
62 m_path = QPainterPath();
62 m_path = QPainterPath();
63 m_rect = QRect();
63 m_rect = QRect();
64 return;
64 return;
65 }
65 }
66
66
67 QPainterPath linePath(points.at(0));
67 QPainterPath linePath(points.at(0));
68
68
69 for(int i=1; i< points.size();i++) {
69 for(int i=1; i< points.size();i++) {
70 linePath.lineTo(points.at(i));
70 linePath.lineTo(points.at(i));
71 }
71 }
72
72
73 prepareGeometryChange();
73 prepareGeometryChange();
74 m_path = linePath;
74 m_path = linePath;
75 m_rect = linePath.boundingRect();
75 m_rect = linePath.boundingRect();
76 setPos(origin());
76 setPos(origin());
77 }
77 }
78
78
79 void LineChartItem::handleUpdated()
79 void LineChartItem::handleUpdated()
80 {
80 {
81 setVisible(m_series->isVisible());
81 setVisible(m_series->isVisible());
82 m_pointsVisible = m_series->pointsVisible();
82 m_pointsVisible = m_series->pointsVisible();
83 m_linePen = m_series->pen();
83 m_linePen = m_series->pen();
84 m_pointPen = m_series->pen();
84 m_pointPen = m_series->pen();
85 m_pointPen.setWidthF(2*m_pointPen.width());
85 m_pointPen.setWidthF(2*m_pointPen.width());
86 update();
86 update();
87 }
87 }
88
88
89 //painter
89 //painter
90
90
91 void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
91 void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
92 {
92 {
93 Q_UNUSED(widget)
93 Q_UNUSED(widget)
94 Q_UNUSED(option)
94 Q_UNUSED(option)
95
95
96 painter->save();
96 painter->save();
97 painter->setPen(m_linePen);
97 painter->setPen(m_linePen);
98 painter->setClipRect(clipRect());
98 painter->setClipRect(clipRect());
99 painter->drawPath(m_path);
99 painter->drawPath(m_path);
100 if (m_pointsVisible){
100 if (m_pointsVisible){
101 painter->setPen(m_pointPen);
101 painter->setPen(m_pointPen);
102 painter->drawPoints(geometryPoints());
102 painter->drawPoints(geometryPoints());
103 }
103 }
104 painter->restore();
104 painter->restore();
105 }
105 }
106
106
107 void LineChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
107 void LineChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
108 {
108 {
109 emit XYChart::clicked(calculateDomainPoint(event->pos()));
109 emit XYChart::clicked(calculateDomainPoint(event->pos()));
110 QGraphicsItem::mousePressEvent(event);
110 }
111 }
111
112
112 #include "moc_linechartitem_p.cpp"
113 #include "moc_linechartitem_p.cpp"
113
114
114 QTCOMMERCIALCHART_END_NAMESPACE
115 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,274 +1,275
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "piesliceitem_p.h"
21 #include "piesliceitem_p.h"
22 #include "piechartitem_p.h"
22 #include "piechartitem_p.h"
23 #include "qpieseries.h"
23 #include "qpieseries.h"
24 #include "qpieslice.h"
24 #include "qpieslice.h"
25 #include "chartpresenter_p.h"
25 #include "chartpresenter_p.h"
26 #include <QPainter>
26 #include <QPainter>
27 #include <qmath.h>
27 #include <qmath.h>
28 #include <QGraphicsSceneEvent>
28 #include <QGraphicsSceneEvent>
29 #include <QTime>
29 #include <QTime>
30 #include <QDebug>
30 #include <QDebug>
31
31
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33
33
34 QPointF offset(qreal angle, qreal length)
34 QPointF offset(qreal angle, qreal length)
35 {
35 {
36 qreal dx = qSin(angle*(M_PI/180)) * length;
36 qreal dx = qSin(angle*(M_PI/180)) * length;
37 qreal dy = qCos(angle*(M_PI/180)) * length;
37 qreal dy = qCos(angle*(M_PI/180)) * length;
38 return QPointF(dx, -dy);
38 return QPointF(dx, -dy);
39 }
39 }
40
40
41 PieSliceItem::PieSliceItem(QGraphicsItem* parent)
41 PieSliceItem::PieSliceItem(QGraphicsItem* parent)
42 :QGraphicsObject(parent),
42 :QGraphicsObject(parent),
43 m_hovered(false)
43 m_hovered(false)
44 {
44 {
45 setAcceptHoverEvents(true);
45 setAcceptHoverEvents(true);
46 setAcceptedMouseButtons(Qt::MouseButtonMask);
46 setAcceptedMouseButtons(Qt::MouseButtonMask);
47 setZValue(ChartPresenter::PieSeriesZValue);
47 setZValue(ChartPresenter::PieSeriesZValue);
48 }
48 }
49
49
50 PieSliceItem::~PieSliceItem()
50 PieSliceItem::~PieSliceItem()
51 {
51 {
52 // If user is hovering over the slice and it gets destroyed we do
52 // If user is hovering over the slice and it gets destroyed we do
53 // not get a hover leave event. So we must emit the signal here.
53 // not get a hover leave event. So we must emit the signal here.
54 if (m_hovered)
54 if (m_hovered)
55 emit hovered(false);
55 emit hovered(false);
56 }
56 }
57
57
58 QRectF PieSliceItem::boundingRect() const
58 QRectF PieSliceItem::boundingRect() const
59 {
59 {
60 return m_boundingRect;
60 return m_boundingRect;
61 }
61 }
62
62
63 QPainterPath PieSliceItem::shape() const
63 QPainterPath PieSliceItem::shape() const
64 {
64 {
65 // Don't include the label and label arm.
65 // Don't include the label and label arm.
66 // This is used to detect a mouse clicks. We do not want clicks from label.
66 // This is used to detect a mouse clicks. We do not want clicks from label.
67 return m_slicePath;
67 return m_slicePath;
68 }
68 }
69
69
70 void PieSliceItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
70 void PieSliceItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
71 {
71 {
72 painter->save();
72 painter->save();
73 painter->setClipRect(parentItem()->boundingRect());
73 painter->setClipRect(parentItem()->boundingRect());
74 painter->setPen(m_data.m_slicePen);
74 painter->setPen(m_data.m_slicePen);
75 painter->setBrush(m_data.m_sliceBrush);
75 painter->setBrush(m_data.m_sliceBrush);
76 painter->drawPath(m_slicePath);
76 painter->drawPath(m_slicePath);
77 painter->restore();
77 painter->restore();
78
78
79 if (m_data.m_isLabelVisible) {
79 if (m_data.m_isLabelVisible) {
80 painter->save();
80 painter->save();
81
81
82 // Pen for label arm not defined in the QPieSeries api, let's use brush's color instead
82 // Pen for label arm not defined in the QPieSeries api, let's use brush's color instead
83 // Also, the drawText actually uses the pen color for the text color (unlike QGraphicsSimpleTextItem)
83 // Also, the drawText actually uses the pen color for the text color (unlike QGraphicsSimpleTextItem)
84 painter->setPen(m_data.m_labelBrush.color());
84 painter->setPen(m_data.m_labelBrush.color());
85 painter->setBrush(m_data.m_labelBrush);
85 painter->setBrush(m_data.m_labelBrush);
86 painter->setFont(m_data.m_labelFont);
86 painter->setFont(m_data.m_labelFont);
87
87
88 switch (m_data.m_labelPosition)
88 switch (m_data.m_labelPosition)
89 {
89 {
90 case QPieSlice::LabelOutside:
90 case QPieSlice::LabelOutside:
91 painter->setClipRect(parentItem()->boundingRect());
91 painter->setClipRect(parentItem()->boundingRect());
92 painter->strokePath(m_labelArmPath, m_data.m_labelBrush.color());
92 painter->strokePath(m_labelArmPath, m_data.m_labelBrush.color());
93 painter->drawText(m_labelTextRect, Qt::AlignCenter, m_data.m_labelText);
93 painter->drawText(m_labelTextRect, Qt::AlignCenter, m_data.m_labelText);
94 break;
94 break;
95 case QPieSlice::LabelInside:
95 case QPieSlice::LabelInside:
96 painter->setClipPath(m_slicePath);
96 painter->setClipPath(m_slicePath);
97 painter->drawText(m_labelTextRect, Qt::AlignCenter, m_data.m_labelText);
97 painter->drawText(m_labelTextRect, Qt::AlignCenter, m_data.m_labelText);
98 break;
98 break;
99 case QPieSlice::LabelInsideTangential:
99 case QPieSlice::LabelInsideTangential:
100 painter->setClipPath(m_slicePath);
100 painter->setClipPath(m_slicePath);
101 painter->translate(m_labelTextRect.center());
101 painter->translate(m_labelTextRect.center());
102 painter->rotate(m_data.m_startAngle + m_data.m_angleSpan / 2);
102 painter->rotate(m_data.m_startAngle + m_data.m_angleSpan / 2);
103 painter->drawText(-m_labelTextRect.width() / 2, -m_labelTextRect.height() / 2, m_labelTextRect.width(), m_labelTextRect.height(), Qt::AlignCenter, m_data.m_labelText);
103 painter->drawText(-m_labelTextRect.width() / 2, -m_labelTextRect.height() / 2, m_labelTextRect.width(), m_labelTextRect.height(), Qt::AlignCenter, m_data.m_labelText);
104 break;
104 break;
105 case QPieSlice::LabelInsideNormal:
105 case QPieSlice::LabelInsideNormal:
106 painter->setClipPath(m_slicePath);
106 painter->setClipPath(m_slicePath);
107 painter->translate(m_labelTextRect.center());
107 painter->translate(m_labelTextRect.center());
108 if (m_data.m_startAngle + m_data.m_angleSpan / 2 < 180)
108 if (m_data.m_startAngle + m_data.m_angleSpan / 2 < 180)
109 painter->rotate(m_data.m_startAngle + m_data.m_angleSpan / 2 - 90);
109 painter->rotate(m_data.m_startAngle + m_data.m_angleSpan / 2 - 90);
110 else
110 else
111 painter->rotate(m_data.m_startAngle + m_data.m_angleSpan / 2 + 90);
111 painter->rotate(m_data.m_startAngle + m_data.m_angleSpan / 2 + 90);
112 painter->drawText(-m_labelTextRect.width() / 2, -m_labelTextRect.height() / 2, m_labelTextRect.width(), m_labelTextRect.height(), Qt::AlignCenter, m_data.m_labelText);
112 painter->drawText(-m_labelTextRect.width() / 2, -m_labelTextRect.height() / 2, m_labelTextRect.width(), m_labelTextRect.height(), Qt::AlignCenter, m_data.m_labelText);
113 break;
113 break;
114 }
114 }
115
115
116 painter->restore();
116 painter->restore();
117 }
117 }
118 }
118 }
119
119
120 void PieSliceItem::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
120 void PieSliceItem::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
121 {
121 {
122 m_hovered = true;
122 m_hovered = true;
123 emit hovered(true);
123 emit hovered(true);
124 }
124 }
125
125
126 void PieSliceItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
126 void PieSliceItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
127 {
127 {
128 m_hovered = false;
128 m_hovered = false;
129 emit hovered(false);
129 emit hovered(false);
130 }
130 }
131
131
132 void PieSliceItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
132 void PieSliceItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
133 {
133 {
134 emit clicked(event->buttons());
134 emit clicked(event->buttons());
135 QGraphicsItem::mousePressEvent(event);
135 }
136 }
136
137
137 void PieSliceItem::setLayout(const PieSliceData &sliceData)
138 void PieSliceItem::setLayout(const PieSliceData &sliceData)
138 {
139 {
139 m_data = sliceData;
140 m_data = sliceData;
140 updateGeometry();
141 updateGeometry();
141 update();
142 update();
142 }
143 }
143
144
144 void PieSliceItem::updateGeometry()
145 void PieSliceItem::updateGeometry()
145 {
146 {
146 if (m_data.m_radius <= 0)
147 if (m_data.m_radius <= 0)
147 return;
148 return;
148
149
149 prepareGeometryChange();
150 prepareGeometryChange();
150
151
151 // slice path
152 // slice path
152 qreal centerAngle;
153 qreal centerAngle;
153 QPointF armStart;
154 QPointF armStart;
154 m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, &centerAngle, &armStart);
155 m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, &centerAngle, &armStart);
155
156
156 // text rect
157 // text rect
157 QFontMetricsF fm(m_data.m_labelFont);
158 QFontMetricsF fm(m_data.m_labelFont);
158 m_labelTextRect = QRectF(0, 0, fm.width(m_data.m_labelText), fm.height());
159 m_labelTextRect = QRectF(0, 0, fm.width(m_data.m_labelText), fm.height());
159
160
160 // label arm path
161 // label arm path
161 QPointF labelTextStart;
162 QPointF labelTextStart;
162 m_labelArmPath = labelArmPath(armStart, centerAngle, m_data.m_radius * m_data.m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
163 m_labelArmPath = labelArmPath(armStart, centerAngle, m_data.m_radius * m_data.m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
163
164
164 // text position
165 // text position
165 switch (m_data.m_labelPosition)
166 switch (m_data.m_labelPosition)
166 {
167 {
167 case QPieSlice::LabelOutside:
168 case QPieSlice::LabelOutside:
168 m_labelTextRect.moveBottomLeft(labelTextStart);
169 m_labelTextRect.moveBottomLeft(labelTextStart);
169 break;
170 break;
170 case QPieSlice::LabelInside:
171 case QPieSlice::LabelInside:
171 case QPieSlice::LabelInsideTangential:
172 case QPieSlice::LabelInsideTangential:
172 case QPieSlice::LabelInsideNormal:{
173 case QPieSlice::LabelInsideNormal:{
173 QPointF textCenter;
174 QPointF textCenter;
174 if (m_data.m_donut)
175 if (m_data.m_donut)
175 textCenter = m_data.m_center + offset(centerAngle, m_data.m_innerRadius + (m_data.m_radius - m_data.m_innerRadius) / 2);
176 textCenter = m_data.m_center + offset(centerAngle, m_data.m_innerRadius + (m_data.m_radius - m_data.m_innerRadius) / 2);
176 else
177 else
177 textCenter = m_data.m_center + offset(centerAngle, m_data.m_radius / 2);
178 textCenter = m_data.m_center + offset(centerAngle, m_data.m_radius / 2);
178 m_labelTextRect.moveCenter(textCenter);
179 m_labelTextRect.moveCenter(textCenter);
179 break;
180 break;
180 }
181 }
181 }
182 }
182
183
183 // bounding rect
184 // bounding rect
184 if (m_data.m_isLabelVisible)
185 if (m_data.m_isLabelVisible)
185 m_boundingRect = m_slicePath.boundingRect().united(m_labelArmPath.boundingRect()).united(m_labelTextRect);
186 m_boundingRect = m_slicePath.boundingRect().united(m_labelArmPath.boundingRect()).united(m_labelTextRect);
186 else
187 else
187 m_boundingRect = m_slicePath.boundingRect();
188 m_boundingRect = m_slicePath.boundingRect();
188 }
189 }
189
190
190 QPointF PieSliceItem::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
191 QPointF PieSliceItem::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
191 {
192 {
192 if (slice->isExploded()) {
193 if (slice->isExploded()) {
193 qreal centerAngle = slice->startAngle() + (slice->angleSpan()/2);
194 qreal centerAngle = slice->startAngle() + (slice->angleSpan()/2);
194 qreal len = radius * slice->explodeDistanceFactor();
195 qreal len = radius * slice->explodeDistanceFactor();
195 point += offset(centerAngle, len);
196 point += offset(centerAngle, len);
196 }
197 }
197 return point;
198 return point;
198 }
199 }
199
200
200 QPainterPath PieSliceItem::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal *centerAngle, QPointF* armStart)
201 QPainterPath PieSliceItem::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal *centerAngle, QPointF* armStart)
201 {
202 {
202 // calculate center angle
203 // calculate center angle
203 *centerAngle = startAngle + (angleSpan/2);
204 *centerAngle = startAngle + (angleSpan/2);
204
205
205 // calculate slice rectangle
206 // calculate slice rectangle
206 QRectF rect(center.x()-radius, center.y()-radius, radius*2, radius*2);
207 QRectF rect(center.x()-radius, center.y()-radius, radius*2, radius*2);
207
208
208 // slice path
209 // slice path
209 QPainterPath path;
210 QPainterPath path;
210 if (m_data.m_donut) {
211 if (m_data.m_donut) {
211 QRectF insideRect(center.x() - m_data.m_innerRadius, center.y()-m_data.m_innerRadius, m_data.m_innerRadius*2, m_data.m_innerRadius*2);
212 QRectF insideRect(center.x() - m_data.m_innerRadius, center.y()-m_data.m_innerRadius, m_data.m_innerRadius*2, m_data.m_innerRadius*2);
212 path.arcMoveTo(rect, -startAngle + 90);
213 path.arcMoveTo(rect, -startAngle + 90);
213 path.arcTo(rect, -startAngle + 90, -angleSpan);
214 path.arcTo(rect, -startAngle + 90, -angleSpan);
214 path.arcTo(insideRect, -startAngle + 90 - angleSpan, angleSpan);
215 path.arcTo(insideRect, -startAngle + 90 - angleSpan, angleSpan);
215 path.closeSubpath();
216 path.closeSubpath();
216 } else {
217 } else {
217 path.moveTo(rect.center());
218 path.moveTo(rect.center());
218 path.arcTo(rect, -startAngle + 90, -angleSpan);
219 path.arcTo(rect, -startAngle + 90, -angleSpan);
219 path.closeSubpath();
220 path.closeSubpath();
220 }
221 }
221
222
222 // calculate label arm start point
223 // calculate label arm start point
223 *armStart = center;
224 *armStart = center;
224 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
225 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
225
226
226 return path;
227 return path;
227 }
228 }
228
229
229 QPainterPath PieSliceItem::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF *textStart)
230 QPainterPath PieSliceItem::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF *textStart)
230 {
231 {
231 // Normalize the angle to 0-360 range
232 // Normalize the angle to 0-360 range
232 // NOTE: We are using int here on purpose. Depenging on platform and hardware
233 // NOTE: We are using int here on purpose. Depenging on platform and hardware
233 // qreal can be a double, float or something the user gives to the Qt configure
234 // qreal can be a double, float or something the user gives to the Qt configure
234 // (QT_COORD_TYPE). Compilers do not seem to support modulo for double or float
235 // (QT_COORD_TYPE). Compilers do not seem to support modulo for double or float
235 // but there are fmod() and fmodf() functions for that. So instead of some #ifdef
236 // but there are fmod() and fmodf() functions for that. So instead of some #ifdef
236 // that might break we just use int. Precision for this is just fine for our needs.
237 // that might break we just use int. Precision for this is just fine for our needs.
237 int normalized = angle * 10.0;
238 int normalized = angle * 10.0;
238 normalized = normalized % 3600;
239 normalized = normalized % 3600;
239 if (normalized < 0)
240 if (normalized < 0)
240 normalized += 3600;
241 normalized += 3600;
241 angle = (qreal) normalized / 10.0;
242 angle = (qreal) normalized / 10.0;
242
243
243 // prevent label arm pointing straight down because it will look bad
244 // prevent label arm pointing straight down because it will look bad
244 if (angle < 180 && angle > 170)
245 if (angle < 180 && angle > 170)
245 angle = 170;
246 angle = 170;
246 if (angle > 180 && angle < 190)
247 if (angle > 180 && angle < 190)
247 angle = 190;
248 angle = 190;
248
249
249 // line from slice to label
250 // line from slice to label
250 QPointF parm1 = start + offset(angle, length);
251 QPointF parm1 = start + offset(angle, length);
251
252
252 // line to underline the label
253 // line to underline the label
253 QPointF parm2 = parm1;
254 QPointF parm2 = parm1;
254 if (angle < 180) { // arm swings the other way on the left side
255 if (angle < 180) { // arm swings the other way on the left side
255 parm2 += QPointF(textWidth, 0);
256 parm2 += QPointF(textWidth, 0);
256 *textStart = parm1;
257 *textStart = parm1;
257 }
258 }
258 else {
259 else {
259 parm2 += QPointF(-textWidth,0);
260 parm2 += QPointF(-textWidth,0);
260 *textStart = parm2;
261 *textStart = parm2;
261 }
262 }
262
263
263 QPainterPath path;
264 QPainterPath path;
264 path.moveTo(start);
265 path.moveTo(start);
265 path.lineTo(parm1);
266 path.lineTo(parm1);
266 path.lineTo(parm2);
267 path.lineTo(parm2);
267
268
268 return path;
269 return path;
269 }
270 }
270
271
271 #include "moc_piesliceitem_p.cpp"
272 #include "moc_piesliceitem_p.cpp"
272
273
273 QTCOMMERCIALCHART_END_NAMESPACE
274 QTCOMMERCIALCHART_END_NAMESPACE
274
275
@@ -1,205 +1,206
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "scatterchartitem_p.h"
21 #include "scatterchartitem_p.h"
22 #include "qscatterseries.h"
22 #include "qscatterseries.h"
23 #include "qscatterseries_p.h"
23 #include "qscatterseries_p.h"
24 #include "chartpresenter_p.h"
24 #include "chartpresenter_p.h"
25 #include <QPainter>
25 #include <QPainter>
26 #include <QGraphicsScene>
26 #include <QGraphicsScene>
27 #include <QDebug>
27 #include <QDebug>
28 #include <QGraphicsSceneMouseEvent>
28 #include <QGraphicsSceneMouseEvent>
29
29
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31
31
32 ScatterChartItem::ScatterChartItem(QScatterSeries *series, ChartPresenter *presenter) :
32 ScatterChartItem::ScatterChartItem(QScatterSeries *series, ChartPresenter *presenter) :
33 XYChart(series,presenter),
33 XYChart(series,presenter),
34 QGraphicsItem(presenter ? presenter->rootItem() : 0),
34 QGraphicsItem(presenter ? presenter->rootItem() : 0),
35 m_series(series),
35 m_series(series),
36 m_items(this),
36 m_items(this),
37 m_visible(true),
37 m_visible(true),
38 m_shape(QScatterSeries::MarkerShapeRectangle),
38 m_shape(QScatterSeries::MarkerShapeRectangle),
39 m_size(15)
39 m_size(15)
40 {
40 {
41 QObject::connect(m_series->d_func(),SIGNAL(updated()), this, SLOT(handleUpdated()));
41 QObject::connect(m_series->d_func(),SIGNAL(updated()), this, SLOT(handleUpdated()));
42 QObject::connect(m_series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
42 QObject::connect(m_series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
43
43
44 setZValue(ChartPresenter::ScatterSeriesZValue);
44 setZValue(ChartPresenter::ScatterSeriesZValue);
45 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
45 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
46
46
47 handleUpdated();
47 handleUpdated();
48
48
49 m_items.setHandlesChildEvents(false);
49 m_items.setHandlesChildEvents(false);
50
50
51 // TODO: how to draw a drop shadow?
51 // TODO: how to draw a drop shadow?
52 // QGraphicsDropShadowEffect *dropShadow = new QGraphicsDropShadowEffect();
52 // QGraphicsDropShadowEffect *dropShadow = new QGraphicsDropShadowEffect();
53 // dropShadow->setOffset(2.0);
53 // dropShadow->setOffset(2.0);
54 // dropShadow->setBlurRadius(2.0);
54 // dropShadow->setBlurRadius(2.0);
55 // setGraphicsEffect(dropShadow);
55 // setGraphicsEffect(dropShadow);
56 }
56 }
57
57
58 QRectF ScatterChartItem::boundingRect() const
58 QRectF ScatterChartItem::boundingRect() const
59 {
59 {
60 return m_rect;
60 return m_rect;
61 }
61 }
62
62
63 void ScatterChartItem::createPoints(int count)
63 void ScatterChartItem::createPoints(int count)
64 {
64 {
65 for (int i = 0; i < count; ++i) {
65 for (int i = 0; i < count; ++i) {
66
66
67 QGraphicsItem *item = 0;
67 QGraphicsItem *item = 0;
68
68
69 switch (m_shape) {
69 switch (m_shape) {
70 case QScatterSeries::MarkerShapeCircle: {
70 case QScatterSeries::MarkerShapeCircle: {
71 QGraphicsEllipseItem* i = new QGraphicsEllipseItem(0,0,m_size,m_size);
71 QGraphicsEllipseItem* i = new QGraphicsEllipseItem(0,0,m_size,m_size,this);
72 const QRectF& rect = i->boundingRect();
72 const QRectF& rect = i->boundingRect();
73 i->setPos(-rect.width()/2,-rect.height()/2);
73 i->setPos(-rect.width()/2,-rect.height()/2);
74 item = new Marker(i,this);
74 item = new Marker(i,this);
75 break;
75 break;
76 }
76 }
77 case QScatterSeries::MarkerShapeRectangle: {
77 case QScatterSeries::MarkerShapeRectangle: {
78 QGraphicsRectItem* i = new QGraphicsRectItem(0,0,m_size,m_size);
78 QGraphicsRectItem* i = new QGraphicsRectItem(0,0,m_size,m_size,this);
79 i->setPos(-m_size/2,-m_size/2);
79 i->setPos(-m_size/2,-m_size/2);
80 item = new Marker(i,this);
80 item = new Marker(i,this);
81 break;
81 break;
82 }
82 }
83 default:
83 default:
84 qWarning()<<"Unsupported marker type";
84 qWarning()<<"Unsupported marker type";
85 break;
85 break;
86
86
87 }
87 }
88 m_items.addToGroup(item);
88 m_items.addToGroup(item);
89 }
89 }
90 }
90 }
91
91
92 void ScatterChartItem::deletePoints(int count)
92 void ScatterChartItem::deletePoints(int count)
93 {
93 {
94 QList<QGraphicsItem *> items = m_items.childItems();
94 QList<QGraphicsItem *> items = m_items.childItems();
95
95
96 for (int i = 0; i < count; ++i) {
96 for (int i = 0; i < count; ++i) {
97 delete(items.takeLast());
97 delete(items.takeLast());
98 }
98 }
99 }
99 }
100
100
101 void ScatterChartItem::markerSelected(Marker *marker)
101 void ScatterChartItem::markerSelected(Marker *marker)
102 {
102 {
103 emit XYChart::clicked(calculateDomainPoint(marker->point()));
103 emit XYChart::clicked(calculateDomainPoint(marker->point()));
104 }
104 }
105
105
106 void ScatterChartItem::updateGeometry()
106 void ScatterChartItem::updateGeometry()
107 {
107 {
108
108
109 const QVector<QPointF>& points = geometryPoints();
109 const QVector<QPointF>& points = geometryPoints();
110
110
111 if(points.size()==0)
111 if(points.size()==0)
112 {
112 {
113 deletePoints(m_items.childItems().count());
113 deletePoints(m_items.childItems().count());
114 return;
114 return;
115 }
115 }
116
116
117 int diff = m_items.childItems().size() - points.size();
117 int diff = m_items.childItems().size() - points.size();
118
118
119 if(diff>0) {
119 if(diff>0) {
120 deletePoints(diff);
120 deletePoints(diff);
121 }
121 }
122 else if(diff<0) {
122 else if(diff<0) {
123 createPoints(-diff);
123 createPoints(-diff);
124 }
124 }
125
125
126 if(diff!=0) handleUpdated();
126 if(diff!=0) handleUpdated();
127
127
128 QList<QGraphicsItem*> items = m_items.childItems();
128 QList<QGraphicsItem*> items = m_items.childItems();
129
129
130 for (int i = 0; i < points.size(); i++) {
130 for (int i = 0; i < points.size(); i++) {
131 Marker* item = static_cast<Marker*>(items.at(i));
131 Marker* item = static_cast<Marker*>(items.at(i));
132 const QPointF& point = points.at(i);
132 const QPointF& point = points.at(i);
133 const QRectF& rect = item->boundingRect();
133 const QRectF& rect = item->boundingRect();
134 item->setPoint(point);
134 item->setPoint(point);
135 item->setPos(point.x()-rect.width()/2,point.y()-rect.height()/2);
135 item->setPos(point.x()-rect.width()/2,point.y()-rect.height()/2);
136 if(!m_visible || !clipRect().contains(point)) {
136 if(!m_visible || !clipRect().contains(point)) {
137 item->setVisible(false);
137 item->setVisible(false);
138 }
138 }
139 else {
139 else {
140 item->setVisible(true);
140 item->setVisible(true);
141 }
141 }
142 }
142 }
143
143
144 prepareGeometryChange();
144 prepareGeometryChange();
145 m_rect = clipRect();
145 m_rect = clipRect();
146 setPos(origin());
146 setPos(origin());
147 }
147 }
148
148
149 void ScatterChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
149 void ScatterChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
150 {
150 {
151 Q_UNUSED(painter)
151 Q_UNUSED(painter)
152 Q_UNUSED(option)
152 Q_UNUSED(option)
153 Q_UNUSED(widget)
153 Q_UNUSED(widget)
154 }
154 }
155
155
156 void ScatterChartItem::setPen(const QPen& pen)
156 void ScatterChartItem::setPen(const QPen& pen)
157 {
157 {
158 foreach(QGraphicsItem* item , m_items.childItems()) {
158 foreach(QGraphicsItem* item , m_items.childItems()) {
159 static_cast<Marker*>(item)->setPen(pen);
159 static_cast<Marker*>(item)->setPen(pen);
160 }
160 }
161 }
161 }
162
162
163 void ScatterChartItem::setBrush(const QBrush& brush)
163 void ScatterChartItem::setBrush(const QBrush& brush)
164 {
164 {
165 foreach(QGraphicsItem* item , m_items.childItems()) {
165 foreach(QGraphicsItem* item , m_items.childItems()) {
166 static_cast<Marker*>(item)->setBrush(brush);
166 static_cast<Marker*>(item)->setBrush(brush);
167 }
167 }
168 }
168 }
169
169
170 void ScatterChartItem::handleUpdated()
170 void ScatterChartItem::handleUpdated()
171 {
171 {
172 int count = m_items.childItems().count();
172 int count = m_items.childItems().count();
173
173
174 if(count==0) return;
174 if(count==0) return;
175
175
176 bool recreate = m_visible != m_series->isVisible()
176 bool recreate = m_visible != m_series->isVisible()
177 || m_size != m_series->markerSize()
177 || m_size != m_series->markerSize()
178 || m_shape != m_series->markerShape();
178 || m_shape != m_series->markerShape();
179
179
180 m_visible = m_series->isVisible();
180 m_visible = m_series->isVisible();
181 m_size = m_series->markerSize();
181 m_size = m_series->markerSize();
182 m_shape = m_series->markerShape();
182 m_shape = m_series->markerShape();
183
183
184 if(recreate) {
184 if(recreate) {
185 // TODO: optimize handleUpdate to recreate points only in case shape changed
185 // TODO: optimize handleUpdate to recreate points only in case shape changed
186 deletePoints(count);
186 deletePoints(count);
187 createPoints(count);
187 createPoints(count);
188
188
189 // Updating geometry is now safe, because it won't call handleUpdated unless it creates/deletes points
189 // Updating geometry is now safe, because it won't call handleUpdated unless it creates/deletes points
190 updateGeometry();
190 updateGeometry();
191 }
191 }
192
192
193 setPen(m_series->pen());
193 setPen(m_series->pen());
194 setBrush(m_series->brush());
194 setBrush(m_series->brush());
195 update();
195 update();
196 }
196 }
197
197
198 void ScatterChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
198 void ScatterChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
199 {
199 {
200 emit XYChart::clicked(calculateDomainPoint(event->pos()));
200 emit XYChart::clicked(calculateDomainPoint(event->pos()));
201 QGraphicsItem::mousePressEvent(event);
201 }
202 }
202
203
203 #include "moc_scatterchartitem_p.cpp"
204 #include "moc_scatterchartitem_p.cpp"
204
205
205 QTCOMMERCIALCHART_END_NAMESPACE
206 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,151 +1,152
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef SCATTERCHARTITEM_H
30 #ifndef SCATTERCHARTITEM_H
31 #define SCATTERCHARTITEM_H
31 #define SCATTERCHARTITEM_H
32
32
33 #include "qchartglobal.h"
33 #include "qchartglobal.h"
34 #include "xychart_p.h"
34 #include "xychart_p.h"
35 #include <QGraphicsEllipseItem>
35 #include <QGraphicsEllipseItem>
36 #include <QPen>
36 #include <QPen>
37
37
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39
39
40 class QScatterSeries;
40 class QScatterSeries;
41 class Marker;
41 class Marker;
42
42
43 class ScatterChartItem : public XYChart, public QGraphicsItem
43 class ScatterChartItem : public XYChart, public QGraphicsItem
44 {
44 {
45 Q_OBJECT
45 Q_OBJECT
46 Q_INTERFACES(QGraphicsItem)
46 Q_INTERFACES(QGraphicsItem)
47 public:
47 public:
48 explicit ScatterChartItem(QScatterSeries *series, ChartPresenter *presenter);
48 explicit ScatterChartItem(QScatterSeries *series, ChartPresenter *presenter);
49
49
50 public:
50 public:
51 //from QGraphicsItem
51 //from QGraphicsItem
52 QRectF boundingRect() const;
52 QRectF boundingRect() const;
53 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
53 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
54
54
55 void setPen(const QPen &pen);
55 void setPen(const QPen &pen);
56 void setBrush(const QBrush &brush);
56 void setBrush(const QBrush &brush);
57
57
58 void markerSelected(Marker *item);
58 void markerSelected(Marker *item);
59
59
60 public Q_SLOTS:
60 public Q_SLOTS:
61 void handleUpdated();
61 void handleUpdated();
62
62
63 private:
63 private:
64 void createPoints(int count);
64 void createPoints(int count);
65 void deletePoints(int count);
65 void deletePoints(int count);
66
66
67 protected:
67 protected:
68 void updateGeometry();
68 void updateGeometry();
69 void mousePressEvent(QGraphicsSceneMouseEvent *event);
69 void mousePressEvent(QGraphicsSceneMouseEvent *event);
70
70
71 private:
71 private:
72 QScatterSeries *m_series;
72 QScatterSeries *m_series;
73 QGraphicsItemGroup m_items;
73 QGraphicsItemGroup m_items;
74 bool m_visible;
74 bool m_visible;
75 int m_shape;
75 int m_shape;
76 int m_size;
76 int m_size;
77 QRectF m_rect;
77 QRectF m_rect;
78 };
78 };
79
79
80
80
81 class Marker: public QAbstractGraphicsShapeItem
81 class Marker: public QAbstractGraphicsShapeItem
82 {
82 {
83
83
84 public:
84 public:
85
85
86 Marker(QAbstractGraphicsShapeItem *item , ScatterChartItem *parent) : QAbstractGraphicsShapeItem(0) ,m_item(item), m_parent(parent)
86 Marker(QAbstractGraphicsShapeItem *item , ScatterChartItem *parent) : QAbstractGraphicsShapeItem(0) ,m_item(item), m_parent(parent)
87 {
87 {
88 }
88 }
89
89
90 ~Marker()
90 ~Marker()
91 {
91 {
92 delete m_item;
92 delete m_item;
93 }
93 }
94
94
95 void setPoint(const QPointF& point)
95 void setPoint(const QPointF& point)
96 {
96 {
97 m_point=point;
97 m_point=point;
98 }
98 }
99
99
100 QPointF point() const
100 QPointF point() const
101 {
101 {
102 return m_point;
102 return m_point;
103 }
103 }
104
104
105 QPainterPath shape() const
105 QPainterPath shape() const
106 {
106 {
107 return m_item->shape();
107 return m_item->shape();
108 }
108 }
109
109
110 QRectF boundingRect() const
110 QRectF boundingRect() const
111 {
111 {
112 return m_item->boundingRect();
112 return m_item->boundingRect();
113 }
113 }
114
114
115 bool contains(const QPointF &point) const
115 bool contains(const QPointF &point) const
116 {
116 {
117 return m_item->contains(point);
117 return m_item->contains(point);
118 }
118 }
119
119
120 void setPen(const QPen &pen)
120 void setPen(const QPen &pen)
121 {
121 {
122 m_item->setPen(pen);
122 m_item->setPen(pen);
123 }
123 }
124
124
125 void setBrush(const QBrush &brush)
125 void setBrush(const QBrush &brush)
126 {
126 {
127 m_item->setBrush(brush);
127 m_item->setBrush(brush);
128 }
128 }
129
129
130 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
130 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
131 {
131 {
132 m_item->paint(painter,option,widget);
132 m_item->paint(painter,option,widget);
133 }
133 }
134
134
135 protected:
135 protected:
136
136
137 void mousePressEvent(QGraphicsSceneMouseEvent *event)
137 void mousePressEvent(QGraphicsSceneMouseEvent *event)
138 {
138 {
139 Q_UNUSED(event)
139 Q_UNUSED(event)
140 m_parent->markerSelected(this);
140 m_parent->markerSelected(this);
141 QAbstractGraphicsShapeItem::mousePressEvent(event);
141 }
142 }
142
143
143 private:
144 private:
144 QAbstractGraphicsShapeItem* m_item;
145 QAbstractGraphicsShapeItem* m_item;
145 ScatterChartItem* m_parent;
146 ScatterChartItem* m_parent;
146 QPointF m_point;
147 QPointF m_point;
147 };
148 };
148
149
149 QTCOMMERCIALCHART_END_NAMESPACE
150 QTCOMMERCIALCHART_END_NAMESPACE
150
151
151 #endif // SCATTERPRESENTER_H
152 #endif // SCATTERPRESENTER_H
@@ -1,176 +1,177
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "splinechartitem_p.h"
21 #include "splinechartitem_p.h"
22 #include "qsplineseries_p.h"
22 #include "qsplineseries_p.h"
23 #include "chartpresenter_p.h"
23 #include "chartpresenter_p.h"
24 #include "splineanimation_p.h"
24 #include "splineanimation_p.h"
25 #include <QPainter>
25 #include <QPainter>
26 #include <QGraphicsSceneMouseEvent>
26 #include <QGraphicsSceneMouseEvent>
27
27
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29
29
30 SplineChartItem::SplineChartItem(QSplineSeries *series, ChartPresenter *presenter) :
30 SplineChartItem::SplineChartItem(QSplineSeries *series, ChartPresenter *presenter) :
31 XYChart(series, presenter),
31 XYChart(series, presenter),
32 QGraphicsItem(presenter ? presenter->rootItem() : 0),
32 QGraphicsItem(presenter ? presenter->rootItem() : 0),
33 m_series(series),
33 m_series(series),
34 m_pointsVisible(false),
34 m_pointsVisible(false),
35 m_animation(0)
35 m_animation(0)
36 {
36 {
37 setZValue(ChartPresenter::LineChartZValue);
37 setZValue(ChartPresenter::SplineChartZValue);
38 QObject::connect(m_series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
38 QObject::connect(m_series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
39 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
39 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
40 handleUpdated();
40 handleUpdated();
41 }
41 }
42
42
43 QRectF SplineChartItem::boundingRect() const
43 QRectF SplineChartItem::boundingRect() const
44 {
44 {
45 return m_rect;
45 return m_rect;
46 }
46 }
47
47
48 QPainterPath SplineChartItem::shape() const
48 QPainterPath SplineChartItem::shape() const
49 {
49 {
50 return m_path;
50 return m_path;
51 }
51 }
52
52
53 void SplineChartItem::setAnimation(SplineAnimation* animation)
53 void SplineChartItem::setAnimation(SplineAnimation* animation)
54 {
54 {
55 m_animation=animation;
55 m_animation=animation;
56 XYChart::setAnimation(animation);
56 XYChart::setAnimation(animation);
57 }
57 }
58
58
59 ChartAnimation* SplineChartItem::animation() const
59 ChartAnimation* SplineChartItem::animation() const
60 {
60 {
61 return m_animation;
61 return m_animation;
62 }
62 }
63
63
64 void SplineChartItem::setControlGeometryPoints(QVector<QPointF>& points)
64 void SplineChartItem::setControlGeometryPoints(QVector<QPointF>& points)
65 {
65 {
66 m_controlPoints=points;
66 m_controlPoints=points;
67 }
67 }
68
68
69 QVector<QPointF> SplineChartItem::controlGeometryPoints() const
69 QVector<QPointF> SplineChartItem::controlGeometryPoints() const
70 {
70 {
71 return m_controlPoints;
71 return m_controlPoints;
72 }
72 }
73
73
74 void SplineChartItem::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
74 void SplineChartItem::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
75 {
75 {
76 QVector<QPointF> controlPoints;
76 QVector<QPointF> controlPoints;
77
77
78 if(newPoints.count()>=2) {
78 if(newPoints.count()>=2) {
79 controlPoints.resize(newPoints.count()*2-2);
79 controlPoints.resize(newPoints.count()*2-2);
80 }
80 }
81
81
82 for (int i = 0; i < newPoints.size() - 1; i++) {
82 for (int i = 0; i < newPoints.size() - 1; i++) {
83 controlPoints[2*i] = calculateGeometryControlPoint(2 * i);
83 controlPoints[2*i] = calculateGeometryControlPoint(2 * i);
84 controlPoints[2 * i + 1] = calculateGeometryControlPoint(2 * i + 1);
84 controlPoints[2 * i + 1] = calculateGeometryControlPoint(2 * i + 1);
85 }
85 }
86
86
87 if (controlPoints.count()<2) {
87 if (controlPoints.count()<2) {
88 setGeometryPoints(newPoints);
88 setGeometryPoints(newPoints);
89 setControlGeometryPoints(controlPoints);
89 setControlGeometryPoints(controlPoints);
90 updateGeometry();
90 updateGeometry();
91 return;
91 return;
92 }
92 }
93
93
94 if (m_animation) {
94 if (m_animation) {
95 m_animation->setup(oldPoints,newPoints,m_controlPoints,controlPoints,index);
95 m_animation->setup(oldPoints,newPoints,m_controlPoints,controlPoints,index);
96 setGeometryPoints(newPoints);
96 setGeometryPoints(newPoints);
97 setDirty(false);
97 setDirty(false);
98 presenter()->startAnimation(m_animation);
98 presenter()->startAnimation(m_animation);
99 }
99 }
100 else {
100 else {
101 setGeometryPoints(newPoints);
101 setGeometryPoints(newPoints);
102 setControlGeometryPoints(controlPoints);
102 setControlGeometryPoints(controlPoints);
103 updateGeometry();
103 updateGeometry();
104 }
104 }
105 }
105 }
106
106
107 QPointF SplineChartItem::calculateGeometryControlPoint(int index) const
107 QPointF SplineChartItem::calculateGeometryControlPoint(int index) const
108 {
108 {
109 return XYChart::calculateGeometryPoint(m_series->d_func()->controlPoint(index));
109 return XYChart::calculateGeometryPoint(m_series->d_func()->controlPoint(index));
110 }
110 }
111
111
112 void SplineChartItem::updateGeometry()
112 void SplineChartItem::updateGeometry()
113 {
113 {
114 const QVector<QPointF> &points = geometryPoints();
114 const QVector<QPointF> &points = geometryPoints();
115 const QVector<QPointF> &controlPoints = controlGeometryPoints();
115 const QVector<QPointF> &controlPoints = controlGeometryPoints();
116
116
117 if ((points.size()<2) || (controlPoints.size()<2)) {
117 if ((points.size()<2) || (controlPoints.size()<2)) {
118 prepareGeometryChange();
118 prepareGeometryChange();
119 m_path = QPainterPath();
119 m_path = QPainterPath();
120 m_rect = QRect();
120 m_rect = QRect();
121 return;
121 return;
122 }
122 }
123
123
124 Q_ASSERT(points.count()*2-2 == controlPoints.count());
124 Q_ASSERT(points.count()*2-2 == controlPoints.count());
125
125
126 QPainterPath splinePath(points.at(0));
126 QPainterPath splinePath(points.at(0));
127
127
128 for (int i = 0; i < points.size() - 1; i++) {
128 for (int i = 0; i < points.size() - 1; i++) {
129 const QPointF& point = points.at(i + 1);
129 const QPointF& point = points.at(i + 1);
130 splinePath.cubicTo(controlPoints[2*i],controlPoints[2 * i + 1],point);
130 splinePath.cubicTo(controlPoints[2*i],controlPoints[2 * i + 1],point);
131 }
131 }
132
132
133 prepareGeometryChange();
133 prepareGeometryChange();
134 m_path = splinePath;
134 m_path = splinePath;
135 m_rect = splinePath.boundingRect();
135 m_rect = splinePath.boundingRect();
136 setPos(origin());
136 setPos(origin());
137 }
137 }
138
138
139 //handlers
139 //handlers
140
140
141 void SplineChartItem::handleUpdated()
141 void SplineChartItem::handleUpdated()
142 {
142 {
143 setVisible(m_series->isVisible());
143 setVisible(m_series->isVisible());
144 m_pointsVisible = m_series->pointsVisible();
144 m_pointsVisible = m_series->pointsVisible();
145 m_linePen = m_series->pen();
145 m_linePen = m_series->pen();
146 m_pointPen = m_series->pen();
146 m_pointPen = m_series->pen();
147 m_pointPen.setWidthF(2*m_pointPen.width());
147 m_pointPen.setWidthF(2*m_pointPen.width());
148 update();
148 update();
149 }
149 }
150
150
151 //painter
151 //painter
152
152
153 void SplineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
153 void SplineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
154 {
154 {
155 Q_UNUSED(widget)
155 Q_UNUSED(widget)
156 Q_UNUSED(option)
156 Q_UNUSED(option)
157
157
158 painter->save();
158 painter->save();
159 painter->setClipRect(clipRect());
159 painter->setClipRect(clipRect());
160 painter->setPen(m_linePen);
160 painter->setPen(m_linePen);
161 painter->drawPath(m_path);
161 painter->drawPath(m_path);
162 if (m_pointsVisible) {
162 if (m_pointsVisible) {
163 painter->setPen(m_pointPen);
163 painter->setPen(m_pointPen);
164 painter->drawPoints(geometryPoints());
164 painter->drawPoints(geometryPoints());
165 }
165 }
166 painter->restore();
166 painter->restore();
167 }
167 }
168
168
169 void SplineChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
169 void SplineChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
170 {
170 {
171 emit XYChart::clicked(calculateDomainPoint(event->pos()));
171 emit XYChart::clicked(calculateDomainPoint(event->pos()));
172 QGraphicsItem::mousePressEvent(event);
172 }
173 }
173
174
174 #include "moc_splinechartitem_p.cpp"
175 #include "moc_splinechartitem_p.cpp"
175
176
176 QTCOMMERCIALCHART_END_NAMESPACE
177 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now