@@ -1,97 +1,97 | |||
|
1 | 1 | #ifndef BARSERIES_H |
|
2 | 2 | #define BARSERIES_H |
|
3 | 3 | |
|
4 | 4 | #include <qseries.h> |
|
5 | 5 | #include <QStringList> |
|
6 | 6 | |
|
7 | 7 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
8 | 8 | |
|
9 | 9 | typedef QStringList QBarCategories; |
|
10 | 10 | |
|
11 | 11 | class QBarSet; |
|
12 | 12 | class BarChartModel; |
|
13 | 13 | class BarCategory; |
|
14 | 14 | |
|
15 | 15 | // Container for series |
|
16 | 16 | class QTCOMMERCIALCHART_EXPORT QBarSeries : public QSeries |
|
17 | 17 | { |
|
18 | 18 | Q_OBJECT |
|
19 | 19 | public: |
|
20 | 20 | QBarSeries(QStringList categories, QObject *parent = 0); |
|
21 | 21 | |
|
22 | 22 | virtual QSeriesType type() const { return QSeries::SeriesTypeBar; } |
|
23 | 23 | |
|
24 | 24 | void addBarSet(QBarSet *set); // Takes ownership of set |
|
25 | 25 | void removeBarSet(QBarSet *set); // Releases ownership, doesn't delete set |
|
26 | 26 | void insertBarSet(int i, QBarSet *set); |
|
27 | 27 | void insertCategory(int i, QString category); |
|
28 | 28 | void removeCategory(int i); |
|
29 | 29 | int barsetCount(); |
|
30 | 30 | int categoryCount(); |
|
31 | 31 | QList<QBarSet*> barSets(); |
|
32 | 32 | QBarCategories categories() const; |
|
33 | 33 | |
|
34 | 34 | bool setModel(QAbstractItemModel *model); |
|
35 | 35 | QAbstractItemModel *modelExt() { return m_model; } |
|
36 | 36 | void setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation = Qt::Vertical); |
|
37 | 37 | void setModelMappingShift(int first, int count); |
|
38 | 38 | |
|
39 | 39 | public: |
|
40 | 40 | // TODO: Functions below this are not part of api and will be moved |
|
41 | 41 | // to private implementation, when we start using it |
|
42 | 42 | // TODO: TO PIMPL ---> |
|
43 | 43 | QBarSet* barsetAt(int index); |
|
44 | 44 | QString categoryName(int category); |
|
45 | 45 | qreal min(); |
|
46 | 46 | qreal max(); |
|
47 | 47 | qreal valueAt(int set, int category); |
|
48 | 48 | qreal percentageAt(int set, int category); |
|
49 | 49 | qreal categorySum(int category); |
|
50 | 50 | qreal maxCategorySum(); |
|
51 | 51 | BarChartModel& model(); |
|
52 | 52 | // <--- TO PIMPL |
|
53 | 53 | |
|
54 | 54 | signals: |
|
55 | 55 | //void changed(int index); |
|
56 | 56 | void clicked(QBarSet *barset, QString category); // Up to user of api, what to do with these signals |
|
57 | 57 | void rightClicked(QBarSet *barset, QString category); |
|
58 | 58 | |
|
59 | 59 | // |
|
60 | 60 | void updatedBars(); |
|
61 | 61 | void restructuredBar(int); |
|
62 | 62 | |
|
63 | 63 | // TODO: internal signals, these to private implementation. |
|
64 | 64 | // TODO: TO PIMPL ---> |
|
65 | 65 | void showToolTip(QPoint pos, QString tip); |
|
66 | 66 | // <--- TO PIMPL |
|
67 | 67 | |
|
68 | 68 | public Q_SLOTS: |
|
69 | 69 | void setToolTipEnabled(bool enabled = true); // enables tooltips |
|
70 | 70 | |
|
71 | 71 | // TODO: TO PIMPL ---> |
|
72 | 72 | void barsetClicked(QString category); |
|
73 | 73 | void barsetRightClicked(QString category); |
|
74 | 74 | // <--- TO PIMPL |
|
75 | 75 | |
|
76 | 76 | private Q_SLOTS: |
|
77 | 77 | // slots for updating bars when data in model changes |
|
78 | 78 | void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight); |
|
79 | 79 | void modelDataAdded(QModelIndex parent, int start, int end); |
|
80 | 80 | void modelDataRemoved(QModelIndex parent, int start, int end); |
|
81 | 81 | void barsetChanged(); |
|
82 | 82 | |
|
83 | 83 | protected: |
|
84 | BarChartModel *m_internalModel; | |
|
84 | BarChartModel *m_internalModel; // TODO: this may change... current "2 models" situation doesn't look good. | |
|
85 | 85 | |
|
86 | 86 | QAbstractItemModel* m_model; |
|
87 | 87 | int m_mapCategories; |
|
88 | 88 | int m_mapBarBottom; |
|
89 | 89 | int m_mapBarTop; |
|
90 | 90 | int m_mapFirst; |
|
91 | 91 | int m_mapCount; |
|
92 | 92 | Qt::Orientation m_mapOrientation; |
|
93 | 93 | }; |
|
94 | 94 | |
|
95 | 95 | QTCOMMERCIALCHART_END_NAMESPACE |
|
96 | 96 | |
|
97 | 97 | #endif // BARSERIES_H |
@@ -1,176 +1,173 | |||
|
1 | 1 | #include "qchartglobal.h" |
|
2 | 2 | #include "legendmarker_p.h" |
|
3 | 3 | #include <qpieslice.h> |
|
4 | 4 | #include <qbarset.h> |
|
5 | 5 | #include <qxyseries.h> |
|
6 | 6 | #include <QPainter> |
|
7 | 7 | #include <QGraphicsSceneEvent> |
|
8 | 8 | #include <QGraphicsSimpleTextItem> |
|
9 | 9 | |
|
10 | 10 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
11 | 11 | |
|
12 |
LegendMarker::LegendMarker(QSeries* |
|
|
13 | : QGraphicsObject(parent) | |
|
14 |
|
|
|
15 | ,mSize(0,0) | |
|
16 |
|
|
|
17 | ,mMarkerBoundingRect(0,0,0,0) | |
|
18 | ,mSeries(series) | |
|
19 |
|
|
|
20 | ,mPieslice(0) | |
|
21 | ,mType(LegendMarkerTypeSeries) | |
|
22 | ,mTextItem(new QGraphicsSimpleTextItem(this)) | |
|
23 | { | |
|
24 | setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton); | |
|
25 | } | |
|
12 | LegendMarker::LegendMarker(QSeries *series, QGraphicsItem *parent) : QGraphicsObject(parent), | |
|
13 | mPos(0,0), | |
|
14 | mSize(0,0), | |
|
15 | mBoundingRect(0,0,0,0), | |
|
16 | mMarkerBoundingRect(0,0,0,0), | |
|
17 | mSeries(series), | |
|
18 | mBarset(0), | |
|
19 | mPieslice(0), | |
|
20 | mType(LegendMarkerTypeSeries), | |
|
21 | mTextItem(new QGraphicsSimpleTextItem(this)) | |
|
22 | { | |
|
23 | setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton); | |
|
24 | } | |
|
26 | 25 | |
|
27 | LegendMarker::LegendMarker(QSeries *series, QBarSet *barset, QGraphicsItem *parent) | |
|
28 | : QGraphicsObject(parent) | |
|
29 |
|
|
|
30 | ,mSize(0,0) | |
|
31 |
|
|
|
32 | ,mMarkerBoundingRect(0,0,0,0) | |
|
33 | ,mSeries(series) | |
|
34 | ,mBarset(barset) | |
|
35 | ,mPieslice(0) | |
|
36 | ,mType(LegendMarkerTypeBarset) | |
|
37 | ,mTextItem(new QGraphicsSimpleTextItem(this)) | |
|
38 | { | |
|
39 | setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton); | |
|
40 | } | |
|
26 | LegendMarker::LegendMarker(QSeries *series, QBarSet *barset, QGraphicsItem *parent) : QGraphicsObject(parent), | |
|
27 | mPos(0,0), | |
|
28 | mSize(0,0), | |
|
29 | mBoundingRect(0,0,0,0), | |
|
30 | mMarkerBoundingRect(0,0,0,0), | |
|
31 | mSeries(series), | |
|
32 | mBarset(barset), | |
|
33 | mPieslice(0), | |
|
34 | mType(LegendMarkerTypeBarset), | |
|
35 | mTextItem(new QGraphicsSimpleTextItem(this)) | |
|
36 | { | |
|
37 | setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton); | |
|
38 | } | |
|
41 | 39 | |
|
42 | LegendMarker::LegendMarker(QSeries *series, QPieSlice *pieslice, QGraphicsItem *parent) | |
|
43 | : QGraphicsObject(parent) | |
|
44 |
|
|
|
45 | ,mSize(0,0) | |
|
46 |
|
|
|
47 | ,mMarkerBoundingRect(0,0,0,0) | |
|
48 | ,mSeries(series) | |
|
49 | ,mBarset(0) | |
|
50 | ,mPieslice(pieslice) | |
|
51 | ,mType(LegendMarkerTypePieslice) | |
|
52 | ,mTextItem(new QGraphicsSimpleTextItem(this)) | |
|
53 | { | |
|
54 | setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton); | |
|
55 | } | |
|
40 | LegendMarker::LegendMarker(QSeries *series, QPieSlice *pieslice, QGraphicsItem *parent) : QGraphicsObject(parent), | |
|
41 | mPos(0,0), | |
|
42 | mSize(0,0), | |
|
43 | mBoundingRect(0,0,0,0), | |
|
44 | mMarkerBoundingRect(0,0,0,0), | |
|
45 | mSeries(series), | |
|
46 | mBarset(0), | |
|
47 | mPieslice(pieslice), | |
|
48 | mType(LegendMarkerTypePieslice), | |
|
49 | mTextItem(new QGraphicsSimpleTextItem(this)) | |
|
50 | { | |
|
51 | setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton); | |
|
52 | } | |
|
56 | 53 | |
|
57 | 54 | void LegendMarker::setPos(qreal x, qreal y) |
|
58 | 55 | { |
|
59 | 56 | mPos = QPointF(x,y); |
|
60 | 57 | layoutChanged(); |
|
61 | 58 | } |
|
62 | 59 | |
|
63 | void LegendMarker::setPen(const QPen pen) | |
|
60 | void LegendMarker::setPen(const QPen &pen) | |
|
64 | 61 | { |
|
65 | 62 | mPen = pen; |
|
66 | 63 | } |
|
67 | 64 | |
|
68 | 65 | QPen LegendMarker::pen() const |
|
69 | 66 | { |
|
70 | 67 | return mPen; |
|
71 | 68 | } |
|
72 | 69 | |
|
73 | void LegendMarker::setBrush(const QBrush brush) | |
|
70 | void LegendMarker::setBrush(const QBrush &brush) | |
|
74 | 71 | { |
|
75 | 72 | mBrush = brush; |
|
76 | 73 | } |
|
77 | 74 | |
|
78 | 75 | QBrush LegendMarker::brush() const |
|
79 | 76 | { |
|
80 | 77 | return mBrush; |
|
81 | 78 | } |
|
82 | 79 | |
|
83 | 80 | void LegendMarker::setName(const QString name) |
|
84 | 81 | { |
|
85 | 82 | mTextItem.setText(name); |
|
86 | 83 | layoutChanged(); |
|
87 | 84 | } |
|
88 | 85 | |
|
89 | 86 | QString LegendMarker::name() const |
|
90 | 87 | { |
|
91 | 88 | return mTextItem.text(); |
|
92 | 89 | } |
|
93 | 90 | |
|
94 | 91 | QSeries* LegendMarker::series() const |
|
95 | 92 | { |
|
96 | 93 | return mSeries; |
|
97 | 94 | } |
|
98 | 95 | |
|
99 | 96 | void LegendMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) |
|
100 | 97 | { |
|
101 | 98 | Q_UNUSED(option) |
|
102 | 99 | Q_UNUSED(widget) |
|
103 | 100 | |
|
104 | 101 | painter->setPen(mPen); |
|
105 | 102 | painter->setBrush(mBrush); |
|
106 | 103 | painter->drawRect(mMarkerBoundingRect); |
|
107 | 104 | } |
|
108 | 105 | |
|
109 | 106 | QRectF LegendMarker::boundingRect() const |
|
110 | 107 | { |
|
111 | 108 | return mBoundingRect; |
|
112 | 109 | } |
|
113 | 110 | |
|
114 | 111 | void LegendMarker::layoutChanged() |
|
115 | 112 | { |
|
116 | 113 | QSizeF markerSize(10,10); |
|
117 | 114 | qreal margin = 2; |
|
118 | 115 | |
|
119 | 116 | mSize.setHeight(markerSize.height() + 2 * margin); |
|
120 | 117 | mSize.setWidth(mTextItem.boundingRect().width() + markerSize.width() + 3 * margin); |
|
121 | 118 | |
|
122 | 119 | mBoundingRect = QRectF(mPos.x(),mPos.y(),mSize.width(),mSize.height()); |
|
123 | 120 | |
|
124 | 121 | mMarkerBoundingRect = QRectF(mPos.x() + margin, mPos.y() + margin, markerSize.width(),markerSize.height()); |
|
125 | 122 | |
|
126 | 123 | mTextItem.setPos(mPos.x() + markerSize.width() + 2 * margin, mPos.y() + margin); |
|
127 | 124 | } |
|
128 | 125 | |
|
129 | 126 | void LegendMarker::mousePressEvent(QGraphicsSceneMouseEvent *event) |
|
130 | 127 | { |
|
131 | 128 | switch (mType) |
|
132 | 129 | { |
|
133 | 130 | case LegendMarkerTypeSeries: { |
|
134 | 131 | emit clicked(mSeries,event->button()); |
|
135 | 132 | break; |
|
136 | 133 | } |
|
137 | 134 | case LegendMarkerTypeBarset: { |
|
138 | 135 | emit clicked(mBarset,event->button()); |
|
139 | 136 | break; |
|
140 | 137 | } |
|
141 | 138 | case LegendMarkerTypePieslice: { |
|
142 | 139 | emit clicked(mPieslice,event->button()); |
|
143 | 140 | break; |
|
144 | 141 | } |
|
145 | 142 | default: { |
|
146 | 143 | break; |
|
147 | 144 | } |
|
148 | 145 | } |
|
149 | 146 | } |
|
150 | 147 | |
|
151 | 148 | void LegendMarker::changed() |
|
152 | 149 | { |
|
153 | 150 | switch (mType) |
|
154 | 151 | { |
|
155 | 152 | case LegendMarkerTypeSeries: { |
|
156 | 153 | QXYSeries* s = static_cast<QXYSeries*> (mSeries); |
|
157 | 154 | setBrush(s->brush()); |
|
158 | 155 | setName(s->name()); |
|
159 | 156 | break; |
|
160 | 157 | } |
|
161 | 158 | case LegendMarkerTypeBarset: { |
|
162 | 159 | setBrush(mBarset->brush()); |
|
163 | 160 | setName(mBarset->name()); |
|
164 | 161 | break; |
|
165 | 162 | } |
|
166 | 163 | case LegendMarkerTypePieslice: { |
|
167 | 164 | setBrush(mPieslice->brush()); |
|
168 | 165 | setName(mPieslice->label()); |
|
169 | 166 | break; |
|
170 | 167 | } |
|
171 | 168 | } |
|
172 | 169 | } |
|
173 | 170 | |
|
174 | 171 | #include "moc_legendmarker_p.cpp" |
|
175 | 172 | |
|
176 | 173 | QTCOMMERCIALCHART_END_NAMESPACE |
@@ -1,81 +1,81 | |||
|
1 | 1 | #ifndef LEGENDMARKER_P_H |
|
2 | 2 | #define LEGENDMARKER_P_H |
|
3 | 3 | |
|
4 | 4 | #include "qchartglobal.h" |
|
5 | 5 | #include <QGraphicsObject> |
|
6 | 6 | #include <QBrush> |
|
7 | 7 | #include <QPen> |
|
8 | 8 | #include <QGraphicsSimpleTextItem> |
|
9 | 9 | |
|
10 | 10 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
11 | 11 | |
|
12 | 12 | class QSeries; |
|
13 | 13 | class QBarSet; |
|
14 | 14 | class QPieSlice; |
|
15 | 15 | |
|
16 | 16 | // TODO: split this to 3 different markers for series, barset and pieslice. Current implementation is easier to misuse... |
|
17 | 17 | class LegendMarker : public QGraphicsObject |
|
18 | 18 | { |
|
19 | 19 | Q_OBJECT |
|
20 | 20 | |
|
21 | 21 | enum LegendMarkerType { |
|
22 | 22 | LegendMarkerTypeSeries, |
|
23 | 23 | LegendMarkerTypeBarset, |
|
24 | 24 | LegendMarkerTypePieslice |
|
25 | 25 | }; |
|
26 | 26 | |
|
27 | 27 | public: |
|
28 |
LegendMarker(QSeries* |
|
|
29 |
LegendMarker(QSeries* |
|
|
30 |
LegendMarker(QSeries* |
|
|
28 | LegendMarker(QSeries *series, QGraphicsItem *parent = 0); | |
|
29 | LegendMarker(QSeries *series, QBarSet *barset, QGraphicsItem *parent = 0); | |
|
30 | LegendMarker(QSeries *series, QPieSlice *pieslice, QGraphicsItem *parent = 0); | |
|
31 | 31 | |
|
32 | 32 | void setPos(qreal x, qreal y); |
|
33 | 33 | |
|
34 | void setPen(const QPen pen); | |
|
34 | void setPen(const QPen &pen); | |
|
35 | 35 | QPen pen() const; |
|
36 | 36 | |
|
37 | void setBrush(const QBrush brush); | |
|
37 | void setBrush(const QBrush &brush); | |
|
38 | 38 | QBrush brush() const; |
|
39 | 39 | |
|
40 | 40 | void setName(const QString name); |
|
41 | 41 | QString name() const; |
|
42 | 42 | |
|
43 | 43 | QSeries* series() const; |
|
44 | 44 | |
|
45 | 45 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); |
|
46 | 46 | |
|
47 | 47 | QRectF boundingRect() const; |
|
48 | 48 | |
|
49 | 49 | void layoutChanged(); |
|
50 | 50 | |
|
51 | 51 | public: |
|
52 | 52 | // From QGraphicsObject |
|
53 | 53 | void mousePressEvent(QGraphicsSceneMouseEvent *event); |
|
54 | 54 | |
|
55 | 55 | Q_SIGNALS: |
|
56 |
void clicked(QSeries* |
|
|
57 |
void clicked(QBarSet* |
|
|
58 |
void clicked(QPieSlice* |
|
|
56 | void clicked(QSeries *series, Qt::MouseButton button); | |
|
57 | void clicked(QBarSet *barset, Qt::MouseButton button); | |
|
58 | void clicked(QPieSlice *pieslice, Qt::MouseButton button); | |
|
59 | 59 | |
|
60 | 60 | public Q_SLOTS: |
|
61 | 61 | void changed(); |
|
62 | 62 | |
|
63 | 63 | private: |
|
64 | 64 | QPointF mPos; |
|
65 | 65 | QSize mSize; |
|
66 | 66 | QRectF mBoundingRect; |
|
67 | 67 | QRectF mMarkerBoundingRect; |
|
68 | 68 | QBrush mBrush; |
|
69 | 69 | QPen mPen; |
|
70 | 70 | |
|
71 |
QSeries* |
|
|
72 |
QBarSet* |
|
|
73 |
QPieSlice* |
|
|
71 | QSeries *mSeries; | |
|
72 | QBarSet *mBarset; | |
|
73 | QPieSlice *mPieslice; | |
|
74 | 74 | |
|
75 | 75 | LegendMarkerType mType; |
|
76 | 76 | QGraphicsSimpleTextItem mTextItem; |
|
77 | 77 | |
|
78 | 78 | }; |
|
79 | 79 | |
|
80 | 80 | QTCOMMERCIALCHART_END_NAMESPACE |
|
81 | 81 | #endif // LEGENDMARKER_P_H |
@@ -1,96 +1,85 | |||
|
1 | 1 | #include "qlineseries.h" |
|
2 | 2 | |
|
3 | 3 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
4 | 4 | |
|
5 | 5 | /*! |
|
6 | 6 | \class QLineSeries |
|
7 | 7 | \brief The QLineSeries class is used for making line charts. |
|
8 | 8 | |
|
9 | 9 | \mainclass |
|
10 | 10 | |
|
11 | 11 | A line chart is used to show information as a series of data points |
|
12 | 12 | connected by straight lines. |
|
13 | 13 | |
|
14 | 14 | \image linechart.png |
|
15 | 15 | |
|
16 | 16 | Creating basic line chart is simple: |
|
17 | 17 | \code |
|
18 | 18 | QLineSeries* series = new QLineSeries(); |
|
19 | 19 | series->add(0, 6); |
|
20 | 20 | series->add(2, 4); |
|
21 | 21 | ... |
|
22 | 22 | chartView->addSeries(series); |
|
23 | 23 | \endcode |
|
24 | 24 | */ |
|
25 | 25 | |
|
26 | 26 | /*! |
|
27 | 27 | \fn virtual QSeriesType QLineSeries::type() const |
|
28 | 28 | \brief Returns type of series. |
|
29 | 29 | \sa QSeries, QSeriesType |
|
30 | 30 | */ |
|
31 | 31 | |
|
32 | 32 | /*! |
|
33 | 33 | \fn bool QLineSeries::pointsVisible() const |
|
34 | 34 | \brief Returns if the points are drawn for this series. |
|
35 | 35 | \sa setPointsVisible() |
|
36 | 36 | */ |
|
37 | 37 | |
|
38 | 38 | /*! |
|
39 | 39 | \fn QPen QLineSeries::linePen() const |
|
40 | 40 | \brief Returns the pen used to draw line connecting points. |
|
41 | 41 | \sa setPen() |
|
42 | 42 | */ |
|
43 | 43 | |
|
44 | 44 | /*! |
|
45 | 45 | Constructs empty series object which is a child of \a parent. |
|
46 | 46 | When series object is added to QChartView or QChart instance ownerships is transfered. |
|
47 | 47 | */ |
|
48 | 48 | QLineSeries::QLineSeries(QObject *parent) : QXYSeries(parent), |
|
49 | 49 | m_pointsVisible(false) |
|
50 | 50 | { |
|
51 | 51 | |
|
52 | 52 | } |
|
53 | 53 | /*! |
|
54 | 54 | Destroys the object. Series added to QChartView or QChart instances are owned by those, |
|
55 | 55 | and are deleted when mentioned object are destroyed. |
|
56 | 56 | */ |
|
57 | 57 | QLineSeries::~QLineSeries() |
|
58 | 58 | { |
|
59 | 59 | } |
|
60 | 60 | |
|
61 | 61 | /*! |
|
62 | Sets \a pen used for drawing line connecting points. | |
|
63 | */ | |
|
64 | void QLineSeries::setLinePen(const QPen &pen) | |
|
65 | { | |
|
66 | if (pen != m_pen){ | |
|
67 | m_pen = pen; | |
|
68 | emit QXYSeries::updated(); | |
|
69 | } | |
|
70 | } | |
|
71 | ||
|
72 | /*! | |
|
73 | 62 | Sets if data points are \a visible and should be drawn on line. |
|
74 | 63 | */ |
|
75 | 64 | void QLineSeries::setPointsVisible(bool visible) |
|
76 | 65 | { |
|
77 | 66 | if (m_pointsVisible != visible){ |
|
78 | 67 | m_pointsVisible = visible; |
|
79 | 68 | emit QXYSeries::updated(); |
|
80 | 69 | } |
|
81 | 70 | } |
|
82 | 71 | |
|
83 | 72 | |
|
84 | 73 | QDebug operator<< (QDebug debug, const QLineSeries series) |
|
85 | 74 | { |
|
86 | 75 | Q_ASSERT(series.m_x.size() == series.m_y.size()); |
|
87 | 76 | |
|
88 | 77 | int size = series.m_x.size(); |
|
89 | 78 | |
|
90 | 79 | for (int i=0; i<size; i++) { |
|
91 | 80 | debug.nospace() << "(" << series.m_x.at(i) << ','<< series.m_y.at(i) << ") "; |
|
92 | 81 | } |
|
93 | 82 | return debug.space(); |
|
94 | 83 | } |
|
95 | 84 | |
|
96 | 85 | QTCOMMERCIALCHART_END_NAMESPACE |
@@ -1,33 +1,29 | |||
|
1 | 1 | #ifndef QLINESERIES_H_ |
|
2 | 2 | #define QLINESERIES_H_ |
|
3 | 3 | |
|
4 | 4 | #include <qchartglobal.h> |
|
5 | 5 | #include <qxyseries.h> |
|
6 | 6 | #include <QPen> |
|
7 | 7 | |
|
8 | 8 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
9 | 9 | |
|
10 | 10 | class QTCOMMERCIALCHART_EXPORT QLineSeries : public QXYSeries |
|
11 | 11 | { |
|
12 | 12 | public: |
|
13 | 13 | QLineSeries(QObject *parent=0); |
|
14 | 14 | virtual ~QLineSeries(); |
|
15 | 15 | |
|
16 | void setLinePen(const QPen &pen); | |
|
17 | QPen linePen() const {return m_pen;} | |
|
18 | ||
|
19 | 16 | void setPointsVisible(bool visible); |
|
20 | 17 | bool pointsVisible() const {return m_pointsVisible;} |
|
21 | 18 | |
|
22 | 19 | public: // from QChartSeries |
|
23 | 20 | virtual QSeriesType type() const {return QSeries::SeriesTypeLine;} |
|
24 | 21 | friend QDebug operator<< (QDebug d, const QLineSeries series); |
|
25 | 22 | private: |
|
26 | QPen m_pen; | |
|
27 | 23 | bool m_pointsVisible; |
|
28 | 24 | |
|
29 | 25 | }; |
|
30 | 26 | |
|
31 | 27 | QTCOMMERCIALCHART_END_NAMESPACE |
|
32 | 28 | |
|
33 | 29 | #endif |
@@ -1,459 +1,459 | |||
|
1 | 1 | /**************************************************************************** |
|
2 | 2 | ** |
|
3 | 3 | ** Copyright (C) 2012 Digia Plc |
|
4 | 4 | ** All rights reserved. |
|
5 | 5 | ** For any questions to Digia, please use contact form at http://qt.digia.com |
|
6 | 6 | ** |
|
7 | 7 | ** This file is part of the Qt Commercial Charts Add-on. |
|
8 | 8 | ** |
|
9 | 9 | ** $QT_BEGIN_LICENSE$ |
|
10 | 10 | ** Licensees holding valid Qt Commercial licenses may use this file in |
|
11 | 11 | ** accordance with the Qt Commercial License Agreement provided with the |
|
12 | 12 | ** Software or, alternatively, in accordance with the terms contained in |
|
13 | 13 | ** a written agreement between you and Digia. |
|
14 | 14 | ** |
|
15 | 15 | ** If you have questions regarding the use of this file, please use |
|
16 | 16 | ** contact form at http://qt.digia.com |
|
17 | 17 | ** $QT_END_LICENSE$ |
|
18 | 18 | ** |
|
19 | 19 | ****************************************************************************/ |
|
20 | 20 | |
|
21 | 21 | #include "qchart.h" |
|
22 | 22 | #include "qchart_p.h" |
|
23 | 23 | #include <QGraphicsScene> |
|
24 | 24 | #include <QGraphicsSceneResizeEvent> |
|
25 | 25 | |
|
26 | 26 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
27 | 27 | |
|
28 | 28 | /*! |
|
29 | 29 | \enum QChart::ChartTheme |
|
30 | 30 | |
|
31 | 31 | This enum describes the theme used by the chart. |
|
32 | 32 | |
|
33 | 33 | \value ChartThemeDefault Follows the GUI style of the Operating System |
|
34 | 34 | \value ChartThemeLight |
|
35 | 35 | \value ChartThemeBlueCerulean |
|
36 | 36 | \value ChartThemeDark |
|
37 | 37 | \value ChartThemeBrownSand |
|
38 | 38 | \value ChartThemeBlueNcs |
|
39 | 39 | \value ChartThemeHighContrast |
|
40 | 40 | \value ChartThemeBlueIcy |
|
41 | 41 | \value ChartThemeCount Not really a theme; the total count of themes. |
|
42 | 42 | */ |
|
43 | 43 | |
|
44 | 44 | /*! |
|
45 | 45 | \enum QChart::AnimationOption |
|
46 | 46 | |
|
47 | 47 | For enabling/disabling animations. Defaults to NoAnimation. |
|
48 | 48 | |
|
49 | 49 | \value NoAnimation |
|
50 | 50 | \value GridAxisAnimations |
|
51 | 51 | \value SeriesAnimations |
|
52 | 52 | \value AllAnimations |
|
53 | 53 | */ |
|
54 | 54 | |
|
55 | 55 | /*! |
|
56 | 56 | \class QChart |
|
57 | 57 | \brief QtCommercial chart API. |
|
58 | 58 | |
|
59 | 59 | QChart is a QGraphicsWidget that you can show in a QGraphicsScene. It manages the graphical |
|
60 | 60 | representation of different types of QChartSeries and other chart related objects like |
|
61 | 61 | QChartAxis and QChartLegend. If you simply want to show a chart in a layout, you can use the |
|
62 | 62 | convenience class QChartView instead of QChart. |
|
63 | 63 | \sa QChartView |
|
64 | 64 | */ |
|
65 | 65 | |
|
66 | 66 | /*! |
|
67 | 67 | Constructs a chart object which is a child of a\a parent. Parameter \a wFlags is passed to the QGraphicsWidget constructor. |
|
68 | 68 | */ |
|
69 | 69 | QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags) : QGraphicsWidget(parent,wFlags), |
|
70 | 70 | d_ptr(new QChartPrivate(this)) |
|
71 | 71 | { |
|
72 | 72 | d_ptr->m_legend = new QLegend(this); |
|
73 | 73 | d_ptr->m_dataset = new ChartDataSet(this); |
|
74 | 74 | d_ptr->m_presenter = new ChartPresenter(this,d_ptr->m_dataset); |
|
75 | 75 | |
|
76 | 76 | connect(d_ptr->m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),d_ptr->m_legend,SLOT(handleSeriesAdded(QSeries*,Domain*))); |
|
77 | 77 | connect(d_ptr->m_dataset,SIGNAL(seriesRemoved(QSeries*)),d_ptr->m_legend,SLOT(handleSeriesRemoved(QSeries*))); |
|
78 | 78 | } |
|
79 | 79 | |
|
80 | 80 | /*! |
|
81 | 81 | Destroys the object and it's children, like QChartSeries and QChartAxis object added to it. |
|
82 | 82 | */ |
|
83 | 83 | QChart::~QChart() |
|
84 | 84 | { |
|
85 | 85 | //delete first presenter , since this is a root of all the graphical items |
|
86 | 86 | delete d_ptr->m_presenter; |
|
87 | 87 | d_ptr->m_presenter=0; |
|
88 | 88 | } |
|
89 | 89 | |
|
90 | 90 | /*! |
|
91 | 91 | Adds the \a series and optional \a axisY onto the chart and takes the ownership of the objects. |
|
92 | 92 | If auto scaling is enabled, re-scales the axes the series is bound to (both the x axis and |
|
93 | 93 | the y axis). |
|
94 | 94 | */ |
|
95 | 95 | void QChart::addSeries(QSeries* series, QChartAxis* axisY) |
|
96 | 96 | { |
|
97 | 97 | d_ptr->m_dataset->addSeries(series, axisY); |
|
98 | 98 | } |
|
99 | 99 | |
|
100 | 100 | /*! |
|
101 | 101 | Removes the \a series specified in a perameter from the QChartView. |
|
102 | 102 | It releses its ownership of the specified QChartSeries object. |
|
103 | 103 | It does not delete the pointed QChartSeries data object |
|
104 | 104 | \sa addSeries(), removeAllSeries() |
|
105 | 105 | */ |
|
106 | 106 | void QChart::removeSeries(QSeries* series) |
|
107 | 107 | { |
|
108 | 108 | d_ptr->m_dataset->removeSeries(series); |
|
109 | 109 | } |
|
110 | 110 | |
|
111 | 111 | /*! |
|
112 | 112 | Removes all the QChartSeries that have been added to the QChartView |
|
113 | 113 | It also deletes the pointed QChartSeries data objects |
|
114 | 114 | \sa addSeries(), removeSeries() |
|
115 | 115 | */ |
|
116 | 116 | void QChart::removeAllSeries() |
|
117 | 117 | { |
|
118 | 118 | d_ptr->m_dataset->removeAllSeries(); |
|
119 | 119 | } |
|
120 | 120 | |
|
121 | 121 | /*! |
|
122 | 122 | Sets the \a brush that is used for painting the background of the chart area. |
|
123 | 123 | */ |
|
124 | 124 | void QChart::setBackgroundBrush(const QBrush& brush) |
|
125 | 125 | { |
|
126 | 126 | d_ptr->createChartBackgroundItem(); |
|
127 | 127 | d_ptr->m_backgroundItem->setBrush(brush); |
|
128 | 128 | d_ptr->m_backgroundItem->update(); |
|
129 | 129 | } |
|
130 | 130 | |
|
131 | 131 | QBrush QChart::backgroundBrush() const |
|
132 | 132 | { |
|
133 | 133 | if (!d_ptr->m_backgroundItem) return QBrush(); |
|
134 | 134 | return (d_ptr->m_backgroundItem)->brush(); |
|
135 | 135 | } |
|
136 | 136 | |
|
137 | 137 | /*! |
|
138 | 138 | Sets the \a pen that is used for painting the background of the chart area. |
|
139 | 139 | */ |
|
140 | 140 | void QChart::setBackgroundPen(const QPen& pen) |
|
141 | 141 | { |
|
142 | 142 | d_ptr->createChartBackgroundItem(); |
|
143 | 143 | d_ptr->m_backgroundItem->setPen(pen); |
|
144 | 144 | d_ptr->m_backgroundItem->update(); |
|
145 | 145 | } |
|
146 | 146 | |
|
147 | 147 | QPen QChart::backgroundPen() const |
|
148 | 148 | { |
|
149 | 149 | if (!d_ptr->m_backgroundItem) return QPen(); |
|
150 | 150 | return d_ptr->m_backgroundItem->pen(); |
|
151 | 151 | } |
|
152 | 152 | |
|
153 | 153 | /*! |
|
154 | 154 | Sets the chart \a title. The description text that is drawn above the chart. |
|
155 | 155 | */ |
|
156 | 156 | void QChart::setTitle(const QString& title) |
|
157 | 157 | { |
|
158 | 158 | d_ptr->createChartTitleItem(); |
|
159 | 159 | d_ptr->m_titleItem->setText(title); |
|
160 | 160 | d_ptr->updateLayout(); |
|
161 | 161 | } |
|
162 | 162 | |
|
163 | 163 | /*! |
|
164 | 164 | Returns the chart title. The description text that is drawn above the chart. |
|
165 | 165 | */ |
|
166 | 166 | QString QChart::title() const |
|
167 | 167 | { |
|
168 | 168 | if (d_ptr->m_titleItem) |
|
169 | 169 | return d_ptr->m_titleItem->text(); |
|
170 | 170 | else |
|
171 | 171 | return QString(); |
|
172 | 172 | } |
|
173 | 173 | |
|
174 | 174 | /*! |
|
175 | 175 | Sets the \a font that is used for rendering the description text that is rendered above the chart. |
|
176 | 176 | */ |
|
177 | 177 | void QChart::setTitleFont(const QFont& font) |
|
178 | 178 | { |
|
179 | 179 | d_ptr->createChartTitleItem(); |
|
180 | 180 | d_ptr->m_titleItem->setFont(font); |
|
181 | 181 | d_ptr->updateLayout(); |
|
182 | 182 | } |
|
183 | 183 | |
|
184 | 184 | /*! |
|
185 | 185 | Sets the \a brush used for rendering the title text. |
|
186 | 186 | */ |
|
187 | 187 | void QChart::setTitleBrush(const QBrush &brush) |
|
188 | 188 | { |
|
189 | 189 | d_ptr->createChartTitleItem(); |
|
190 | 190 | d_ptr->m_titleItem->setBrush(brush); |
|
191 | 191 | d_ptr->updateLayout(); |
|
192 | 192 | } |
|
193 | 193 | |
|
194 | 194 | /*! |
|
195 | 195 | Returns the brush used for rendering the title text. |
|
196 | 196 | */ |
|
197 | 197 | QBrush QChart::titleBrush() const |
|
198 | 198 | { |
|
199 | 199 | if (!d_ptr->m_titleItem) return QBrush(); |
|
200 | 200 | return d_ptr->m_titleItem->brush(); |
|
201 | 201 | } |
|
202 | 202 | |
|
203 | 203 | /*! |
|
204 | 204 | Sets the \a theme used by the chart for rendering the graphical representation of the data |
|
205 | 205 | \sa ChartTheme, chartTheme() |
|
206 | 206 | */ |
|
207 | 207 | void QChart::setTheme(QChart::ChartTheme theme) |
|
208 | 208 | { |
|
209 | 209 | d_ptr->m_presenter->setTheme(theme); |
|
210 | 210 | } |
|
211 | 211 | |
|
212 | 212 | /*! |
|
213 | 213 | Returns the theme enum used by the chart. |
|
214 | 214 | \sa ChartTheme, setChartTheme() |
|
215 | 215 | */ |
|
216 | 216 | QChart::ChartTheme QChart::theme() const |
|
217 | 217 | { |
|
218 | 218 | return d_ptr->m_presenter->theme(); |
|
219 | 219 | } |
|
220 | 220 | |
|
221 | 221 | /*! |
|
222 | 222 | Zooms in the view by a factor of 2 |
|
223 | 223 | */ |
|
224 | 224 | void QChart::zoomIn() |
|
225 | 225 | { |
|
226 | 226 | d_ptr->m_presenter->zoomIn(); |
|
227 | 227 | } |
|
228 | 228 | |
|
229 | 229 | /*! |
|
230 | 230 | Zooms in the view to a maximum level at which \a rect is still fully visible. |
|
231 | 231 | */ |
|
232 | 232 | void QChart::zoomIn(const QRectF& rect) |
|
233 | 233 | { |
|
234 | 234 | if (!rect.isValid()) return; |
|
235 | 235 | d_ptr->m_presenter->zoomIn(rect); |
|
236 | 236 | } |
|
237 | 237 | |
|
238 | 238 | /*! |
|
239 | 239 | Restores the view zoom level to the previous one. |
|
240 | 240 | */ |
|
241 | 241 | void QChart::zoomOut() |
|
242 | 242 | { |
|
243 | 243 | d_ptr->m_presenter->zoomOut(); |
|
244 | 244 | } |
|
245 | 245 | |
|
246 | 246 | /*! |
|
247 | 247 | Returns the pointer to the x axis object of the chart |
|
248 | 248 | */ |
|
249 | 249 | QChartAxis* QChart::axisX() const |
|
250 | 250 | { |
|
251 | 251 | return d_ptr->m_dataset->axisX(); |
|
252 | 252 | } |
|
253 | 253 | |
|
254 | 254 | /*! |
|
255 | 255 | Returns the pointer to the y axis object of the chart |
|
256 | 256 | */ |
|
257 | 257 | QChartAxis* QChart::axisY() const |
|
258 | 258 | { |
|
259 | 259 | return d_ptr->m_dataset->axisY(); |
|
260 | 260 | } |
|
261 | 261 | |
|
262 | 262 | /*! |
|
263 | 263 | Returns the legend object of the chart. Ownership stays in chart. |
|
264 | 264 | */ |
|
265 | 265 | QLegend& QChart::legend() const |
|
266 | 266 | { |
|
267 | 267 | return *d_ptr->m_legend; |
|
268 | 268 | } |
|
269 | 269 | |
|
270 | 270 | /*! |
|
271 | 271 | Gives ownership of legend to user. |
|
272 | 272 | */ |
|
273 | 273 | QLegend* QChart::takeLegend() |
|
274 | 274 | { |
|
275 | 275 | QLegend* l = d_ptr->m_legend; |
|
276 | 276 | d_ptr->m_legend = 0; |
|
277 | 277 | return l; |
|
278 | 278 | } |
|
279 | 279 | |
|
280 | 280 | /*! |
|
281 | 281 | Gives ownership of legend back to chart. QChart takes ownership of \a legend and deletes existing one |
|
282 | 282 | */ |
|
283 | 283 | void QChart::giveLegend(QLegend *legend) |
|
284 | 284 | { |
|
285 | 285 | if (d_ptr->m_legend) { |
|
286 | 286 | // Should not happen. |
|
287 | 287 | qDebug() << "Warning! Giving more than one legend to chart."; |
|
288 | 288 | delete d_ptr->m_legend; |
|
289 | 289 | } |
|
290 | 290 | |
|
291 | 291 | d_ptr->m_legend = legend; |
|
292 | 292 | |
|
293 | 293 | // Reconnect legend, in case not already connected. |
|
294 | 294 | disconnect(d_ptr->m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),d_ptr->m_legend,SLOT(handleSeriesAdded(QSeries*,Domain*))); |
|
295 | 295 | disconnect(d_ptr->m_dataset,SIGNAL(seriesRemoved(QSeries*)),d_ptr->m_legend,SLOT(handleSeriesRemoved(QSeries*))); |
|
296 | 296 | connect(d_ptr->m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),d_ptr->m_legend,SLOT(handleSeriesAdded(QSeries*,Domain*))); |
|
297 | 297 | connect(d_ptr->m_dataset,SIGNAL(seriesRemoved(QSeries*)),d_ptr->m_legend,SLOT(handleSeriesRemoved(QSeries*))); |
|
298 | 298 | } |
|
299 | 299 | |
|
300 | 300 | /*! |
|
301 | 301 | Resizes and updates the chart area using the \a event data |
|
302 | 302 | */ |
|
303 | 303 | void QChart::resizeEvent(QGraphicsSceneResizeEvent *event) |
|
304 | 304 | { |
|
305 | 305 | d_ptr->m_rect = QRectF(QPoint(0,0),event->newSize()); |
|
306 | 306 | d_ptr->updateLayout(); |
|
307 | 307 | QGraphicsWidget::resizeEvent(event); |
|
308 | 308 | update(); |
|
309 | 309 | } |
|
310 | 310 | |
|
311 | 311 | /*! |
|
312 | 312 | Sets animation \a options for the chart |
|
313 | 313 | */ |
|
314 | 314 | void QChart::setAnimationOptions(AnimationOptions options) |
|
315 | 315 | { |
|
316 | 316 | d_ptr->m_presenter->setAnimationOptions(options); |
|
317 | 317 | } |
|
318 | 318 | |
|
319 | 319 | /*! |
|
320 | 320 | Returns animation options for the chart |
|
321 | 321 | */ |
|
322 | 322 | QChart::AnimationOptions QChart::animationOptions() const |
|
323 | 323 | { |
|
324 | 324 | return d_ptr->m_presenter->animationOptions(); |
|
325 | 325 | } |
|
326 | 326 | |
|
327 | 327 | void QChart::scrollLeft() |
|
328 | 328 | { |
|
329 | 329 | d_ptr->m_presenter->scroll(-d_ptr->m_presenter->geometry().width()/(axisX()->ticksCount()-1),0); |
|
330 | 330 | } |
|
331 | 331 | |
|
332 | 332 | void QChart::scrollRight() |
|
333 | 333 | { |
|
334 | 334 | d_ptr->m_presenter->scroll(d_ptr->m_presenter->geometry().width()/(axisX()->ticksCount()-1),0); |
|
335 | 335 | } |
|
336 | 336 | |
|
337 | 337 | void QChart::scrollUp() |
|
338 | 338 | { |
|
339 | 339 | d_ptr->m_presenter->scroll(0,d_ptr->m_presenter->geometry().width()/(axisY()->ticksCount()-1)); |
|
340 | 340 | } |
|
341 | 341 | |
|
342 | 342 | void QChart::scrollDown() |
|
343 | 343 | { |
|
344 | 344 | d_ptr->m_presenter->scroll(0,-d_ptr->m_presenter->geometry().width()/(axisY()->ticksCount()-1)); |
|
345 | 345 | } |
|
346 | 346 | |
|
347 | 347 | void QChart::setBackgroundVisible(bool visible) |
|
348 | 348 | { |
|
349 | 349 | d_ptr->createChartBackgroundItem(); |
|
350 | 350 | d_ptr->m_backgroundItem->setVisible(visible); |
|
351 | 351 | } |
|
352 | 352 | |
|
353 | 353 | bool QChart::isBackgroundVisible() const |
|
354 | 354 | { |
|
355 | 355 | if (!d_ptr->m_backgroundItem) return false; |
|
356 | 356 | return d_ptr->m_backgroundItem->isVisible(); |
|
357 | 357 | } |
|
358 | 358 | |
|
359 | 359 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
360 | 360 | |
|
361 | 361 | QChartPrivate::QChartPrivate(QChart *parent): |
|
362 | 362 | q_ptr(parent), |
|
363 | 363 | m_backgroundItem(0), |
|
364 | 364 | m_titleItem(0), |
|
365 | 365 | m_legend(0), |
|
366 | 366 | m_dataset(0), |
|
367 | 367 | m_presenter(0) |
|
368 | 368 | { |
|
369 | 369 | |
|
370 | 370 | } |
|
371 | 371 | |
|
372 | 372 | QChartPrivate::~QChartPrivate() |
|
373 | 373 | { |
|
374 | 374 | |
|
375 | 375 | } |
|
376 | 376 | |
|
377 | 377 | void QChartPrivate::createChartBackgroundItem() |
|
378 | 378 | { |
|
379 | 379 | if (!m_backgroundItem) { |
|
380 | 380 | m_backgroundItem = new ChartBackground(q_ptr); |
|
381 | 381 | m_backgroundItem->setPen(Qt::NoPen); |
|
382 | 382 | m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue); |
|
383 | 383 | } |
|
384 | 384 | } |
|
385 | 385 | |
|
386 | 386 | void QChartPrivate::createChartTitleItem() |
|
387 | 387 | { |
|
388 | 388 | if (!m_titleItem) { |
|
389 | 389 | m_titleItem = new QGraphicsSimpleTextItem(q_ptr); |
|
390 | 390 | m_titleItem->setZValue(ChartPresenter::BackgroundZValue); |
|
391 | 391 | } |
|
392 | 392 | } |
|
393 | 393 | |
|
394 | 394 | void QChartPrivate::updateLegendLayout() |
|
395 | 395 | { |
|
396 | 396 | int padding = m_presenter->padding(); |
|
397 | 397 | QRectF plotRect = m_rect.adjusted(padding,padding,-padding,-padding); |
|
398 | 398 | QRectF legendRect; |
|
399 | 399 | |
|
400 |
switch (m_legend-> |
|
|
400 | switch (m_legend->alignment()) | |
|
401 | 401 | { |
|
402 |
case QLegend:: |
|
|
402 | case QLegend::LayoutTop: { | |
|
403 | 403 | // legendRect = plotRect.adjusted(m_padding,0,-m_padding,-m_padding - plotRect.height()); |
|
404 | 404 | legendRect = plotRect.adjusted(0,0,0,-padding - plotRect.height()); |
|
405 | 405 | break; |
|
406 | 406 | } |
|
407 |
case QLegend:: |
|
|
407 | case QLegend::LayoutBottom: { | |
|
408 | 408 | legendRect = plotRect.adjusted(padding,padding + plotRect.height(),-padding,0); |
|
409 | 409 | break; |
|
410 | 410 | } |
|
411 |
case QLegend:: |
|
|
411 | case QLegend::LayoutLeft: { | |
|
412 | 412 | legendRect = plotRect.adjusted(0,padding,-padding - plotRect.width(),-padding); |
|
413 | 413 | break; |
|
414 | 414 | } |
|
415 |
case QLegend:: |
|
|
415 | case QLegend::LayoutRight: { | |
|
416 | 416 | legendRect = plotRect.adjusted(padding + plotRect.width(),padding,0,-padding); |
|
417 | 417 | break; |
|
418 | 418 | } |
|
419 | 419 | default: { |
|
420 | 420 | legendRect = plotRect; |
|
421 | 421 | break; |
|
422 | 422 | } |
|
423 | 423 | } |
|
424 | 424 | |
|
425 | 425 | m_legend->setMaximumSize(legendRect.size()); |
|
426 | 426 | m_legend->setPos(legendRect.topLeft()); |
|
427 | 427 | } |
|
428 | 428 | |
|
429 | 429 | void QChartPrivate::updateLayout() |
|
430 | 430 | { |
|
431 | 431 | if (!m_rect.isValid()) return; |
|
432 | 432 | |
|
433 | 433 | int padding = m_presenter->padding(); |
|
434 | 434 | int backgroundPadding = m_presenter->backgroundPadding(); |
|
435 | 435 | |
|
436 | 436 | QRectF rect = m_rect.adjusted(padding,padding,-padding,-padding); |
|
437 | 437 | |
|
438 | 438 | // recalculate title position |
|
439 | 439 | if (m_titleItem) { |
|
440 | 440 | QPointF center = m_rect.center() -m_titleItem->boundingRect().center(); |
|
441 | 441 | m_titleItem->setPos(center.x(),m_rect.top()/2 + padding/2); |
|
442 | 442 | } |
|
443 | 443 | |
|
444 | 444 | //recalculate background gradient |
|
445 | 445 | if (m_backgroundItem) { |
|
446 | 446 | m_backgroundItem->setRect(m_rect.adjusted(backgroundPadding,backgroundPadding, -backgroundPadding, -backgroundPadding)); |
|
447 | 447 | } |
|
448 | 448 | |
|
449 | 449 | // recalculate legend position |
|
450 | 450 | if (m_legend) { |
|
451 | 451 | if (m_legend->parentObject() == q_ptr) { |
|
452 | 452 | updateLegendLayout(); |
|
453 | 453 | } |
|
454 | 454 | } |
|
455 | 455 | } |
|
456 | 456 | |
|
457 | 457 | #include "moc_qchart.cpp" |
|
458 | 458 | |
|
459 | 459 | QTCOMMERCIALCHART_END_NAMESPACE |
@@ -1,788 +1,706 | |||
|
1 | 1 | #include "qchartglobal.h" |
|
2 | 2 | #include "qlegend.h" |
|
3 | 3 | #include "qseries.h" |
|
4 | 4 | #include "legendmarker_p.h" |
|
5 | 5 | #include "legendscrollbutton_p.h" |
|
6 | 6 | #include "qxyseries.h" |
|
7 | 7 | #include "qlineseries.h" |
|
8 | 8 | #include "qareaseries.h" |
|
9 | 9 | #include "qscatterseries.h" |
|
10 | 10 | #include "qsplineseries.h" |
|
11 | 11 | #include "qbarseries.h" |
|
12 | 12 | #include "qstackedbarseries.h" |
|
13 | 13 | #include "qpercentbarseries.h" |
|
14 | 14 | #include "qbarset.h" |
|
15 | 15 | #include "qpieseries.h" |
|
16 | 16 | #include "qpieslice.h" |
|
17 | 17 | #include "chartpresenter_p.h" |
|
18 | 18 | #include <QPainter> |
|
19 | 19 | #include <QPen> |
|
20 | 20 | |
|
21 | 21 | #include <QGraphicsSceneEvent> |
|
22 | 22 | |
|
23 | 23 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
24 | 24 | |
|
25 | 25 | /*! |
|
26 | 26 | \class QLegend |
|
27 | 27 | \brief part of QtCommercial chart API. |
|
28 | 28 | |
|
29 | 29 | QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when |
|
30 | 30 | series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and |
|
31 | 31 | handle the drawing manually. |
|
32 | 32 | User isn't supposed to create or delete legend objects, but can reference it via QChart class. |
|
33 | 33 | |
|
34 | 34 | \mainclass |
|
35 | 35 | |
|
36 | 36 | \sa QChart, QSeries |
|
37 | 37 | */ |
|
38 | 38 | |
|
39 | 39 | /*! |
|
40 |
\enum QLegend:: |
|
|
40 | \enum QLegend::Layout | |
|
41 | 41 | |
|
42 | 42 | This enum describes the possible position for legend inside chart. |
|
43 | 43 | |
|
44 |
\value |
|
|
45 |
\value |
|
|
46 |
\value |
|
|
47 |
\value |
|
|
44 | \value LayoutTop | |
|
45 | \value LayoutBottom | |
|
46 | \value LayoutLeft | |
|
47 | \value LayoutRight | |
|
48 | 48 | */ |
|
49 | 49 | |
|
50 | 50 | |
|
51 | 51 | /*! |
|
52 | 52 | \fn void QLegend::clicked(QSeries* series, Qt::MouseButton button) |
|
53 | 53 | \brief Notifies when series has been clicked on legend \a series \a button |
|
54 | 54 | */ |
|
55 | 55 | |
|
56 | 56 | /*! |
|
57 | 57 | \fn void QLegend::clicked(QBarSet* barset, Qt::MouseButton button) |
|
58 | 58 | \brief Notifies when barset has been clicked on legend \a barset \a button |
|
59 | 59 | */ |
|
60 | 60 | |
|
61 | 61 | /*! |
|
62 | 62 | \fn void QLegend::clicked(QPieSlice* slice, Qt::MouseButton button) |
|
63 | 63 | \brief Notifies when pie slice has been clicked on legend \a slice \a button |
|
64 | 64 | */ |
|
65 | 65 | |
|
66 | 66 | /*! |
|
67 | 67 | Constructs the legend object and sets the parent to \a parent |
|
68 | 68 | */ |
|
69 | 69 | QLegend::QLegend(QGraphicsItem *parent) : QGraphicsObject(parent), |
|
70 |
m_ |
|
|
71 |
m_ |
|
|
72 |
m_ |
|
|
73 |
m_ |
|
|
70 | m_pos(0,0), | |
|
71 | m_size(0,0), | |
|
72 | m_minimumSize(50,20), // TODO: magic numbers | |
|
73 | m_maximumSize(150,100), | |
|
74 | 74 | m_brush(Qt::darkGray), // TODO: from theme? |
|
75 |
m_ |
|
|
75 | m_alignment(QLegend::LayoutTop), | |
|
76 | 76 | mFirstMarker(0), |
|
77 |
m_ |
|
|
77 | m_margin(5) | |
|
78 | 78 | { |
|
79 |
m_ |
|
|
80 |
m_ |
|
|
81 |
m_ |
|
|
82 |
m_ |
|
|
79 | m_scrollButtonLeft = new LegendScrollButton(LegendScrollButton::ScrollButtonIdLeft, this); | |
|
80 | m_scrollButtonRight = new LegendScrollButton(LegendScrollButton::ScrollButtonIdRight, this); | |
|
81 | m_scrollButtonUp = new LegendScrollButton(LegendScrollButton::ScrollButtonIdUp, this); | |
|
82 | m_scrollButtonDown = new LegendScrollButton(LegendScrollButton::ScrollButtonIdDown, this); | |
|
83 | 83 | |
|
84 |
connect(m_ |
|
|
84 | connect(m_scrollButtonLeft, SIGNAL(clicked(QGraphicsSceneMouseEvent*)), | |
|
85 | 85 | this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*))); |
|
86 |
connect(m_ |
|
|
86 | connect(m_scrollButtonRight, SIGNAL(clicked(QGraphicsSceneMouseEvent*)), | |
|
87 | 87 | this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*))); |
|
88 |
connect(m_ |
|
|
88 | connect(m_scrollButtonUp, SIGNAL(clicked(QGraphicsSceneMouseEvent*)), | |
|
89 | 89 | this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*))); |
|
90 |
connect(m_ |
|
|
90 | connect(m_scrollButtonDown, SIGNAL(clicked(QGraphicsSceneMouseEvent*)), | |
|
91 | 91 | this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*))); |
|
92 | 92 | |
|
93 | 93 | setZValue(ChartPresenter::LegendZValue); |
|
94 | 94 | } |
|
95 | 95 | |
|
96 | 96 | /*! |
|
97 | 97 | Paints the legend to given \a painter. Paremeters \a option and \a widget arent used. |
|
98 | 98 | */ |
|
99 | 99 | void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) |
|
100 | 100 | { |
|
101 | 101 | Q_UNUSED(option) |
|
102 | 102 | Q_UNUSED(widget) |
|
103 | 103 | |
|
104 | 104 | painter->setOpacity(opacity()); |
|
105 | 105 | painter->setPen(m_pen); |
|
106 | 106 | painter->setBrush(m_brush); |
|
107 | 107 | painter->drawRect(boundingRect()); |
|
108 | 108 | } |
|
109 | 109 | |
|
110 | 110 | /*! |
|
111 | 111 | Bounding rect of legend. |
|
112 | 112 | */ |
|
113 | 113 | QRectF QLegend::boundingRect() const |
|
114 | 114 | { |
|
115 |
return QRectF(m_ |
|
|
115 | return QRectF(m_pos,m_size); | |
|
116 | 116 | } |
|
117 | 117 | |
|
118 | 118 | /*! |
|
119 | 119 | Sets the \a brush of legend. Brush affects the background of legend. |
|
120 | 120 | */ |
|
121 | 121 | void QLegend::setBrush(const QBrush &brush) |
|
122 | 122 | { |
|
123 | 123 | if (m_brush != brush) { |
|
124 | 124 | m_brush = brush; |
|
125 | 125 | update(); |
|
126 | 126 | } |
|
127 | 127 | } |
|
128 | 128 | |
|
129 | 129 | /*! |
|
130 | 130 | Returns the brush used by legend. |
|
131 | 131 | */ |
|
132 | 132 | QBrush QLegend::brush() const |
|
133 | 133 | { |
|
134 | 134 | return m_brush; |
|
135 | 135 | } |
|
136 | 136 | |
|
137 | 137 | /*! |
|
138 | 138 | Sets the \a pen of legend. Pen affects the legend borders. |
|
139 | 139 | */ |
|
140 | 140 | void QLegend::setPen(const QPen &pen) |
|
141 | 141 | { |
|
142 | 142 | if (m_pen != pen) { |
|
143 | 143 | m_pen = pen; |
|
144 | 144 | update(); |
|
145 | 145 | } |
|
146 | 146 | } |
|
147 | 147 | |
|
148 | 148 | /*! |
|
149 | 149 | Returns the pen used by legend |
|
150 | 150 | */ |
|
151 | 151 | |
|
152 | 152 | QPen QLegend::pen() const |
|
153 | 153 | { |
|
154 | 154 | return m_pen; |
|
155 | 155 | } |
|
156 | 156 | |
|
157 | 157 | /*! |
|
158 | 158 | Sets the \a preferred layout for legend. Legend tries to paint itself on the defined position in chart. |
|
159 |
\sa QLegend:: |
|
|
159 | \sa QLegend::Layout | |
|
160 | 160 | */ |
|
161 |
void QLegend::set |
|
|
161 | void QLegend::setAlignmnent(QLegend::Layout alignment) | |
|
162 | 162 | { |
|
163 | m_PreferredLayout = preferred; | |
|
163 | m_alignment = alignment; | |
|
164 | 164 | updateLayout(); |
|
165 | 165 | } |
|
166 | 166 | |
|
167 | 167 | /*! |
|
168 | 168 | Returns the preferred layout for legend |
|
169 | 169 | */ |
|
170 |
QLegend:: |
|
|
170 | QLegend::Layout QLegend::alignment() const | |
|
171 | 171 | { |
|
172 |
return m_ |
|
|
172 | return m_alignment; | |
|
173 | 173 | } |
|
174 | 174 | |
|
175 | 175 | /*! |
|
176 | 176 | Returns the maximum size of legend. |
|
177 | 177 | */ |
|
178 | 178 | QSizeF QLegend::maximumSize() const |
|
179 | 179 | { |
|
180 |
return m_ |
|
|
180 | return m_maximumSize; | |
|
181 | 181 | } |
|
182 | 182 | |
|
183 | 183 | /*! |
|
184 | 184 | Sets the maximum \a size for legend. The legend can't grow bigger than this size. If there are |
|
185 | 185 | more series than legend can fit to this size, scroll buttons are displayed. |
|
186 | 186 | */ |
|
187 | 187 | void QLegend::setMaximumSize(const QSizeF size) |
|
188 | 188 | { |
|
189 |
m_ |
|
|
189 | m_maximumSize = size; | |
|
190 | 190 | updateLayout(); |
|
191 | 191 | } |
|
192 | 192 | |
|
193 | 193 | /*! |
|
194 | 194 | Returns the current size of legend. |
|
195 | 195 | */ |
|
196 | 196 | QSizeF QLegend::size() const |
|
197 | 197 | { |
|
198 |
return m_ |
|
|
198 | return m_size; | |
|
199 | 199 | } |
|
200 | 200 | |
|
201 | 201 | /*! |
|
202 | 202 | Sets the \a size of legend. If size is bigger than maximum size of legend, the legend is resized to the maximum size. |
|
203 | 203 | \sa setMmaximumSize() |
|
204 | 204 | */ |
|
205 | 205 | void QLegend::setSize(const QSizeF size) |
|
206 | 206 | { |
|
207 |
m_ |
|
|
208 |
if (m_ |
|
|
209 |
m_ |
|
|
207 | m_size = size; | |
|
208 | if (m_size.width() > m_maximumSize.width()) { | |
|
209 | m_size.setWidth(m_maximumSize.width()); | |
|
210 | 210 | } |
|
211 |
if (m_ |
|
|
212 |
m_ |
|
|
211 | if (m_size.height() > m_maximumSize.height()) { | |
|
212 | m_size.setHeight(m_maximumSize.height()); | |
|
213 | 213 | } |
|
214 | 214 | } |
|
215 | 215 | |
|
216 | 216 | /*! |
|
217 | 217 | Sets position of legend to \a pos |
|
218 | 218 | */ |
|
219 | 219 | void QLegend::setPos(const QPointF &pos) |
|
220 | 220 | { |
|
221 |
m_ |
|
|
221 | m_pos = pos; | |
|
222 | 222 | updateLayout(); |
|
223 | 223 | } |
|
224 | 224 | |
|
225 | 225 | /*! |
|
226 | 226 | \internal \a series \a domain Should be called when series is added to chart. |
|
227 | 227 | */ |
|
228 | 228 | void QLegend::handleSeriesAdded(QSeries *series, Domain *domain) |
|
229 | 229 | { |
|
230 | 230 | Q_UNUSED(domain) |
|
231 | 231 | |
|
232 | 232 | createMarkers(series); |
|
233 | 233 | connectSeries(series); |
|
234 | 234 | updateLayout(); |
|
235 | 235 | } |
|
236 | 236 | |
|
237 | 237 | /*! |
|
238 | 238 | \internal \a series Should be called when series is removed from chart. |
|
239 | 239 | */ |
|
240 | 240 | void QLegend::handleSeriesRemoved(QSeries *series) |
|
241 | 241 | { |
|
242 | 242 | disconnectSeries(series); |
|
243 | 243 | |
|
244 | if (series->type() == QSeries::SeriesTypeArea) | |
|
245 | { | |
|
244 | if (series->type() == QSeries::SeriesTypeArea) { | |
|
246 | 245 | // This is special case. Area series has upper and lower series, which each have markers |
|
247 | 246 | QAreaSeries* s = static_cast<QAreaSeries *> (series); |
|
248 | 247 | deleteMarkers(s->upperSeries()); |
|
249 | 248 | deleteMarkers(s->lowerSeries()); |
|
250 | 249 | } else { |
|
251 | 250 | deleteMarkers(series); |
|
252 | 251 | } |
|
253 | 252 | |
|
254 | 253 | updateLayout(); |
|
255 | 254 | } |
|
256 | 255 | |
|
257 | 256 | /*! |
|
258 | 257 | \internal \a slices Should be called when slices are added to pie chart. |
|
259 | 258 | */ |
|
260 | 259 | void QLegend::handleAdded(QList<QPieSlice *> slices) |
|
261 | 260 | { |
|
262 | 261 | QPieSeries* series = static_cast<QPieSeries *> (sender()); |
|
263 | 262 | foreach(QPieSlice* s, slices) { |
|
264 | 263 | LegendMarker* marker = new LegendMarker(series, s, this); |
|
265 | 264 | marker->setName(s->label()); |
|
266 | 265 | marker->setBrush(s->brush()); |
|
267 | 266 | connect(marker, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)), |
|
268 | 267 | this, SIGNAL(clicked(QPieSlice*,Qt::MouseButton))); |
|
269 | 268 | connect(s, SIGNAL(changed()), marker, SLOT(changed())); |
|
270 | 269 | connect(s, SIGNAL(destroyed()), marker, SLOT(deleteLater())); |
|
271 | 270 | connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed())); |
|
272 |
m_ |
|
|
271 | m_markers.append(marker); | |
|
273 | 272 | childItems().append(marker); |
|
274 | 273 | } |
|
275 | 274 | updateLayout(); |
|
276 | 275 | } |
|
277 | 276 | |
|
278 | 277 | /*! |
|
279 | 278 | \internal \a slices Should be called when slices are removed from pie chart. Currently unused, |
|
280 | 279 | because removed slices are also deleted and we listen destroyed signal |
|
281 | 280 | */ |
|
282 | 281 | void QLegend::handleRemoved(QList<QPieSlice *> slices) |
|
283 | 282 | { |
|
284 | 283 | Q_UNUSED(slices) |
|
285 | 284 | } |
|
286 | 285 | |
|
287 | 286 | |
|
288 | 287 | /*! |
|
289 | 288 | \internal Notifies legend that some marker has been removed. Sent by legend markers when destroyed |
|
290 | 289 | */ |
|
291 | 290 | void QLegend::handleMarkerDestroyed() |
|
292 | 291 | { |
|
293 | // TODO: what if more than one markers are destroyed and we update layout after first one? | |
|
294 | 292 | LegendMarker* m = static_cast<LegendMarker *> (sender()); |
|
295 |
m_ |
|
|
293 | m_markers.removeOne(m); | |
|
296 | 294 | updateLayout(); |
|
297 | 295 | } |
|
298 | 296 | |
|
299 | 297 | /*! |
|
300 | 298 | \internal \a event Handles clicked signals from scroll buttons |
|
301 | 299 | */ |
|
302 | 300 | void QLegend::handleScrollButtonClicked(QGraphicsSceneMouseEvent *event) |
|
303 | 301 | { |
|
304 | 302 | Q_UNUSED(event); // Maybe later something happens with right click... |
|
305 | 303 | |
|
306 | 304 | LegendScrollButton* scrollButton = static_cast<LegendScrollButton *> (sender()); |
|
307 | 305 | Q_ASSERT(scrollButton); |
|
308 | 306 | |
|
309 | 307 | switch (scrollButton->id()) { |
|
310 | 308 | case LegendScrollButton::ScrollButtonIdLeft: |
|
311 | 309 | case LegendScrollButton::ScrollButtonIdUp: { |
|
312 | 310 | // Lower limit is same in these cases |
|
313 | 311 | mFirstMarker--; |
|
314 | 312 | checkFirstMarkerBounds(); |
|
315 | 313 | break; |
|
316 | 314 | } |
|
317 | 315 | case LegendScrollButton::ScrollButtonIdRight: |
|
318 | 316 | case LegendScrollButton::ScrollButtonIdDown: { |
|
319 | 317 | mFirstMarker++; |
|
320 | 318 | checkFirstMarkerBounds(); |
|
321 | 319 | break; |
|
322 | 320 | } |
|
323 | 321 | default: { |
|
324 | 322 | break; |
|
325 | 323 | } |
|
326 | 324 | } |
|
327 | 325 | updateLayout(); |
|
328 | 326 | } |
|
329 | 327 | |
|
330 | 328 | /*! |
|
331 | 329 | \internal Connects the \a series to legend. Legend listens changes in series, for example pie slices added / removed. |
|
332 | 330 | Not all series notify about events |
|
333 | 331 | */ |
|
334 | 332 | void QLegend::connectSeries(QSeries *series) |
|
335 | 333 | { |
|
336 | // Connect relevant signals from series | |
|
337 | switch (series->type()) | |
|
338 | { | |
|
339 | case QSeries::SeriesTypeLine: { | |
|
340 | // QLineSeries* lineSeries = static_cast<QLineSeries*>(series); | |
|
341 | break; | |
|
342 | } | |
|
343 | case QSeries::SeriesTypeArea: { | |
|
344 | // QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series); | |
|
345 | break; | |
|
346 | } | |
|
347 | case QSeries::SeriesTypeBar: { | |
|
348 | // QBarSeries* barSeries = static_cast<QBarSeries*>(series); | |
|
349 | break; | |
|
350 | } | |
|
351 | case QSeries::SeriesTypeStackedBar: { | |
|
352 | // QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series); | |
|
353 | break; | |
|
354 | } | |
|
355 | case QSeries::SeriesTypePercentBar: { | |
|
356 | // QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series); | |
|
357 | break; | |
|
358 | } | |
|
359 | case QSeries::SeriesTypeScatter: { | |
|
360 | // QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series); | |
|
361 | break; | |
|
362 | } | |
|
363 | case QSeries::SeriesTypePie: { | |
|
334 | // Connect relevant signals from series. Currently only pie series has interesting signals | |
|
335 | // TODO: bar chart may have | |
|
336 | if (series->type() == QSeries::SeriesTypePie) { | |
|
364 | 337 | QPieSeries *pieSeries = static_cast<QPieSeries *>(series); |
|
365 | 338 | connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>))); |
|
366 | // connect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleRemoved(QList<QPieSlice*>))); | |
|
367 | break; | |
|
368 | } | |
|
369 | case QSeries::SeriesTypeSpline: { | |
|
370 | // QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series); | |
|
371 | break; | |
|
372 | } | |
|
373 | default: { | |
|
374 | qWarning() << "QLegend::connectSeries" << series->type() << "not implemented."; | |
|
375 | break; | |
|
376 | } | |
|
377 | 339 | } |
|
378 | 340 | } |
|
379 | 341 | |
|
380 | 342 | /*! |
|
381 | 343 | \internal Disconnects \a series from legend. No more status updates from series to legend. |
|
382 | 344 | */ |
|
383 | 345 | void QLegend::disconnectSeries(QSeries *series) |
|
384 | 346 | { |
|
385 | // Connect relevant signals from series | |
|
386 | switch (series->type()) | |
|
387 | { | |
|
388 | case QSeries::SeriesTypeLine: { | |
|
389 | // QLineSeries* lineSeries = static_cast<QLineSeries*>(series); | |
|
390 | break; | |
|
391 | } | |
|
392 | case QSeries::SeriesTypeArea: { | |
|
393 | // QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series); | |
|
394 | break; | |
|
395 | } | |
|
396 | case QSeries::SeriesTypeBar: { | |
|
397 | // QBarSeries* barSeries = static_cast<QBarSeries*>(series); | |
|
398 | break; | |
|
399 | } | |
|
400 | case QSeries::SeriesTypeStackedBar: { | |
|
401 | // QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series); | |
|
402 | break; | |
|
403 | } | |
|
404 | case QSeries::SeriesTypePercentBar: { | |
|
405 | // QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series); | |
|
406 | break; | |
|
407 | } | |
|
408 | case QSeries::SeriesTypeScatter: { | |
|
409 | // QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series); | |
|
410 | break; | |
|
411 | } | |
|
412 | case QSeries::SeriesTypePie: { | |
|
347 | if (series->type() == QSeries::SeriesTypePie) { | |
|
413 | 348 | QPieSeries *pieSeries = static_cast<QPieSeries *>(series); |
|
414 | 349 | disconnect(pieSeries, SIGNAL(added(QList<QPieSlice *>)), this, SLOT(handleAdded(QList<QPieSlice *>))); |
|
415 | // disconnect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleRemoved(QList<QPieSlice*>))); | |
|
416 | break; | |
|
417 | } | |
|
418 | case QSeries::SeriesTypeSpline: { | |
|
419 | // QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series); | |
|
420 | break; | |
|
421 | } | |
|
422 | default: { | |
|
423 | qWarning()<< "QLegend::disconnectSeries" << series->type() << "not implemented."; | |
|
424 | break; | |
|
425 | } | |
|
426 | 350 | } |
|
427 | 351 | } |
|
428 | 352 | |
|
429 | 353 | /*! |
|
430 | 354 | \internal Creates new markers for \a series. Marker contains the colored rectangle and series name. |
|
431 | 355 | With pie chart, created markers depend on pie slices. |
|
432 | 356 | With bar chart, created markers depend on bar sets. |
|
433 | 357 | */ |
|
434 | 358 | void QLegend::createMarkers(QSeries *series) |
|
435 | 359 | { |
|
436 | 360 | switch (series->type()) |
|
437 | 361 | { |
|
438 | 362 | case QSeries::SeriesTypeLine: { |
|
439 | 363 | QLineSeries *lineSeries = static_cast<QLineSeries *>(series); |
|
440 | 364 | appendMarkers(lineSeries); |
|
441 | 365 | break; |
|
442 | 366 | } |
|
443 | 367 | case QSeries::SeriesTypeArea: { |
|
444 | 368 | QAreaSeries *areaSeries = static_cast<QAreaSeries *>(series); |
|
445 | 369 | appendMarkers(areaSeries->upperSeries()); |
|
446 | 370 | if(areaSeries->lowerSeries()) |
|
447 | 371 | appendMarkers(areaSeries->lowerSeries()); |
|
448 | 372 | break; |
|
449 | 373 | } |
|
450 | ||
|
451 | 374 | case QSeries::SeriesTypeBar: { |
|
452 | 375 | QBarSeries *barSeries = static_cast<QBarSeries *>(series); |
|
453 | 376 | appendMarkers(barSeries); |
|
454 | 377 | break; |
|
455 | 378 | } |
|
456 | ||
|
457 | 379 | case QSeries::SeriesTypeStackedBar: { |
|
458 | 380 | QStackedBarSeries *stackedBarSeries = static_cast<QStackedBarSeries *>(series); |
|
459 | 381 | appendMarkers(stackedBarSeries); |
|
460 | 382 | break; |
|
461 | 383 | } |
|
462 | ||
|
463 | 384 | case QSeries::SeriesTypePercentBar: { |
|
464 | 385 | QPercentBarSeries *percentBarSeries = static_cast<QPercentBarSeries *>(series); |
|
465 | 386 | appendMarkers(percentBarSeries); |
|
466 | 387 | break; |
|
467 | 388 | } |
|
468 | ||
|
469 | 389 | case QSeries::SeriesTypeScatter: { |
|
470 | 390 | QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series); |
|
471 | 391 | appendMarkers(scatterSeries); |
|
472 | 392 | break; |
|
473 | 393 | } |
|
474 | ||
|
475 | 394 | case QSeries::SeriesTypePie: { |
|
476 | 395 | QPieSeries *pieSeries = static_cast<QPieSeries *>(series); |
|
477 | 396 | appendMarkers(pieSeries); |
|
478 | 397 | break; |
|
479 | 398 | } |
|
480 | ||
|
481 | 399 | case QSeries::SeriesTypeSpline: { |
|
482 | 400 | QSplineSeries *splineSeries = static_cast<QSplineSeries *>(series); |
|
483 | 401 | appendMarkers(splineSeries); |
|
484 | 402 | break; |
|
485 | 403 | } |
|
486 | 404 | default: { |
|
487 |
qWarning()<< "QLegend::createMarkers" << series->type() << " |
|
|
405 | qWarning()<< "QLegend::createMarkers" << series->type() << "unknown series type."; | |
|
488 | 406 | break; |
|
489 | 407 | } |
|
490 | 408 | } |
|
491 | 409 | } |
|
492 | 410 | |
|
493 | 411 | /*! |
|
494 | 412 | \internal Helper function. Appends markers from \a series to legend. |
|
495 | 413 | */ |
|
496 | 414 | void QLegend::appendMarkers(QXYSeries* series) |
|
497 | 415 | { |
|
498 | 416 | LegendMarker* marker = new LegendMarker(series,this); |
|
499 | 417 | marker->setName(series->name()); |
|
500 | 418 | marker->setPen(series->pen()); |
|
501 | 419 | marker->setBrush(series->brush()); |
|
502 | 420 | connect(marker, SIGNAL(clicked(QSeries *, Qt::MouseButton)), this, SIGNAL(clicked(QSeries *, Qt::MouseButton))); |
|
503 | 421 | connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed())); |
|
504 |
m_ |
|
|
422 | m_markers.append(marker); | |
|
505 | 423 | childItems().append(marker); |
|
506 | 424 | } |
|
507 | 425 | |
|
508 | 426 | /*! |
|
509 | 427 | \internal Helper function. Appends markers from \a series to legend. |
|
510 | 428 | */ |
|
511 | 429 | void QLegend::appendMarkers(QBarSeries *series) |
|
512 | 430 | { |
|
513 | 431 | foreach(QBarSet* s, series->barSets()) { |
|
514 | 432 | LegendMarker* marker = new LegendMarker(series, s, this); |
|
515 | 433 | marker->setName(s->name()); |
|
516 | 434 | marker->setPen(s->pen()); |
|
517 | 435 | marker->setBrush(s->brush()); |
|
518 | 436 | connect(marker, SIGNAL(clicked(QBarSet *, Qt::MouseButton)), |
|
519 | 437 | this, SIGNAL(clicked(QBarSet *, Qt::MouseButton))); |
|
520 | 438 | connect(s, SIGNAL(valueChanged()), marker, SLOT(changed())); |
|
521 | 439 | connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed())); |
|
522 |
m_ |
|
|
440 | m_markers.append(marker); | |
|
523 | 441 | childItems().append(marker); |
|
524 | 442 | } |
|
525 | 443 | } |
|
526 | 444 | |
|
527 | 445 | /*! |
|
528 | 446 | \internal Helper function. Appends markers from \a series to legend. |
|
529 | 447 | */ |
|
530 | 448 | void QLegend::appendMarkers(QPieSeries *series) |
|
531 | 449 | { |
|
532 | 450 | foreach(QPieSlice* s, series->slices()) { |
|
533 | 451 | LegendMarker* marker = new LegendMarker(series, s, this); |
|
534 | 452 | marker->setName(s->label()); |
|
535 | 453 | marker->setPen(s->pen()); |
|
536 | 454 | marker->setBrush(s->brush()); |
|
537 | 455 | connect(marker, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)), |
|
538 | 456 | this, SIGNAL(clicked(QPieSlice *, Qt::MouseButton))); |
|
539 | 457 | connect(s, SIGNAL(changed()), marker, SLOT(changed())); |
|
540 | 458 | connect(s, SIGNAL(destroyed()), marker, SLOT(deleteLater())); |
|
541 | 459 | connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed())); |
|
542 |
m_ |
|
|
460 | m_markers.append(marker); | |
|
543 | 461 | childItems().append(marker); |
|
544 | 462 | } |
|
545 | 463 | } |
|
546 | 464 | |
|
547 | 465 | /*! |
|
548 | 466 | \internal Deletes all markers that are created from \a series |
|
549 | 467 | */ |
|
550 | 468 | void QLegend::deleteMarkers(QSeries *series) |
|
551 | 469 | { |
|
552 | 470 | // Search all markers that belong to given series and delete them. |
|
553 |
foreach (LegendMarker *m, m_ |
|
|
471 | foreach (LegendMarker *m, m_markers) { | |
|
554 | 472 | if (m->series() == series) { |
|
555 |
m_ |
|
|
473 | m_markers.removeOne(m); | |
|
556 | 474 | delete m; |
|
557 | 475 | } |
|
558 | 476 | } |
|
559 | 477 | } |
|
560 | 478 | |
|
561 | 479 | /*! |
|
562 | 480 | \internal Updates layout of legend. Tries to fit as many markers as possible up to the maximum size of legend. |
|
563 | 481 | If items don't fit, sets the visibility of scroll buttons accordingly. |
|
564 | 482 | Causes legend to be resized. |
|
565 | 483 | */ |
|
566 | 484 | void QLegend::updateLayout() |
|
567 | 485 | { |
|
568 | 486 | // Calculate layout for markers and text |
|
569 |
if (m_ |
|
|
487 | if (m_markers.count() <= 0) { | |
|
570 | 488 | // Nothing to do |
|
571 | 489 | return; |
|
572 | 490 | } |
|
573 | 491 | |
|
574 | 492 | // Find out widest item. |
|
575 | 493 | QSizeF markerMaxSize = maximumMarkerSize(); |
|
576 | 494 | checkFirstMarkerBounds(); |
|
577 | 495 | |
|
578 | 496 | // Use max height as scroll button size |
|
579 | 497 | rescaleScrollButtons(QSize(markerMaxSize.height() ,markerMaxSize.height())); |
|
580 | 498 | |
|
581 | 499 | qreal totalWidth = 0; |
|
582 | 500 | qreal totalHeight = 0; |
|
583 |
switch (m_ |
|
|
501 | switch (m_alignment) | |
|
584 | 502 | { |
|
585 | 503 | // Both cases organise items horizontally |
|
586 |
case QLegend:: |
|
|
587 |
case QLegend:: |
|
|
504 | case QLegend::LayoutBottom: | |
|
505 | case QLegend::LayoutTop: { | |
|
588 | 506 | |
|
589 | 507 | qreal xStep = markerMaxSize.width(); |
|
590 |
qreal x = m_ |
|
|
591 |
qreal y = m_ |
|
|
508 | qreal x = m_pos.x() + m_margin; | |
|
509 | qreal y = m_pos.y() + m_margin; | |
|
592 | 510 | int column = 0; |
|
593 | 511 | int maxColumns = 1; |
|
594 | 512 | qreal scrollButtonWidth = 0; |
|
595 | 513 | |
|
596 | 514 | // Set correct visibility for scroll scrollbuttons |
|
597 | 515 | if (scrollButtonsVisible()) { |
|
598 |
m_ |
|
|
599 |
m_ |
|
|
516 | m_scrollButtonLeft->setVisible(true); | |
|
517 | m_scrollButtonRight->setVisible(true); | |
|
600 | 518 | // scrollbuttons visible, so add their width to total width |
|
601 |
totalWidth += (m_ |
|
|
602 |
scrollButtonWidth = m_ |
|
|
519 | totalWidth += (m_scrollButtonLeft->boundingRect().width() + m_margin) * 2; | |
|
520 | scrollButtonWidth = m_scrollButtonLeft->boundingRect().width() + m_margin; | |
|
603 | 521 | // start position changes by scrollbutton width |
|
604 | 522 | x += scrollButtonWidth; |
|
605 | 523 | } else { |
|
606 |
m_ |
|
|
607 |
m_ |
|
|
524 | m_scrollButtonLeft->setVisible(false); | |
|
525 | m_scrollButtonRight->setVisible(false); | |
|
608 | 526 | } |
|
609 |
m_ |
|
|
610 |
m_ |
|
|
527 | m_scrollButtonUp->setVisible(false); | |
|
528 | m_scrollButtonDown->setVisible(false); | |
|
611 | 529 | |
|
612 |
for (int i=0; i < m_ |
|
|
613 |
LegendMarker *m = m_ |
|
|
530 | for (int i=0; i < m_markers.count(); i++) { | |
|
531 | LegendMarker *m = m_markers.at(i); | |
|
614 | 532 | if (i < mFirstMarker) { |
|
615 | 533 | // Markers before first are not visible. |
|
616 | 534 | m->setVisible(false); |
|
617 | 535 | } else { |
|
618 |
if ((x + xStep + scrollButtonWidth + m_ |
|
|
536 | if ((x + xStep + scrollButtonWidth + m_margin) > (m_pos.x() + m_maximumSize.width())) { | |
|
619 | 537 | // This marker would go outside legend rect. |
|
620 | 538 | m->setVisible(false); |
|
621 | 539 | } else { |
|
622 | 540 | // This marker is ok |
|
623 | 541 | m->setVisible(true); |
|
624 | 542 | m->setPos(x, y); |
|
625 | 543 | x += xStep; |
|
626 | 544 | column++; |
|
627 | 545 | } |
|
628 | 546 | } |
|
629 | 547 | maxColumns = column; |
|
630 | 548 | } |
|
631 | 549 | |
|
632 |
m_ |
|
|
633 |
m_ |
|
|
550 | m_scrollButtonLeft->setPos(m_pos.x() + m_margin, y); | |
|
551 | m_scrollButtonRight->setPos(x + m_margin, y); | |
|
634 | 552 | |
|
635 |
totalWidth += maxColumns * markerMaxSize.width() + m_ |
|
|
636 |
totalHeight = markerMaxSize.height() + m_ |
|
|
553 | totalWidth += maxColumns * markerMaxSize.width() + m_margin * 2; | |
|
554 | totalHeight = markerMaxSize.height() + m_margin * 2; | |
|
637 | 555 | |
|
638 | 556 | break; |
|
639 | 557 | } |
|
640 | 558 | // Both cases organize items vertically |
|
641 |
case QLegend:: |
|
|
642 |
case QLegend:: |
|
|
559 | case QLegend::LayoutLeft: | |
|
560 | case QLegend::LayoutRight: { | |
|
643 | 561 | qreal yStep = markerMaxSize.height(); |
|
644 |
qreal x = m_ |
|
|
645 |
qreal y = m_ |
|
|
562 | qreal x = m_pos.x() + m_margin; | |
|
563 | qreal y = m_pos.y() + m_margin; | |
|
646 | 564 | int row = 1; |
|
647 | 565 | int maxRows = 1; |
|
648 | 566 | qreal scrollButtonHeight = 0; |
|
649 | 567 | |
|
650 | 568 | // Set correct visibility for scroll scrollbuttons |
|
651 | 569 | if (scrollButtonsVisible()) { |
|
652 |
m_ |
|
|
653 |
m_ |
|
|
654 |
totalHeight += (m_ |
|
|
655 |
scrollButtonHeight = m_ |
|
|
656 |
y += scrollButtonHeight + m_ |
|
|
570 | m_scrollButtonUp->setVisible(true); | |
|
571 | m_scrollButtonDown->setVisible(true); | |
|
572 | totalHeight += (m_scrollButtonUp->boundingRect().height() + m_margin) * 2; // scrollbuttons visible, so add their height to total height | |
|
573 | scrollButtonHeight = m_scrollButtonUp->boundingRect().height(); | |
|
574 | y += scrollButtonHeight + m_margin; // start position changes by scrollbutton height | |
|
657 | 575 | } else { |
|
658 |
m_ |
|
|
659 |
m_ |
|
|
576 | m_scrollButtonUp->setVisible(false); | |
|
577 | m_scrollButtonDown->setVisible(false); | |
|
660 | 578 | } |
|
661 |
m_ |
|
|
662 |
m_ |
|
|
579 | m_scrollButtonLeft->setVisible(false); | |
|
580 | m_scrollButtonRight->setVisible(false); | |
|
663 | 581 | |
|
664 |
for (int i=0; i < m_ |
|
|
665 |
LegendMarker* m = m_ |
|
|
582 | for (int i=0; i < m_markers.count(); i++) { | |
|
583 | LegendMarker* m = m_markers.at(i); | |
|
666 | 584 | if (i < mFirstMarker) { |
|
667 | 585 | // Markers before first are not visible. |
|
668 | 586 | m->setVisible(false); |
|
669 | 587 | } else { |
|
670 |
if ((y + yStep + scrollButtonHeight) > (m_ |
|
|
588 | if ((y + yStep + scrollButtonHeight) > (m_pos.y() + m_maximumSize.height())) { | |
|
671 | 589 | // This marker would go outside legend rect. |
|
672 | 590 | m->setVisible(false); |
|
673 | 591 | } else { |
|
674 | 592 | // This marker is ok |
|
675 | 593 | m->setVisible(true); |
|
676 | 594 | m->setPos(x, y); |
|
677 | 595 | y += yStep; |
|
678 | 596 | row++; |
|
679 | 597 | } |
|
680 | 598 | } |
|
681 | 599 | maxRows = row; |
|
682 | 600 | } |
|
683 | 601 | |
|
684 |
m_ |
|
|
685 |
m_ |
|
|
602 | m_scrollButtonUp->setPos(m_pos.x() + m_margin, m_pos.y() + m_margin); | |
|
603 | m_scrollButtonDown->setPos(m_pos.x() + m_margin, y + m_margin); | |
|
686 | 604 | |
|
687 |
totalWidth += markerMaxSize.width() + m_ |
|
|
688 |
totalHeight = maxRows * markerMaxSize.height() + m_ |
|
|
605 | totalWidth += markerMaxSize.width() + m_margin * 2; | |
|
606 | totalHeight = maxRows * markerMaxSize.height() + m_margin * 4 + scrollButtonHeight; // TODO: check this | |
|
689 | 607 | break; |
|
690 | 608 | } |
|
691 | 609 | default: { |
|
692 | 610 | break; |
|
693 | 611 | } |
|
694 | 612 | } |
|
695 | 613 | |
|
696 |
m_ |
|
|
697 |
m_ |
|
|
614 | m_size.setWidth(totalWidth); | |
|
615 | m_size.setHeight(totalHeight); | |
|
698 | 616 | |
|
699 | 617 | update(); |
|
700 | 618 | } |
|
701 | 619 | |
|
702 | 620 | /*! |
|
703 | 621 | \internal Sets the size of scroll buttons to \a size |
|
704 | 622 | */ |
|
705 | 623 | void QLegend::rescaleScrollButtons(const QSize &size) |
|
706 | 624 | { |
|
707 | 625 | QPolygonF left; |
|
708 | 626 | left << QPointF(size.width(), 0) << QPointF(0, size.height() / 2) << QPointF(size.width(), size.height()); |
|
709 | 627 | QPolygonF right; |
|
710 | 628 | right << QPointF(0, 0) << QPointF(size.width(), size.height() / 2) << QPointF(0, size.height()); |
|
711 | 629 | QPolygonF up; |
|
712 | 630 | up << QPointF(0, size.height()) << QPointF(size.width() / 2,0) << QPointF(size.width(), size.height()); |
|
713 | 631 | QPolygonF down; |
|
714 | 632 | down << QPointF(0, 0) << QPointF(size.width() / 2, size.height()) << QPointF(size.width(), 0); |
|
715 | 633 | |
|
716 |
m_ |
|
|
717 |
m_ |
|
|
718 |
m_ |
|
|
719 |
m_ |
|
|
634 | m_scrollButtonLeft->setPolygon(left); | |
|
635 | m_scrollButtonRight->setPolygon(right); | |
|
636 | m_scrollButtonUp->setPolygon(up); | |
|
637 | m_scrollButtonDown->setPolygon(down); | |
|
720 | 638 | } |
|
721 | 639 | |
|
722 | 640 | /*! |
|
723 | 641 | \internal Finds out maximum size of single marker. Marker sizes depend on series names. |
|
724 | 642 | */ |
|
725 | 643 | QSizeF QLegend::maximumMarkerSize() |
|
726 | 644 | { |
|
727 | 645 | QSizeF max(0,0); |
|
728 |
foreach (LegendMarker* m, m_ |
|
|
646 | foreach (LegendMarker* m, m_markers) { | |
|
729 | 647 | if (m->boundingRect().width() > max.width()) |
|
730 | 648 | max.setWidth(m->boundingRect().width()); |
|
731 | 649 | if (m->boundingRect().height() > max.height()) |
|
732 | 650 | max.setHeight(m->boundingRect().height()); |
|
733 | 651 | } |
|
734 | 652 | return max; |
|
735 | 653 | } |
|
736 | 654 | |
|
737 | 655 | /*! |
|
738 | 656 | \internal Checks that first marker is in acceptable bounds. Bounds range from 0 to (maximum number of markers - visible markers) |
|
739 | 657 | If scrollbuttons are visible, they affect the number of visible markers. |
|
740 | 658 | */ |
|
741 | 659 | void QLegend::checkFirstMarkerBounds() |
|
742 | 660 | { |
|
743 |
if ((m_ |
|
|
661 | if ((m_alignment == QLegend::LayoutLeft) || (m_alignment == QLegend::LayoutRight)) { | |
|
744 | 662 | // Bounds limited by height. |
|
745 | 663 | int max; |
|
746 | 664 | if (scrollButtonsVisible()) { |
|
747 |
max = (m_ |
|
|
665 | max = (m_maximumSize.height() - m_scrollButtonLeft->boundingRect().height() * 2 - m_margin * 4) / maximumMarkerSize().height(); | |
|
748 | 666 | } else { |
|
749 |
max = m_ |
|
|
667 | max = m_maximumSize.height() / maximumMarkerSize().height(); | |
|
750 | 668 | } |
|
751 | 669 | |
|
752 |
if (mFirstMarker > m_ |
|
|
753 |
mFirstMarker = m_ |
|
|
670 | if (mFirstMarker > m_markers.count() - max) | |
|
671 | mFirstMarker = m_markers.count() - max; | |
|
754 | 672 | } else { |
|
755 | 673 | // Bounds limited by width |
|
756 | 674 | int max; |
|
757 | 675 | if (scrollButtonsVisible()) { |
|
758 |
max = (m_ |
|
|
676 | max = (m_maximumSize.width() - m_scrollButtonLeft->boundingRect().width() * 2 - m_margin*4) / maximumMarkerSize().width(); | |
|
759 | 677 | } else { |
|
760 |
max = m_ |
|
|
678 | max = m_maximumSize.width() / maximumMarkerSize().width(); | |
|
761 | 679 | } |
|
762 | 680 | |
|
763 |
if (mFirstMarker > m_ |
|
|
764 |
mFirstMarker = m_ |
|
|
681 | if (mFirstMarker > m_markers.count() - max) | |
|
682 | mFirstMarker = m_markers.count() - max; | |
|
765 | 683 | } |
|
766 | 684 | |
|
767 | 685 | if (mFirstMarker < 0) |
|
768 | 686 | mFirstMarker = 0; |
|
769 | 687 | } |
|
770 | 688 | |
|
771 | 689 | /*! |
|
772 | 690 | \internal Helper function. Visibility of scroll buttons isn't quite obvious, so helper function clarifies the logic. |
|
773 | 691 | */ |
|
774 | 692 | bool QLegend::scrollButtonsVisible() |
|
775 | 693 | { |
|
776 | 694 | // Just a helper to clarify, what the magic below means :) |
|
777 |
if ((m_ |
|
|
778 |
return (maximumMarkerSize().width() * m_ |
|
|
779 |
} else if ((m_ |
|
|
780 |
return (maximumMarkerSize().height() * m_ |
|
|
695 | if ((m_alignment == QLegend::LayoutTop) || (m_alignment == QLegend::LayoutBottom)) { | |
|
696 | return (maximumMarkerSize().width() * m_markers.count() + m_margin * 2 > m_maximumSize.width()); | |
|
697 | } else if ((m_alignment == QLegend::LayoutLeft) || (m_alignment == QLegend::LayoutRight)) { | |
|
698 | return (maximumMarkerSize().height() * m_markers.count() + m_margin * 2 > m_maximumSize.height()); | |
|
781 | 699 | } |
|
782 | 700 | |
|
783 |
return (maximumMarkerSize().height() * m_ |
|
|
701 | return (maximumMarkerSize().height() * m_markers.count() + m_margin * 2 > m_maximumSize.height()); | |
|
784 | 702 | } |
|
785 | 703 | |
|
786 | 704 | #include "moc_qlegend.cpp" |
|
787 | 705 | |
|
788 | 706 | QTCOMMERCIALCHART_END_NAMESPACE |
@@ -1,109 +1,111 | |||
|
1 | 1 | #ifndef QLEGEND_H |
|
2 | 2 | #define QLEGEND_H |
|
3 | 3 | |
|
4 | 4 | #include <qchartglobal.h> |
|
5 | 5 | #include <QGraphicsObject> |
|
6 | 6 | #include <QPen> |
|
7 | 7 | #include <QBrush> |
|
8 | 8 | |
|
9 | 9 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
10 | 10 | |
|
11 | 11 | class Domain; |
|
12 | 12 | class LegendMarker; |
|
13 | 13 | class QPieSlice; |
|
14 | 14 | class QXYSeries; |
|
15 | 15 | class QBarSet; |
|
16 | 16 | class QBarSeries; |
|
17 | 17 | class QPieSeries; |
|
18 | 18 | class LegendScrollButton; |
|
19 | 19 | class QSeries; |
|
20 | 20 | |
|
21 | // TODO: This as widget | |
|
21 | 22 | class QTCOMMERCIALCHART_EXPORT QLegend : public QGraphicsObject |
|
22 | 23 | { |
|
23 | 24 | Q_OBJECT |
|
24 | 25 | public: |
|
25 | 26 | |
|
26 | enum PreferredLayout { | |
|
27 | PreferredLayoutTop, | |
|
28 | PreferredLayoutBottom, | |
|
29 | PreferredLayoutLeft, | |
|
30 | PreferredLayoutRight | |
|
27 | // We only support these alignments (for now) | |
|
28 | enum Layout { | |
|
29 | LayoutTop = Qt::AlignTop, | |
|
30 | LayoutBottom = Qt::AlignBottom, | |
|
31 | LayoutLeft = Qt::AlignLeft, | |
|
32 | LayoutRight = Qt::AlignRight | |
|
31 | 33 | }; |
|
32 | 34 | |
|
33 | 35 | explicit QLegend(QGraphicsItem *parent = 0); |
|
34 | 36 | |
|
35 | 37 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); |
|
36 | 38 | QRectF boundingRect() const; |
|
37 | 39 | |
|
38 | 40 | void setBrush(const QBrush &brush); |
|
39 | 41 | QBrush brush() const; |
|
40 | 42 | |
|
41 | 43 | void setPen(const QPen &pen); |
|
42 | 44 | QPen pen() const; |
|
43 | 45 | |
|
44 | void setPreferredLayout(QLegend::PreferredLayout preferred); | |
|
45 |
QLegend:: |
|
|
46 | void setAlignmnent(QLegend::Layout alignment); | |
|
47 | QLegend::Layout alignment() const; | |
|
46 | 48 | |
|
47 | 49 | QSizeF maximumSize() const; |
|
48 | 50 | void setMaximumSize(const QSizeF size); |
|
49 | 51 | |
|
50 | 52 | QSizeF size() const; |
|
51 | 53 | void setSize(const QSizeF size); |
|
52 | 54 | void setPos(const QPointF &pos); |
|
53 | 55 | |
|
54 | 56 | signals: |
|
55 | 57 | // for interactions. |
|
56 | 58 | void clicked(QSeries *series, Qt::MouseButton button); |
|
57 | 59 | void clicked(QBarSet *barset, Qt::MouseButton button); |
|
58 | 60 | void clicked(QPieSlice *slice, Qt::MouseButton button); |
|
59 | 61 | |
|
60 | 62 | public slots: |
|
61 | 63 | // PIMPL ---> |
|
62 | 64 | void handleSeriesAdded(QSeries *series, Domain *domain); |
|
63 | 65 | void handleSeriesRemoved(QSeries *series); |
|
64 | 66 | void handleAdded(QList<QPieSlice *> slices); |
|
65 | 67 | void handleRemoved(QList<QPieSlice *> slices); |
|
66 | 68 | void handleMarkerDestroyed(); |
|
67 | 69 | void handleScrollButtonClicked(QGraphicsSceneMouseEvent *event); |
|
68 | 70 | // PIMPL <--- |
|
69 | 71 | |
|
70 | 72 | private: |
|
71 | 73 | // PIMPL ---> |
|
72 | 74 | void connectSeries(QSeries *series); |
|
73 | 75 | void disconnectSeries(QSeries *series); |
|
74 | 76 | void createMarkers(QSeries *series); |
|
75 | 77 | void appendMarkers(QXYSeries *series); // All line series are derived from QXYSeries, so this works for now |
|
76 | 78 | void appendMarkers(QBarSeries *series); |
|
77 | 79 | void appendMarkers(QPieSeries *series); |
|
78 | 80 | void deleteMarkers(QSeries *series); |
|
79 | 81 | void updateLayout(); |
|
80 | 82 | void rescaleScrollButtons(const QSize &size); |
|
81 | 83 | QSizeF maximumMarkerSize(); |
|
82 | 84 | void checkFirstMarkerBounds(); |
|
83 | 85 | bool scrollButtonsVisible(); |
|
84 | 86 | |
|
85 |
QPointF m_ |
|
|
86 |
QSizeF m_ |
|
|
87 |
QSizeF m_ |
|
|
88 |
QSizeF m_ |
|
|
87 | QPointF m_pos; | |
|
88 | QSizeF m_size; | |
|
89 | QSizeF m_minimumSize; | |
|
90 | QSizeF m_maximumSize; | |
|
89 | 91 | |
|
90 |
QList<LegendMarker *> m_ |
|
|
92 | QList<LegendMarker *> m_markers; | |
|
91 | 93 | |
|
92 | 94 | QBrush m_brush; |
|
93 | 95 | QPen m_pen; |
|
94 |
QLegend:: |
|
|
96 | QLegend::Layout m_alignment; | |
|
95 | 97 | |
|
96 | 98 | int mFirstMarker; |
|
97 | 99 | |
|
98 |
LegendScrollButton *m_ |
|
|
99 |
LegendScrollButton *m_ |
|
|
100 |
LegendScrollButton *m_ |
|
|
101 |
LegendScrollButton *m_ |
|
|
100 | LegendScrollButton *m_scrollButtonLeft; | |
|
101 | LegendScrollButton *m_scrollButtonRight; | |
|
102 | LegendScrollButton *m_scrollButtonUp; | |
|
103 | LegendScrollButton *m_scrollButtonDown; | |
|
102 | 104 | |
|
103 |
qreal m_ |
|
|
105 | qreal m_margin; | |
|
104 | 106 | // <--- PIMPL |
|
105 | 107 | }; |
|
106 | 108 | |
|
107 | 109 | QTCOMMERCIALCHART_END_NAMESPACE |
|
108 | 110 | |
|
109 | 111 | #endif // QLEGEND_H |
General Comments 0
You need to be logged in to leave comments.
Login now