##// END OF EJS Templates
legend fixes
sauimone -
r766:a9c9a730026d
parent child
Show More
@@ -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* series, QGraphicsItem *parent)
13 : QGraphicsObject(parent)
14 ,mPos(0,0)
15 ,mSize(0,0)
16 ,mBoundingRect(0,0,0,0)
17 ,mMarkerBoundingRect(0,0,0,0)
18 ,mSeries(series)
19 ,mBarset(0)
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 ,mPos(0,0)
30 ,mSize(0,0)
31 ,mBoundingRect(0,0,0,0)
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 ,mPos(0,0)
45 ,mSize(0,0)
46 ,mBoundingRect(0,0,0,0)
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* series, QGraphicsItem *parent = 0);
29 LegendMarker(QSeries* series, QBarSet* barset, QGraphicsItem *parent = 0);
30 LegendMarker(QSeries* series, QPieSlice* pieslice, QGraphicsItem *parent = 0);
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* series, Qt::MouseButton button);
57 void clicked(QBarSet* barset, Qt::MouseButton button);
58 void clicked(QPieSlice* pieslice, Qt::MouseButton button);
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* mSeries;
72 QBarSet* mBarset;
73 QPieSlice* mPieslice;
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->preferredLayout())
400 switch (m_legend->alignment())
401 401 {
402 case QLegend::PreferredLayoutTop: {
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::PreferredLayoutBottom: {
407 case QLegend::LayoutBottom: {
408 408 legendRect = plotRect.adjusted(padding,padding + plotRect.height(),-padding,0);
409 409 break;
410 410 }
411 case QLegend::PreferredLayoutLeft: {
411 case QLegend::LayoutLeft: {
412 412 legendRect = plotRect.adjusted(0,padding,-padding - plotRect.width(),-padding);
413 413 break;
414 414 }
415 case QLegend::PreferredLayoutRight: {
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::PreferredLayout
40 \enum QLegend::Layout
41 41
42 42 This enum describes the possible position for legend inside chart.
43 43
44 \value PreferredLayoutTop
45 \value PreferredLayoutBottom
46 \value PreferredLayoutLeft
47 \value PreferredLayoutRight
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_Pos(0,0),
71 m_Size(0,0),
72 m_MinimumSize(50,20), // TODO: magic numbers
73 m_MaximumSize(150,100),
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_PreferredLayout(QLegend::PreferredLayoutTop),
75 m_alignment(QLegend::LayoutTop),
76 76 mFirstMarker(0),
77 m_Margin(5)
77 m_margin(5)
78 78 {
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);
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_ScrollButtonLeft, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
84 connect(m_scrollButtonLeft, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
85 85 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
86 connect(m_ScrollButtonRight, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
86 connect(m_scrollButtonRight, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
87 87 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
88 connect(m_ScrollButtonUp, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
88 connect(m_scrollButtonUp, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
89 89 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
90 connect(m_ScrollButtonDown, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
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_Pos,m_Size);
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::PreferredLayout
159 \sa QLegend::Layout
160 160 */
161 void QLegend::setPreferredLayout(QLegend::PreferredLayout preferred)
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::PreferredLayout QLegend::preferredLayout() const
170 QLegend::Layout QLegend::alignment() const
171 171 {
172 return m_PreferredLayout;
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_MaximumSize;
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_MaximumSize = size;
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_Size;
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_Size = size;
208 if (m_Size.width() > m_MaximumSize.width()) {
209 m_Size.setWidth(m_MaximumSize.width());
207 m_size = size;
208 if (m_size.width() > m_maximumSize.width()) {
209 m_size.setWidth(m_maximumSize.width());
210 210 }
211 if (m_Size.height() > m_MaximumSize.height()) {
212 m_Size.setHeight(m_MaximumSize.height());
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_Pos = pos;
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_Markers.append(marker);
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_Markers.removeOne(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() << "not implemented.";
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_Markers.append(marker);
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_Markers.append(marker);
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_Markers.append(marker);
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_Markers) {
471 foreach (LegendMarker *m, m_markers) {
554 472 if (m->series() == series) {
555 m_Markers.removeOne(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_Markers.count() <= 0) {
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_PreferredLayout)
501 switch (m_alignment)
584 502 {
585 503 // Both cases organise items horizontally
586 case QLegend::PreferredLayoutBottom:
587 case QLegend::PreferredLayoutTop: {
504 case QLegend::LayoutBottom:
505 case QLegend::LayoutTop: {
588 506
589 507 qreal xStep = markerMaxSize.width();
590 qreal x = m_Pos.x() + m_Margin;
591 qreal y = m_Pos.y() + m_Margin;
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_ScrollButtonLeft->setVisible(true);
599 m_ScrollButtonRight->setVisible(true);
516 m_scrollButtonLeft->setVisible(true);
517 m_scrollButtonRight->setVisible(true);
600 518 // scrollbuttons visible, so add their width to total width
601 totalWidth += (m_ScrollButtonLeft->boundingRect().width() + m_Margin) * 2;
602 scrollButtonWidth = m_ScrollButtonLeft->boundingRect().width() + m_Margin;
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_ScrollButtonLeft->setVisible(false);
607 m_ScrollButtonRight->setVisible(false);
524 m_scrollButtonLeft->setVisible(false);
525 m_scrollButtonRight->setVisible(false);
608 526 }
609 m_ScrollButtonUp->setVisible(false);
610 m_ScrollButtonDown->setVisible(false);
527 m_scrollButtonUp->setVisible(false);
528 m_scrollButtonDown->setVisible(false);
611 529
612 for (int i=0; i < m_Markers.count(); i++) {
613 LegendMarker *m = m_Markers.at(i);
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_Margin) > (m_Pos.x() + m_MaximumSize.width())) {
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_ScrollButtonLeft->setPos(m_Pos.x() + m_Margin, y);
633 m_ScrollButtonRight->setPos(x + m_Margin, y);
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_Margin * 2;
636 totalHeight = markerMaxSize.height() + m_Margin * 2;
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::PreferredLayoutLeft:
642 case QLegend::PreferredLayoutRight: {
559 case QLegend::LayoutLeft:
560 case QLegend::LayoutRight: {
643 561 qreal yStep = markerMaxSize.height();
644 qreal x = m_Pos.x() + m_Margin;
645 qreal y = m_Pos.y() + m_Margin;
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_ScrollButtonUp->setVisible(true);
653 m_ScrollButtonDown->setVisible(true);
654 totalHeight += (m_ScrollButtonUp->boundingRect().height() + m_Margin) * 2; // scrollbuttons visible, so add their height to total height
655 scrollButtonHeight = m_ScrollButtonUp->boundingRect().height();
656 y += scrollButtonHeight + m_Margin; // start position changes by scrollbutton height
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_ScrollButtonUp->setVisible(false);
659 m_ScrollButtonDown->setVisible(false);
576 m_scrollButtonUp->setVisible(false);
577 m_scrollButtonDown->setVisible(false);
660 578 }
661 m_ScrollButtonLeft->setVisible(false);
662 m_ScrollButtonRight->setVisible(false);
579 m_scrollButtonLeft->setVisible(false);
580 m_scrollButtonRight->setVisible(false);
663 581
664 for (int i=0; i < m_Markers.count(); i++) {
665 LegendMarker* m = m_Markers.at(i);
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_Pos.y() + m_MaximumSize.height())) {
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_ScrollButtonUp->setPos(m_Pos.x() + m_Margin, m_Pos.y() + m_Margin);
685 m_ScrollButtonDown->setPos(m_Pos.x() + m_Margin, y + m_Margin);
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_Margin * 2;
688 totalHeight = maxRows * markerMaxSize.height() + m_Margin * 4 + scrollButtonHeight; // TODO: check this
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_Size.setWidth(totalWidth);
697 m_Size.setHeight(totalHeight);
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_ScrollButtonLeft->setPolygon(left);
717 m_ScrollButtonRight->setPolygon(right);
718 m_ScrollButtonUp->setPolygon(up);
719 m_ScrollButtonDown->setPolygon(down);
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_Markers) {
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_PreferredLayout == QLegend::PreferredLayoutLeft) || (m_PreferredLayout == QLegend::PreferredLayoutRight)) {
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_MaximumSize.height() - m_ScrollButtonLeft->boundingRect().height() * 2 - m_Margin * 4) / maximumMarkerSize().height();
665 max = (m_maximumSize.height() - m_scrollButtonLeft->boundingRect().height() * 2 - m_margin * 4) / maximumMarkerSize().height();
748 666 } else {
749 max = m_MaximumSize.height() / maximumMarkerSize().height();
667 max = m_maximumSize.height() / maximumMarkerSize().height();
750 668 }
751 669
752 if (mFirstMarker > m_Markers.count() - max)
753 mFirstMarker = m_Markers.count() - max;
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_MaximumSize.width() - m_ScrollButtonLeft->boundingRect().width() * 2 - m_Margin*4) / maximumMarkerSize().width();
676 max = (m_maximumSize.width() - m_scrollButtonLeft->boundingRect().width() * 2 - m_margin*4) / maximumMarkerSize().width();
759 677 } else {
760 max = m_MaximumSize.width() / maximumMarkerSize().width();
678 max = m_maximumSize.width() / maximumMarkerSize().width();
761 679 }
762 680
763 if (mFirstMarker > m_Markers.count() - max)
764 mFirstMarker = m_Markers.count() - max;
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_PreferredLayout == QLegend::PreferredLayoutTop) || (m_PreferredLayout == QLegend::PreferredLayoutBottom)) {
778 return (maximumMarkerSize().width() * m_Markers.count() + m_Margin * 2 > m_MaximumSize.width());
779 } else if ((m_PreferredLayout == QLegend::PreferredLayoutLeft) || (m_PreferredLayout == QLegend::PreferredLayoutRight)) {
780 return (maximumMarkerSize().height() * m_Markers.count() + m_Margin * 2 > m_MaximumSize.height());
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_Markers.count() + m_Margin * 2 > m_MaximumSize.height());
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::PreferredLayout preferredLayout() const;
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_Pos;
86 QSizeF m_Size;
87 QSizeF m_MinimumSize;
88 QSizeF m_MaximumSize;
87 QPointF m_pos;
88 QSizeF m_size;
89 QSizeF m_minimumSize;
90 QSizeF m_maximumSize;
89 91
90 QList<LegendMarker *> m_Markers;
92 QList<LegendMarker *> m_markers;
91 93
92 94 QBrush m_brush;
93 95 QPen m_pen;
94 QLegend::PreferredLayout m_PreferredLayout;
96 QLegend::Layout m_alignment;
95 97
96 98 int mFirstMarker;
97 99
98 LegendScrollButton *m_ScrollButtonLeft;
99 LegendScrollButton *m_ScrollButtonRight;
100 LegendScrollButton *m_ScrollButtonUp;
101 LegendScrollButton *m_ScrollButtonDown;
100 LegendScrollButton *m_scrollButtonLeft;
101 LegendScrollButton *m_scrollButtonRight;
102 LegendScrollButton *m_scrollButtonUp;
103 LegendScrollButton *m_scrollButtonDown;
102 104
103 qreal m_Margin;
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