##// END OF EJS Templates
added LegendMarkerItem. Updated new legend example to test clicked of LegendMarker
sauimone -
r2164:7e465403ab2c
parent child
Show More
@@ -0,0 +1,253
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
14 **
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
18 **
19 ****************************************************************************/
20
21 #include "legendmarkeritem_p.h"
22 #include "qxyseries.h"
23 #include "qxyseries_p.h"
24 #include "qlegend.h"
25 #include "qabstractbarseries.h"
26 #include "qpieseries.h"
27 #include "qpieslice.h"
28 #include "qbarset.h"
29 #include "qbarset_p.h"
30 #include "qareaseries.h"
31 #include "qareaseries_p.h"
32 #include <QPainter>
33 #include <QGraphicsSceneEvent>
34 #include <QGraphicsSimpleTextItem>
35 #include <QDebug>
36
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38
39 LegendMarkerItem::LegendMarkerItem(QAbstractSeries *series, QGraphicsObject *parent) :
40 QGraphicsObject(parent),
41 m_series(series),
42 m_markerRect(0,0,10.0,10.0),
43 m_boundingRect(0,0,0,0),
44 m_textItem(new QGraphicsSimpleTextItem(this)),
45 m_rectItem(new QGraphicsRectItem(this)),
46 m_margin(4),
47 m_space(4)
48 {
49 //setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
50 m_rectItem->setRect(m_markerRect);
51 }
52
53 void LegendMarkerItem::setPen(const QPen &pen)
54 {
55 m_rectItem->setPen(pen);
56 }
57
58 QPen LegendMarkerItem::pen() const
59 {
60 return m_rectItem->pen();
61 }
62
63 void LegendMarkerItem::setBrush(const QBrush &brush)
64 {
65 m_rectItem->setBrush(brush);
66 }
67
68 QBrush LegendMarkerItem::brush() const
69 {
70 return m_rectItem->brush();
71 }
72
73 void LegendMarkerItem::setFont(const QFont &font)
74 {
75 m_textItem->setFont(font);
76 QFontMetrics fn(font);
77 m_markerRect = QRectF(0,0,fn.height()/2,fn.height()/2);
78 updateGeometry();
79 }
80
81 QFont LegendMarkerItem::font() const
82 {
83 return m_textItem->font();
84 }
85
86 void LegendMarkerItem::setLabel(const QString label)
87 {
88 m_text = label;
89 updateGeometry();
90 }
91
92 QString LegendMarkerItem::label() const
93 {
94 return m_text;
95 }
96
97 QRectF LegendMarkerItem::boundingRect() const
98 {
99 return m_boundingRect;
100 }
101
102 void LegendMarkerItem::setLabelBrush(const QBrush &brush)
103 {
104 m_textItem->setBrush(brush);
105 }
106
107 QBrush LegendMarkerItem::labelBrush() const
108 {
109 return m_textItem->brush();
110 }
111
112
113 void LegendMarkerItem::setGeometry(const QRectF& rect)
114 {
115 QFontMetrics fn (font());
116
117 int width = rect.width();
118 qreal x = m_margin + m_markerRect.width() + m_space + m_margin;
119 qreal y = qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin);
120
121 if (fn.boundingRect(m_text).width() + x > width)
122 {
123 QString string = m_text + "...";
124 while(fn.boundingRect(string).width() + x > width && string.length() > 3)
125 string.remove(string.length() - 4, 1);
126 m_textItem->setText(string);
127 }
128 else
129 m_textItem->setText(m_text);
130
131 const QRectF& textRect = m_textItem->boundingRect();
132
133
134 m_textItem->setPos(x-m_margin,y/2 - textRect.height()/2);
135 m_rectItem->setRect(m_markerRect);
136 m_rectItem->setPos(m_margin,y/2 - m_markerRect.height()/2);
137
138 prepareGeometryChange();
139 m_boundingRect = QRectF(0,0,x+textRect.width()+m_margin,y);
140 }
141
142 void LegendMarkerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
143 {
144 Q_UNUSED(option)
145 Q_UNUSED(widget)
146 Q_UNUSED(painter)
147 }
148
149 QSizeF LegendMarkerItem::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
150 {
151 Q_UNUSED(constraint)
152
153 QFontMetrics fn(m_textItem->font());
154 QSizeF sh;
155
156 switch (which) {
157 case Qt::MinimumSize:
158 sh = QSizeF(fn.boundingRect("...").width() + 2*m_margin + m_space +m_markerRect.width(),qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin));
159 break;
160 case Qt::PreferredSize:
161 sh = QSizeF(fn.boundingRect(m_text).width() + 2*m_margin + m_space +m_markerRect.width(),qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin));
162 break;
163 default:
164 break;
165 }
166
167 return sh;
168 }
169
170 void LegendMarkerItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
171 {
172 qDebug() << "LegendMarkerItem::mousePressEvent";
173 QGraphicsObject::mousePressEvent(event);
174 //TODO: selected signal removed for now
175 }
176
177 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
178
179 AreaLegendMarkerItem::AreaLegendMarkerItem(QAreaSeries *series,QLegend *legend) : LegendMarkerItem(series,legend),
180 m_series(series)
181 {
182 //QObject::connect(this, SIGNAL(selected()), series, SIGNAL(selected()));
183 // QObject::connect(series->d_func(),SIGNAL(updated()), this, SLOT(updated()));
184 // QObject::connect(series, SIGNAL(nameChanged()), this, SLOT(updated()));
185 updated();
186 }
187
188 void AreaLegendMarkerItem::updated()
189 {
190 setBrush(m_series->brush());
191 setLabel(m_series->name());
192 }
193
194 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
195
196 BarLegendMarkerItem::BarLegendMarkerItem(QAbstractBarSeries *barseries,QBarSet *barset, QLegend *legend) : LegendMarkerItem(barseries,legend),
197 m_barset(barset)
198 {
199 //QObject::connect(this, SIGNAL(selected()),barset->d_ptr.data(), SIGNAL(selected()));
200 // QObject::connect(barset->d_ptr.data(), SIGNAL(updatedBars()), this, SLOT(updated()));
201 updated();
202 }
203
204 void BarLegendMarkerItem::updated()
205 {
206 setBrush(m_barset->brush());
207 setLabel(m_barset->label());
208 }
209
210 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
211
212 PieLegendMarkerItem::PieLegendMarkerItem(QPieSeries* series,QPieSlice *pieslice, QLegend *legend) : LegendMarkerItem(series,legend),
213 m_pieslice(pieslice)
214 {
215 // QObject::connect(pieslice, SIGNAL(labelChanged()), this, SLOT(updated()));
216 // QObject::connect(pieslice, SIGNAL(brushChanged()), this, SLOT(updated()));
217 updated();
218 }
219
220 void PieLegendMarkerItem::updated()
221 {
222 setBrush(m_pieslice->brush());
223 setLabel(m_pieslice->label());
224 }
225
226 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
227
228 XYLegendMarkerItem::XYLegendMarkerItem(QXYSeries *series, QLegend *legend) : LegendMarkerItem(series,legend),
229 m_series(series)
230 {
231 //QObject::connect(this, SIGNAL(selected()), series, SIGNAL(selected()));
232 // QObject::connect(series->d_func(),SIGNAL(updated()), this, SLOT(updated()));
233 // QObject::connect(series, SIGNAL(nameChanged()), this, SLOT(updated()));
234 updated();
235 }
236
237 void XYLegendMarkerItem::updated()
238 {
239 setLabel(m_series->name());
240
241 if(m_series->type()== QAbstractSeries::SeriesTypeScatter)
242 {
243 setBrush(m_series->brush());
244
245 }
246 else {
247 setBrush(QBrush(m_series->pen().color()));
248 }
249 }
250
251 #include "moc_legendmarkeritem_p.cpp"
252
253 QTCOMMERCIALCHART_END_NAMESPACE
@@ -0,0 +1,146
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
14 **
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
18 **
19 ****************************************************************************/
20
21 // W A R N I N G
22 // -------------
23 //
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
26 // version without notice, or even be removed.
27 //
28 // We mean it.
29
30 #ifndef LEGENDMARKERITEM_P_H
31 #define LEGENDMARKERITEM_P_H
32
33 #include "qchartglobal.h"
34 #include <QGraphicsObject>
35 #include <QBrush>
36 #include <QPen>
37 #include <QGraphicsSimpleTextItem>
38 #include <QGraphicsLayoutItem>
39
40 QTCOMMERCIALCHART_BEGIN_NAMESPACE
41
42 class QAbstractSeries;
43 class QAreaSeries;
44 class QXYSeries;
45 class QBarSet;
46 class QAbstractBarSeries;
47 class QPieSlice;
48 class QLegend;
49 class QPieSeries;
50
51 class LegendMarkerItem : public QGraphicsObject, public QGraphicsLayoutItem
52 {
53 Q_OBJECT
54 Q_INTERFACES(QGraphicsLayoutItem)
55 public:
56 explicit LegendMarkerItem(QAbstractSeries *m_series, QGraphicsObject *parent);
57
58 void setPen(const QPen &pen);
59 QPen pen() const;
60
61 void setBrush(const QBrush &brush);
62 QBrush brush() const;
63
64 void setFont(const QFont &font);
65 QFont font() const;
66
67 void setLabel(const QString label);
68 QString label() const;
69
70 void setLabelBrush(const QBrush &brush);
71 QBrush labelBrush() const;
72
73 QAbstractSeries *series() const { return m_series;}
74
75 void setGeometry(const QRectF& rect);
76
77 QRectF boundingRect() const;
78
79 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
80
81 QSizeF sizeHint (Qt::SizeHint which, const QSizeF& constraint) const;
82
83 protected:
84 // From QGraphicsObject
85 void mousePressEvent(QGraphicsSceneMouseEvent *event);
86
87 //public Q_SLOTS:
88 //virtual void updated() = 0;
89
90 protected:
91 QAbstractSeries *m_series;
92 QRectF m_markerRect;
93 QRectF m_boundingRect;
94 // QLegend* m_legend;
95 QGraphicsSimpleTextItem *m_textItem;
96 QGraphicsRectItem *m_rectItem;
97 qreal m_margin;
98 qreal m_space;
99 QString m_text;
100
101 };
102
103 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
104 class XYLegendMarkerItem : public LegendMarkerItem
105 {
106 public:
107 XYLegendMarkerItem(QXYSeries *series, QLegend *legend);
108 protected:
109 void updated();
110 private:
111 QXYSeries *m_series;
112 };
113 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
114 class AreaLegendMarkerItem : public LegendMarkerItem
115 {
116 public:
117 AreaLegendMarkerItem(QAreaSeries *series, QLegend *legend);
118 protected:
119 void updated();
120 private:
121 QAreaSeries *m_series;
122 };
123 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
124 class BarLegendMarkerItem : public LegendMarkerItem
125 {
126 public:
127 BarLegendMarkerItem(QAbstractBarSeries *barseries, QBarSet *barset,QLegend *legend);
128 protected:
129 void updated();
130 private:
131 QBarSet *m_barset;
132 };
133 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
134 class PieLegendMarkerItem : public LegendMarkerItem
135 {
136 public:
137 PieLegendMarkerItem(QPieSeries *pieSeries, QPieSlice *pieslice, QLegend *legend);
138 protected:
139 void updated();
140 private:
141 QPieSlice *m_pieslice;
142 };
143
144 QTCOMMERCIALCHART_END_NAMESPACE
145
146 #endif // LEGENDMARKERITEM_P_H
@@ -1,259 +1,301
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 "mainwidget.h"
22 22 #include <QChart>
23 23 #include <QChartView>
24 24 #include <QPushButton>
25 25 #include <QLabel>
26 26 #include <QDebug>
27 27 #include <QLegend>
28 28 #include <QFormLayout>
29 29 #include <QPieSeries>
30 30 #include <QPieSlice>
31 31 #include <QLegendMarker>
32 32
33 33 QTCOMMERCIALCHART_USE_NAMESPACE
34 34
35 35 MainWidget::MainWidget(QWidget *parent) :
36 36 QWidget(parent)
37 37 {
38 38 // Create buttons for ui
39 39 m_buttonLayout = new QGridLayout();
40 40 QPushButton *detachLegendButton = new QPushButton("Toggle attached");
41 41 connect(detachLegendButton, SIGNAL(clicked()), this, SLOT(toggleAttached()));
42 42 m_buttonLayout->addWidget(detachLegendButton, 0, 0);
43 43
44 44 QPushButton *addSliceButton = new QPushButton("add slice");
45 45 connect(addSliceButton, SIGNAL(clicked()), this, SLOT(addSlice()));
46 46 m_buttonLayout->addWidget(addSliceButton, 2, 0);
47 47 QPushButton *removeSliceButton = new QPushButton("remove slice");
48 48 connect(removeSliceButton, SIGNAL(clicked()), this, SLOT(removeSlice()));
49 49 m_buttonLayout->addWidget(removeSliceButton, 3, 0);
50 50
51 51 QPushButton *alignButton = new QPushButton("Align (Bottom)");
52 52 connect(alignButton, SIGNAL(clicked()), this, SLOT(setLegendAlignment()));
53 53 m_buttonLayout->addWidget(alignButton, 4, 0);
54 54
55 55 QPushButton *boldButton = new QPushButton("Toggle bold");
56 56 connect(boldButton, SIGNAL(clicked()), this, SLOT(toggleBold()));
57 57 m_buttonLayout->addWidget(boldButton, 5, 0);
58 58
59 59 QPushButton *italicButton = new QPushButton("Toggle italic");
60 60 connect(italicButton, SIGNAL(clicked()), this, SLOT(toggleItalic()));
61 61 m_buttonLayout->addWidget(italicButton, 6, 0);
62 62
63 63 QPushButton *infoButton = new QPushButton("Debug info");
64 64 connect(infoButton, SIGNAL(clicked()), this, SLOT(showDebugInfo()));
65 65 m_buttonLayout->addWidget(infoButton, 7, 0);
66 66
67 QPushButton *connectButton = new QPushButton("Connect markers");
68 connect(connectButton, SIGNAL(clicked()), this, SLOT(connectMarkers()));
69 m_buttonLayout->addWidget(connectButton, 8, 0);
70
71 QPushButton *disConnectButton = new QPushButton("Disconnect markers");
72 connect(disConnectButton, SIGNAL(clicked()), this, SLOT(disconnectMarkers()));
73 m_buttonLayout->addWidget(connectButton, 8, 0);
74
75
67 76 m_legendPosX = new QDoubleSpinBox();
68 77 m_legendPosY = new QDoubleSpinBox();
69 78 m_legendWidth = new QDoubleSpinBox();
70 79 m_legendHeight = new QDoubleSpinBox();
71 80
72 81 connect(m_legendPosX, SIGNAL(valueChanged(double)), this, SLOT(updateLegendLayout()));
73 82 connect(m_legendPosY, SIGNAL(valueChanged(double)), this, SLOT(updateLegendLayout()));
74 83 connect(m_legendWidth, SIGNAL(valueChanged(double)), this, SLOT(updateLegendLayout()));
75 84 connect(m_legendHeight, SIGNAL(valueChanged(double)), this, SLOT(updateLegendLayout()));
76 85
77 86 QFormLayout* legendLayout = new QFormLayout();
78 87 legendLayout->addRow("HPos", m_legendPosX);
79 88 legendLayout->addRow("VPos", m_legendPosY);
80 89 legendLayout->addRow("Width", m_legendWidth);
81 90 legendLayout->addRow("Height", m_legendHeight);
82 91 m_legendSettings = new QGroupBox("Detached legend");
83 92 m_legendSettings->setLayout(legendLayout);
84 93 m_buttonLayout->addWidget(m_legendSettings);
85 94 m_legendSettings->setVisible(false);
86 95
87 96 // Create chart view with the chart
88 97 m_chart = new QChart();
89 98 m_chartView = new QChartView(m_chart, this);
90 99
91 100 // Create spinbox to modify font size
92 101 m_fontSize = new QDoubleSpinBox();
93 102 m_fontSize->setValue(m_chart->legend()->font().pointSizeF());
94 103 connect(m_fontSize, SIGNAL(valueChanged(double)), this, SLOT(fontSizeChanged()));
95 104
96 105 QFormLayout* fontLayout = new QFormLayout();
97 106 fontLayout->addRow("Legend font size", m_fontSize);
98 107
99 108 // Create layout for grid and detached legend
100 109 m_mainLayout = new QGridLayout();
101 110 m_mainLayout->addLayout(m_buttonLayout, 0, 0);
102 111 m_mainLayout->addLayout(fontLayout,1,0);
103 112 m_mainLayout->addWidget(m_chartView, 0, 1, 3, 1);
104 113 setLayout(m_mainLayout);
105 114
106 115 createSeries();
107 116 }
108 117
109 118 void MainWidget::createSeries()
110 119 {
111 120 m_series = new QPieSeries();
112 121 addSlice();
113 122 addSlice();
114 123 addSlice();
115 124 addSlice();
116 125
117 126 m_chart->addSeries(m_series);
118 127 m_chart->setTitle("Legend detach example");
119 128 m_chart->createDefaultAxes();
120 129 //![1]
121 130 m_chart->legend()->setVisible(true);
122 131 m_chart->legend()->setAlignment(Qt::AlignBottom);
123 132 //![1]
124 133
125 134 m_chartView->setRenderHint(QPainter::Antialiasing);
126 135 }
127 136
128 137 void MainWidget::showLegendSpinbox()
129 138 {
130 139 m_legendSettings->setVisible(true);
131 140 QRectF chartViewRect = m_chartView->rect();
132 141
133 142 m_legendPosX->setMinimum(0);
134 143 m_legendPosX->setMaximum(chartViewRect.width());
135 144 m_legendPosX->setValue(150);
136 145
137 146 m_legendPosY->setMinimum(0);
138 147 m_legendPosY->setMaximum(chartViewRect.height());
139 148 m_legendPosY->setValue(150);
140 149
141 150 m_legendWidth->setMinimum(0);
142 151 m_legendWidth->setMaximum(chartViewRect.width());
143 152 m_legendWidth->setValue(150);
144 153
145 154 m_legendHeight->setMinimum(0);
146 155 m_legendHeight->setMaximum(chartViewRect.height());
147 156 m_legendHeight->setValue(75);
148 157 }
149 158
150 159 void MainWidget::hideLegendSpinbox()
151 160 {
152 161 m_legendSettings->setVisible(false);
153 162 }
154 163
155 164
156 165 void MainWidget::toggleAttached()
157 166 {
158 167 QLegend *legend = m_chart->legend();
159 168 if (legend->isAttachedToChart()) {
160 169 //![2]
161 170 legend->detachFromChart();
162 171 m_chart->legend()->setBackgroundVisible(true);
163 172 m_chart->legend()->setBrush(QBrush(QColor(128,128,128,128)));
164 173 m_chart->legend()->setPen(QPen(QColor(192,192,192,192)));
165 174 //![2]
166 175 showLegendSpinbox();
167 176 updateLegendLayout();
168 177 } else {
169 178 //![3]
170 179 legend->attachToChart();
171 180 legend->setBackgroundVisible(false);
172 181 //![3]
173 182 hideLegendSpinbox();
174 183 }
175 184 update();
176 185 }
177 186
178 187 void MainWidget::addSlice()
179 188 {
180 189 QPieSlice* slice = new QPieSlice(QString("slice " + QString::number(m_series->count())), m_series->count()+1);
181 // slice->setValue();
182 190 m_series->append(slice);
183 191 }
184 192
185 193 void MainWidget::removeSlice()
186 194 {
187 195 QList<QPieSlice*> slices = m_series->slices();
188 196 if (slices.count() > 0) {
189 197 m_series->remove(slices.at(slices.count()-1));
190 198 }
191 199 }
192 200
201 void MainWidget::connectMarkers()
202 {
203 // Example use case.
204 // Explode slice via marker.
205 // Should be doable via public api.
206
207 foreach (QLegendMarker* marker, m_chart->legend()->markers()) {
208 // Disconnect possible existing connection to avoid multiple connections
209 QObject::disconnect(marker, SIGNAL(clicked()), this, SLOT(handleMarkerClicked()));
210 QObject::connect(marker, SIGNAL(clicked()), this, SLOT(handleMarkerClicked()));
211 }
212 }
213
214 void MainWidget::disconnectMarkers()
215 {
216 foreach (QLegendMarker* marker, m_chart->legend()->markers()) {
217 QObject::disconnect(marker, SIGNAL(clicked()), this, SLOT(handleMarkerClicked()));
218 }
219 }
220
193 221 void MainWidget::setLegendAlignment()
194 222 {
195 223 QPushButton *button = qobject_cast<QPushButton *>(sender());
196 224
197 225 switch (m_chart->legend()->alignment()) {
198 226 case Qt::AlignTop:
199 227 m_chart->legend()->setAlignment(Qt::AlignLeft);
200 228 if (button)
201 229 button->setText("Align (Left)");
202 230 break;
203 231 case Qt::AlignLeft:
204 232 m_chart->legend()->setAlignment(Qt::AlignBottom);
205 233 if (button)
206 234 button->setText("Align (Bottom)");
207 235 break;
208 236 case Qt::AlignBottom:
209 237 m_chart->legend()->setAlignment(Qt::AlignRight);
210 238 if (button)
211 239 button->setText("Align (Right)");
212 240 break;
213 241 default:
214 242 if (button)
215 243 button->setText("Align (Top)");
216 244 m_chart->legend()->setAlignment(Qt::AlignTop);
217 245 break;
218 246 }
219 247 }
220 248
221 249 void MainWidget::toggleBold()
222 250 {
223 251 QFont font = m_chart->legend()->font();
224 252 font.setBold(!font.bold());
225 253 m_chart->legend()->setFont(font);
226 254 }
227 255
228 256 void MainWidget::toggleItalic()
229 257 {
230 258 QFont font = m_chart->legend()->font();
231 259 font.setItalic(!font.italic());
232 260 m_chart->legend()->setFont(font);
233 261 }
234 262
235 263 void MainWidget::showDebugInfo()
236 264 {
237 265 qDebug() << "marker count:" << m_chart->legend()->markers().count();
238 266 foreach (QLegendMarker* marker, m_chart->legend()->markers()) {
267 qDebug() << "marker series type:" << marker->series()->type();
268 qDebug() << "peer object:" << marker->peerObject();
239 269 qDebug() << "label:" << marker->label();
240 270 }
241 271 }
242 272
243 273 void MainWidget::fontSizeChanged()
244 274 {
245 275 QFont font = m_chart->legend()->font();
246 276 font.setPointSizeF(m_fontSize->value());
247 277 m_chart->legend()->setFont(font);
248 278 }
249 279
250 280 void MainWidget::updateLegendLayout()
251 281 {
252 282 //![4]
253 283 m_chart->legend()->setGeometry(QRectF(m_legendPosX->value()
254 284 ,m_legendPosY->value()
255 285 ,m_legendWidth->value()
256 286 ,m_legendHeight->value()));
257 287 m_chart->legend()->update();
258 288 //![4]
259 289 }
290
291 void MainWidget::handleMarkerClicked()
292 {
293 QLegendMarker* marker = qobject_cast<QLegendMarker*> (sender());
294
295 qDebug() << "marker clicked:" << marker;
296
297 QPieSlice* slice = qobject_cast<QPieSlice*> (marker->peerObject());
298 Q_ASSERT(slice);
299
300 slice->setExploded(!slice->isExploded());
301 }
@@ -1,84 +1,88
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 #ifndef MAINWIDGET_H
22 22 #define MAINWIDGET_H
23 23
24 24 #include "qchartglobal.h"
25 25 #include "qchart.h"
26 26 #include "qchartview.h"
27 27 #include <QWidget>
28 28 #include <QGraphicsWidget>
29 29 #include <QGridLayout>
30 30 #include <QGraphicsGridLayout>
31 31 #include <QDoubleSpinBox>
32 32 #include <QGroupBox>
33 33 #include <QPieSlice>
34 34 #include <QPieSeries>
35 35
36 36 QTCOMMERCIALCHART_USE_NAMESPACE
37 37
38 38 class MainWidget : public QWidget
39 39 {
40 40 Q_OBJECT
41 41 public:
42 42 explicit MainWidget(QWidget *parent = 0);
43 43 void createSeries();
44 44 void showLegendSpinbox();
45 45 void hideLegendSpinbox();
46 46
47 47 signals:
48 48
49 49 public slots:
50 50 void toggleAttached();
51 51 void addSlice();
52 52 void removeSlice();
53 void connectMarkers();
54 void disconnectMarkers();
53 55
54 56 void setLegendAlignment();
55 57
56 58 void toggleBold();
57 59 void toggleItalic();
58 60 void showDebugInfo();
59 61 void fontSizeChanged();
60 62
61 63 void updateLegendLayout();
62 64
65 void handleMarkerClicked();
66
63 67
64 68 private:
65 69
66 70 QChart *m_chart;
67 71 QPieSeries *m_series;
68 72
69 73 QChartView *m_chartView;
70 74 QGridLayout *m_mainLayout;
71 75 QGridLayout *m_buttonLayout;
72 76 QGridLayout *m_fontLayout;
73 77
74 78 QDoubleSpinBox *m_fontSize;
75 79
76 80 // For detached layout
77 81 QGroupBox* m_legendSettings;
78 82 QDoubleSpinBox *m_legendPosX;
79 83 QDoubleSpinBox *m_legendPosY;
80 84 QDoubleSpinBox *m_legendWidth;
81 85 QDoubleSpinBox *m_legendHeight;
82 86 };
83 87
84 88 #endif // MAINWIDGET_H
@@ -1,22 +1,24
1 1 INCLUDEPATH += $$PWD
2 2 DEPENDPATH += $$PWD
3 3
4 4 SOURCES += \
5 5 $$PWD/qlegend.cpp \
6 6 $$PWD/legendmarker.cpp \
7 7 $$PWD/legendlayout.cpp \
8 8 $$PWD/qlegendmarker.cpp \
9 $$PWD/qpielegendmarker.cpp
9 $$PWD/qpielegendmarker.cpp \
10 $$PWD/legendmarkeritem.cpp
10 11
11 12 PRIVATE_HEADERS += \
12 13 $$PWD/legendmarker_p.h \
13 14 $$PWD/legendscroller_p.h \
14 15 $$PWD/qlegend_p.h \
15 16 $$PWD/legendlayout_p.h \
16 $$PWD/qlegendmarker_p.h
17 $$PWD/qlegendmarker_p.h \
18 $$PWD/legendmarkeritem_p.h
17 19
18 20
19 21 PUBLIC_HEADERS += \
20 22 $$PWD/qlegend.h \
21 23 $$PWD/qlegendmarker.h \
22 24 $$PWD/qpielegendmarker.h
@@ -1,561 +1,564
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 "qlegend.h"
22 22 #include "qlegend_p.h"
23 23 #include "qabstractseries.h"
24 24 #include "qabstractseries_p.h"
25 25 #include "qchart_p.h"
26 26 #include "legendlayout_p.h"
27 27 #include "legendmarker_p.h"
28 28 #include "qxyseries.h"
29 29 #include "qlineseries.h"
30 30 #include "qareaseries.h"
31 31 #include "qscatterseries.h"
32 32 #include "qsplineseries.h"
33 33 #include "qabstractbarseries.h"
34 34 #include "qstackedbarseries.h"
35 35 #include "qpercentbarseries.h"
36 36 #include "qbarset.h"
37 37 #include "qpieseries.h"
38 38 #include "qpieseries_p.h"
39 39 #include "qpieslice.h"
40 40 #include "chartpresenter_p.h"
41 41 #include "chartlayout_p.h"
42 42 #include <QPainter>
43 43 #include <QPen>
44 44 #include <QTimer>
45 45 #include <QGraphicsSceneEvent>
46 46
47 47 #include <QLegendMarker>
48 48
49 49 QTCOMMERCIALCHART_BEGIN_NAMESPACE
50 50
51 51 /*!
52 52 \class QLegend
53 53 \brief Legend object
54 54 \mainclass
55 55
56 56 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
57 57 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
58 58 handle the drawing manually.
59 59 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
60 60
61 61 \image examples_percentbarchart_legend.png
62 62
63 63 \sa QChart
64 64 */
65 65 /*!
66 66 \qmlclass Legend QLegend
67 67 \brief Legend is part of QtCommercial Chart QML API.
68 68
69 69 Legend is a graphical object, whics displays legend of the chart. Legend state is updated by ChartView, when
70 70 series have been changed. Legend is used via ChartView class. For example:
71 71 \code
72 72 ChartView {
73 73 legend.visible: true
74 74 legend.alignment: Qt.AlignBottom
75 75 // Add a few series...
76 76 }
77 77 \endcode
78 78
79 79 \image examples_percentbarchart_legend.png
80 80 */
81 81
82 82 /*!
83 83 \property QLegend::alignment
84 84 \brief The alignment of the legend.
85 85
86 86 Legend paints on the defined position in the chart. The following alignments are supported:
87 87 Qt::AlignTop, Qt::AlignBottom, Qt::AlignLeft, Qt::AlignRight. If you set more than one flag the result is undefined.
88 88 */
89 89 /*!
90 90 \qmlproperty Qt.Alignment Legend::alignment
91 91 \brief The alignment of the legend.
92 92
93 93 Legend paints on the defined position in the chart. The following alignments are supported:
94 94 Qt.AlignTop, Qt.AlignBottom, Qt.AlignLeft, Qt.AlignRight. If you set more than one flag the result is undefined.
95 95 */
96 96
97 97 /*!
98 98 \property QLegend::backgroundVisible
99 99 Whether the legend background is visible or not.
100 100 */
101 101 /*!
102 102 \qmlproperty bool Legend::backgroundVisible
103 103 Whether the legend background is visible or not.
104 104 */
105 105
106 106 /*!
107 107 \property QLegend::color
108 108 The color of the legend, i.e. the background (brush) color. Note that if you change the color
109 109 of the legend, the style of the legend brush is set to Qt::SolidPattern.
110 110 */
111 111 /*!
112 112 \qmlproperty color Legend::color
113 113 The color of the legend, i.e. the background (brush) color.
114 114 */
115 115
116 116 /*!
117 117 \property QLegend::borderColor
118 118 The border color of the legend, i.e. the line color.
119 119 */
120 120 /*!
121 121 \qmlproperty color Legend::borderColor
122 122 The border color of the legend, i.e. the line color.
123 123 */
124 124
125 125 /*!
126 126 \property QLegend::font
127 127 The font of markers used by legend
128 128 */
129 129 /*!
130 130 \qmlproperty Font Legend::font
131 131 The font of markers used by legend
132 132 */
133 133
134 134 /*!
135 135 \property QLegend::labelColor
136 136 The color of brush used to draw labels.
137 137 */
138 138 /*!
139 139 \qmlproperty color QLegend::labelColor
140 140 The color of brush used to draw labels.
141 141 */
142 142
143 143 /*!
144 144 \fn void QLegend::backgroundVisibleChanged(bool)
145 145 The visibility of the legend background changed to \a visible.
146 146 */
147 147
148 148 /*!
149 149 \fn void QLegend::colorChanged(QColor)
150 150 The color of the legend background changed to \a color.
151 151 */
152 152
153 153 /*!
154 154 \fn void QLegend::borderColorChanged(QColor)
155 155 The border color of the legend background changed to \a color.
156 156 */
157 157
158 158 /*!
159 159 \fn void QLegend::fontChanged(QFont)
160 160 The font of markers of the legend changed to \a font.
161 161 */
162 162
163 163 /*!
164 164 \fn void QLegend::labelColorChanged(QColor color)
165 165 This signal is emitted when the color of brush used to draw labels has changed to \a color.
166 166 */
167 167
168 168 /*!
169 169 Constructs the legend object and sets the parent to \a parent
170 170 */
171 171
172 172 QLegend::QLegend(QChart *chart): QGraphicsWidget(chart),
173 173 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter, chart, this))
174 174 {
175 175 setZValue(ChartPresenter::LegendZValue);
176 176 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
177 177 QObject::connect(chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries*,Domain*)), d_ptr.data(), SLOT(handleSeriesAdded(QAbstractSeries*,Domain*)));
178 178 QObject::connect(chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), d_ptr.data(), SLOT(handleSeriesRemoved(QAbstractSeries*)));
179 179 // QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesUpdated(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesUpdated(QAbstractSeries*)));
180 180 setLayout(d_ptr->m_layout);
181 181 }
182 182
183 183 /*!
184 184 Destroys the legend object. Legend is always owned by a QChart, so an application should never call this.
185 185 */
186 186 QLegend::~QLegend()
187 187 {
188 188 }
189 189
190 190 /*!
191 191 \internal
192 192 */
193 193 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
194 194 {
195 195 Q_UNUSED(option)
196 196 Q_UNUSED(widget)
197 197
198 198 if (!d_ptr->m_backgroundVisible)
199 199 return;
200 200
201 201 painter->setOpacity(opacity());
202 202 painter->setPen(d_ptr->m_pen);
203 203 painter->setBrush(d_ptr->m_brush);
204 204 painter->drawRoundRect(rect(), d_ptr->roundness(rect().width()), d_ptr->roundness(rect().height()));
205 205 }
206 206
207 207
208 208 /*!
209 209 Sets the \a brush of legend. Brush affects the background of legend.
210 210 */
211 211 void QLegend::setBrush(const QBrush &brush)
212 212 {
213 213 if (d_ptr->m_brush != brush) {
214 214 d_ptr->m_brush = brush;
215 215 update();
216 216 emit colorChanged(brush.color());
217 217 }
218 218 }
219 219
220 220 /*!
221 221 Returns the brush used by legend.
222 222 */
223 223 QBrush QLegend::brush() const
224 224 {
225 225 return d_ptr->m_brush;
226 226 }
227 227
228 228 void QLegend::setColor(QColor color)
229 229 {
230 230 QBrush b = d_ptr->m_brush;
231 231 if (b.style() != Qt::SolidPattern || b.color() != color) {
232 232 b.setStyle(Qt::SolidPattern);
233 233 b.setColor(color);
234 234 setBrush(b);
235 235 }
236 236 }
237 237
238 238 QColor QLegend::color()
239 239 {
240 240 return d_ptr->m_brush.color();
241 241 }
242 242
243 243 /*!
244 244 Sets the \a pen of legend. Pen affects the legend borders.
245 245 */
246 246 void QLegend::setPen(const QPen &pen)
247 247 {
248 248 if (d_ptr->m_pen != pen) {
249 249 d_ptr->m_pen = pen;
250 250 update();
251 251 emit borderColorChanged(pen.color());
252 252 }
253 253 }
254 254
255 255 /*!
256 256 Returns the pen used by legend
257 257 */
258 258
259 259 QPen QLegend::pen() const
260 260 {
261 261 return d_ptr->m_pen;
262 262 }
263 263
264 264 void QLegend::setFont(const QFont &font)
265 265 {
266 266 if (d_ptr->m_font != font) {
267 267 d_ptr->m_font = font;
268 268 foreach (LegendMarker *marker, d_ptr->markers())
269 269 marker->setFont(d_ptr->m_font);
270 270 layout()->invalidate();
271 271 emit fontChanged(font);
272 272 }
273 273 }
274 274
275 275 QFont QLegend::font() const
276 276 {
277 277 return d_ptr->m_font;
278 278 }
279 279
280 280 void QLegend::setBorderColor(QColor color)
281 281 {
282 282 QPen p = d_ptr->m_pen;
283 283 if (p.color() != color) {
284 284 p.setColor(color);
285 285 setPen(p);
286 286 }
287 287 }
288 288
289 289 QColor QLegend::borderColor()
290 290 {
291 291 return d_ptr->m_pen.color();
292 292 }
293 293
294 294 /*!
295 295 Set brush used to draw labels to \a brush.
296 296 */
297 297 void QLegend::setLabelBrush(const QBrush &brush)
298 298 {
299 299 if (d_ptr->m_labelBrush != brush) {
300 300 d_ptr->m_labelBrush = brush;
301 301 foreach (LegendMarker *marker, d_ptr->markers()) {
302 302 marker->setLabelBrush(d_ptr->m_labelBrush);
303 303 // Note: The pen of the marker rectangle could be exposed in the public QLegend API
304 304 // instead of mapping it from label brush color
305 305 marker->setPen(brush.color());
306 306 }
307 307 emit labelColorChanged(brush.color());
308 308 }
309 309 }
310 310
311 311 /*!
312 312 Brush used to draw labels.
313 313 */
314 314 QBrush QLegend::labelBrush() const
315 315 {
316 316 return d_ptr->m_labelBrush;
317 317 }
318 318
319 319 void QLegend::setLabelColor(QColor color)
320 320 {
321 321 QBrush b = d_ptr->m_labelBrush;
322 322 if (b.style() != Qt::SolidPattern || b.color() != color) {
323 323 b.setStyle(Qt::SolidPattern);
324 324 b.setColor(color);
325 325 setLabelBrush(b);
326 326 }
327 327 }
328 328
329 329 QColor QLegend::labelColor() const
330 330 {
331 331 return d_ptr->m_labelBrush.color();
332 332 }
333 333
334 334
335 335 void QLegend::setAlignment(Qt::Alignment alignment)
336 336 {
337 337 if (d_ptr->m_alignment != alignment) {
338 338 d_ptr->m_alignment = alignment;
339 339 layout()->invalidate();
340 340 }
341 341 }
342 342
343 343 Qt::Alignment QLegend::alignment() const
344 344 {
345 345 return d_ptr->m_alignment;
346 346 }
347 347
348 348 /*!
349 349 Detaches the legend from chart. Chart won't change layout of the legend.
350 350 */
351 351 void QLegend::detachFromChart()
352 352 {
353 353 d_ptr->m_attachedToChart = false;
354 354 layout()->invalidate();
355 355 setParent(0);
356 356
357 357 }
358 358
359 359 /*!
360 360 Attaches the legend to chart. Chart may change layout of the legend.
361 361 */
362 362 void QLegend::attachToChart()
363 363 {
364 364 d_ptr->m_attachedToChart = true;
365 365 layout()->invalidate();
366 366 setParent(d_ptr->m_chart);
367 367 }
368 368
369 369 /*!
370 370 Returns true, if legend is attached to chart.
371 371 */
372 372 bool QLegend::isAttachedToChart()
373 373 {
374 374 return d_ptr->m_attachedToChart;
375 375 }
376 376
377 377 /*!
378 378 Sets the visibility of legend background to \a visible
379 379 */
380 380 void QLegend::setBackgroundVisible(bool visible)
381 381 {
382 382 if (d_ptr->m_backgroundVisible != visible) {
383 383 d_ptr->m_backgroundVisible = visible;
384 384 update();
385 385 emit backgroundVisibleChanged(visible);
386 386 }
387 387 }
388 388
389 389 /*!
390 390 Returns the visibility of legend background
391 391 */
392 392 bool QLegend::isBackgroundVisible() const
393 393 {
394 394 return d_ptr->m_backgroundVisible;
395 395 }
396 396
397 397
398 398 QList<QLegendMarker*> QLegend::markers() const
399 399 {
400 400 // TODO: name of PIMPL method will change.
401 401 return d_ptr->legendMarkers();
402 402 }
403 403
404 404
405 405 /*!
406 406 \internal \a event see QGraphicsWidget for details
407 407 */
408 408 void QLegend::hideEvent(QHideEvent *event)
409 409 {
410 410 if (isAttachedToChart())
411 411 d_ptr->m_presenter->layout()->invalidate();
412 412 QGraphicsWidget::hideEvent(event);
413 413 }
414 414 /*!
415 415 \internal \a event see QGraphicsWidget for details
416 416 */
417 417 void QLegend::showEvent(QShowEvent *event)
418 418 {
419 419 if (isAttachedToChart()) {
420 420 d_ptr->items()->setVisible(false);
421 421 layout()->invalidate();
422 422 }
423 423 QGraphicsWidget::showEvent(event);
424 424 //layout activation will show the items
425 425 }
426 426
427 427 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
428 428
429 429 QLegendPrivate::QLegendPrivate(ChartPresenter *presenter, QChart *chart, QLegend *q)
430 430 : q_ptr(q),
431 431 m_presenter(presenter),
432 432 m_layout(new LegendLayout(q)),
433 433 m_chart(chart),
434 434 m_items(new QGraphicsItemGroup(q)),
435 435 m_alignment(Qt::AlignTop),
436 436 m_brush(QBrush()),
437 437 m_pen(QPen()),
438 438 m_labelBrush(QBrush()),
439 439 m_diameter(5),
440 440 m_attachedToChart(true),
441 441 m_backgroundVisible(false)
442 442 {
443 443
444 444 }
445 445
446 446 QLegendPrivate::~QLegendPrivate()
447 447 {
448 448
449 449 }
450 450
451 451 void QLegendPrivate::setOffset(qreal x, qreal y)
452 452 {
453 453 m_layout->setOffset(x, y);
454 454 }
455 455
456 456 QPointF QLegendPrivate::offset() const
457 457 {
458 458 return m_layout->offset();
459 459 }
460 460
461 461 int QLegendPrivate::roundness(qreal size)
462 462 {
463 463 return 100 * m_diameter / int(size);
464 464 }
465 465
466 466 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
467 467 {
468 468 Q_UNUSED(domain)
469 469
470 qDebug() << "QLegendPrivate::handleSeriesAdded";
471
470 472 // New markers --->
471 473 QList<QLegendMarker*> newMarkers = series->d_ptr->createLegendMarkers(q_ptr);
472 474 foreach (QLegendMarker* marker, newMarkers) {
473 475 marker->setFont(m_font);
474 476 marker->setLabelBrush(m_labelBrush);
475 477 marker->setVisible(series->isVisible());
476 478 // TODO: QLegendMarker has QGraphicsItem vs QLegendMarker is QGraphicsItem
477 // m_items->addToGroup(marker);
479 // TODO: possible hazard. What if marker is deleted and group still has pointer?
480 // m_items->addToGroup(marker->d_ptr.data());
478 481 m_legendMarkers << marker;
479 482 }
480 483
481 484 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
482 485 // <--- New markers
483 486
484 487 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
485 488
486 489 foreach (LegendMarker *marker, markers) {
487 490 marker->setFont(m_font);
488 491 marker->setLabelBrush(m_labelBrush);
489 492 marker->setVisible(series->isVisible());
490 493 m_items->addToGroup(marker);
491 494 m_markers << marker;
492 495 }
493 496
494 497 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
495 498 QObject::connect(series->d_ptr.data(), SIGNAL(countChanged()), this, SLOT(handleCountChanged()));
496 499
497 500 m_items->setVisible(false);
498 501 m_layout->invalidate();
499 502 }
500 503
501 504 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
502 505 {
503 506 // New markers --->
504 507 foreach (QLegendMarker *marker, m_legendMarkers) {
505 508 if (marker->series() == series) {
506 509 delete marker;
507 510 m_legendMarkers.removeAll(marker);
508 511 }
509 512 }
510 513
511 514 QObject::disconnect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
512 515 // <--- New markers
513 516
514 517 foreach (LegendMarker *marker, m_markers) {
515 518 if (marker->series() == series) {
516 519 delete marker;
517 520 m_markers.removeAll(marker);
518 521 }
519 522 }
520 523
521 524 QObject::disconnect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
522 525 QObject::disconnect(series->d_ptr.data(), SIGNAL(countChanged()), this, SLOT(handleCountChanged()));
523 526 m_layout->invalidate();
524 527 }
525 528
526 529 void QLegendPrivate::handleSeriesVisibleChanged()
527 530 {
528 531 QAbstractSeries *series = qobject_cast<QAbstractSeries *> (sender());
529 532 Q_ASSERT(series);
530 533
531 534 // New markers --->
532 535 foreach (QLegendMarker* marker, m_legendMarkers) {
533 536 if (marker->series() == series) {
534 537 marker->setVisible(series->isVisible());
535 538 }
536 539 }
537 540
538 541 // <--- New markers
539 542
540 543 foreach (LegendMarker* marker, m_markers) {
541 544 if (marker->series() == series) {
542 545 marker->setVisible(series->isVisible());
543 546 }
544 547 m_layout->invalidate();
545 548 }
546 549
547 550 void QLegendPrivate::handleCountChanged()
548 551 {
549 552 // With new markers, the series shoud notify markers directly?
550 553
551 554 // Handle new or removed markers
552 555 // Handle changes of marker pen/brush/label. every property that legend is interested
553 556 handleSeriesRemoved(series);
554 557 Domain domain;
555 558 handleSeriesAdded(series, &domain);
556 559 }
557 560
558 561 #include "moc_qlegend.cpp"
559 562 #include "moc_qlegend_p.cpp"
560 563
561 564 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,185 +1,187
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 "qlegendmarker.h"
22 22 #include "qlegendmarker_p.h"
23 #include "legendmarkeritem_p.h"
23 24 #include <QDebug>
24 25 #include <QFontMetrics>
25 26
26 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 28
28 29 QLegendMarker::QLegendMarker(QAbstractSeries* series, QObject *parent) :
29 30 QObject(parent),
30 31 d_ptr(new QLegendMarkerPrivate(series, this))
31 32 {
32 33 }
33 34
34 35 QLegendMarker::~QLegendMarker()
35 36 {
36 37 }
37 38
38 39 QString QLegendMarker::label() const
39 40 {
40 41 return d_ptr->m_label;
41 42 }
42 43
43 44 void QLegendMarker::setLabel(const QString &label)
44 45 {
45 46 d_ptr->m_label = label;
46 47 }
47 48
48 49 QBrush QLegendMarker::labelBrush() const
49 50 {
50 51 return d_ptr->m_labelBrush;
51 52 }
52 53
53 54 void QLegendMarker::setLabelBrush(const QBrush &brush)
54 55 {
55 56 d_ptr->m_labelBrush = brush;
56 57 }
57 58
58 59 QFont QLegendMarker::font() const
59 60 {
60 61 return d_ptr->m_font;
61 62 }
62 63
63 64 void QLegendMarker::setFont(const QFont &font)
64 65 {
65 66 d_ptr->m_font = font;
66 67 }
67 68
68 69 QPen QLegendMarker::pen() const
69 70 {
70 71 return d_ptr->m_pen;
71 72 }
72 73
73 74 void QLegendMarker::setPen(const QPen &pen)
74 75 {
75 76 d_ptr->m_pen = pen;
76 77 }
77 78
78 79 QBrush QLegendMarker::brush() const
79 80 {
80 81 return d_ptr->m_brush;
81 82 }
82 83
83 84 void QLegendMarker::setBrush(const QBrush &brush)
84 85 {
85 86 d_ptr->m_brush = brush;
86 87 }
87 88
88 89 bool QLegendMarker::isVisible() const
89 90 {
90 91 return d_ptr->m_visible;
91 92 }
92 93
93 94 void QLegendMarker::setVisible(bool visible)
94 95 {
95 96 d_ptr->m_visible = visible;
96 97 }
97 98
98 99 QAbstractSeries* QLegendMarker::series()
99 100 {
100 101 return d_ptr->m_series;
101 102 }
102 103
103 104 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
104 105
105 106 QLegendMarkerPrivate::QLegendMarkerPrivate(QAbstractSeries *series, QLegendMarker *q) :
106 107 q_ptr(q),
107 108 m_series(series)
108 109 {
109
110 m_item = new LegendMarkerItem(m_series,this);
110 111 }
111 112
112 113 void QLegendMarkerPrivate::setGeometry(const QRectF& rect)
113 114 {
114 115 QFontMetrics fn (m_font);
115 116
116 117
117 118 int width = rect.width();
118 119 qreal x = m_margin + m_markerRect.width() + m_space + m_margin;
119 120 qreal y = qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin);
120 121
121 122 if (fn.boundingRect(m_label).width() + x > width)
122 123 {
123 124 QString string = m_label + "...";
124 125 while(fn.boundingRect(string).width() + x > width && string.length() > 3)
125 126 string.remove(string.length() - 4, 1);
126 127 m_textItem->setText(string);
127 128 }
128 129 else
129 130 m_textItem->setText(m_label);
130 131
131 132 const QRectF& textRect = m_textItem->boundingRect();
132 133
133 134
134 135 m_textItem->setPos(x-m_margin,y/2 - textRect.height()/2);
135 136 m_rectItem->setRect(m_markerRect);
136 137 m_rectItem->setPos(m_margin,y/2 - m_markerRect.height()/2);
137 138
138 139 prepareGeometryChange();
139 140 m_boundingRect = QRectF(0,0,x+textRect.width()+m_margin,y);
140 141 }
141 142
142 143 QRectF QLegendMarkerPrivate::boundingRect() const
143 144 {
144 145 return m_boundingRect;
145 146 }
146 147
147 148 void QLegendMarkerPrivate::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
148 149 {
149 150 Q_UNUSED(option)
150 151 Q_UNUSED(widget)
151 152 Q_UNUSED(painter)
152 153 }
153 154
154 155 QSizeF QLegendMarkerPrivate::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
155 156 {
156 157 Q_UNUSED(constraint)
157 158
158 159 QFontMetrics fn(m_textItem->font());
159 160 QSizeF sh;
160 161
161 162 switch (which) {
162 163 case Qt::MinimumSize:
163 164 sh = QSizeF(fn.boundingRect("...").width() + 2*m_margin + m_space +m_markerRect.width(),qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin));
164 165 break;
165 166 case Qt::PreferredSize:
166 167 sh = QSizeF(fn.boundingRect(m_label).width() + 2*m_margin + m_space +m_markerRect.width(),qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin));
167 168 break;
168 169 default:
169 170 break;
170 171 }
171 172
172 173 return sh;
173 174 }
174 175
175 176 void QLegendMarkerPrivate::mousePressEvent(QGraphicsSceneMouseEvent *event)
176 177 {
178 qDebug() << "QLegendMarkerPrivate::mousePressEvent" << event;
177 179 QGraphicsObject::mousePressEvent(event);
178 180 //TODO: selected signal removed for now
179 181 }
180 182
181 183
182 184 #include "moc_qlegendmarker.cpp"
183 185 #include "moc_qlegendmarker_p.cpp"
184 186
185 187 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,121 +1,124
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 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef QLEGENDMARKERPRIVATE_H
31 31 #define QLEGENDMARKERPRIVATE_H
32 32
33 33 #include "qchartglobal.h"
34 34 #include <QGraphicsObject>
35 35 #include <QBrush>
36 36 #include <QPen>
37 37 #include <QGraphicsSimpleTextItem>
38 38 #include <QGraphicsLayoutItem>
39 39
40 40 QTCOMMERCIALCHART_BEGIN_NAMESPACE
41 41
42 42 // TODO: check these
43 43 class QAbstractSeries;
44 44 class QAreaSeries;
45 45 class QXYSeries;
46 46 class QBarSet;
47 47 class QAbstractBarSeries;
48 48 class QPieSlice;
49 49 class QLegend;
50 50 class QPieSeries;
51 51
52 52 class QLegendMarker;
53 class LegendMarkerItem;
53 54
54 55 class QLegendMarkerPrivate : public QGraphicsObject, public QGraphicsLayoutItem
55 56 {
56 57 Q_OBJECT
57 58 Q_INTERFACES(QGraphicsLayoutItem)
58 59 public:
59 60 explicit QLegendMarkerPrivate(QAbstractSeries *series, QLegendMarker *q);
60 61 /*
61 62 void setPen(const QPen &pen);
62 63 QPen pen() const;
63 64
64 65 void setBrush(const QBrush &brush);
65 66 QBrush brush() const;
66 67
67 68 void setFont(const QFont &font);
68 69 QFont font() const;
69 70
70 71 void setLabel(const QString label);
71 72 QString label() const;
72 73
73 74 void setLabelBrush(const QBrush &brush);
74 75 QBrush labelBrush() const;
75 76 */
76 77 void setGeometry(const QRectF& rect);
77 78
78 79 QRectF boundingRect() const;
79 80
80 81 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
81 82
82 83 QSizeF sizeHint (Qt::SizeHint which, const QSizeF& constraint) const;
83 84
84 85 protected:
85 86 // From QGraphicsObject
86 87 void mousePressEvent(QGraphicsSceneMouseEvent *event);
87 88
88 89 public Q_SLOTS:
89 90 virtual void updated() {};
90 91
91 92 private:
92 93 QLegendMarker *q_ptr;
93 94
95 LegendMarkerItem *m_item;
96
94 97 /*
95 98 QLegend* m_legend;
96 99 */
97 100
98 101 // New legend marker properties
99 102 QAbstractSeries* m_series;
100 103 QString m_label;
101 104 QBrush m_labelBrush;
102 105 QFont m_font;
103 106 QPen m_pen;
104 107 QBrush m_brush;
105 108 bool m_visible;
106 109
107 110 // Implementation details of new marker
108 111 QRectF m_markerRect;
109 112 QRectF m_boundingRect;
110 113 QGraphicsSimpleTextItem *m_textItem;
111 114 QGraphicsRectItem *m_rectItem;
112 115 qreal m_margin;
113 116 qreal m_space;
114 117
115 118 friend class QLegendPrivate; // TODO: Is this needed?
116 119 Q_DECLARE_PUBLIC(QLegendMarker)
117 120 };
118 121
119 122 QTCOMMERCIALCHART_END_NAMESPACE
120 123
121 124 #endif // QLEGENDMARKERPRIVATE_H
@@ -1,45 +1,50
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 "qpielegendmarker.h"
22 22 #include <QPieSeries>
23 23
24 24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25 25
26 26 QPieLegendMarker::QPieLegendMarker(QPieSeries* series, QPieSlice* slice, QObject *parent) :
27 27 QLegendMarker(series, parent),
28 28 m_slice(slice)
29 29 {
30 30 QObject::connect(slice, SIGNAL(labelChanged()), this, SLOT(updated()));
31 31 QObject::connect(slice, SIGNAL(brushChanged()), this, SLOT(updated()));
32 32 updated();
33 33 }
34 34
35 QPieSlice* QPieLegendMarker::peerObject()
36 {
37 return m_slice;
38 }
39
35 40 void QPieLegendMarker::updated()
36 41 {
37 42 // TODO: to PIMPL.
38 43 setBrush(m_slice->brush());
39 44 setLabel(m_slice->label());
40 45 }
41 46
42 47 #include "moc_qpielegendmarker.cpp"
43 48 //#include "moc_qpielegendmarker_p.cpp"
44 49
45 50 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,56 +1,57
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 #ifndef QPIELEGENDMARKER_H
22 22 #define QPIELEGENDMARKER_H
23 23
24 24 #include <QChartGlobal>
25 25 #include <QLegendMarker>
26 26 #include <QPieSlice>
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 class QTCOMMERCIALCHART_EXPORT QPieLegendMarker : public QLegendMarker
31 31 {
32 32 Q_OBJECT
33 33
34 34 public:
35 35 explicit QPieLegendMarker(QPieSeries* series, QPieSlice* slice, QObject *parent = 0);
36 36
37 virtual QPieSlice* peerObject() { return m_slice; }
37 virtual QPieSlice* peerObject();
38 38
39 // TODO: to pimp.
39 // TODO: to pimpl.
40 40 void updated();
41 41
42 42 //Q_SIGNALS:
43 43
44 44 //public Q_SLOTS:
45 45
46 46 private:
47 47 // TODO:
48 48 // QScopedPointer<QPieLegendMarkerPrivate> d_ptr;
49 49 Q_DISABLE_COPY(QPieLegendMarker)
50 50
51 // TODO: PIMPL
51 52 QPieSlice* m_slice;
52 53
53 54 };
54 55
55 56 QTCOMMERCIALCHART_END_NAMESPACE
56 57 #endif // QPIELEGENDMARKER_H
@@ -1,891 +1,892
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 "qpieseries.h"
22 22 #include "qpieseries_p.h"
23 23 #include "qpieslice.h"
24 24 #include "qpieslice_p.h"
25 25 #include "pieslicedata_p.h"
26 26 #include "chartdataset_p.h"
27 27 #include "charttheme_p.h"
28 28 #include "legendmarker_p.h"
29 29 #include "qabstractaxis.h"
30 30 #include "pieanimation_p.h"
31 31
32 32 #include "qpielegendmarker.h"
33 33
34 34 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 35
36 36 /*!
37 37 \class QPieSeries
38 38 \brief Pie series API for QtCommercial Charts
39 39
40 40 The pie series defines a pie chart which consists of pie slices which are defined as QPieSlice objects.
41 41 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
42 42 The actual slice size is determined by that relative value.
43 43
44 44 Pie size and position on the chart is controlled by using relative values which range from 0.0 to 1.0
45 45 These relate to the actual chart rectangle.
46 46
47 47 By default the pie is defined as a full pie but it can also be a partial pie.
48 48 This can be done by setting a starting angle and angle span to the series.
49 49 Full pie is 360 degrees where 0 is at 12 a'clock.
50 50
51 51 See the \l {PieChart Example} {pie chart example} or \l {DonutChart Example} {donut chart example} to learn how to use QPieSeries.
52 52 \table 100%
53 53 \row
54 54 \o \image examples_piechart.png
55 55 \o \image examples_donut.png
56 56 \endtable
57 57 */
58 58 /*!
59 59 \qmlclass PieSeries QPieSeries
60 60 \inherits AbstractSeries
61 61
62 62 The following QML shows how to create a simple pie chart.
63 63
64 64 \snippet ../demos/qmlchart/qml/qmlchart/View1.qml 1
65 65
66 66 \beginfloatleft
67 67 \image demos_qmlchart1.png
68 68 \endfloat
69 69 \clearfloat
70 70 */
71 71
72 72 /*!
73 73 \property QPieSeries::horizontalPosition
74 74 \brief Defines the horizontal position of the pie.
75 75
76 76 The value is a relative value to the chart rectangle where:
77 77
78 78 \list
79 79 \o 0.0 is the absolute left.
80 80 \o 1.0 is the absolute right.
81 81 \endlist
82 82 Default value is 0.5 (center).
83 83 \sa verticalPosition
84 84 */
85 85
86 86 /*!
87 87 \qmlproperty real PieSeries::horizontalPosition
88 88
89 89 Defines the horizontal position of the pie.
90 90
91 91 The value is a relative value to the chart rectangle where:
92 92
93 93 \list
94 94 \o 0.0 is the absolute left.
95 95 \o 1.0 is the absolute right.
96 96 \endlist
97 97 Default value is 0.5 (center).
98 98 \sa verticalPosition
99 99 */
100 100
101 101 /*!
102 102 \property QPieSeries::verticalPosition
103 103 \brief Defines the vertical position of the pie.
104 104
105 105 The value is a relative value to the chart rectangle where:
106 106
107 107 \list
108 108 \o 0.0 is the absolute top.
109 109 \o 1.0 is the absolute bottom.
110 110 \endlist
111 111 Default value is 0.5 (center).
112 112 \sa horizontalPosition
113 113 */
114 114
115 115 /*!
116 116 \qmlproperty real PieSeries::verticalPosition
117 117
118 118 Defines the vertical position of the pie.
119 119
120 120 The value is a relative value to the chart rectangle where:
121 121
122 122 \list
123 123 \o 0.0 is the absolute top.
124 124 \o 1.0 is the absolute bottom.
125 125 \endlist
126 126 Default value is 0.5 (center).
127 127 \sa horizontalPosition
128 128 */
129 129
130 130 /*!
131 131 \property QPieSeries::size
132 132 \brief Defines the pie size.
133 133
134 134 The value is a relative value to the chart rectangle where:
135 135
136 136 \list
137 137 \o 0.0 is the minimum size (pie not drawn).
138 138 \o 1.0 is the maximum size that can fit the chart.
139 139 \endlist
140 140
141 141 When setting this property the holeSize property is adjusted if necessary, to ensure that the hole size is not greater than the outer size.
142 142
143 143 Default value is 0.7.
144 144 */
145 145
146 146 /*!
147 147 \qmlproperty real PieSeries::size
148 148
149 149 Defines the pie size.
150 150
151 151 The value is a relative value to the chart rectangle where:
152 152
153 153 \list
154 154 \o 0.0 is the minimum size (pie not drawn).
155 155 \o 1.0 is the maximum size that can fit the chart.
156 156 \endlist
157 157
158 158 Default value is 0.7.
159 159 */
160 160
161 161 /*!
162 162 \property QPieSeries::holeSize
163 163 \brief Defines the donut hole size.
164 164
165 165 The value is a relative value to the chart rectangle where:
166 166
167 167 \list
168 168 \o 0.0 is the minimum size (full pie drawn, without any hole inside).
169 169 \o 1.0 is the maximum size that can fit the chart. (donut has no width)
170 170 \endlist
171 171
172 172 The value is never greater then size property.
173 173 Default value is 0.0.
174 174 */
175 175
176 176 /*!
177 177 \qmlproperty real PieSeries::holeSize
178 178
179 179 Defines the donut hole size.
180 180
181 181 The value is a relative value to the chart rectangle where:
182 182
183 183 \list
184 184 \o 0.0 is the minimum size (full pie drawn, without any hole inside).
185 185 \o 1.0 is the maximum size that can fit the chart. (donut has no width)
186 186 \endlist
187 187
188 188 When setting this property the size property is adjusted if necessary, to ensure that the inner size is not greater than the outer size.
189 189
190 190 Default value is 0.0.
191 191 */
192 192
193 193 /*!
194 194 \property QPieSeries::startAngle
195 195 \brief Defines the starting angle of the pie.
196 196
197 197 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
198 198
199 199 Default is value is 0.
200 200 */
201 201
202 202 /*!
203 203 \qmlproperty real PieSeries::startAngle
204 204
205 205 Defines the starting angle of the pie.
206 206
207 207 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
208 208
209 209 Default is value is 0.
210 210 */
211 211
212 212 /*!
213 213 \property QPieSeries::endAngle
214 214 \brief Defines the ending angle of the pie.
215 215
216 216 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
217 217
218 218 Default is value is 360.
219 219 */
220 220
221 221 /*!
222 222 \qmlproperty real PieSeries::endAngle
223 223
224 224 Defines the ending angle of the pie.
225 225
226 226 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
227 227
228 228 Default is value is 360.
229 229 */
230 230
231 231 /*!
232 232 \property QPieSeries::count
233 233
234 234 Number of slices in the series.
235 235 */
236 236
237 237 /*!
238 238 \qmlproperty int PieSeries::count
239 239
240 240 Number of slices in the series.
241 241 */
242 242
243 243 /*!
244 244 \fn void QPieSeries::countChanged()
245 245 Emitted when the slice count has changed.
246 246 \sa count
247 247 */
248 248 /*!
249 249 \qmlsignal PieSeries::onCountChanged()
250 250 Emitted when the slice count has changed.
251 251 */
252 252
253 253 /*!
254 254 \property QPieSeries::sum
255 255
256 256 Sum of all slices.
257 257
258 258 The series keeps track of the sum of all slices it holds.
259 259 */
260 260
261 261 /*!
262 262 \qmlproperty real PieSeries::sum
263 263
264 264 Sum of all slices.
265 265
266 266 The series keeps track of the sum of all slices it holds.
267 267 */
268 268
269 269 /*!
270 270 \fn void QPieSeries::sumChanged()
271 271 Emitted when the sum of all slices has changed.
272 272 \sa sum
273 273 */
274 274 /*!
275 275 \qmlsignal PieSeries::onSumChanged()
276 276 Emitted when the sum of all slices has changed. This may happen for example if you add or remove slices, or if you
277 277 change value of a slice.
278 278 */
279 279
280 280 /*!
281 281 \fn void QPieSeries::added(QList<QPieSlice*> slices)
282 282
283 283 This signal is emitted when \a slices have been added to the series.
284 284
285 285 \sa append(), insert()
286 286 */
287 287 /*!
288 288 \qmlsignal PieSeries::onAdded(PieSlice slice)
289 289 Emitted when \a slice has been added to the series.
290 290 */
291 291
292 292 /*!
293 293 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
294 294 This signal is emitted when \a slices have been removed from the series.
295 295 \sa remove()
296 296 */
297 297 /*!
298 298 \qmlsignal PieSeries::onRemoved(PieSlice slice)
299 299 Emitted when \a slice has been removed from the series.
300 300 */
301 301
302 302 /*!
303 303 \fn void QPieSeries::clicked(QPieSlice* slice)
304 304 This signal is emitted when a \a slice has been clicked.
305 305 \sa QPieSlice::clicked()
306 306 */
307 307 /*!
308 308 \qmlsignal PieSeries::onClicked(PieSlice slice)
309 309 This signal is emitted when a \a slice has been clicked.
310 310 */
311 311
312 312 /*!
313 313 \fn void QPieSeries::hovered(QPieSlice* slice, bool state)
314 314 This signal is emitted when user has hovered over or away from the \a slice.
315 315 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
316 316 \sa QPieSlice::hovered()
317 317 */
318 318 /*!
319 319 \qmlsignal PieSeries::onHovered(PieSlice slice, bool state)
320 320 This signal is emitted when user has hovered over or away from the \a slice. \a state is true when user has hovered
321 321 over the slice and false when hover has moved away from the slice.
322 322 */
323 323
324 324 /*!
325 325 \qmlmethod PieSlice PieSeries::at(int index)
326 326 Returns slice at \a index. Returns null if the index is not valid.
327 327 */
328 328
329 329 /*!
330 330 \qmlmethod PieSlice PieSeries::find(string label)
331 331 Returns the first slice with \a label. Returns null if the index is not valid.
332 332 */
333 333
334 334 /*!
335 335 \qmlmethod PieSlice PieSeries::append(string label, real value)
336 336 Adds a new slice with \a label and \a value to the pie.
337 337 */
338 338
339 339 /*!
340 340 \qmlmethod bool PieSeries::remove(PieSlice slice)
341 341 Removes the \a slice from the pie. Returns true if the removal was successful, false otherwise.
342 342 */
343 343
344 344 /*!
345 345 \qmlmethod PieSeries::clear()
346 346 Removes all slices from the pie.
347 347 */
348 348
349 349 /*!
350 350 Constructs a series object which is a child of \a parent.
351 351 */
352 352 QPieSeries::QPieSeries(QObject *parent)
353 353 : QAbstractSeries(*new QPieSeriesPrivate(this), parent)
354 354 {
355 355 Q_D(QPieSeries);
356 356 QObject::connect(this, SIGNAL(countChanged()), d, SIGNAL(countChanged()));
357 357 }
358 358
359 359 /*!
360 360 Destroys the series and its slices.
361 361 */
362 362 QPieSeries::~QPieSeries()
363 363 {
364 364 // NOTE: d_prt destroyed by QObject
365 365 }
366 366
367 367 /*!
368 368 Returns QChartSeries::SeriesTypePie.
369 369 */
370 370 QAbstractSeries::SeriesType QPieSeries::type() const
371 371 {
372 372 return QAbstractSeries::SeriesTypePie;
373 373 }
374 374
375 375 /*!
376 376 Appends a single \a slice to the series.
377 377 Slice ownership is passed to the series.
378 378
379 379 Returns true if append was succesfull.
380 380 */
381 381 bool QPieSeries::append(QPieSlice *slice)
382 382 {
383 383 return append(QList<QPieSlice *>() << slice);
384 384 }
385 385
386 386 /*!
387 387 Appends an array of \a slices to the series.
388 388 Slice ownership is passed to the series.
389 389
390 390 Returns true if append was successful.
391 391 */
392 392 bool QPieSeries::append(QList<QPieSlice *> slices)
393 393 {
394 394 Q_D(QPieSeries);
395 395
396 396 if (slices.count() == 0)
397 397 return false;
398 398
399 399 foreach (QPieSlice *s, slices) {
400 400 if (!s || d->m_slices.contains(s))
401 401 return false;
402 402 if (s->series()) // already added to some series
403 403 return false;
404 404 }
405 405
406 406 foreach (QPieSlice *s, slices) {
407 407 s->setParent(this);
408 408 QPieSlicePrivate::fromSlice(s)->m_series = this;
409 409 d->m_slices << s;
410 410 }
411 411
412 412 d->updateDerivativeData();
413 413
414 414 foreach(QPieSlice * s, slices) {
415 415 connect(s, SIGNAL(valueChanged()), d, SLOT(sliceValueChanged()));
416 416 connect(s, SIGNAL(clicked()), d, SLOT(sliceClicked()));
417 417 connect(s, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
418 418 }
419 419
420 420 emit added(slices);
421 421 emit countChanged();
422 422
423 423 return true;
424 424 }
425 425
426 426 /*!
427 427 Appends a single \a slice to the series and returns a reference to the series.
428 428 Slice ownership is passed to the series.
429 429 */
430 430 QPieSeries &QPieSeries::operator << (QPieSlice *slice)
431 431 {
432 432 append(slice);
433 433 return *this;
434 434 }
435 435
436 436
437 437 /*!
438 438 Appends a single slice to the series with give \a value and \a label.
439 439 Slice ownership is passed to the series.
440 440 */
441 441 QPieSlice *QPieSeries::append(QString label, qreal value)
442 442 {
443 443 QPieSlice *slice = new QPieSlice(label, value);
444 444 append(slice);
445 445 return slice;
446 446 }
447 447
448 448 /*!
449 449 Inserts a single \a slice to the series before the slice at \a index position.
450 450 Slice ownership is passed to the series.
451 451
452 452 Returns true if insert was successful.
453 453 */
454 454 bool QPieSeries::insert(int index, QPieSlice *slice)
455 455 {
456 456 Q_D(QPieSeries);
457 457
458 458 if (index < 0 || index > d->m_slices.count())
459 459 return false;
460 460
461 461 if (!slice || d->m_slices.contains(slice))
462 462 return false;
463 463
464 464 if (slice->series()) // already added to some series
465 465 return false;
466 466
467 467 slice->setParent(this);
468 468 QPieSlicePrivate::fromSlice(slice)->m_series = this;
469 469 d->m_slices.insert(index, slice);
470 470
471 471 d->updateDerivativeData();
472 472
473 473 connect(slice, SIGNAL(valueChanged()), d, SLOT(sliceValueChanged()));
474 474 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
475 475 connect(slice, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
476 476
477 477
478 478 emit added(QList<QPieSlice *>() << slice);
479 479 emit countChanged();
480 480
481 481 return true;
482 482 }
483 483
484 484 /*!
485 485 Removes a single \a slice from the series and deletes the slice.
486 486
487 487 Do not reference the pointer after this call.
488 488
489 489 Returns true if remove was successful.
490 490 */
491 491 bool QPieSeries::remove(QPieSlice *slice)
492 492 {
493 493 Q_D(QPieSeries);
494 494
495 495 if (!d->m_slices.removeOne(slice))
496 496 return false;
497 497
498 498 d->updateDerivativeData();
499 499
500 500 emit removed(QList<QPieSlice *>() << slice);
501 501 emit countChanged();
502 502
503 503 delete slice;
504 504 slice = 0;
505 505
506 506 return true;
507 507 }
508 508
509 509 /*!
510 510 Takes a single \a slice from the series. Does not destroy the slice object.
511 511
512 512 NOTE: The series remains as the slice's parent object. You must set the
513 513 parent object to take full ownership.
514 514
515 515 Returns true if take was successful.
516 516 */
517 517 bool QPieSeries::take(QPieSlice *slice)
518 518 {
519 519 Q_D(QPieSeries);
520 520
521 521 if (!d->m_slices.removeOne(slice))
522 522 return false;
523 523
524 524 QPieSlicePrivate::fromSlice(slice)->m_series = 0;
525 525 slice->disconnect(d);
526 526
527 527 d->updateDerivativeData();
528 528
529 529 emit removed(QList<QPieSlice *>() << slice);
530 530 emit countChanged();
531 531
532 532 return true;
533 533 }
534 534
535 535 /*!
536 536 Clears all slices from the series.
537 537 */
538 538 void QPieSeries::clear()
539 539 {
540 540 Q_D(QPieSeries);
541 541 if (d->m_slices.count() == 0)
542 542 return;
543 543
544 544 QList<QPieSlice *> slices = d->m_slices;
545 545 foreach (QPieSlice *s, d->m_slices)
546 546 d->m_slices.removeOne(s);
547 547
548 548 d->updateDerivativeData();
549 549
550 550 emit removed(slices);
551 551 emit countChanged();
552 552
553 553 foreach (QPieSlice *s, slices)
554 554 delete s;
555 555 }
556 556
557 557 /*!
558 558 Returns a list of slices that belong to this series.
559 559 */
560 560 QList<QPieSlice *> QPieSeries::slices() const
561 561 {
562 562 Q_D(const QPieSeries);
563 563 return d->m_slices;
564 564 }
565 565
566 566 /*!
567 567 returns the number of the slices in this series.
568 568 */
569 569 int QPieSeries::count() const
570 570 {
571 571 Q_D(const QPieSeries);
572 572 return d->m_slices.count();
573 573 }
574 574
575 575 /*!
576 576 Returns true is the series is empty.
577 577 */
578 578 bool QPieSeries::isEmpty() const
579 579 {
580 580 Q_D(const QPieSeries);
581 581 return d->m_slices.isEmpty();
582 582 }
583 583
584 584 /*!
585 585 Returns the sum of all slice values in this series.
586 586
587 587 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
588 588 */
589 589 qreal QPieSeries::sum() const
590 590 {
591 591 Q_D(const QPieSeries);
592 592 return d->m_sum;
593 593 }
594 594
595 595 void QPieSeries::setHoleSize(qreal holeSize)
596 596 {
597 597 Q_D(QPieSeries);
598 598 holeSize = qBound((qreal)0.0, holeSize, (qreal)1.0);
599 599 d->setSizes(holeSize, qMax(d->m_pieRelativeSize, holeSize));
600 600 }
601 601
602 602 qreal QPieSeries::holeSize() const
603 603 {
604 604 Q_D(const QPieSeries);
605 605 return d->m_holeRelativeSize;
606 606 }
607 607
608 608 void QPieSeries::setHorizontalPosition(qreal relativePosition)
609 609 {
610 610 Q_D(QPieSeries);
611 611
612 612 if (relativePosition < 0.0)
613 613 relativePosition = 0.0;
614 614 if (relativePosition > 1.0)
615 615 relativePosition = 1.0;
616 616
617 617 if (!qFuzzyIsNull(d->m_pieRelativeHorPos - relativePosition)) {
618 618 d->m_pieRelativeHorPos = relativePosition;
619 619 emit d->horizontalPositionChanged();
620 620 }
621 621 }
622 622
623 623 qreal QPieSeries::horizontalPosition() const
624 624 {
625 625 Q_D(const QPieSeries);
626 626 return d->m_pieRelativeHorPos;
627 627 }
628 628
629 629 void QPieSeries::setVerticalPosition(qreal relativePosition)
630 630 {
631 631 Q_D(QPieSeries);
632 632
633 633 if (relativePosition < 0.0)
634 634 relativePosition = 0.0;
635 635 if (relativePosition > 1.0)
636 636 relativePosition = 1.0;
637 637
638 638 if (!qFuzzyIsNull(d->m_pieRelativeVerPos - relativePosition)) {
639 639 d->m_pieRelativeVerPos = relativePosition;
640 640 emit d->verticalPositionChanged();
641 641 }
642 642 }
643 643
644 644 qreal QPieSeries::verticalPosition() const
645 645 {
646 646 Q_D(const QPieSeries);
647 647 return d->m_pieRelativeVerPos;
648 648 }
649 649
650 650 void QPieSeries::setPieSize(qreal relativeSize)
651 651 {
652 652 Q_D(QPieSeries);
653 653 relativeSize = qBound((qreal)0.0, relativeSize, (qreal)1.0);
654 654 d->setSizes(qMin(d->m_holeRelativeSize, relativeSize), relativeSize);
655 655
656 656 }
657 657
658 658 qreal QPieSeries::pieSize() const
659 659 {
660 660 Q_D(const QPieSeries);
661 661 return d->m_pieRelativeSize;
662 662 }
663 663
664 664
665 665 void QPieSeries::setPieStartAngle(qreal angle)
666 666 {
667 667 Q_D(QPieSeries);
668 668 if (qFuzzyIsNull(d->m_pieStartAngle - angle))
669 669 return;
670 670 d->m_pieStartAngle = angle;
671 671 d->updateDerivativeData();
672 672 emit d->pieStartAngleChanged();
673 673 }
674 674
675 675 qreal QPieSeries::pieStartAngle() const
676 676 {
677 677 Q_D(const QPieSeries);
678 678 return d->m_pieStartAngle;
679 679 }
680 680
681 681 /*!
682 682 Sets the end angle of the pie.
683 683
684 684 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
685 685
686 686 \a angle must be greater than start angle.
687 687
688 688 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
689 689 */
690 690 void QPieSeries::setPieEndAngle(qreal angle)
691 691 {
692 692 Q_D(QPieSeries);
693 693 if (qFuzzyIsNull(d->m_pieEndAngle - angle))
694 694 return;
695 695 d->m_pieEndAngle = angle;
696 696 d->updateDerivativeData();
697 697 emit d->pieEndAngleChanged();
698 698 }
699 699
700 700 /*!
701 701 Returns the end angle of the pie.
702 702
703 703 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
704 704
705 705 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
706 706 */
707 707 qreal QPieSeries::pieEndAngle() const
708 708 {
709 709 Q_D(const QPieSeries);
710 710 return d->m_pieEndAngle;
711 711 }
712 712
713 713 /*!
714 714 Sets the all the slice labels \a visible or invisible.
715 715
716 716 Note that this affects only the current slices in the series.
717 717 If user adds a new slice the default label visibility is false.
718 718
719 719 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
720 720 */
721 721 void QPieSeries::setLabelsVisible(bool visible)
722 722 {
723 723 Q_D(QPieSeries);
724 724 foreach (QPieSlice *s, d->m_slices)
725 725 s->setLabelVisible(visible);
726 726 }
727 727
728 728 /*!
729 729 Sets the all the slice labels \a position
730 730
731 731 Note that this affects only the current slices in the series.
732 732 If user adds a new slice the default label position is LabelOutside
733 733
734 734 \sa QPieSlice::labelPosition(), QPieSlice::setLabelPosition()
735 735 */
736 736 void QPieSeries::setLabelsPosition(QPieSlice::LabelPosition position)
737 737 {
738 738 Q_D(QPieSeries);
739 739 foreach (QPieSlice *s, d->m_slices)
740 740 s->setLabelPosition(position);
741 741 }
742 742
743 743 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
744 744
745 745
746 746 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
747 747 QAbstractSeriesPrivate(parent),
748 748 m_pieRelativeHorPos(0.5),
749 749 m_pieRelativeVerPos(0.5),
750 750 m_pieRelativeSize(0.7),
751 751 m_pieStartAngle(0),
752 752 m_pieEndAngle(360),
753 753 m_sum(0),
754 754 m_holeRelativeSize(0.0)
755 755 {
756 756 }
757 757
758 758 QPieSeriesPrivate::~QPieSeriesPrivate()
759 759 {
760 760 }
761 761
762 762 void QPieSeriesPrivate::updateDerivativeData()
763 763 {
764 764 // calculate sum of all slices
765 765 qreal sum = 0;
766 766 foreach (QPieSlice *s, m_slices)
767 767 sum += s->value();
768 768
769 769 if (!qFuzzyIsNull(m_sum - sum)) {
770 770 m_sum = sum;
771 771 emit q_func()->sumChanged();
772 772 }
773 773
774 774 // nothing to show..
775 775 if (qFuzzyIsNull(m_sum))
776 776 return;
777 777
778 778 // update slice attributes
779 779 qreal sliceAngle = m_pieStartAngle;
780 780 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
781 781 QVector<QPieSlice *> changed;
782 782 foreach (QPieSlice *s, m_slices) {
783 783 QPieSlicePrivate *d = QPieSlicePrivate::fromSlice(s);
784 784 d->setPercentage(s->value() / m_sum);
785 785 d->setStartAngle(sliceAngle);
786 786 d->setAngleSpan(pieSpan * s->percentage());
787 787 sliceAngle += s->angleSpan();
788 788 }
789 789
790 790
791 791 emit calculatedDataChanged();
792 792 }
793 793
794 794 void QPieSeriesPrivate::setSizes(qreal innerSize, qreal outerSize)
795 795 {
796 796 bool changed = false;
797 797
798 798 if (!qFuzzyIsNull(m_holeRelativeSize - innerSize)) {
799 799 m_holeRelativeSize = innerSize;
800 800 changed = true;
801 801 }
802 802
803 803 if (!qFuzzyIsNull(m_pieRelativeSize - outerSize)) {
804 804 m_pieRelativeSize = outerSize;
805 805 changed = true;
806 806 }
807 807
808 808 if (changed)
809 809 emit pieSizeChanged();
810 810 }
811 811
812 812 QPieSeriesPrivate *QPieSeriesPrivate::fromSeries(QPieSeries *series)
813 813 {
814 814 return series->d_func();
815 815 }
816 816
817 817 void QPieSeriesPrivate::sliceValueChanged()
818 818 {
819 819 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
820 820 updateDerivativeData();
821 821 }
822 822
823 823 void QPieSeriesPrivate::sliceClicked()
824 824 {
825 825 QPieSlice *slice = qobject_cast<QPieSlice *>(sender());
826 826 Q_ASSERT(m_slices.contains(slice));
827 827 Q_Q(QPieSeries);
828 828 emit q->clicked(slice);
829 829 }
830 830
831 831 void QPieSeriesPrivate::sliceHovered(bool state)
832 832 {
833 833 QPieSlice *slice = qobject_cast<QPieSlice *>(sender());
834 834 Q_ASSERT(m_slices.contains(slice));
835 835 Q_Q(QPieSeries);
836 836 emit q->hovered(slice, state);
837 837 }
838 838
839 839 void QPieSeriesPrivate::scaleDomain(Domain &domain)
840 840 {
841 841 Q_UNUSED(domain);
842 842 // does not apply to pie
843 843 }
844 844
845 845 ChartElement *QPieSeriesPrivate::createGraphics(ChartPresenter *presenter)
846 846 {
847 847 Q_Q(QPieSeries);
848 848 PieChartItem *pie = new PieChartItem(q, presenter);
849 849 if (presenter->animationOptions().testFlag(QChart::SeriesAnimations))
850 850 pie->setAnimation(new PieAnimation(pie));
851 851 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
852 852 return pie;
853 853 }
854 854
855 855 QList<LegendMarker *> QPieSeriesPrivate::createLegendMarker(QLegend *legend)
856 856 {
857 857 Q_Q(QPieSeries);
858 858 QList<LegendMarker *> markers;
859 859 foreach (QPieSlice *slice, q->slices()) {
860 860 PieLegendMarker* marker = new PieLegendMarker(q, slice, legend);
861 861 markers << marker;
862 862 }
863 863 return markers;
864 864 }
865 865
866 866 QList<QLegendMarker*> QPieSeriesPrivate::createLegendMarkers(QLegend* legend)
867 867 {
868 Q_UNUSED(legend);
868 869 Q_Q(QPieSeries);
869 870 QList<QLegendMarker*> markers;
870 871 foreach(QPieSlice* slice, q->slices()) {
871 QPieLegendMarker* marker = new QPieLegendMarker(q,slice,legend);
872 QPieLegendMarker* marker = new QPieLegendMarker(q,slice);
872 873 markers << marker;
873 874 }
874 875 return markers;
875 876 }
876 877
877 878 void QPieSeriesPrivate::initializeAxis(QAbstractAxis *axis)
878 879 {
879 880 Q_UNUSED(axis);
880 881 }
881 882
882 883 QAbstractAxis::AxisType QPieSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
883 884 {
884 885 Q_UNUSED(orientation);
885 886 return QAbstractAxis::AxisTypeNoAxis;
886 887 }
887 888
888 889 #include "moc_qpieseries.cpp"
889 890 #include "moc_qpieseries_p.cpp"
890 891
891 892 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now