diff --git a/examples/stackedbarchartdrilldown/main.cpp b/examples/stackedbarchartdrilldown/main.cpp index 8cf510e..bed0ce4 100644 --- a/examples/stackedbarchartdrilldown/main.cpp +++ b/examples/stackedbarchartdrilldown/main.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -142,6 +143,9 @@ int main(int argc, char *argv[]) drilldownChart->axisX()->setGridVisible(false); // drilldownChart->axisX()->setLabelsVisible(false); + QLegend* l = drilldownChart->legend(); + l->handleGeometryChanged(QRectF(20,20,100,100)); + window.setCentralWidget(drilldownChart); window.resize(400, 300); window.show(); diff --git a/src/barchart/barchartmodel.cpp b/src/barchart/barchartmodel.cpp index d4913ad..0f9c14e 100644 --- a/src/barchart/barchartmodel.cpp +++ b/src/barchart/barchartmodel.cpp @@ -46,7 +46,7 @@ QList BarChartModel::legendEntries() for (int i=0; iname(); - l.mPen = mDataModel.at(i)->pen(); + l.mBrush = mDataModel.at(i)->brush(); legend.append(l); } return legend; diff --git a/src/qchartview.cpp b/src/qchartview.cpp index 22e5960..da59489 100644 --- a/src/qchartview.cpp +++ b/src/qchartview.cpp @@ -357,6 +357,15 @@ QChartAxis* QChartView::axisY() const } /*! + Returns the pointer to legend object of the chart +*/ +QLegend* QChartView::legend() const +{ + return m_chart->legend(); +} + + +/*! Sets animation \a options for the chart */ void QChartView::setAnimationOptions(QChart::AnimationOptions options) diff --git a/src/qchartview.h b/src/qchartview.h index 205c0cc..7663458 100644 --- a/src/qchartview.h +++ b/src/qchartview.h @@ -53,6 +53,8 @@ public: QChartAxis* axisX() const; QChartAxis* axisY() const; + QLegend* legend() const; + protected: void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); diff --git a/src/qlegend.cpp b/src/qlegend.cpp index 08338bf..251a71c 100644 --- a/src/qlegend.cpp +++ b/src/qlegend.cpp @@ -1,24 +1,54 @@ #include "qchartglobal.h" #include "qlegend.h" #include "qseries.h" +#include +#include QTCOMMERCIALCHART_BEGIN_NAMESPACE + +// TODO: this to legendmarker_p.h header +class LegendMarker : public QGraphicsItem +{ +public: + LegendMarker(QGraphicsItem *parent = 0) : QGraphicsItem(parent) + ,mBoundingRect(0,0,1,1) + {} + + void setBoundingRect(const QRectF rect) { mBoundingRect = rect; } + void setBrush(const QBrush brush) { mBrush = brush; } + void setName(const QString name) { mName = name; } + QString name() const { return mName; } + QColor color() const { return mBrush.color(); } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) + { + qDebug() << "LegendMarker::paint" << mBoundingRect; + painter->setBrush(mBrush); + painter->drawRect(mBoundingRect); + } + + QRectF boundingRect() const { return mBoundingRect; } + +private: + QRectF mBoundingRect; + QBrush mBrush; + QString mName; +}; + QLegend::QLegend(QGraphicsItem *parent) : QGraphicsObject(parent) - ,mBoundingRect(0,0,0,0) + ,mBoundingRect(0,0,1,1) { } - void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { - // TODO: - qDebug() << "QLegend::paint"; - foreach(QSeries* s, mSeriesList) { - for (int i=0; ilegendEntries().count(); i++) { - // Paint it... - //qDebug() << s->legendEntries().at(i).mName; - } + // TODO: layout for text. using marker layout + magic for now. + foreach(LegendMarker* m, mMarkers) { + QRectF r = m->boundingRect(); + painter->setPen(m->color()); + // TODO: r.y + r.height is incorrect. should be r.y. Find the bug, and remove the hack + painter->drawText(r.x() + 20, r.y()+r.height(), m->name()); } } @@ -29,16 +59,69 @@ QRectF QLegend::boundingRect() const void QLegend::handleSeriesAdded(QSeries* series,Domain* domain) { - // TODO: append entries mSeriesList.append(series); + dataChanged(); + layoutChanged(); } void QLegend::handleSeriesRemoved(QSeries* series) { - // TODO: remove entries mSeriesList.removeOne(series); + dataChanged(); + layoutChanged(); +} + +void QLegend::handleGeometryChanged(const QRectF& size) +{ + mBoundingRect = size; + layoutChanged(); } +void QLegend::dataChanged() +{ + foreach (QGraphicsItem* i, childItems()) { + delete i; + } + + mMarkers.clear(); + + foreach (QSeries* s, mSeriesList) { + for (int i=0; ilegendEntries().count(); i++) { + LegendMarker *marker = new LegendMarker(this); + marker->setBrush(s->legendEntries().at(i).mBrush); + marker->setName(s->legendEntries().at(i).mName); + mMarkers.append(marker); + childItems().append(marker); + } + } +} + + +void QLegend::layoutChanged() +{ + // Calculate layout for markers and text + if (mMarkers.count() <= 0) { + // Nothing to do + return; + } + + // TODO: marker defined by series. + QSizeF markerSize(10,10); + + // TODO: better layout, this is just concept. + // Leave some space around markers like this: | x x x x | + qreal steps = mMarkers.count() * 2 + 1; + + qreal yStep = mBoundingRect.height() / steps; + qreal x = 0; + qreal y = yStep; // first step is empty + foreach (LegendMarker* m, mMarkers) { + m->setBoundingRect(QRectF(x,y,markerSize.width(),markerSize.height())); + y += yStep*2; // 2 steps per marker (marker and empty space) + } +} + + #include "moc_qlegend.cpp" QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/qlegend.h b/src/qlegend.h index 8b90557..c5a6a31 100644 --- a/src/qlegend.h +++ b/src/qlegend.h @@ -8,8 +8,9 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE class Domain; +class LegendMarker; -class QLegend : public QGraphicsObject +class QTCOMMERCIALCHART_EXPORT QLegend : public QGraphicsObject { Q_OBJECT public: @@ -24,11 +25,15 @@ signals: public slots: void handleSeriesAdded(QSeries* series,Domain* domain); void handleSeriesRemoved(QSeries* series); + void handleGeometryChanged(const QRectF& size); private: + void dataChanged(); + void layoutChanged(); QRectF mBoundingRect; QList mSeriesList; + QList mMarkers; }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/qseries.h b/src/qseries.h index 1cb9ece..6fbf9d5 100644 --- a/src/qseries.h +++ b/src/qseries.h @@ -24,11 +24,11 @@ public: }; // Helper class to contain legend and color for it - // TODO: This as private class? Or should we expose this to user of API + // TODO: This is actually quite close to current LegendMarker.. combine them? class LegendEntry { public: QString mName; - QPen mPen; + QBrush mBrush; }; protected: