From f77f13ee265a663f4a968f7b7bf6c77fcb664615 2012-01-26 14:22:11 From: Michal Klocek Date: 2012-01-26 14:22:11 Subject: [PATCH] Refactora axis and line chart to use graphics items insted of painter. --- diff --git a/example/colorlinechart/main.cpp b/example/colorlinechart/main.cpp index 5b8a53b..2a9e30c 100644 --- a/example/colorlinechart/main.cpp +++ b/example/colorlinechart/main.cpp @@ -16,9 +16,13 @@ int main(int argc, char *argv[]) QMainWindow window; QXYChartSeries* series0 = QXYChartSeries::create(); - series0->setColor(Qt::blue); + QPen blue(Qt::blue); + blue.setWidth(3); + series0->setPen(blue); QXYChartSeries* series1 = QXYChartSeries::create(); - series1->setColor(Qt::red); + QPen red(Qt::red); + red.setWidth(3); + series1->setPen(red); int numPoints = 100; @@ -30,7 +34,7 @@ int main(int argc, char *argv[]) QChartView* chartView = new QChartView(&window); chartView->addSeries(series0); chartView->addSeries(series1); - chartView->setBackgroundColor(Qt::yellow); + //chartView->setBackgroundColor(Qt::yellow); window.setCentralWidget(chartView); window.resize(400, 300); diff --git a/example/linechart/main.cpp b/example/linechart/main.cpp index aea986b..2e328fe 100644 --- a/example/linechart/main.cpp +++ b/example/linechart/main.cpp @@ -16,9 +16,13 @@ int main(int argc, char *argv[]) QMainWindow window; QXYChartSeries* series0 = QXYChartSeries::create(); - series0->setColor(Qt::blue); + QPen blue(Qt::blue); + blue.setWidth(3); + series0->setPen(blue); QXYChartSeries* series1 = QXYChartSeries::create(); - series1->setColor(Qt::red); + QPen red(Qt::red); + red.setWidth(3); + series1->setPen(red); int numPoints = 100; @@ -28,6 +32,7 @@ int main(int argc, char *argv[]) } QChartView* chartView = new QChartView(&window); + chartView->setRenderHint(QPainter::Antialiasing); chartView->addSeries(series0); chartView->addSeries(series1); diff --git a/example/zoomlinechart/main.cpp b/example/zoomlinechart/main.cpp index 1067080..2ebcc61 100644 --- a/example/zoomlinechart/main.cpp +++ b/example/zoomlinechart/main.cpp @@ -15,9 +15,13 @@ int main(int argc, char *argv[]) QMainWindow window; QXYChartSeries* series0 = QXYChartSeries::create(); - series0->setColor(Qt::blue); + QPen blue(Qt::blue); + blue.setWidth(3); + series0->setPen(blue); QXYChartSeries* series1 = QXYChartSeries::create(); - series1->setColor(Qt::red); + QPen red(Qt::red); + red.setWidth(3); + series1->setPen(red); int numPoints = 100; diff --git a/src/axisitem.cpp b/src/axisitem.cpp index a87a286..3aea090 100644 --- a/src/axisitem.cpp +++ b/src/axisitem.cpp @@ -2,6 +2,8 @@ #include #include +#define LABEL_PADDING 5 + QTCOMMERCIALCHART_BEGIN_NAMESPACE AxisItem::AxisItem(AxisType type,QGraphicsItem* parent): ChartItem(parent), @@ -17,6 +19,7 @@ AxisItem::~AxisItem() void AxisItem::setSize(const QSize& size) { m_rect = QRectF(QPoint(0,0),size); + createItems(); } void AxisItem::setLength(int length) @@ -42,52 +45,124 @@ QRectF AxisItem::boundingRect() const void AxisItem::setPlotDomain(const PlotDomain& plotDomain) { m_plotDomain = plotDomain; + createItems(); } - +/* void AxisItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget) { if (!m_rect.isValid()) - return; + return; if(m_type==X_AXIS) { - const qreal deltaX = (m_rect.width() -1) / m_ticks; + const qreal deltaX = m_rect.width() / m_ticks; + + for (int i = 0; i <= m_ticks; ++i) { + + int x = i * deltaX + m_rect.left(); - for (int i = 0; i <= m_ticks; ++i) { + if(i==0) x--; + if(i==m_ticks) x++; - int x = i * deltaX + m_rect.left(); - qreal label = m_plotDomain.m_minX + (i * m_plotDomain.spanX() - / m_ticks); - painter->drawLine(x, m_rect.top()+1, x, m_rect.bottom()); - //painter->drawLine(x, m_rect.bottom(), x, m_rect.bottom() + 5); + qreal label = m_plotDomain.m_minX + (i * m_plotDomain.spanX() + / m_ticks); + painter->drawLine(x, m_rect.top()-1, x, m_rect.bottom()+1); + // painter->drawLine(x, m_rect.bottom()-1, x, m_rect.bottom()-1 + 5); - painter->drawText(x - 50, m_rect.bottom() + 5, 100, 20, - Qt::AlignHCenter | Qt::AlignTop, - QString::number(label)); - } + painter->drawText(x - 50, m_rect.bottom() + 5, 100, 20,Qt::AlignHCenter | Qt::AlignTop, QString::number(label)); + } } if(m_type==Y_AXIS) { - const qreal deltaY = (m_rect.height() - 1) / m_ticks; + const qreal deltaY = (m_rect.height()) / m_ticks; - for (int j = 0; j <= m_ticks; ++j) { + for (int j = 0; j <= m_ticks; ++j) { - int y = j * -deltaY + m_rect.bottom(); - qreal label = m_plotDomain.m_minY + (j * m_plotDomain.spanY() - / m_ticks); + int y = j * -deltaY + m_rect.bottom(); - painter->drawLine(m_rect.left(), y, m_rect.right()-1, y); - //painter->drawLine(m_rect.left() - 5, y, m_rect.left(), y); - //TODO : margin = 50 ; - painter->drawText(m_rect.left() - 50, y - 10, 50 - 5, 20, - Qt::AlignRight | Qt::AlignVCenter, - QString::number(label)); - } + if(j==0) y++; + if(j==m_ticks) y--; + + qreal label = m_plotDomain.m_minY + (j * m_plotDomain.spanY() + / m_ticks); + + painter->drawLine(m_rect.left()-1, y, m_rect.right()+1, y); + //painter->drawLine(m_rect.left() - 5, y, m_rect.left(), y); + //TODO : margin = 50 ; + painter->drawText(m_rect.left() - 50, y - 10, 50 - 5, 20, + Qt::AlignRight | Qt::AlignVCenter, + QString::number(label)); + } } //painter->drawRect(m_rect.adjusted(0, 0, -1, -1)); +} +*/ +void AxisItem::createItems() +{ + + //TODO: this is very inefficient handling + + qDeleteAll(m_shades); + m_shades.clear(); + qDeleteAll(m_grid); + m_grid.clear(); + qDeleteAll(m_labels); + m_labels.clear(); + + + if(m_type==X_AXIS) { + + const qreal deltaX = m_rect.width() / m_ticks; + + for (int i = 0; i <= m_ticks; ++i) { + + int x = i * deltaX + m_rect.left(); + + //last grid outside chart rect + if(i==0) x--; + if(i==m_ticks) x++; + + qreal label = m_plotDomain.m_minX + (i * m_plotDomain.spanX()/ m_ticks); + + m_grid<boundingRect().center(); + text->setPos(x - center.x(), m_rect.bottom() + LABEL_PADDING); + //text->rotate(-45); + m_labels<boundingRect().center(); + + text->setPos(m_rect.left() - text->boundingRect().width() - LABEL_PADDING , y-center.y()); + //text->rotate(-45); + m_labels<drawRect(m_rect.adjusted(0, 0, -1, -1)); } //TODO "nice numbers algorithm" diff --git a/src/axisitem_p.h b/src/axisitem_p.h index 645330a..859c149 100644 --- a/src/axisitem_p.h +++ b/src/axisitem_p.h @@ -17,7 +17,7 @@ public: //from QGraphicsItem QRectF boundingRect() const; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){}; //from ChartItem void setSize(const QSize& size); @@ -28,10 +28,16 @@ public: AxisType axisType() const {return m_type;}; private: + void createItems(); +private: QRectF m_rect; int m_ticks; PlotDomain m_plotDomain; QPainterPath m_path; + + QList m_grid; + QList m_shades; + QList m_labels; AxisType m_type; }; diff --git a/src/qchart.cpp b/src/qchart.cpp index 66e827b..0a731dc 100644 --- a/src/qchart.cpp +++ b/src/qchart.cpp @@ -4,7 +4,7 @@ #include "qscatterseries_p.h" #include "qpieseries.h" #include "qxychartseries.h" - +#include "qchartaxis.h" #include "barchartseries.h" #include "bargroup.h" @@ -17,21 +17,21 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE QChart::QChart(QGraphicsObject* parent) : QGraphicsObject(parent), - m_background(new QGraphicsRectItem(this)), + m_background(new QGraphicsRectItem()), m_title(new QGraphicsTextItem(this)), m_axisX(new AxisItem(AxisItem::X_AXIS,this)), - m_axisY(new AxisItem(AxisItem::Y_AXIS,this)), m_plotDataIndex(0), m_marginSize(0) { // TODO: the default theme? - setTheme(QChart::ChartThemeVanilla); - // setFlags(QGraphicsItem::ItemClipsChildrenToShape); + //setTheme(QChart::ChartThemeVanilla); + m_backgroundGradient.setColorAt(0.0, Qt::white); + PlotDomain domain; m_plotDomainList<(series); // Use color defined by theme in case the series does not define a custom color - if (!xyseries->color().isValid() && m_themeColors.count()) - xyseries->setColor(nextColor()); + + if (!xyseries->pen().color().isValid() && m_themeColors.count()) //TODO: wtf + xyseries->setPen(nextColor()); m_plotDataIndex = 0 ; m_plotDomainList.resize(1); @@ -168,6 +169,7 @@ void QChart::setSize(const QSize& size) m_background->setRect(rect); m_backgroundGradient.setFinalStop(0,m_background->rect().height()); m_background->setBrush(m_backgroundGradient); + m_background->setPen(Qt::NoPen); //resize elements foreach (ChartItem* item ,m_chartItems) { @@ -271,7 +273,7 @@ void QChart::setTheme(QChart::ChartThemeId theme) // TODO: other series interested on themes? if (series->type() == QChartSeries::SeriesTypeLine) { QXYChartSeries *lineseries = reinterpret_cast(series); - lineseries->setColor(nextColor()); + lineseries->setPen(nextColor()); } else if (series->type() == QChartSeries::SeriesTypeScatter) { QScatterSeries *scatter = qobject_cast(series); scatter->setMarkerColor(nextColor()); @@ -340,6 +342,25 @@ void QChart::zoomOut() } } +void QChart::setAxisX(const QChartAxis& axis) +{ + setAxis(m_axisX,axis); +} +void QChart::setAxisY(const QChartAxis& axis) +{ + setAxis(m_axisY.at(0),axis); +} + +void QChart::setAxisY(const QList& axis) +{ + //TODO not implemented +} + +void QChart::setAxis(AxisItem *item, const QChartAxis& axis) +{ + item->setVisible(axis.isAxisVisible()); +} + #include "moc_qchart.cpp" QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/qchart.h b/src/qchart.h index bb1942f..4708336 100644 --- a/src/qchart.h +++ b/src/qchart.h @@ -62,10 +62,12 @@ public: void zoomIn(); void zoomOut(); - void setAxisX(QChartAxis* axis){}; - void setAxisY(QChartAxis* axis){}; - void setAxisY(QList axis){}; + void setAxisX(const QChartAxis& axis); + void setAxisY(const QChartAxis& axis); + void setAxisY(const QList& axis); +private: + void setAxis(AxisItem *item, const QChartAxis& axis); signals: //TODO chage to const QSize& size @@ -80,7 +82,7 @@ private: QLinearGradient m_backgroundGradient; QGraphicsTextItem* m_title; AxisItem* m_axisX; - AxisItem* m_axisY; + QList m_axisY; QRect m_rect; QList m_chartSeries; QVector m_plotDomainList; diff --git a/src/qchartaxis.cpp b/src/qchartaxis.cpp index b0a98fb..66456de 100644 --- a/src/qchartaxis.cpp +++ b/src/qchartaxis.cpp @@ -1,7 +1,13 @@ #include "qchartaxis.h" -QChartAxis::QChartAxis() +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +QChartAxis::QChartAxis(): +m_axisVisible(true), +m_girdVisible(true), +m_labelsVisible(true), +m_rowShadesVisible(true) { // TODO Auto-generated constructor stub @@ -12,3 +18,26 @@ QChartAxis::~QChartAxis() // TODO Auto-generated destructor stub } +void QChartAxis::setAxisVisible(bool visible) +{ + m_axisVisible=visible; +} + +void QChartAxis::setGridVisible(bool visible) +{ + m_girdVisible=visible; +} + +void QChartAxis::setLabelsVisible(bool visible) +{ + m_labelsVisible=visible; +} + +void QChartAxis::setRowShadesVisible(bool visible) +{ + m_rowShadesVisible=visible; +} + + + +QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/qchartaxis.h b/src/qchartaxis.h index d2faafd..2e817e3 100644 --- a/src/qchartaxis.h +++ b/src/qchartaxis.h @@ -1,11 +1,31 @@ #ifndef QCHARTAXIS_H_ #define QCHARTAXIS_H_ +#include + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + class QChartAxis { public: QChartAxis(); virtual ~QChartAxis(); + + bool isAxisVisible() const { return m_axisVisible;}; + void setAxisVisible(bool visible); + bool isGridVisible() const { return m_girdVisible;}; + void setGridVisible(bool visible); + bool isLabelsVisible() const { return m_labelsVisible;}; + void setLabelsVisible(bool visible); + bool isRowShadesVisible() const { return m_rowShadesVisible;}; + void setRowShadesVisible(bool visible); + +private: + bool m_axisVisible; + bool m_girdVisible; + bool m_labelsVisible; + bool m_rowShadesVisible; }; +QTCOMMERCIALCHART_END_NAMESPACE #endif /* QCHARTAXIS_H_ */ diff --git a/src/xylinechart/qxychartseries.cpp b/src/xylinechart/qxychartseries.cpp index 8811aa4..02ad4f6 100644 --- a/src/xylinechart/qxychartseries.cpp +++ b/src/xylinechart/qxychartseries.cpp @@ -2,8 +2,7 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE -QXYChartSeries::QXYChartSeries(QObject* parent):QChartSeries(parent), - m_color() +QXYChartSeries::QXYChartSeries(QObject* parent):QChartSeries(parent) { } @@ -18,11 +17,6 @@ QXYChartSeries* QXYChartSeries::create(QObject* parent) return new QXYChartSeries(parent); } -void QXYChartSeries::setColor(const QColor& color) -{ - m_color = color; -} - void QXYChartSeries::add(qreal x,qreal y) { m_x< -#include +#include +#include QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -23,17 +24,22 @@ public: void add(qreal x, qreal y); void clear(); - void setColor(const QColor& color); - const QColor& color() const { return m_color;} + + void setPen(const QPen& pen); + const QPen& pen() const { return m_pen;} + void setBrush(const QBrush& brush); + const QBrush& brush() const { return m_brush;} + int count() const; qreal x(int pos) const; qreal y(int pos) const; friend QDebug operator<< (QDebug d, const QXYChartSeries series); private: - QColor m_color; QList m_x; QList m_y; + QBrush m_brush; + QPen m_pen; }; diff --git a/src/xylinechart/xylinechartitem.cpp b/src/xylinechart/xylinechartitem.cpp index f5ef4dc..5aa9010 100644 --- a/src/xylinechart/xylinechartitem.cpp +++ b/src/xylinechart/xylinechartitem.cpp @@ -9,59 +9,59 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE XYLineChartItem::XYLineChartItem(QXYChartSeries* series,QGraphicsItem *parent):ChartItem(parent), m_series(series), -m_dirty(false) +m_pathItem(new QGraphicsPathItem(this)) { - + setFlags(QGraphicsItem::ItemClipsChildrenToShape); } void XYLineChartItem::setSize(const QSize& size) { m_rect=QRect(0,0,size.width(),size.height()); - m_dirty=true; + prepareGeometryChange(); + updateGeometry(); + } void XYLineChartItem::setPlotDomain(const PlotDomain& data) { m_plotDomain=data; - m_dirty=true; + prepareGeometryChange(); + updateGeometry(); + } QRectF XYLineChartItem::boundingRect() const { - return m_polyline.boundingRect(); + return m_rect; } - +/* +QPainterPath XYLineChartItem::shape() const +{ + return m_pathItem->shape(); +} +*/ void XYLineChartItem::updateGeometry() { if (!m_rect.isValid()) return; - const qreal deltaX = (m_rect.width()-1)/m_plotDomain.spanX(); - const qreal deltaY = (m_rect.height()-1)/m_plotDomain.spanY(); + const qreal deltaX = m_rect.width()/m_plotDomain.spanX(); + const qreal deltaY = m_rect.height()/m_plotDomain.spanY(); - m_polyline.clear(); - m_polyline.resize(m_series->count()); + QPainterPath path; for (int j = 0; j < m_series->count(); ++j) { qreal dx = m_series->x(j) - m_plotDomain.m_minX; qreal dy = m_series->y(j) - m_plotDomain.m_minY; qreal x = (dx * deltaX) + m_rect.left(); qreal y = - (dy * deltaY) + m_rect.bottom(); - m_polyline[j] = QPointF(x, y); + if(j==0) path.moveTo(x,y); + else path.lineTo(x,y); } + m_pathItem->setPath(path); + m_pathItem->setPen(m_series->pen()); + m_pathItem->setBrush(m_series->brush()); } -void XYLineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget) -{ - //TODO: remove it - if (m_dirty) { - updateGeometry(); - m_dirty=false; - } - painter->setClipRect(m_rect.adjusted(+1, +1, -1, -1)); - painter->setPen(m_series->color()); - painter->drawPolyline(m_polyline); -} - QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/xylinechart/xylinechartitem_p.h b/src/xylinechart/xylinechartitem_p.h index 34de143..b8fe1a7 100644 --- a/src/xylinechart/xylinechartitem_p.h +++ b/src/xylinechart/xylinechartitem_p.h @@ -17,7 +17,8 @@ public: //from QGraphicsItem QRectF boundingRect() const; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){}; + // virtual QPainterPath shape() const; //from ChartItem void setSize(const QSize& size); void setPlotDomain(const PlotDomain& data); @@ -30,7 +31,7 @@ private: QPolygonF m_polyline; QXYChartSeries* m_series; PlotDomain m_plotDomain; - bool m_dirty; + QGraphicsPathItem *m_pathItem; }; QTCOMMERCIALCHART_END_NAMESPACE