##// END OF EJS Templates
Adds area chart...
Michal Klocek -
r421:fe0a0dc06876
parent child
Show More
1 NO CONTENT: new file 100644, binary diff hidden
@@ -0,0 +1,30
1 /*!
2 \example example/areachart
3 \title AreaChart Example
4 \subtitle
5
6 The example shows how to create simple area chart.
7
8 \image areachart.png
9
10 To create area charts, we need two QLineSeries instances. They are going to define upper and lower boundary of the area.
11
12 \snippet ../example/areachart/main.cpp 1
13
14 We add data to both series, we use stream operator.
15
16 \snippet ../example/areachart/main.cpp 2
17
18 Now we create QAreaSeries instance using two line series objects. We set the custom gradient fill and width of the outline.
19
20 \snippet ../example/areachart/main.cpp 3
21
22 In the end we create QChartView instance, set title, set anti-aliasing and add area series. We also set the specific range for axes.
23
24 \snippet ../example/areachart/main.cpp 4
25
26 Chart is ready to be shown.
27
28 \snippet ../example/areachart/main.cpp 5
29
30 */ No newline at end of file
@@ -0,0 +1,8
1 !include( ../example.pri ) {
2 error( "Couldn't find the example.pri file!" )
3 }
4 TARGET = areachart
5 SOURCES += main.cpp
6
7
8
@@ -0,0 +1,59
1 #include <QApplication>
2 #include <QMainWindow>
3 #include <qchartview.h>
4 #include <qlineseries.h>
5 #include <qareaseries.h>
6 #include <qchart.h>
7 #include <qchartaxis.h>
8 #include <cmath>
9
10 QTCOMMERCIALCHART_USE_NAMESPACE
11
12 int main(int argc, char *argv[])
13 {
14 QApplication a(argc, argv);
15
16 //![1]
17
18 QLineSeries* series0 = new QLineSeries();
19 QLineSeries* series1 = new QLineSeries();
20
21 //![1]
22
23 //![2]
24 *series0 << QPointF(1, 5) << QPointF(3, 7) << QPointF(7, 6) << QPointF(9, 7) << QPointF(12,6)<<QPointF(16,7)<<QPointF(18,5);
25 *series1 << QPointF(1, 3) << QPointF(3, 4) << QPointF(7, 3) << QPointF(8, 2) << QPointF(12,3)<<QPointF(16,4)<<QPointF(18,3);
26 //![2]
27 //![3]
28
29 QAreaSeries* series = new QAreaSeries(series0,series1);
30 QPen pen(0x059605);
31 pen.setWidth(3);
32 series->setPen(pen);
33
34 QLinearGradient gradient(QPointF(0, 0), QPointF(0, 1));
35 gradient.setColorAt(0.0,0x3cc63c);
36 gradient.setColorAt(1.0, 0x26f626);
37 gradient.setCoordinateMode(QGradient::ObjectBoundingMode);
38 series->setBrush(gradient);
39
40 //![3]
41 //![4]
42 QMainWindow window;
43 QChartView* chartView = new QChartView(&window);
44
45 chartView->setChartTitle("Basic area chart example");
46 chartView->setRenderHint(QPainter::Antialiasing);
47
48 chartView->addSeries(series);
49 chartView->axisX()->setRange(0,20);
50 chartView->axisY()->setRange(0,10);
51 //![4]
52 //![5]
53 window.setCentralWidget(chartView);
54 window.resize(400, 300);
55 window.show();
56 //![5]
57
58 return a.exec();
59 }
@@ -0,0 +1,14
1 INCLUDEPATH += $$PWD
2 DEPENDPATH += $$PWD
3
4 SOURCES += \
5 #$$PWD/areachartanimationitem.cpp \
6 $$PWD/areachartitem.cpp \
7 $$PWD/qareaseries.cpp
8
9 PRIVATE_HEADERS += \
10 $$PWD/areachartitem_p.h \
11 # $$PWD/linechartanimationitem_p.h
12
13 PUBLIC_HEADERS += \
14 $$PWD/qareaseries.h No newline at end of file
@@ -0,0 +1,63
1 #include "linechartanimationitem_p.h"
2 #include "linechartitem_p.h"
3 #include <QPropertyAnimation>
4
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6
7 const static int duration = 500;
8
9
10 LineChartAnimationItem::LineChartAnimationItem(ChartPresenter* presenter, QLineSeries* series,QGraphicsItem *parent):
11 LineChartItem(presenter,series,parent)
12 {
13
14 }
15
16 LineChartAnimationItem::~LineChartAnimationItem()
17 {
18 }
19
20 void LineChartAnimationItem::addPoints(const QVector<QPointF>& points)
21 {
22 m_data=points;
23 clearView();
24 QPropertyAnimation *animation = new QPropertyAnimation(this, "a_addPoints", parent());
25 animation->setDuration(duration);
26 //animation->setEasingCurve(QEasingCurve::InOutBack);
27 animation->setKeyValueAt(0.0, 0);
28 animation->setKeyValueAt(1.0, m_data.size());
29 animation->start(QAbstractAnimation::DeleteWhenStopped);
30 }
31
32 void LineChartAnimationItem::setPoint(int index,const QPointF& point)
33 {
34 AnimationHelper* helper = new AnimationHelper(this,index);
35 QPropertyAnimation *animation = new QPropertyAnimation(helper, "point", parent());
36 animation->setDuration(duration);
37 //animation->setEasingCurve(QEasingCurve::InOutBack);
38 animation->setKeyValueAt(0.0, points().value(index));
39 animation->setKeyValueAt(1.0, point);
40 animation->start(QAbstractAnimation::DeleteWhenStopped);
41 }
42
43 void LineChartAnimationItem::aw_addPoints(int points)
44 {
45 int index = count();
46 for(int i = index;i< points ;i++){
47 LineChartItem::addPoint(m_data.at(i));
48 }
49 updateGeometry();
50 update();
51 }
52
53 void LineChartAnimationItem::aw_setPoint(int index,const QPointF& point)
54 {
55 LineChartItem::setPoint(index,point);
56 updateGeometry();
57 update();
58 }
59
60
61 #include "moc_linechartanimationitem_p.cpp"
62
63 QTCOMMERCIALCHART_END_NAMESPACE
@@ -0,0 +1,55
1 #ifndef LINECHARTANIMATIONITEM_P_H_
2 #define LINECHARTANIMATIONITEM_P_H_
3
4 #include "qchartglobal.h"
5 #include "linechartitem_p.h"
6 #include "domain_p.h"
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
10 class LineChartItem;
11
12 class LineChartAnimationItem : public LineChartItem {
13 Q_OBJECT
14 Q_PROPERTY(int a_addPoints READ ar_addPoints WRITE aw_addPoints);
15 // Q_PROPERTY(QPointF a_setPoint READ ar_setPoint WRITE aw_setPoint);
16 public:
17 LineChartAnimationItem(ChartPresenter* presenter, QLineSeries *series, QGraphicsItem *parent = 0);
18 virtual ~LineChartAnimationItem();
19
20 void addPoints(const QVector<QPointF>& points);
21 void setPoint(int index,const QPointF& point);
22 //void removePoint(const QPointF& point){};
23 //void setPoint(const QPointF& oldPoint, const QPointF& newPoint){};
24
25 int ar_addPoints() const { return m_addPoints;}
26 void aw_addPoints(int points);
27 const QPointF& ar_setPoint() const { return m_setPoint;}
28 void aw_setPoint(int index,const QPointF& point);
29
30 private:
31 QVector<QPointF> m_data;
32 Domain m_domain;
33 int m_addPoints;
34 QPointF m_setPoint;
35 int m_setPoint_index;
36 };
37
38 class AnimationHelper: public QObject
39 {
40 Q_OBJECT
41 Q_PROPERTY(QPointF point READ point WRITE setPoint);
42 public:
43 AnimationHelper(LineChartAnimationItem* item,int index):m_item(item),m_index(index){};
44 void setPoint(const QPointF& point){
45 m_item->aw_setPoint(m_index,point);
46 }
47 QPointF point(){return m_point;}
48 QPointF m_point;
49 LineChartAnimationItem* m_item;
50 int m_index;
51 };
52
53 QTCOMMERCIALCHART_END_NAMESPACE
54
55 #endif
@@ -0,0 +1,116
1 #include "areachartitem_p.h"
2 #include "qareaseries.h"
3 #include "qlineseries.h"
4 #include "chartpresenter_p.h"
5 #include <QPainter>
6
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
10 //TODO: optimize : remove points which are not visible
11
12 AreaChartItem::AreaChartItem(ChartPresenter* presenter, QAreaSeries* areaSeries,QGraphicsItem *parent):ChartItem(parent),
13 m_presenter(presenter),
14 m_series(areaSeries),
15 m_upper(0),
16 m_lower(0)
17 {
18 //m_items.setZValue(ChartPresenter::LineChartZValue);
19 m_upper = new AreaBoundItem(this,presenter,m_series->upperSeries());
20 if(m_series->lowerSeries()){
21 m_lower = new AreaBoundItem(this,presenter,m_series->lowerSeries());
22 }
23 setZValue(ChartPresenter::LineChartZValue);
24
25 QObject::connect(presenter,SIGNAL(geometryChanged(const QRectF&)),this,SLOT(handleGeometryChanged(const QRectF&)));
26 QObject::connect(areaSeries,SIGNAL(updated()),this,SLOT(handleUpdated()));
27
28 handleUpdated();
29 }
30
31 AreaChartItem::~AreaChartItem()
32 {
33 delete m_upper;
34 delete m_lower;
35 };
36
37 QRectF AreaChartItem::boundingRect() const
38 {
39 return m_rect;
40 }
41
42 QPainterPath AreaChartItem::shape() const
43 {
44 return m_path;
45 }
46
47 void AreaChartItem::setPen(const QPen& pen)
48 {
49 m_pen = pen;
50 }
51
52 void AreaChartItem::setBrush(const QBrush& brush)
53 {
54 m_brush = brush;
55 }
56
57 void AreaChartItem::updatePath()
58 {
59 QPainterPath path;
60
61 path.connectPath(m_upper->shape());
62 if(m_lower){
63 path.connectPath(m_lower->shape().toReversed());
64 }
65 else{
66 QPointF first = path.pointAtPercent(0);
67 QPointF last = path.pointAtPercent(1);
68 path.lineTo(last.x(),m_clipRect.bottom());
69 path.lineTo(first.x(),m_clipRect.bottom());
70 }
71 path.closeSubpath();
72 prepareGeometryChange();
73 m_path=path;
74 m_rect=path.boundingRect();
75 update();
76 }
77
78 void AreaChartItem::handleUpdated()
79 {
80 setPen(m_series->pen());
81 setBrush(m_series->brush());
82 update();
83 }
84
85 void AreaChartItem::handleDomainChanged(const Domain& domain)
86 {
87 m_upper->handleDomainChanged(domain);
88 if(m_lower)
89 m_lower->handleDomainChanged(domain);
90 }
91
92 void AreaChartItem::handleGeometryChanged(const QRectF& rect)
93 {
94 m_clipRect=rect.translated(-rect.topLeft());
95 setPos(rect.topLeft());
96 m_upper->handleGeometryChanged(rect);
97 if(m_lower)
98 m_lower->handleGeometryChanged(rect);
99 }
100 //painter
101
102 void AreaChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
103 {
104 Q_UNUSED(widget);
105 Q_UNUSED(option);
106 painter->save();
107 painter->setPen(m_pen);
108 painter->setBrush(m_brush);
109 painter->setClipRect(m_clipRect);
110 painter->drawPath(m_path);
111 painter->restore();
112 }
113
114 #include "moc_areachartitem_p.cpp"
115
116 QTCOMMERCIALCHART_END_NAMESPACE
@@ -0,0 +1,67
1 #ifndef AREACHARTITEM_H
2 #define AREACHARTITEM_H
3
4 #include "qchartglobal.h"
5 #include "linechartitem_p.h"
6 #include <QPen>
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
10 class ChartPresenter;
11 class QAreaSeries;
12 class AreaChartItem;
13
14 class AreaChartItem : public QObject ,public ChartItem
15 {
16 Q_OBJECT
17 public:
18 AreaChartItem(ChartPresenter* presenter, QAreaSeries* areaSeries, QGraphicsItem *parent = 0);
19 ~ AreaChartItem();
20
21 //from QGraphicsItem
22 QRectF boundingRect() const;
23 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
24 QPainterPath shape() const;
25
26 void setPen(const QPen& pen);
27 void setBrush(const QBrush& brush);
28 void setPointsVisible(bool visible);
29 void updatePath();
30 public slots:
31 void handleUpdated();
32 void handleDomainChanged(const Domain& domain);
33 void handleGeometryChanged(const QRectF& size);
34
35 private:
36 ChartPresenter* m_presenter;
37 QPainterPath m_path;
38 QAreaSeries* m_series;
39 LineChartItem* m_upper;
40 LineChartItem* m_lower;
41 QRectF m_rect;
42 QRectF m_clipRect;
43 QPen m_pen;
44 QBrush m_brush;
45 };
46
47 class AreaBoundItem : public LineChartItem
48 {
49 public:
50 AreaBoundItem(AreaChartItem* item,ChartPresenter* presenter, QLineSeries* lineSeries):LineChartItem(presenter,lineSeries),
51 m_item(item){};
52
53 ~AreaBoundItem(){};
54
55 void applyGeometry(QVector<QPointF>& points){
56 LineChartItem::applyGeometry(points);
57 m_item->updatePath();
58 }
59
60 private:
61 AreaChartItem* m_item;
62
63 };
64
65 QTCOMMERCIALCHART_END_NAMESPACE
66
67 #endif
@@ -0,0 +1,115
1 #include "qareaseries.h"
2 #include "qlineseries.h"
3
4 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5
6 /*!
7 \class QAreaSeries
8 \brief The QAreaSeries class is used for making area charts.
9
10 \mainclass
11
12 An area chart is used to show quantitative data. It is based on line chart, in the way that area between axis and the line
13 is emphasized with color. Since the area chart is based on line chart, QAreaSeries constructor needs QLineSeries instance,
14 which defines "upper" boundary of the area. "Lower" boundary is defined by default by axis X (y=0). Instead of axis X "lower" boundary can be also specified also by other line.
15 In that case QAreaSeries should be initiated with two QLineSerie instances. Please note terms "upper" and "lower" boundary can be misleading in cases
16 where "lower" boundary had bigger values than the "upper" one, however the main point that area between these two boundary will be filled.
17
18 \image areachart.png
19
20 Creating basic area chart is simple:
21 \code
22 QLineSeries* lineSeries = new QLineSeries();
23 series->add(0, 6);
24 series->add(2, 4);
25 QAreaSeries* areaSeries = new QAreaSeries(lineSeries);
26 ...
27 chartView->addSeries(areaSeries);
28 \endcode
29 */
30
31 /*!
32 \fn virtual QSeriesType QAreaSeries::type() const
33 \brief Returns type of series.
34 \sa QSeries, QSeriesType
35 */
36
37 /*!
38 \fn QLineSeries* QAreaSeries::upperSeries() const
39 \brief Returns upperSeries used to define one of area boundaries.
40 */
41
42 /*!
43 \fn QLineSeries* QAreaSeries::lowerSeries() const
44 \brief Returns lowerSeries used to define one of area boundaries. Note if QAreaSeries where counstucted wihtout a\ lowerSeries
45 this function return Null pointer.
46 */
47
48 /*!
49 \fn QPen QAreaSeries::pen() const
50 \brief Returns the pen used to draw line for this series.
51 \sa setPen()
52 */
53
54 /*!
55 \fn QPen QAreaSeries::brush() const
56 \brief Returns the brush used to draw line for this series.
57 \sa setBrush()
58 */
59
60 /*!
61 \fn bool QAreaSeries::pointsVisible() const
62 \brief Returns if the points are drawn for this series.
63 \sa setPointsVisible()
64 */
65
66 /*!
67 \fn void QAreaSeries::updated()
68 \brief \internal
69 */
70
71 /*!
72 Constructs area series object which is a child of \a upperSeries. Area will be spanned between \a
73 upperSeries line and \a lowerSeries line. If no \a lowerSeries is passed to constructor, area is specified by axis x (y=0) instead.
74 When series object is added to QChartView or QChart instance ownerships is transfered.
75 */
76 QAreaSeries::QAreaSeries(QLineSeries* upperSeries,QLineSeries* lowerSeries):QSeries(upperSeries),
77 m_upperSeries(upperSeries),
78 m_lowerSeries(lowerSeries),
79 m_pointsVisible(false)
80 {
81 }
82 /*!
83 Destroys the object. Series added to QChartView or QChart instances are owned by those,
84 and are deleted when mentioned object are destroyed.
85 */
86 QAreaSeries::~QAreaSeries()
87 {
88 }
89
90 /*!
91 Sets \a pen used for drawing area outline.
92 */
93 void QAreaSeries::setPen(const QPen& pen)
94 {
95 m_pen=pen;
96 }
97
98 /*!
99 Sets \a brush used for filling the area.
100 */
101 void QAreaSeries::setBrush(const QBrush& brush)
102 {
103 m_brush=brush;
104 }
105 /*!
106 Sets if data points are \a visible and should be drawn on line.
107 */
108 void QAreaSeries::setPointsVisible(bool visible)
109 {
110 m_pointsVisible=visible;
111 }
112
113 #include "moc_qareaseries.cpp"
114
115 QTCOMMERCIALCHART_END_NAMESPACE
@@ -0,0 +1,48
1 #ifndef QAREASERIES_H_
2 #define QAREASERIES_H_
3
4 #include "qchartglobal.h"
5 #include "qseries.h"
6 #include <QDebug>
7 #include <QPen>
8 #include <QBrush>
9
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 class QLineSeries;
12
13 class QTCOMMERCIALCHART_EXPORT QAreaSeries : public QSeries
14 {
15 Q_OBJECT
16 public:
17 QAreaSeries(QLineSeries* upperSeries,QLineSeries* lowerSeries=0);
18 virtual ~QAreaSeries();
19
20 public: // from QChartSeries
21 virtual QSeriesType type() const { return QSeries::SeriesTypeArea;}
22
23 QLineSeries* upperSeries() const { return m_upperSeries;}
24 QLineSeries* lowerSeries() const { return m_lowerSeries;}
25
26 void setPen(const QPen& pen);
27 QPen pen() const { return m_pen;}
28
29 void setBrush(const QBrush& brush);
30 QBrush brush() const { return m_brush;}
31
32 void setPointsVisible(bool visible);
33 bool pointsVisible() const {return m_pointsVisible;}
34
35 signals:
36 void updated();
37
38 private:
39 QBrush m_brush;
40 QPen m_pen;
41 QLineSeries* m_upperSeries;
42 QLineSeries* m_lowerSeries;
43 bool m_pointsVisible;
44 };
45
46 QTCOMMERCIALCHART_END_NAMESPACE
47
48 #endif
@@ -1,50 +1,51
1 1 /*!
2 2 \page classes.html
3 3 \title QtCommercial Charts API
4 4 \keyword All Classes
5 5
6 6 \raw HTML
7 7 <table cellpadding="2" cellspacing="1" border="0" width="100%" class="indextable">
8 8 <tr>
9 9 <th class="titleheader" width="33%">
10 10 List of classes
11 11 </th>
12 12 </tr>
13 13 <tr>
14 14 <td valign="top">
15 15 <ul>
16 <li><a href="qareaseries.html">QAreaSeries</a></li>
16 17 <li><a href="qbarseries.html">QBarSeries</a></li>
17 18 <li><a href="qbarset.html">QBarSet</a></li>
18 19 <li><a href="qchart.html">QChart</a></li>
19 20 <li><a href="qchartaxis.html">QChartAxis</a></li>
20 21 <li><a href="qchartview.html">QChartView</a></li>
21 22 <li><a href="qlineseries.html">QLineSeries</a></li>
22 23 <li><a href="qpercentbarseries.html">QPercentBarSeries</a></li>
23 24 <li><a href="qpieseries.html">QPieSeries</a></li>
24 25 <li><a href="qpieslice.html">QPieSlice</a></li>
25 26 <li><a href="qscatterseries.html">QScatterSeries</a></li>
26 27 <li><a href="qseries.html">QSeries</a></li>
27 28 <li><a href="qstackedbarseries.html">QStackedBarSeries</a></li>
28 29 </ul>
29 30 </td>
30 31 </tr>
31 32 </table>
32 33
33 34 <table cellpadding="2" cellspacing="1" border="0" width="100%" class="indextable">
34 35 <tr>
35 36 <th class="titleheader" width="33%">
36 37 Other files:
37 38 </th>
38 39 </tr>
39 40 <tr>
40 41 <td valign="top">
41 42 <ul>
42 43 <li><a href="qchartglobal.html">QChartGlobal</a></li>
43 44 </ul>
44 45 </td>
45 46 </tr>
46 47 </table>
47 48
48 49 \endraw
49 50
50 51 */
@@ -1,26 +1,27
1 1 /*!
2 2 \page examples.html
3 3 \title Examples
4 4 \keyword Examples
5 5
6 6 \raw HTML
7 7 <table cellpadding="2" cellspacing="1" border="0" width="100%" class="indextable">
8 8 <tr>
9 9 <th class="titleheader" width="33%">
10 10 List of examples
11 11 </th>
12 12 </tr>
13 13 <tr>
14 14 <td valign="top">
15 15 <ul>
16 <li><a href="example-areachart.html">Area Chart example</a></li>
16 17 <li><a href="example-barchart.html">Bar Chart example</a></li>
17 18 <li><a href="example-stackedbarchart.html">Stacked Bar Chart example</a></li>
18 19 <li><a href="example-percentbarchart.html">Percent Bar Chart example</a></li>
19 20 <li><a href="example-linechart.html">Line Chart example</a></li>
20 21 <li><a href="example-piechart.html">Pie Chart example</a></li>
21 22 </ul>
22 23 </td>
23 24 </tr>
24 25 </table>
25 26 \endraw
26 27 */
@@ -1,40 +1,41
1 1 /*!
2 2 \page index.html
3 3 \keyword About
4 4
5 5 \raw HTML
6 6 <div class="qchart">
7 7 <img src="images/qt_commercial_logo.png" alt="qtcommercial"/>
8 8
9 9 <p>
10 10 QCharts is a part of Qt Commercial addons package. It provides a set of easy to use chart
11 11 components which are available for Qt Commercial customers. It uses Qt Graphics View
12 12 Framework, therefore charts can be easily integrated to modern 2D user interfaces. QCharts can
13 13 be used as QWidgets, QGraphicsWidget or QML elements. Users can easily create impressive
14 14 graphs by selecting one of the charts themes.
15 15 </p>
16 16
17 17 <table><tr>
18 18 <td><a href="example-linechart.html"><img src="images/linechart.png" alt="linechart" /></a></td>
19 <td><a href="example-barchart.html"><img src="images/barchart.png" alt="barchart" /></a></td>
19 <td><a href="example-areachart.html"><img src="images/areachart.png" alt="areachart" /></a></td>
20 20 </tr>
21 21 <tr>
22 <td><a href="example-barchart.html"><img src="images/barchart.png" alt="barchart" /></a></td>
22 23 <td><a href="example-percentbarchart.html"><img src="images/percentbarchart.png" alt="percentbarcchart" /></a></td>
23 <td><a href="example-stackedbarchart.html"><img src="images/stackedbarchart.png" alt="stackedbarchart" /></a></td>
24 24 </tr>
25 25 <tr>
26 <td><a href="example-stackedbarchart.html"><img src="images/stackedbarchart.png" alt="stackedbarchart" /></a></td>
26 27 <td><img src="images/chartview_example.jpg " alt="linechart" /></td>
27 <td><img src="images/chartview_example_pie.jpg " alt="piechart" /></td>
28 28 </tr><tr>
29 29 <td><img src="images/chartview_example_scatter.jpg " alt="scatterchart" /></td>
30 30 <td><img src="images/chartview_example_theme.jpg " alt="themechart" /></td>
31 31 </tr>
32 32 <tr>
33 <td><img src="images/chartview_example_bar.jpg " alt="barchart" /></td>
33 <td><img src="images/chartview_example_bar.jpg " alt="barchart" /></td>
34 <td><img src="images/chartview_example_pie.jpg " alt="piechart" /></td>
34 35 </tr>
35 36 </table>
36 37 </div>
37 38 \endraw
38 39
39 40
40 41 */
@@ -1,17 +1,18
1 1 TEMPLATE = subdirs
2 2 SUBDIRS += linechart \
3 3 zoomlinechart \
4 4 colorlinechart \
5 5 barchart \
6 6 stackedbarchart \
7 7 percentbarchart \
8 8 scatter \
9 9 piechart \
10 10 piechartdrilldown \
11 11 dynamiclinechart \
12 12 axischart \
13 13 multichart \
14 14 gdpbarchart \
15 15 presenterchart \
16 16 chartview \
17 scatterinteractions
17 scatterinteractions \
18 areachart
@@ -1,403 +1,432
1 1 #include "chartdataset_p.h"
2 2 #include "qchartaxis.h"
3 3 //series
4 4 #include "qlineseries.h"
5 #include "qareaseries.h"
5 6 #include "qbarseries.h"
6 7 #include "qstackedbarseries.h"
7 8 #include "qpercentbarseries.h"
8 9 #include "qpieseries.h"
9 10 #include "qscatterseries.h"
10 11
11 12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 13
13 14 ChartDataSet::ChartDataSet(QObject *parent):QObject(parent),
14 15 m_axisX(new QChartAxis(this)),
15 16 m_axisY(new QChartAxis(this)),
16 17 m_domainIndex(0),
17 18 m_axisXInitialized(false)
18 19 {
19 20 }
20 21
21 22 ChartDataSet::~ChartDataSet()
22 23 {
23 24 // TODO Auto-generated destructor stub
24 25 }
25 26
26 27 const Domain ChartDataSet::domain(QChartAxis *axisY) const
27 28 {
28 29 int i = m_domainMap.count(axisY);
29 30 if(i == 0) {
30 31 return Domain();
31 32 }
32 33 i = i - m_domainIndex -1;
33 34 return m_domainMap.values(axisY).at(i);
34 35 }
35 36
36 37 void ChartDataSet::addSeries(QSeries* series, QChartAxis *axisY)
37 38 {
38 39 // TODO: we should check the series not already added
39 40
40 41 series->setParent(this);// take ownership
41 42 clearDomains();
42 43
43 44 if(axisY==0) axisY = m_axisY;
44 45 axisY->setParent(this);// take ownership
45 46
46 47 QList<QSeries*> seriesList = m_seriesMap.values(axisY);
47 48
48 49 QList<Domain> domainList = m_domainMap.values(axisY);
49 50
50 51 Q_ASSERT(domainList.size()<=1);
51 52
52 53 Domain domain;
53 54
54 55 if(domainList.size()>0) domain = domainList.at(0);
55 56
56 57 switch(series->type())
57 58 {
58 59 case QSeries::SeriesTypeLine: {
59 60
60 QLineSeries* xyseries = static_cast<QLineSeries*>(series);
61 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
61 62
62 for (int i = 0; i < xyseries->count(); i++)
63 for (int i = 0; i < lineSeries->count(); i++)
63 64 {
64 qreal x = xyseries->x(i);
65 qreal y = xyseries->y(i);
65 qreal x = lineSeries->x(i);
66 qreal y = lineSeries->y(i);
66 67 domain.m_minX = qMin(domain.m_minX,x);
67 68 domain.m_minY = qMin(domain.m_minY,y);
68 69 domain.m_maxX = qMax(domain.m_maxX,x);
69 70 domain.m_maxY = qMax(domain.m_maxY,y);
70 71 }
71 72 break;
72 73 }
74 case QSeries::SeriesTypeArea: {
75
76 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
77
78 QLineSeries* upperSeries = areaSeries->upperSeries();
79 QLineSeries* lowerSeries = areaSeries->lowerSeries();
80
81 for (int i = 0; i < upperSeries->count(); i++)
82 {
83 qreal x = upperSeries->x(i);
84 qreal y = upperSeries->y(i);
85 domain.m_minX = qMin(domain.m_minX,x);
86 domain.m_minY = qMin(domain.m_minY,y);
87 domain.m_maxX = qMax(domain.m_maxX,x);
88 domain.m_maxY = qMax(domain.m_maxY,y);
89 }
90 if(lowerSeries){
91 for (int i = 0; i < lowerSeries->count(); i++)
92 {
93 qreal x = lowerSeries->x(i);
94 qreal y = lowerSeries->y(i);
95 domain.m_minX = qMin(domain.m_minX,x);
96 domain.m_minY = qMin(domain.m_minY,y);
97 domain.m_maxX = qMax(domain.m_maxX,x);
98 domain.m_maxY = qMax(domain.m_maxY,y);
99 }}
100 break;
101 }
73 102 case QSeries::SeriesTypeBar: {
74 103 qDebug() << "QChartSeries::SeriesTypeBar";
75 104 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
76 105 qreal x = barSeries->categoryCount();
77 106 qreal y = barSeries->max();
78 107 domain.m_minX = qMin(domain.m_minX,x);
79 108 domain.m_minY = qMin(domain.m_minY,y);
80 109 domain.m_maxX = qMax(domain.m_maxX,x);
81 110 domain.m_maxY = qMax(domain.m_maxY,y);
82 111 break;
83 112 }
84 113 case QSeries::SeriesTypeStackedBar: {
85 114 qDebug() << "QChartSeries::SeriesTypeStackedBar";
86 115
87 116 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
88 117 qreal x = stackedBarSeries->categoryCount();
89 118 qreal y = stackedBarSeries->maxCategorySum();
90 119 domain.m_minX = qMin(domain.m_minX,x);
91 120 domain.m_minY = qMin(domain.m_minY,y);
92 121 domain.m_maxX = qMax(domain.m_maxX,x);
93 122 domain.m_maxY = qMax(domain.m_maxY,y);
94 123 break;
95 124 }
96 125 case QSeries::SeriesTypePercentBar: {
97 126 qDebug() << "QChartSeries::SeriesTypePercentBar";
98 127
99 128 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
100 129 qreal x = percentBarSeries->categoryCount();
101 130 domain.m_minX = qMin(domain.m_minX,x);
102 131 domain.m_minY = 0;
103 132 domain.m_maxX = qMax(domain.m_maxX,x);
104 133 domain.m_maxY = 100;
105 134 break;
106 135 }
107 136
108 137 case QSeries::SeriesTypePie: {
109 138 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
110 139 // TODO: domain stuff
111 140 break;
112 141 }
113 142
114 143 case QSeries::SeriesTypeScatter: {
115 144 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
116 145 Q_ASSERT(scatterSeries);
117 146 foreach (QPointF point, scatterSeries->data()) {
118 147 domain.m_minX = qMin(domain.m_minX, point.x());
119 148 domain.m_maxX = qMax(domain.m_maxX, point.x());
120 149 domain.m_minY = qMin(domain.m_minY, point.y());
121 150 domain.m_maxY = qMax(domain.m_maxY, point.y());
122 151 }
123 152 break;
124 153 }
125 154
126 155 default: {
127 156 qDebug()<<__FUNCTION__<<"type" << series->type()<<"not supported";
128 157 return;
129 158 break;
130 159 }
131 160
132 161 }
133 162
134 163 if(!m_domainMap.contains(axisY))
135 164 {
136 165 emit axisAdded(axisY);
137 166 QObject::connect(axisY,SIGNAL(rangeChanged(QChartAxis*)),this,SLOT(handleRangeChanged(QChartAxis*)));
138 167 QObject::connect(axisY,SIGNAL(ticksChanged(QChartAxis*)),this,SLOT(handleTickChanged(QChartAxis*)));
139 168 }
140 169
141 170 if(!m_axisXInitialized)
142 171 {
143 172 emit axisAdded(axisX());
144 173 QObject::connect(axisX(),SIGNAL(rangeChanged(QChartAxis*)),this,SLOT(handleRangeChanged(QChartAxis*)));
145 174 QObject::connect(axisX(),SIGNAL(ticksChanged(QChartAxis*)),this,SLOT(handleTickChanged(QChartAxis*)));
146 175 m_axisXInitialized=true;
147 176 }
148 177
149 178 m_domainMap.replace(axisY,domain);
150 179 m_seriesMap.insert(axisY,series);
151 180 emit seriesAdded(series);
152 181 setDomain(m_domainIndex,axisY);
153 182
154 183 }
155 184
156 185 void ChartDataSet::removeSeries(QSeries* series)
157 186 {
158 187 QList<QChartAxis*> keys = m_seriesMap.uniqueKeys();
159 188 foreach(QChartAxis* axis , keys) {
160 189 if(m_seriesMap.contains(axis,series)) {
161 190 emit seriesRemoved(series);
162 191 m_seriesMap.remove(axis,series);
163 192 //remove axis if no longer there
164 193 if(!m_seriesMap.contains(axis)) {
165 194 emit axisRemoved(axis);
166 195 m_domainMap.remove(axis);
167 196 if(axis != m_axisY)
168 197 delete axis;
169 198 }
170 199 series->setParent(0);
171 200 break;
172 201 }
173 202 }
174 203 }
175 204
176 205 void ChartDataSet::removeAllSeries()
177 206 {
178 207 QList<QChartAxis*> keys = m_seriesMap.uniqueKeys();
179 208 foreach(QChartAxis* axis , keys) {
180 209 QList<QSeries*> seriesList = m_seriesMap.values(axis);
181 210 for(int i =0; i < seriesList.size();i++ )
182 211 {
183 212 emit seriesRemoved(seriesList.at(i));
184 213 delete(seriesList.at(i));
185 214 }
186 215 m_seriesMap.remove(axis);
187 216 m_domainMap.remove(axis);
188 217 emit axisRemoved(axis);
189 218 if(axis != m_axisY) delete axis;
190 219 }
191 220 m_domainIndex=0;
192 221 }
193 222
194 223 bool ChartDataSet::nextDomain()
195 224 {
196 225 int limit = (m_domainMap.values().size()/m_domainMap.uniqueKeys().size())-1;
197 226
198 227 if (m_domainIndex < limit) {
199 228 m_domainIndex++;
200 229 setDomain(m_domainIndex);
201 230 return true;
202 231 }
203 232 else {
204 233 return false;
205 234 }
206 235 }
207 236
208 237 bool ChartDataSet::previousDomain()
209 238 {
210 239 if (m_domainIndex > 0) {
211 240 m_domainIndex--;
212 241 setDomain(m_domainIndex);
213 242 return true;
214 243 }
215 244 else {
216 245 return false;
217 246 }
218 247 }
219 248
220 249 void ChartDataSet::setDomain(int index)
221 250 {
222 251 QList<QChartAxis*> domainList = m_domainMap.uniqueKeys();
223 252
224 253 if(domainList.count()==0) return;
225 254
226 255 Domain domain;
227 256
228 257 foreach (QChartAxis* axis , domainList) {
229 258 int i = m_domainMap.count(axis) - index -1;
230 259 Q_ASSERT(i>=0);
231 260 domain = m_domainMap.values(axis).at(i);
232 261 QStringList labels = createLabels(axis,domain.m_minY,domain.m_maxY);
233 262 QList<QSeries*> seriesList = m_seriesMap.values(axis);
234 263 foreach(QSeries* series, seriesList) {
235 264 emit seriesDomainChanged(series,domain);
236 265 }
237 266 axis->updateRange(domain.m_minY,domain.m_maxY);
238 267 emit axisRangeChanged(axis,labels);
239 268
240 269 }
241 270
242 271 QStringList labels = createLabels(axisX(),domain.m_minX,domain.m_maxX);
243 272 axisX()->updateRange(domain.m_minX,domain.m_maxY);
244 273 emit axisRangeChanged(axisX(),labels);
245 274 }
246 275
247 276 void ChartDataSet::setDomain(int index,QChartAxis* axis)
248 277 {
249 278 int i = m_domainMap.count(axis) - index -1;
250 279 Q_ASSERT(i>=0);
251 280 Domain domain = m_domainMap.values(axis).at(i);
252 281 {
253 282 QStringList labels = createLabels(axis,domain.m_minY,domain.m_maxY);
254 283 QList<QSeries*> seriesList = m_seriesMap.values(axis);
255 284 foreach(QSeries* series, seriesList) {
256 285 emit seriesDomainChanged(series,domain);
257 286 }
258 287 axis->updateRange(domain.m_minY,domain.m_maxY);
259 288 emit axisRangeChanged(axis,labels);
260 289 }
261 290
262 291 QStringList labels = createLabels(axisX(),domain.m_minX,domain.m_maxX);
263 292 axisX()->updateRange(domain.m_minX,domain.m_maxY);
264 293 emit axisRangeChanged(axisX(),labels);
265 294 }
266 295
267 296 void ChartDataSet::clearDomains(int toIndex)
268 297 {
269 298 Q_ASSERT(toIndex>=0);
270 299
271 300 m_domainIndex = toIndex;
272 301
273 302 QList<QChartAxis*> keys = m_domainMap.uniqueKeys();
274 303
275 304 foreach (QChartAxis* key , keys)
276 305 {
277 306 QList<Domain> domains = m_domainMap.values(key);
278 307 m_domainMap.remove(key);
279 308 int i = domains.size() - toIndex - 1;
280 309 while(i--) {
281 310 domains.removeFirst();
282 311 }
283 312 for(int j=domains.size()-1; j>=0;j--)
284 313 m_domainMap.insert(key,domains.at(j));
285 314 }
286 315 }
287 316
288 317 void ChartDataSet::addDomain(const QRectF& rect, const QRectF& viewport)
289 318 {
290 319 Q_ASSERT(rect.isValid());
291 320 Q_ASSERT(viewport.isValid());
292 321
293 322 clearDomains(m_domainIndex);
294 323
295 324 QList<QChartAxis*> domainList = m_domainMap.uniqueKeys();
296 325
297 326 Domain domain;
298 327
299 328 foreach (QChartAxis* axis , domainList) {
300 329 domain = m_domainMap.value(axis).subDomain(rect,viewport.width(),viewport.height());
301 330 m_domainMap.insert(axis,domain);
302 331 }
303 332
304 333 setDomain(++m_domainIndex);
305 334 }
306 335
307 336 QChartAxis* ChartDataSet::axisY(QSeries* series) const
308 337 {
309 338 if(series == 0) return m_axisY;
310 339
311 340 QList<QChartAxis*> keys = m_seriesMap.uniqueKeys();
312 341
313 342 foreach(QChartAxis* axis , keys) {
314 343 if(m_seriesMap.contains(axis,series)) {
315 344 return axis;
316 345 }
317 346 }
318 347 return 0;
319 348 }
320 349
321 350 QStringList ChartDataSet::createLabels(QChartAxis* axis,qreal min, qreal max)
322 351 {
323 352 Q_ASSERT(max>=min);
324 353
325 354 QStringList labels;
326 355
327 356 int ticks = axis->ticksCount()-1;
328 357
329 358 for(int i=0; i<= ticks; i++) {
330 359 qreal value = min + (i * (max - min)/ ticks);
331 360 QString label = axis->axisTickLabel(value);
332 361 if(label.isEmpty()) {
333 362 labels << QString::number(value);
334 363 }
335 364 else {
336 365 labels << label;
337 366 }
338 367 }
339 368 return labels;
340 369 }
341 370
342 371 void ChartDataSet::handleRangeChanged(QChartAxis* axis)
343 372 {
344 373 qreal min = axis->min();
345 374 qreal max = axis->max();
346 375
347 376 if(axis==axisX()) {
348 377
349 378 m_domainIndex=0;
350 379
351 380 clearDomains(m_domainIndex);
352 381
353 382 QList<QChartAxis*> domainList = m_domainMap.uniqueKeys();
354 383
355 384 foreach (QChartAxis* axis , domainList) {
356 385
357 386 Q_ASSERT(m_domainMap.values(axis).size()==1);
358 387
359 388 Domain domain = m_domainMap.value(axis);
360 389 domain.m_minX=min;
361 390 domain.m_maxX=max;
362 391 m_domainMap.replace(axis,domain);
363 392 }
364 393
365 394 setDomain(m_domainIndex);
366 395
367 396 }
368 397 else {
369 398
370 399 QList<Domain> domains = m_domainMap.values(axis);
371 400 m_domainMap.remove(axis);
372 401
373 402 for(int i=0;i<domains.size();i++)
374 403 {
375 404 domains[i].m_minY=min;
376 405 domains[i].m_maxY=max;
377 406 }
378 407
379 408 for(int j=domains.size()-1; j>=0;j--)
380 409 m_domainMap.insert(axis,domains.at(j));
381 410
382 411 setDomain(m_domainIndex,axis);
383 412 }
384 413
385 414 }
386 415
387 416 void ChartDataSet::handleTickChanged(QChartAxis* axis)
388 417 {
389 418 if(axis==axisX()) {
390 419 Domain domain = m_domainMap.value(axisY());
391 420 QStringList labels = createLabels(axis,domain.m_minX,domain.m_maxX);
392 421 emit axisRangeChanged(axis,labels);
393 422 }
394 423 else {
395 424 Domain domain = m_domainMap.value(axis);
396 425 QStringList labels = createLabels(axis,domain.m_minY,domain.m_maxY);
397 426 emit axisRangeChanged(axis,labels);
398 427 }
399 428 }
400 429
401 430 #include "moc_chartdataset_p.cpp"
402 431
403 432 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,287 +1,300
1 1 #include "qchart.h"
2 2 #include "qchartaxis.h"
3 3 #include "chartpresenter_p.h"
4 4 #include "chartdataset_p.h"
5 5 #include "charttheme_p.h"
6 6 //series
7 7 #include "qbarseries.h"
8 8 #include "qstackedbarseries.h"
9 9 #include "qpercentbarseries.h"
10 10 #include "qlineseries.h"
11 #include "qareaseries.h"
11 12 #include "qpieseries.h"
12 13 #include "qscatterseries.h"
13 14 //items
14 15 #include "axisitem_p.h"
15 16 #include "axisanimationitem_p.h"
17 #include "areachartitem_p.h"
16 18 #include "barpresenter_p.h"
17 19 #include "stackedbarpresenter_p.h"
18 20 #include "percentbarpresenter_p.h"
19 21 #include "linechartitem_p.h"
20 22 #include "linechartanimationitem_p.h"
21 23 #include "piepresenter_p.h"
22 24 #include "scatterpresenter_p.h"
23 25
24 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25 27
26 28 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
27 29 m_chart(chart),
28 30 m_dataset(dataset),
29 31 m_chartTheme(0),
30 32 m_marginSize(0),
31 33 m_rect(QRectF(QPoint(0,0),m_chart->size())),
32 34 m_options(0)
33 35 {
34 36 createConnections();
35 37 setChartTheme(QChart::ChartThemeDefault);
36 38
37 39 }
38 40
39 41 ChartPresenter::~ChartPresenter()
40 42 {
41 43 }
42 44
43 45 void ChartPresenter::createConnections()
44 46 {
45 47 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
46 48 QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*)),this,SLOT(handleSeriesAdded(QSeries*)));
47 49 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),this,SLOT(handleSeriesRemoved(QSeries*)));
48 50 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*)),this,SLOT(handleAxisAdded(QChartAxis*)));
49 51 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
50 52 QObject::connect(m_dataset,SIGNAL(seriesDomainChanged(QSeries*,const Domain&)),this,SLOT(handleSeriesDomainChanged(QSeries*,const Domain&)));
51 53 QObject::connect(m_dataset,SIGNAL(axisRangeChanged(QChartAxis*,const QStringList&)),this,SLOT(handleAxisRangeChanged(QChartAxis*,const QStringList&)));
52 54 }
53 55
54 56
55 57 QRectF ChartPresenter::geometry() const
56 58 {
57 59 return m_rect;
58 60 }
59 61
60 62 void ChartPresenter::handleGeometryChanged()
61 63 {
62 64 m_rect = QRectF(QPoint(0,0),m_chart->size());
63 65 m_rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize);
64 66 Q_ASSERT(m_rect.isValid());
65 67 emit geometryChanged(m_rect);
66 68 }
67 69
68 70 int ChartPresenter::margin() const
69 71 {
70 72 return m_marginSize;
71 73 }
72 74
73 75 void ChartPresenter::setMargin(int margin)
74 76 {
75 77 m_marginSize = margin;
76 78 }
77 79
78 80 void ChartPresenter::handleAxisAdded(QChartAxis* axis)
79 81 {
80 82
81 83 AxisItem* item ;
82 84
83 85 if(!m_options.testFlag(QChart::GridAxisAnimations))
84 86 {
85 87 item = new AxisItem(axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
86 88 }else{
87 89 item = new AxisAnimationItem(axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
88 90 }
89 91
90 92 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
91 93 QObject::connect(axis,SIGNAL(update(QChartAxis*)),item,SLOT(handleAxisUpdate(QChartAxis*)));
92 94
93 95 item->handleAxisUpdate(axis);
94 96 item->handleGeometryChanged(m_rect);
95 97 m_chartTheme->decorate(axis,item);
96 98 m_axisItems.insert(axis,item);
97 99 }
98 100
99 101 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
100 102 {
101 103 AxisItem* item = m_axisItems.take(axis);
102 104 Q_ASSERT(item);
103 105 delete item;
104 106 }
105 107
106 108
107 109 void ChartPresenter::handleSeriesAdded(QSeries* series)
108 110 {
109 111 switch(series->type())
110 112 {
111 113 case QSeries::SeriesTypeLine: {
114
112 115 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
113 116 LineChartItem* item;
114 117 if(m_options.testFlag(QChart::SeriesAnimations)){
115 118 item = new LineChartAnimationItem(this,lineSeries,m_chart);
116 119 }else{
117 120 item = new LineChartItem(this,lineSeries,m_chart);
118 121 }
119 122 m_chartTheme->decorate(item,lineSeries,m_chartItems.count());
120 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
121 QObject::connect(lineSeries,SIGNAL(pointReplaced(int)),item,SLOT(handlePointReplaced(int)));
122 QObject::connect(lineSeries,SIGNAL(pointAdded(int)),item,SLOT(handlePointAdded(int)));
123 QObject::connect(lineSeries,SIGNAL(pointRemoved(int)),item,SLOT(handlePointRemoved(int)));
124 QObject::connect(lineSeries,SIGNAL(updated()),item,SLOT(handleUpdated()));
125 123 m_chartItems.insert(series,item);
126 124 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
127 item->handleUpdated();
125 break;
126 }
127
128 case QSeries::SeriesTypeArea: {
129
130 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
131 AreaChartItem* item;
132 if(m_options.testFlag(QChart::SeriesAnimations)) {
133 item = new AreaChartItem(this,areaSeries,m_chart);
134 }
135 else {
136 item = new AreaChartItem(this,areaSeries,m_chart);
137 }
138 m_chartTheme->decorate(item,areaSeries,m_chartItems.count());
139 m_chartItems.insert(series,item);
140 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
128 141 break;
129 142 }
130 143
131 144 case QSeries::SeriesTypeBar: {
132 145 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
133 146 BarPresenter* item = new BarPresenter(barSeries,m_chart);
134 147 m_chartTheme->decorate(item,barSeries,m_chartItems.count());
135 148 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
136 149 QObject::connect(barSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
137 150 m_chartItems.insert(series,item);
138 151 // m_axisXItem->setVisible(false);
139 152 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
140 153 break;
141 154 }
142 155
143 156 case QSeries::SeriesTypeStackedBar: {
144 157
145 158 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
146 159 StackedBarPresenter* item = new StackedBarPresenter(stackedBarSeries,m_chart);
147 160 m_chartTheme->decorate(item,stackedBarSeries,m_chartItems.count());
148 161 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
149 162 QObject::connect(stackedBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
150 163 m_chartItems.insert(series,item);
151 164 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
152 165 break;
153 166 }
154 167
155 168 case QSeries::SeriesTypePercentBar: {
156 169
157 170 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
158 171 PercentBarPresenter* item = new PercentBarPresenter(percentBarSeries,m_chart);
159 172 m_chartTheme->decorate(item,percentBarSeries ,m_chartItems.count());
160 173 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
161 174 QObject::connect(percentBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
162 175 m_chartItems.insert(series,item);
163 176 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
164 177 break;
165 178 }
166 179 case QSeries::SeriesTypeScatter: {
167 180 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
168 181 ScatterPresenter *scatterPresenter = new ScatterPresenter(scatterSeries, m_chart);
169 182 QObject::connect(scatterPresenter, SIGNAL(clicked(QPointF)),
170 183 scatterSeries, SIGNAL(clicked(QPointF)));
171 184 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)),
172 185 scatterPresenter, SLOT(handleGeometryChanged(const QRectF&)));
173 186 m_chartTheme->decorate(scatterPresenter, scatterSeries, m_chartItems.count());
174 187 m_chartItems.insert(scatterSeries, scatterPresenter);
175 188 if(m_rect.isValid()) scatterPresenter->handleGeometryChanged(m_rect);
176 189 break;
177 190 }
178 191 case QSeries::SeriesTypePie: {
179 192 QPieSeries *s = qobject_cast<QPieSeries *>(series);
180 193 PiePresenter* pie = new PiePresenter(m_chart, s);
181 194 m_chartTheme->decorate(pie, s, m_chartItems.count());
182 195 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), pie, SLOT(handleGeometryChanged(const QRectF&)));
183 196
184 197 // Hide all from background when there is only piechart
185 198 // TODO: refactor this ugly code... should be one setting for this
186 199 if (m_chartItems.count() == 0) {
187 200 m_chart->axisX()->setAxisVisible(false);
188 201 m_chart->axisY()->setAxisVisible(false);
189 202 m_chart->axisX()->setGridVisible(false);
190 203 m_chart->axisY()->setGridVisible(false);
191 204 m_chart->axisX()->setLabelsVisible(false);
192 205 m_chart->axisY()->setLabelsVisible(false);
193 206 m_chart->axisX()->setShadesVisible(false);
194 207 m_chart->axisY()->setShadesVisible(false);
195 208 m_chart->setChartBackgroundBrush(Qt::transparent);
196 209 }
197 210
198 211 m_chartItems.insert(series, pie);
199 212 pie->handleGeometryChanged(m_rect);
200 213 break;
201 214 }
202 215 default: {
203 216 qDebug()<< "Series type" << series->type() << "not implemented.";
204 217 break;
205 218 }
206 219 }
207 220 }
208 221
209 222 void ChartPresenter::handleSeriesRemoved(QSeries* series)
210 223 {
211 224 ChartItem* item = m_chartItems.take(series);
212 225 delete item;
213 226 }
214 227
215 228 void ChartPresenter::handleSeriesDomainChanged(QSeries* series, const Domain& domain)
216 229 {
217 230 m_chartItems.value(series)->handleDomainChanged(domain);
218 231 }
219 232
220 233 void ChartPresenter::handleAxisRangeChanged(QChartAxis* axis,const QStringList& labels)
221 234 {
222 235 m_axisItems.value(axis)->handleRangeChanged(axis,labels);
223 236 }
224 237
225 238 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
226 239 {
227 240 delete m_chartTheme;
228 241
229 242 m_chartTheme = ChartTheme::createTheme(theme);
230 243
231 244 m_chartTheme->decorate(m_chart);
232 245 QMapIterator<QSeries*,ChartItem*> i(m_chartItems);
233 246
234 247 int index=0;
235 248 while (i.hasNext()) {
236 249 i.next();
237 250 m_chartTheme->decorate(i.value(),i.key(),index);
238 251 index++;
239 252 }
240 253
241 254 QMapIterator<QChartAxis*,AxisItem*> j(m_axisItems);
242 255 while (j.hasNext()) {
243 256 j.next();
244 257 m_chartTheme->decorate(j.key(),j.value());
245 258 }
246 259 }
247 260
248 261 QChart::ChartTheme ChartPresenter::chartTheme()
249 262 {
250 263 return m_chartTheme->id();
251 264 }
252 265
253 266 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
254 267 {
255 268 if(m_options!=options) {
256 269
257 270 m_options=options;
258 271
259 272 //recreate elements
260 273
261 274 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
262 275 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
263 276
264 277 foreach(QChartAxis* axis, axisList) {
265 278 handleAxisRemoved(axis);
266 279 handleAxisAdded(axis);
267 280 }
268 281 foreach(QSeries* series, seriesList) {
269 282 handleSeriesRemoved(series);
270 283 handleSeriesAdded(series);
271 284 }
272 285
273 286 //now reintialize view data
274 287 //TODO: make it more nice
275 288 m_dataset->setDomain(m_dataset->domainIndex());
276 289 }
277 290 }
278 291
279 292 QChart::AnimationOptions ChartPresenter::animationOptions() const
280 293 {
281 294 return m_options;
282 295 }
283 296
284 297
285 298 #include "moc_chartpresenter_p.cpp"
286 299
287 300 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,270 +1,300
1 1 #include "charttheme_p.h"
2 2 #include "qchart.h"
3 3 #include "qchartaxis.h"
4 4 #include <QTime>
5 5
6 6 //series
7 7 #include "qbarset.h"
8 8 #include "qbarseries.h"
9 9 #include "qstackedbarseries.h"
10 10 #include "qpercentbarseries.h"
11 11 #include "qlineseries.h"
12 #include "qareaseries.h"
12 13 #include "qscatterseries.h"
13 14 #include "qpieseries.h"
14 15 #include "qpieslice.h"
15 16
16 17 //items
17 18 #include "axisitem_p.h"
18 19 #include "barpresenter_p.h"
19 20 #include "stackedbarpresenter_p.h"
20 21 #include "percentbarpresenter_p.h"
21 22 #include "linechartitem_p.h"
23 #include "areachartitem_p.h"
22 24 #include "scatterpresenter_p.h"
23 25 #include "piepresenter_p.h"
24 26
25 27 //themes
26 28 #include "chartthemevanilla_p.h"
27 29 #include "chartthemeicy_p.h"
28 30 #include "chartthemegrayscale_p.h"
29 31 #include "chartthemescientific_p.h"
30 32
31 33
32 34 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 35
34 36 /* TODO
35 37 case QChart::ChartThemeUnnamed1:
36 38 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xff3fa9f5)), 2));
37 39 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xff7AC943)), 2));
38 40 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF931E)), 2));
39 41 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF1D25)), 2));
40 42 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF7BAC)), 2));
41 43
42 44 m_gradientStartColor = QColor(QRgb(0xfff3dc9e));
43 45 m_gradientEndColor = QColor(QRgb(0xffafafaf));
44 46 */
45 47
46 48 ChartTheme::ChartTheme(QChart::ChartTheme id)
47 49 {
48 50 m_id = id;
49 51 m_seriesColor.append(QRgb(0xff000000));
50 52 m_seriesColor.append(QRgb(0xff707070));
51 53 m_gradientStartColor = QColor(QRgb(0xffffffff));
52 54 m_gradientEndColor = QColor(QRgb(0xffafafaf));
53 55
54 56 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
55 57 }
56 58
57 59
58 60 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
59 61 {
60 62 switch(theme) {
61 63 case QChart::ChartThemeDefault:
62 return new ChartThemeIcy();
64 return new ChartTheme();
63 65 case QChart::ChartThemeVanilla:
64 66 return new ChartThemeVanilla();
65 67 case QChart::ChartThemeIcy:
66 68 return new ChartThemeIcy();
67 69 case QChart::ChartThemeGrayscale:
68 70 return new ChartThemeGrayscale();
69 71 case QChart::ChartThemeScientific:
70 72 return new ChartThemeScientific();
71 73 }
72 74 }
73 75
74 76 void ChartTheme::decorate(QChart* chart)
75 77 {
76 78 QLinearGradient backgroundGradient;
77 79 backgroundGradient.setColorAt(0.0, m_gradientStartColor);
78 80 backgroundGradient.setColorAt(1.0, m_gradientEndColor);
79 81 backgroundGradient.setCoordinateMode(QGradient::ObjectBoundingMode);
80 82 chart->setChartBackgroundBrush(backgroundGradient);
81 83 }
82 84 //TODO helper to by removed later
83 85 void ChartTheme::decorate(ChartItem* item, QSeries* series,int count)
84 86 {
85 87 switch(series->type())
86 88 {
87 89 case QSeries::SeriesTypeLine: {
88 90 QLineSeries* s = static_cast<QLineSeries*>(series);
89 91 LineChartItem* i = static_cast<LineChartItem*>(item);
90 92 decorate(i,s,count);
91 93 break;
92 94 }
95 case QSeries::SeriesTypeArea: {
96 QAreaSeries* s = static_cast<QAreaSeries*>(series);
97 AreaChartItem* i = static_cast<AreaChartItem*>(item);
98 decorate(i,s,count);
99 break;
100 }
93 101 case QSeries::SeriesTypeBar: {
94 102 QBarSeries* b = static_cast<QBarSeries*>(series);
95 103 BarPresenter* i = static_cast<BarPresenter*>(item);
96 104 decorate(i,b,count);
97 105 break;
98 106 }
99 107 case QSeries::SeriesTypeStackedBar: {
100 108 QStackedBarSeries* s = static_cast<QStackedBarSeries*>(series);
101 109 StackedBarPresenter* i = static_cast<StackedBarPresenter*>(item);
102 110 decorate(i,s,count);
103 111 break;
104 112 }
105 113 case QSeries::SeriesTypePercentBar: {
106 114 QPercentBarSeries* s = static_cast<QPercentBarSeries*>(series);
107 115 PercentBarPresenter* i = static_cast<PercentBarPresenter*>(item);
108 116 decorate(i,s,count);
109 117 break;
110 118 }
111 119 case QSeries::SeriesTypeScatter: {
112 120 QScatterSeries* s = qobject_cast<QScatterSeries*>(series);
113 121 Q_ASSERT(s);
114 122 ScatterPresenter* i = static_cast<ScatterPresenter*>(item);
115 123 Q_ASSERT(i);
116 124 decorate(i, s, count);
117 125 break;
118 126 }
119 127 case QSeries::SeriesTypePie: {
120 128 QPieSeries* s = static_cast<QPieSeries*>(series);
121 129 PiePresenter* i = static_cast<PiePresenter*>(item);
122 130 decorate(i,s,count);
123 131 break;
124 132 }
125 133 default:
126 134 qDebug()<<"Wrong item to be decorated by theme";
127 135 break;
128 136 }
129 137
130 138 }
131 139
140 void ChartTheme::decorate(AreaChartItem* item, QAreaSeries* series,int count)
141 {
142 QPen pen;
143 QBrush brush;
144
145 if(pen != series->pen()){
146 item->setPen(series->pen());
147 }else{
148 pen.setColor(m_seriesColor.at(count%m_seriesColor.size()));
149 pen.setWidthF(2);
150 item->setPen(pen);
151 }
152
153 if(brush != series->brush()){
154 item->setBrush(series->brush());
155 }else{
156 QBrush brush(m_seriesColor.at(count%m_seriesColor.size()));
157 item->setBrush(brush);
158 }
159 }
160
161
132 162 void ChartTheme::decorate(LineChartItem* item, QLineSeries* series,int count)
133 163 {
134 164 QPen pen;
135 165 if(pen != series->pen()){
136 166 item->setPen(series->pen());
137 167 return;
138 168 }
139 169 pen.setColor(m_seriesColor.at(count%m_seriesColor.size()));
140 170 pen.setWidthF(2);
141 171 item->setPen(pen);
142 172 }
143 173
144 174 void ChartTheme::decorate(BarPresenter* item, QBarSeries* series,int count)
145 175 {
146 176 QList<QBarSet*> sets = series->barSets();
147 177 for (int i=0; i<series->barsetCount(); i++) {
148 178 sets.at(i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count())));
149 179 }
150 180 }
151 181
152 182 void ChartTheme::decorate(StackedBarPresenter* item, QStackedBarSeries* series,int count)
153 183 {
154 184 QList<QBarSet*> sets = series->barSets();
155 185 for (int i=0; i<series->barsetCount(); i++) {
156 186 sets.at(i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count())));
157 187 }
158 188 }
159 189
160 190 void ChartTheme::decorate(PercentBarPresenter* item, QPercentBarSeries* series,int count)
161 191 {
162 192 QList<QBarSet*> sets = series->barSets();
163 193 for (int i=0; i<series->barsetCount(); i++) {
164 194 sets.at(i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count())));
165 195 }
166 196 }
167 197
168 198 void ChartTheme::decorate(ScatterPresenter* presenter, QScatterSeries* series, int count)
169 199 {
170 200 Q_ASSERT(presenter);
171 201 Q_ASSERT(series);
172 202
173 203 QColor color = m_seriesColor.at(count % m_seriesColor.size());
174 204 // TODO: define alpha in the theme? or in the series?
175 205 //color.setAlpha(120);
176 206
177 207 QBrush brush(color, Qt::SolidPattern);
178 208 presenter->m_markerBrush = brush;
179 209
180 210 QPen pen(brush, 3);
181 211 pen.setColor(color);
182 212 presenter->m_markerPen = pen;
183 213 }
184 214
185 215 void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int /*count*/)
186 216 {
187 217 // create a list of slice colors based on current theme
188 218 int i = 0;
189 219 QList<QColor> colors;
190 220 while (colors.count() < series->count()) {
191 221
192 222 // get base color
193 223 QColor c = m_seriesColor[i++];
194 224 i = i % m_seriesColor.count();
195 225
196 226 // dont use black colors... looks bad
197 227 if (c == Qt::black)
198 228 continue;
199 229
200 230 // by default use the "raw" theme color
201 231 if (!colors.contains(c)) {
202 232 colors << c;
203 233 continue;
204 234 }
205 235 // ...ok we need to generate something that looks like the same color
206 236 // but different lightness
207 237
208 238 int tryCount = 0;
209 239 while (tryCount++ < 100) {
210 240
211 241 // find maximum value we can raise the lightness
212 242 int lMax = 255;
213 243 if (lMax > 255 - c.red())
214 244 lMax = 255 - c.red();
215 245 if (lMax > 255 - c.green())
216 246 lMax = 255 - c.green();
217 247 if (lMax > 255 - c.blue())
218 248 lMax = 255 - c.blue();
219 249
220 250 // find maximum value we can make it darker
221 251 int dMax = 255;
222 252 if (dMax > c.red())
223 253 dMax = c.red();
224 254 if (dMax > c.green())
225 255 dMax = c.green();
226 256 if (dMax > c.blue())
227 257 dMax = c.blue();
228 258
229 259 int max = dMax + lMax;
230 260 if (max == 0) {
231 261 // no room to make color lighter or darker...
232 262 qDebug() << "cannot generate a color for pie!";
233 263 break;
234 264 }
235 265
236 266 // generate random color
237 267 int r = c.red() - dMax;
238 268 int g = c.green() - dMax;
239 269 int b = c.blue() - dMax;
240 270 int d = qrand() % max;
241 271 c.setRgb(r+d, g+d, b+d);
242 272
243 273 // found a unique color?
244 274 if (!colors.contains(c))
245 275 break;
246 276 }
247 277
248 278 qDebug() << "generated a color for pie" << c;
249 279 colors << c;
250 280 }
251 281
252 282 // finally update colors
253 283 foreach (QPieSlice* s, series->slices()) {
254 284 QColor c = colors.takeFirst();
255 285 s->setPen(c);
256 286 s->setBrush(c);
257 287 }
258 288 }
259 289
260 290
261 291 void ChartTheme::decorate(QChartAxis* axis,AxisItem* item)
262 292 {
263 293 //TODO: dummy defults for now
264 294 axis->setLabelsBrush(Qt::black);
265 295 axis->setLabelsPen(Qt::NoPen);
266 296 axis->setShadesPen(Qt::NoPen);
267 297 axis->setShadesOpacity(0.5);
268 298 }
269 299
270 300 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,52 +1,55
1 1 #ifndef CHARTTHEME_H
2 2 #define CHARTTHEME_H
3 3
4 4 #include "qchartglobal.h"
5 5 #include "qchart.h"
6 6 #include <QColor>
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 10 class ChartItem;
11 11 class QSeries;
12 12 class LineChartItem;
13 13 class QLineSeries;
14 14 class BarPresenter;
15 15 class QBarSeries;
16 16 class StackedBarPresenter;
17 17 class QStackedBarSeries;
18 18 class QPercentBarSeries;
19 19 class PercentBarPresenter;
20 20 class QScatterSeries;
21 21 class ScatterPresenter;
22 22 class PiePresenter;
23 23 class QPieSeries;
24 class AreaChartItem;
25 class QAreaSeries;
24 26
25 27 class ChartTheme
26 28 {
27 29 protected:
28 30 explicit ChartTheme(QChart::ChartTheme id = QChart::ChartThemeDefault);
29 31 public:
30 32 static ChartTheme* createTheme(QChart::ChartTheme theme);
31 33 QChart::ChartTheme id() const {return m_id;}
32 34 void decorate(QChart* chart);
33 35 void decorate(ChartItem* item, QSeries* series,int count);
34 36 void decorate(BarPresenter* item, QBarSeries* series,int count);
35 37 void decorate(StackedBarPresenter* item, QStackedBarSeries* series,int count);
36 38 void decorate(PercentBarPresenter* item, QPercentBarSeries* series,int count);
37 void decorate(LineChartItem* item, QLineSeries*, int count);
39 void decorate(LineChartItem* item, QLineSeries* series,int count);
40 void decorate(AreaChartItem* item, QAreaSeries* series,int count);
38 41 void decorate(ScatterPresenter* presenter, QScatterSeries* series, int count);
39 42 void decorate(PiePresenter* item, QPieSeries* series, int count);
40 43 void decorate(QChartAxis* axis,AxisItem* item);
41 44
42 45 protected:
43 46 QChart::ChartTheme m_id;
44 47 QColor m_gradientStartColor;
45 48 QColor m_gradientEndColor;
46 49 QList<QColor> m_seriesColor;
47 50
48 51 };
49 52
50 53 QTCOMMERCIALCHART_END_NAMESPACE
51 54
52 55 #endif // CHARTTHEME_H
@@ -1,219 +1,225
1 1 #include "linechartitem_p.h"
2 2 #include "qlineseries.h"
3 3 #include "chartpresenter_p.h"
4 4 #include <QPainter>
5 5
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 9 //TODO: optimize : remove points which are not visible
10 10
11 11 LineChartItem::LineChartItem(ChartPresenter* presenter, QLineSeries* series,QGraphicsItem *parent):ChartItem(parent),
12 12 m_presenter(presenter),
13 13 m_series(series),
14 14 m_items(this)
15 15 {
16 16 //m_items.setZValue(ChartPresenter::LineChartZValue);
17 17 setZValue(ChartPresenter::LineChartZValue);
18
19 QObject::connect(presenter,SIGNAL(geometryChanged(const QRectF&)),this,SLOT(handleGeometryChanged(const QRectF&)));
20 QObject::connect(series,SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
21 QObject::connect(series,SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
22 QObject::connect(series,SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
23 QObject::connect(series,SIGNAL(updated()),this,SLOT(handleUpdated()));
18 24 }
19 25
20 26 QRectF LineChartItem::boundingRect() const
21 27 {
22 28 return m_rect;
23 29 }
24 30
25 31 QPainterPath LineChartItem::shape() const
26 32 {
27 33 return m_path;
28 34 }
29 35
30 36 void LineChartItem::createPoints(int count)
31 37 {
32 38 for (int i = 0; i < count; ++i) {
33 39 QGraphicsRectItem* item = new QGraphicsRectItem(0,0,3,3);
34 40 m_items.addToGroup(item);
35 41 }
36 42 }
37 43
38 44 void LineChartItem::clearPoints(int count)
39 45 {
40 46 QList<QGraphicsItem *> items = m_items.childItems();
41 47
42 48 for (int i = 0; i < count; ++i) {
43 49 delete(items.takeLast());
44 50 }
45 51 }
46 52
47 53 QPointF LineChartItem::calculateGeometryPoint(int index) const
48 54 {
49 55 const qreal deltaX = m_size.width()/m_domain.spanX();
50 56 const qreal deltaY = m_size.height()/m_domain.spanY();
51 57 qreal x = (m_series->x(index) - m_domain.m_minX)* deltaX;
52 58 qreal y = (m_series->y(index) - m_domain.m_minY)*-deltaY + m_size.height();
53 59 return QPointF(x,y);
54 60 }
55 61
56 62 QVector<QPointF> LineChartItem::calculateGeometryPoints() const
57 63 {
58 64 const qreal deltaX = m_size.width()/m_domain.spanX();
59 65 const qreal deltaY = m_size.height()/m_domain.spanY();
60 66
61 67 QVector<QPointF> points;
62 68 points.reserve(m_series->count());
63 69 for (int i = 0; i < m_series->count(); ++i) {
64 70 qreal x = (m_series->x(i) - m_domain.m_minX)* deltaX;
65 71 qreal y = (m_series->y(i) - m_domain.m_minY)*-deltaY + m_size.height();
66 72 points << QPointF(x,y);
67 73 }
68 74 return points;
69 75 }
70 76
71 77 void LineChartItem::updateItem(QVector<QPointF>& oldPoints,QVector<QPointF>& newPoints)
72 78 {
73 79 applyGeometry(newPoints);
74 80 oldPoints = newPoints;
75 81 }
76 82
77 83 void LineChartItem::updateItem(QVector<QPointF>& oldPoints,int index,QPointF& newPoint)
78 84 {
79 85 oldPoints.replace(index,newPoint);
80 86 applyGeometry(oldPoints);
81 87 }
82 88
83 89 void LineChartItem::applyGeometry(QVector<QPointF>& points)
84 90 {
85 91 if(points.size()==0) return;
86 92
87 93 QList<QGraphicsItem*> items = m_items.childItems();
88 94
89 95 QPainterPath path;
90 96 const QPointF& point = points.at(0);
91 97 path.moveTo(point);
92 98 QGraphicsItem* item = items.at(0);
93 99 item->setPos(point.x()-1,point.y()-1);
94 100 if(!m_clipRect.contains(point)) item->setVisible(false);
95 101
96 102 for(int i=1 ; i< points.size();i++) {
97 103 QGraphicsItem* item = items.at(i);
98 104 const QPointF& point = points.at(i);
99 105 item->setPos(point.x()-1,point.y()-1);
100 106 if(!m_clipRect.contains(point)) item->setVisible(false);
101 107 path.lineTo(point);
102 108 }
103 109
104 110 prepareGeometryChange();
105 111 m_path = path;
106 112 m_rect = path.boundingRect();
107 113 }
108 114
109 115 void LineChartItem::setPen(const QPen& pen)
110 116 {
111 117 m_pen = pen;
112 118 }
113 119
114 120 //handlers
115 121
116 122 void LineChartItem::handlePointAdded(int index)
117 123 {
118 124 Q_ASSERT(index<m_series->count());
119 125 Q_ASSERT(index>=0);
120 126
121 127 QPointF point = calculateGeometryPoint(index);
122 128 createPoints(1);
123 129 QVector<QPointF> points = m_points;
124 130 points.insert(index,point);
125 131 updateItem(m_points,points);
126 132 update();
127 133 }
128 134 void LineChartItem::handlePointRemoved(int index)
129 135 {
130 136 Q_ASSERT(index<m_series->count());
131 137 Q_ASSERT(index>=0);
132 138 QPointF point = calculateGeometryPoint(index);
133 139 clearPoints(1);
134 140 QVector<QPointF> points = m_points;
135 141 points.remove(index);
136 142 updateItem(m_points,points);
137 143 update();
138 144 }
139 145
140 146 void LineChartItem::handlePointReplaced(int index)
141 147 {
142 148 Q_ASSERT(index<m_series->count());
143 149 Q_ASSERT(index>=0);
144 150 QPointF point = calculateGeometryPoint(index);
145 151 updateItem(m_points,index,point);
146 152 update();
147 153 }
148 154
149 155 void LineChartItem::handleDomainChanged(const Domain& domain)
150 156 {
151 157
152 158 m_domain = domain;
153 159
154 160 if(m_domain.isEmpty()) return;
155 161 if(!m_clipRect.isValid()) return;
156 162
157 163 QVector<QPointF> points = calculateGeometryPoints();
158 164
159 165 int diff = m_points.size() - points.size();
160 166
161 167 if(diff>0) {
162 168 clearPoints(diff);
163 169 }
164 170 else if(diff<0) {
165 171 createPoints(-diff);
166 172 }
167 173
168 174 updateItem(m_points,points);
169 175 update();
170 176 }
171 177
172 178 void LineChartItem::handleGeometryChanged(const QRectF& rect)
173 179 {
174 180 Q_ASSERT(rect.isValid());
175 181 m_size=rect.size();
176 182 m_clipRect=rect.translated(-rect.topLeft());
177 183 setPos(rect.topLeft());
178 184
179 185 if(m_domain.isEmpty()) return;
180 186
181 187 QVector<QPointF> points = calculateGeometryPoints();
182 188
183 189 int diff = m_points.size() - points.size();
184 190
185 191 if(diff>0) {
186 192 clearPoints(diff);
187 193 }
188 194 else if(diff<0) {
189 195 createPoints(-diff);
190 196 }
191 197
192 198 updateItem(m_points,points);
193 199 update();
194 200 }
195 201
196 202 void LineChartItem::handleUpdated()
197 203 {
198 204 m_items.setVisible(m_series->pointsVisible());
199 205 setPen(m_series->pen());
200 206 update();
201 207 }
202 208
203 209 //painter
204 210
205 211 void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
206 212 {
207 213 Q_UNUSED(widget);
208 214 Q_UNUSED(option);
209 215 painter->save();
210 216 painter->setPen(m_pen);
211 217 painter->setClipRect(m_clipRect);
212 218 painter->drawPath(m_path);
213 219 painter->restore();
214 220 }
215 221
216 222
217 223 #include "moc_linechartitem_p.cpp"
218 224
219 225 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,61 +1,61
1 1 #ifndef LINECHARTITEM_H
2 2 #define LINECHARTITEM_H
3 3
4 4 #include "qchartglobal.h"
5 5 #include "chartitem_p.h"
6 6 #include <QPen>
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 10 class ChartPresenter;
11 11 class QLineSeries;
12 12
13 13 class LineChartItem : public QObject , public ChartItem
14 14 {
15 15 Q_OBJECT
16 16 public:
17 17 LineChartItem(ChartPresenter* presenter, QLineSeries* series,QGraphicsItem *parent = 0);
18 18 ~ LineChartItem(){};
19 19
20 20 //from QGraphicsItem
21 21 QRectF boundingRect() const;
22 22 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
23 23 QPainterPath shape() const;
24 24
25 25 void setPen(const QPen& pen);
26 26 void setPointsVisible(bool visible);
27 27
28 28 public slots:
29 29 void handlePointAdded(int index);
30 30 void handlePointRemoved(int index);
31 31 void handlePointReplaced(int index);
32 32 void handleUpdated();
33 33 void handleDomainChanged(const Domain& domain);
34 34 void handleGeometryChanged(const QRectF& size);
35 35
36 36 public:
37 37 virtual void updateItem(QVector<QPointF>& oldPoints,QVector<QPointF>& newPoints);
38 38 virtual void updateItem(QVector<QPointF>& oldPoints,int index,QPointF& newPoint);
39 void applyGeometry(QVector<QPointF>& points);
39 virtual void applyGeometry(QVector<QPointF>& points);
40 40 void createPoints(int count);
41 41 void clearPoints(int count);
42 42 QPointF calculateGeometryPoint(int index) const;
43 43 QVector<QPointF> calculateGeometryPoints() const;
44 44
45 45 private:
46 46 ChartPresenter* m_presenter;
47 47 QPainterPath m_path;
48 48 QLineSeries* m_series;
49 49 QSizeF m_size;
50 50 QRectF m_rect;
51 51 QRectF m_clipRect;
52 52 Domain m_domain;
53 53 QGraphicsItemGroup m_items;
54 54 QVector<QPointF> m_points;
55 55 QPen m_pen;
56 56
57 57 };
58 58
59 59 QTCOMMERCIALCHART_END_NAMESPACE
60 60
61 61 #endif
@@ -1,89 +1,90
1 1 !include( ../common.pri ):error( Couldn't find the common.pri file! )
2 2 TARGET = QtCommercialChart
3 3 DESTDIR = $$CHART_BUILD_LIB_DIR
4 4 TEMPLATE = lib
5 5 QT += core \
6 6 gui
7 7 CONFIG += debug_and_release
8 8 CONFIG(debug, debug|release):TARGET = QtCommercialChartd
9 9 SOURCES += axisitem.cpp \
10 10 axisanimationitem.cpp \
11 11 chartdataset.cpp \
12 12 chartpresenter.cpp \
13 13 charttheme.cpp \
14 14 domain.cpp \
15 15 qchart.cpp \
16 16 qchartaxis.cpp \
17 17 qchartview.cpp \
18 18 qseries.cpp
19 19 PRIVATE_HEADERS += axisitem_p.h \
20 20 axisanimationitem_p.h \
21 21 chartdataset_p.h \
22 22 chartitem_p.h \
23 23 chartpresenter_p.h \
24 24 charttheme_p.h \
25 25 domain_p.h
26 26 PUBLIC_HEADERS += qchart.h \
27 27 qchartaxis.h \
28 28 qchartglobal.h \
29 29 qseries.h \
30 30 qchartview.h
31 31 include(linechart/linechart.pri)
32 include(areachart/areachart.pri)
32 33 include(barchart/barchart.pri)
33 34 include(piechart/piechart.pri)
34 35 include(scatterseries/scatter.pri)
35 36 THEMES += themes/chartthemeicy_p.h \
36 37 themes/chartthemegrayscale_p.h \
37 38 themes/chartthemescientific_p.h \
38 39 themes/chartthemevanilla_p.h
39 40 HEADERS += $$PUBLIC_HEADERS
40 41 HEADERS += $$PRIVATE_HEADERS
41 42 HEADERS += $$THEMES
42 43 INCLUDEPATH += linechart \
43 44 barchart \
44 45 themes \
45 46 .
46 47 OBJECTS_DIR = $$CHART_BUILD_DIR/lib
47 48 MOC_DIR = $$CHART_BUILD_DIR/lib
48 49 UI_DIR = $$CHART_BUILD_DIR/lib
49 50 RCC_DIR = $$CHART_BUILD_DIR/lib
50 51 DEFINES += QTCOMMERCIALCHART_LIBRARY
51 52 public_headers.path = $$[QT_INSTALL_HEADERS]/QtCommercialChart
52 53 public_headers.files = $$PUBLIC_HEADERS
53 54 target.path = $$[QT_INSTALL_LIBS]
54 55 INSTALLS += target \
55 56 public_headers
56 57 install_build_public_headers.name = bild_public_headers
57 58 install_build_public_headers.output = $$CHART_BUILD_PUBLIC_HEADER_DIR/${QMAKE_FILE_BASE}.h
58 59 install_build_public_headers.input = PUBLIC_HEADERS
59 60 install_build_public_headers.commands = $$QMAKE_COPY \
60 61 ${QMAKE_FILE_NAME} \
61 62 $$CHART_BUILD_PUBLIC_HEADER_DIR
62 63 install_build_public_headers.CONFIG += target_predeps \
63 64 no_link
64 65 install_build_private_headers.name = bild_private_headers
65 66 install_build_private_headers.output = $$CHART_BUILD_PRIVATE_HEADER_DIR/${QMAKE_FILE_BASE}.h
66 67 install_build_private_headers.input = PRIVATE_HEADERS
67 68 install_build_private_headers.commands = $$QMAKE_COPY \
68 69 ${QMAKE_FILE_NAME} \
69 70 $$CHART_BUILD_PRIVATE_HEADER_DIR
70 71 install_build_private_headers.CONFIG += target_predeps \
71 72 no_link
72 73 QMAKE_EXTRA_COMPILERS += install_build_public_headers \
73 74 install_build_private_headers
74 75 chartversion.target = qchartversion_p.h
75 76 chartversion.commands = @echo \
76 77 "build_time" \
77 78 > \
78 79 $$chartversion.target;
79 80 chartversion.depends = $$HEADERS \
80 81 $$SOURCES
81 82 PRE_TARGETDEPS += qchartversion_p.h
82 83 QMAKE_CLEAN += qchartversion_p.h
83 84 QMAKE_EXTRA_TARGETS += chartversion
84 85 unix:QMAKE_DISTCLEAN += -r \
85 86 $$CHART_BUILD_HEADER_DIR \
86 87 $$CHART_BUILD_LIB_DIR
87 88 win32:QMAKE_DISTCLEAN += /Q \
88 89 $$CHART_BUILD_HEADER_DIR \
89 90 $$CHART_BUILD_LIB_DIR
General Comments 0
You need to be logged in to leave comments. Login now