##// END OF EJS Templates
Marek Rosa -
r426:95162da3dc01 merge
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. Instead of axis X "lower" boundary can be specified 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 lines 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,27 +1,28
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 <li><a href="example-gdpbarchart.html">GDP Chart example</a></li>
22 23 </ul>
23 24 </td>
24 25 </tr>
25 26 </table>
26 27 \endraw
27 28 */
@@ -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,18 +1,19
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 17 scatterinteractions \
18 splinechart
18 splinechart \
19 areachart
@@ -1,420 +1,459
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 #include "qsplineseries.h"
11 12
12 13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13 14
14 15 ChartDataSet::ChartDataSet(QObject *parent):QObject(parent),
15 16 m_axisX(new QChartAxis(this)),
16 17 m_axisY(new QChartAxis(this)),
17 18 m_domainIndex(0),
18 19 m_axisXInitialized(false)
19 20 {
20 21 }
21 22
22 23 ChartDataSet::~ChartDataSet()
23 24 {
24 25 // TODO Auto-generated destructor stub
25 26 }
26 27
27 28 const Domain ChartDataSet::domain(QChartAxis *axisY) const
28 29 {
29 30 int i = m_domainMap.count(axisY);
30 31 if(i == 0){
31 32 return Domain();
32 33 }
33 34 i = i - m_domainIndex -1;
34 35 return m_domainMap.values(axisY).at(i);
35 36 }
36 37
37 38 void ChartDataSet::addSeries(QSeries* series, QChartAxis *axisY)
38 39 {
39 40 // TODO: we should check the series not already added
40 41
41 series->setParent(this); // take ownership
42 series->setParent(this);// take ownership
42 43 clearDomains();
43 44
44 45 if(axisY==0) axisY = m_axisY;
45 axisY->setParent(this); // take ownership
46 axisY->setParent(this);// take ownership
46 47
47 QList<QSeries*> seriesList = m_seriesMap.values(axisY);
48 QList<QSeries*> seriesList = m_seriesMap.values(axisY);
48 49
49 50 QList<Domain> domainList = m_domainMap.values(axisY);
50 51
51 52 Q_ASSERT(domainList.size()<=1);
52 53
53 54 Domain domain;
54 55
55 56 if(domainList.size()>0) domain = domainList.at(0);
56 57
57 58 switch(series->type())
58 59 {
59 60 case QSeries::SeriesTypeLine: {
60 61
61 QLineSeries* xyseries = static_cast<QLineSeries*>(series);
62 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
62 63
63 for (int i = 0; i < xyseries->count(); i++)
64 for (int i = 0; i < lineSeries->count(); i++)
64 65 {
65 qreal x = xyseries->x(i);
66 qreal y = xyseries->y(i);
66 qreal x = lineSeries->x(i);
67 qreal y = lineSeries->y(i);
67 68 domain.m_minX = qMin(domain.m_minX,x);
68 69 domain.m_minY = qMin(domain.m_minY,y);
69 70 domain.m_maxX = qMax(domain.m_maxX,x);
70 71 domain.m_maxY = qMax(domain.m_maxY,y);
71 72 }
72 73 break;
73 74 }
75 case QSeries::SeriesTypeArea: {
76
77 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
78
79 QLineSeries* upperSeries = areaSeries->upperSeries();
80 QLineSeries* lowerSeries = areaSeries->lowerSeries();
81
82 for (int i = 0; i < upperSeries->count(); i++)
83 {
84 qreal x = upperSeries->x(i);
85 qreal y = upperSeries->y(i);
86 domain.m_minX = qMin(domain.m_minX,x);
87 domain.m_minY = qMin(domain.m_minY,y);
88 domain.m_maxX = qMax(domain.m_maxX,x);
89 domain.m_maxY = qMax(domain.m_maxY,y);
90 }
91 if(lowerSeries){
92 for (int i = 0; i < lowerSeries->count(); i++)
93 {
94 qreal x = lowerSeries->x(i);
95 qreal y = lowerSeries->y(i);
96 domain.m_minX = qMin(domain.m_minX,x);
97 domain.m_minY = qMin(domain.m_minY,y);
98 domain.m_maxX = qMax(domain.m_maxX,x);
99 domain.m_maxY = qMax(domain.m_maxY,y);
100 }}
101 break;
102 }
103 case QSeries::SeriesTypeBar: {
104 qDebug() << "QChartSeries::SeriesTypeBar";
105 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
106 qreal x = barSeries->categoryCount();
107 qreal y = barSeries->max();
108 domain.m_minX = qMin(domain.m_minX,x);
109 domain.m_minY = qMin(domain.m_minY,y);
110 domain.m_maxX = qMax(domain.m_maxX,x);
111 domain.m_maxY = qMax(domain.m_maxY,y);
112 break;
113 }
74 114 case QSeries::SeriesTypeBar: {
75 115 qDebug() << "QChartSeries::SeriesTypeBar";
76 116 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
77 117 qreal x = barSeries->categoryCount();
78 118 qreal y = barSeries->max();
79 119 domain.m_minX = qMin(domain.m_minX,x);
80 120 domain.m_minY = qMin(domain.m_minY,y);
81 121 domain.m_maxX = qMax(domain.m_maxX,x);
82 122 domain.m_maxY = qMax(domain.m_maxY,y);
83 123 break;
84 124 }
85 125 case QSeries::SeriesTypeStackedBar: {
86 126 qDebug() << "QChartSeries::SeriesTypeStackedBar";
87 127
88 128 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
89 129 qreal x = stackedBarSeries->categoryCount();
90 130 qreal y = stackedBarSeries->maxCategorySum();
91 131 domain.m_minX = qMin(domain.m_minX,x);
92 132 domain.m_minY = qMin(domain.m_minY,y);
93 133 domain.m_maxX = qMax(domain.m_maxX,x);
94 134 domain.m_maxY = qMax(domain.m_maxY,y);
95 135 break;
96 136 }
97 137 case QSeries::SeriesTypePercentBar: {
98 138 qDebug() << "QChartSeries::SeriesTypePercentBar";
99 139
100 140 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
101 141 qreal x = percentBarSeries->categoryCount();
102 142 domain.m_minX = qMin(domain.m_minX,x);
103 143 domain.m_minY = 0;
104 144 domain.m_maxX = qMax(domain.m_maxX,x);
105 145 domain.m_maxY = 100;
106 146 break;
107 147 }
108 148
109 149 case QSeries::SeriesTypePie: {
110 150 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
111 151 // TODO: domain stuff
112 152 break;
113 153 }
114 154
115 155 case QSeries::SeriesTypeScatter: {
116 156 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
117 157 Q_ASSERT(scatterSeries);
118 158 foreach (QPointF point, scatterSeries->data()) {
119 159 domain.m_minX = qMin(domain.m_minX, point.x());
120 160 domain.m_maxX = qMax(domain.m_maxX, point.x());
121 161 domain.m_minY = qMin(domain.m_minY, point.y());
122 162 domain.m_maxY = qMax(domain.m_maxY, point.y());
123 163 }
124 164 break;
125 165 }
126 166
127 167 case QSeries::SeriesTypeSpline: {
128 168 QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
129 169
130 170 for (int i = 0; i < splineSeries->count(); i++)
131 171 {
132 172 qreal x = splineSeries->x(i);
133 173 qreal y = splineSeries->y(i);
134 174 domain.m_minX = qMin(domain.m_minX,x);
135 175 domain.m_minY = qMin(domain.m_minY,y);
136 176 domain.m_maxX = qMax(domain.m_maxX,x);
137 177 domain.m_maxY = qMax(domain.m_maxY,y);
138 178 }
139 179 break;
140 180 }
141 181
142 182 default: {
143 183 qDebug()<<__FUNCTION__<<"type" << series->type()<<"not supported";
144 184 return;
145 185 break;
146 186 }
147 187
148 188 }
149 189
150 190 if(!m_domainMap.contains(axisY))
151 191 {
152 192 emit axisAdded(axisY);
153 193 QObject::connect(axisY,SIGNAL(rangeChanged(QChartAxis*)),this,SLOT(handleRangeChanged(QChartAxis*)));
154 194 QObject::connect(axisY,SIGNAL(ticksChanged(QChartAxis*)),this,SLOT(handleTickChanged(QChartAxis*)));
155 195 }
156 196
157 197 if(!m_axisXInitialized)
158 198 {
159 199 emit axisAdded(axisX());
160 200 QObject::connect(axisX(),SIGNAL(rangeChanged(QChartAxis*)),this,SLOT(handleRangeChanged(QChartAxis*)));
161 201 QObject::connect(axisX(),SIGNAL(ticksChanged(QChartAxis*)),this,SLOT(handleTickChanged(QChartAxis*)));
162 202 m_axisXInitialized=true;
163 203 }
164 204
165 205 m_domainMap.replace(axisY,domain);
166 206 m_seriesMap.insert(axisY,series);
167 207 emit seriesAdded(series);
168 208 setDomain(m_domainIndex,axisY);
169 209
170 210 }
171 211
172 212 void ChartDataSet::removeSeries(QSeries* series)
173 213 {
174 214 QList<QChartAxis*> keys = m_seriesMap.uniqueKeys();
175 215 foreach(QChartAxis* axis , keys) {
176 if(m_seriesMap.contains(axis,series)){
216 if(m_seriesMap.contains(axis,series)) {
177 217 emit seriesRemoved(series);
178 218 m_seriesMap.remove(axis,series);
179 219 //remove axis if no longer there
180 if(!m_seriesMap.contains(axis)){
220 if(!m_seriesMap.contains(axis)) {
181 221 emit axisRemoved(axis);
182 222 m_domainMap.remove(axis);
183 223 if(axis != m_axisY)
184 224 delete axis;
185 225 }
186 226 series->setParent(0);
187 227 break;
188 228 }
189 229 }
190 230 }
191 231
192 232 void ChartDataSet::removeAllSeries()
193 233 {
194 234 QList<QChartAxis*> keys = m_seriesMap.uniqueKeys();
195 235 foreach(QChartAxis* axis , keys) {
196 236 QList<QSeries*> seriesList = m_seriesMap.values(axis);
197 for(int i =0 ; i < seriesList.size();i++ )
237 for(int i =0; i < seriesList.size();i++ )
198 238 {
199 239 emit seriesRemoved(seriesList.at(i));
200 240 delete(seriesList.at(i));
201 241 }
202 242 m_seriesMap.remove(axis);
203 243 m_domainMap.remove(axis);
204 244 emit axisRemoved(axis);
205 245 if(axis != m_axisY) delete axis;
206 246 }
207 247 m_domainIndex=0;
208 248 }
209 249
210 250 bool ChartDataSet::nextDomain()
211 251 {
212 252 int limit = (m_domainMap.values().size()/m_domainMap.uniqueKeys().size())-1;
213 253
214 254 if (m_domainIndex < limit) {
215 255 m_domainIndex++;
216 256 setDomain(m_domainIndex);
217 257 return true;
218 258 }
219 259 else {
220 260 return false;
221 261 }
222 262 }
223 263
224 264 bool ChartDataSet::previousDomain()
225 265 {
226 266 if (m_domainIndex > 0) {
227 267 m_domainIndex--;
228 268 setDomain(m_domainIndex);
229 269 return true;
230 270 }
231 271 else {
232 272 return false;
233 273 }
234 274 }
235 275
236 276 void ChartDataSet::setDomain(int index)
237 277 {
238 278 QList<QChartAxis*> domainList = m_domainMap.uniqueKeys();
239 279
240 280 if(domainList.count()==0) return;
241 281
242 282 Domain domain;
243 283
244 284 foreach (QChartAxis* axis , domainList) {
245 285 int i = m_domainMap.count(axis) - index -1;
246 286 Q_ASSERT(i>=0);
247 287 domain = m_domainMap.values(axis).at(i);
248 288 QStringList labels = createLabels(axis,domain.m_minY,domain.m_maxY);
249 289 QList<QSeries*> seriesList = m_seriesMap.values(axis);
250 290 foreach(QSeries* series, seriesList) {
251 291 emit seriesDomainChanged(series,domain);
252 292 }
253 293 axis->updateRange(domain.m_minY,domain.m_maxY);
254 294 emit axisRangeChanged(axis,labels);
255 295
256 296 }
257 297
258 298 QStringList labels = createLabels(axisX(),domain.m_minX,domain.m_maxX);
259 299 axisX()->updateRange(domain.m_minX,domain.m_maxY);
260 300 emit axisRangeChanged(axisX(),labels);
261 301 }
262 302
263 303 void ChartDataSet::setDomain(int index,QChartAxis* axis)
264 304 {
265 305 int i = m_domainMap.count(axis) - index -1;
266 306 Q_ASSERT(i>=0);
267 307 Domain domain = m_domainMap.values(axis).at(i);
268 308 {
269 309 QStringList labels = createLabels(axis,domain.m_minY,domain.m_maxY);
270 310 QList<QSeries*> seriesList = m_seriesMap.values(axis);
271 311 foreach(QSeries* series, seriesList) {
272 312 emit seriesDomainChanged(series,domain);
273 313 }
274 314 axis->updateRange(domain.m_minY,domain.m_maxY);
275 315 emit axisRangeChanged(axis,labels);
276 316 }
277 317
278 318 QStringList labels = createLabels(axisX(),domain.m_minX,domain.m_maxX);
279 319 axisX()->updateRange(domain.m_minX,domain.m_maxY);
280 320 emit axisRangeChanged(axisX(),labels);
281 321 }
282 322
283
284 323 void ChartDataSet::clearDomains(int toIndex)
285 324 {
286 325 Q_ASSERT(toIndex>=0);
287 326
288 327 m_domainIndex = toIndex;
289 328
290 329 QList<QChartAxis*> keys = m_domainMap.uniqueKeys();
291 330
292 331 foreach (QChartAxis* key , keys)
293 332 {
294 333 QList<Domain> domains = m_domainMap.values(key);
295 334 m_domainMap.remove(key);
296 335 int i = domains.size() - toIndex - 1;
297 while(i--){
336 while(i--) {
298 337 domains.removeFirst();
299 338 }
300 for(int j=domains.size()-1; j>=0 ;j--)
339 for(int j=domains.size()-1; j>=0;j--)
301 340 m_domainMap.insert(key,domains.at(j));
302 341 }
303 342 }
304 343
305 344 void ChartDataSet::addDomain(const QRectF& rect, const QRectF& viewport)
306 345 {
307 346 Q_ASSERT(rect.isValid());
308 347 Q_ASSERT(viewport.isValid());
309 348
310 349 clearDomains(m_domainIndex);
311 350
312 351 QList<QChartAxis*> domainList = m_domainMap.uniqueKeys();
313 352
314 353 Domain domain;
315 354
316 foreach (QChartAxis* axis , domainList){
355 foreach (QChartAxis* axis , domainList) {
317 356 domain = m_domainMap.value(axis).subDomain(rect,viewport.width(),viewport.height());
318 357 m_domainMap.insert(axis,domain);
319 358 }
320 359
321 360 setDomain(++m_domainIndex);
322 361 }
323 362
324 363 QChartAxis* ChartDataSet::axisY(QSeries* series) const
325 364 {
326 365 if(series == 0) return m_axisY;
327 366
328 367 QList<QChartAxis*> keys = m_seriesMap.uniqueKeys();
329 368
330 369 foreach(QChartAxis* axis , keys) {
331 if(m_seriesMap.contains(axis,series)){
370 if(m_seriesMap.contains(axis,series)) {
332 371 return axis;
333 372 }
334 373 }
335 374 return 0;
336 375 }
337 376
338 377 QStringList ChartDataSet::createLabels(QChartAxis* axis,qreal min, qreal max)
339 378 {
340 379 Q_ASSERT(max>=min);
341 380
342 381 QStringList labels;
343 382
344 383 int ticks = axis->ticksCount()-1;
345 384
346 for(int i=0; i<= ticks; i++){
385 for(int i=0; i<= ticks; i++) {
347 386 qreal value = min + (i * (max - min)/ ticks);
348 387 QString label = axis->axisTickLabel(value);
349 if(label.isEmpty()){
388 if(label.isEmpty()) {
350 389 labels << QString::number(value);
351 }else{
390 }
391 else {
352 392 labels << label;
353 393 }
354 394 }
355 395 return labels;
356 396 }
357 397
358
359 398 void ChartDataSet::handleRangeChanged(QChartAxis* axis)
360 399 {
361 400 qreal min = axis->min();
362 401 qreal max = axis->max();
363 402
364 403 if(axis==axisX()) {
365 404
366 405 m_domainIndex=0;
367 406
368 407 clearDomains(m_domainIndex);
369 408
370 409 QList<QChartAxis*> domainList = m_domainMap.uniqueKeys();
371 410
372 411 foreach (QChartAxis* axis , domainList) {
373 412
374 413 Q_ASSERT(m_domainMap.values(axis).size()==1);
375 414
376 415 Domain domain = m_domainMap.value(axis);
377 416 domain.m_minX=min;
378 417 domain.m_maxX=max;
379 418 m_domainMap.replace(axis,domain);
380 419 }
381 420
382 421 setDomain(m_domainIndex);
383 422
384 423 }
385 424 else {
386 425
387 426 QList<Domain> domains = m_domainMap.values(axis);
388 427 m_domainMap.remove(axis);
389 428
390 429 for(int i=0;i<domains.size();i++)
391 430 {
392 431 domains[i].m_minY=min;
393 432 domains[i].m_maxY=max;
394 433 }
395 434
396 435 for(int j=domains.size()-1; j>=0;j--)
397 436 m_domainMap.insert(axis,domains.at(j));
398 437
399 438 setDomain(m_domainIndex,axis);
400 439 }
401 440
402
403 441 }
404 442
405 443 void ChartDataSet::handleTickChanged(QChartAxis* axis)
406 444 {
407 if(axis==axisX()){
445 if(axis==axisX()) {
408 446 Domain domain = m_domainMap.value(axisY());
409 447 QStringList labels = createLabels(axis,domain.m_minX,domain.m_maxX);
410 448 emit axisRangeChanged(axis,labels);
411 }else{
449 }
450 else {
412 451 Domain domain = m_domainMap.value(axis);
413 452 QStringList labels = createLabels(axis,domain.m_minY,domain.m_maxY);
414 453 emit axisRangeChanged(axis,labels);
415 454 }
416 455 }
417 456
418 457 #include "moc_chartdataset_p.cpp"
419 458
420 459 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,298 +1,311
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 #include "qsplineseries.h"
14 15 //items
15 16 #include "axisitem_p.h"
16 17 #include "axisanimationitem_p.h"
18 #include "areachartitem_p.h"
17 19 #include "barpresenter_p.h"
18 20 #include "stackedbarpresenter_p.h"
19 21 #include "percentbarpresenter_p.h"
20 22 #include "linechartitem_p.h"
21 23 #include "linechartanimationitem_p.h"
22 24 #include "piepresenter_p.h"
23 25 #include "scatterpresenter_p.h"
24 26 #include "splinepresenter_p.h"
25 27
26 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 29
28 30 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
29 31 m_chart(chart),
30 32 m_dataset(dataset),
31 33 m_chartTheme(0),
32 34 m_marginSize(0),
33 35 m_rect(QRectF(QPoint(0,0),m_chart->size())),
34 36 m_options(0)
35 37 {
36 38 createConnections();
37 39 setChartTheme(QChart::ChartThemeDefault);
38 40
39 41 }
40 42
41 43 ChartPresenter::~ChartPresenter()
42 44 {
43 45 }
44 46
45 47 void ChartPresenter::createConnections()
46 48 {
47 49 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
48 50 QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*)),this,SLOT(handleSeriesAdded(QSeries*)));
49 51 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),this,SLOT(handleSeriesRemoved(QSeries*)));
50 52 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*)),this,SLOT(handleAxisAdded(QChartAxis*)));
51 53 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
52 54 QObject::connect(m_dataset,SIGNAL(seriesDomainChanged(QSeries*,const Domain&)),this,SLOT(handleSeriesDomainChanged(QSeries*,const Domain&)));
53 55 QObject::connect(m_dataset,SIGNAL(axisRangeChanged(QChartAxis*,const QStringList&)),this,SLOT(handleAxisRangeChanged(QChartAxis*,const QStringList&)));
54 56 }
55 57
56 58
57 59 QRectF ChartPresenter::geometry() const
58 60 {
59 61 return m_rect;
60 62 }
61 63
62 64 void ChartPresenter::handleGeometryChanged()
63 65 {
64 66 m_rect = QRectF(QPoint(0,0),m_chart->size());
65 67 m_rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize);
66 68 Q_ASSERT(m_rect.isValid());
67 69 emit geometryChanged(m_rect);
68 70 }
69 71
70 72 int ChartPresenter::margin() const
71 73 {
72 74 return m_marginSize;
73 75 }
74 76
75 77 void ChartPresenter::setMargin(int margin)
76 78 {
77 79 m_marginSize = margin;
78 80 }
79 81
80 82 void ChartPresenter::handleAxisAdded(QChartAxis* axis)
81 83 {
82 84
83 85 AxisItem* item ;
84 86
85 87 if(!m_options.testFlag(QChart::GridAxisAnimations))
86 88 {
87 89 item = new AxisItem(axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
88 90 }else{
89 91 item = new AxisAnimationItem(axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
90 92 }
91 93
92 94 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
93 95 QObject::connect(axis,SIGNAL(update(QChartAxis*)),item,SLOT(handleAxisUpdate(QChartAxis*)));
94 96
95 97 item->handleAxisUpdate(axis);
96 98 item->handleGeometryChanged(m_rect);
97 99 m_chartTheme->decorate(axis,item);
98 100 m_axisItems.insert(axis,item);
99 101 }
100 102
101 103 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
102 104 {
103 105 AxisItem* item = m_axisItems.take(axis);
104 106 Q_ASSERT(item);
105 107 delete item;
106 108 }
107 109
108 110
109 111 void ChartPresenter::handleSeriesAdded(QSeries* series)
110 112 {
111 113 switch(series->type())
112 114 {
113 115 case QSeries::SeriesTypeLine: {
116
114 117 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
115 118 LineChartItem* item;
116 119 if(m_options.testFlag(QChart::SeriesAnimations)){
117 120 item = new LineChartAnimationItem(this,lineSeries,m_chart);
118 121 }else{
119 122 item = new LineChartItem(this,lineSeries,m_chart);
120 123 }
121 124 m_chartTheme->decorate(item,lineSeries,m_chartItems.count());
122 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
123 QObject::connect(lineSeries,SIGNAL(pointReplaced(int)),item,SLOT(handlePointReplaced(int)));
124 QObject::connect(lineSeries,SIGNAL(pointAdded(int)),item,SLOT(handlePointAdded(int)));
125 QObject::connect(lineSeries,SIGNAL(pointRemoved(int)),item,SLOT(handlePointRemoved(int)));
126 QObject::connect(lineSeries,SIGNAL(updated()),item,SLOT(handleUpdated()));
127 125 m_chartItems.insert(series,item);
128 126 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
129 item->handleUpdated();
127 break;
128 }
129
130 case QSeries::SeriesTypeArea: {
131
132 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
133 AreaChartItem* item;
134 if(m_options.testFlag(QChart::SeriesAnimations)) {
135 item = new AreaChartItem(this,areaSeries,m_chart);
136 }
137 else {
138 item = new AreaChartItem(this,areaSeries,m_chart);
139 }
140 m_chartTheme->decorate(item,areaSeries,m_chartItems.count());
141 m_chartItems.insert(series,item);
142 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
130 143 break;
131 144 }
132 145
133 146 case QSeries::SeriesTypeBar: {
134 147 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
135 148 BarPresenter* item = new BarPresenter(barSeries,m_chart);
136 149 m_chartTheme->decorate(item,barSeries,m_chartItems.count());
137 150 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
138 151 QObject::connect(barSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
139 152 m_chartItems.insert(series,item);
140 153 // m_axisXItem->setVisible(false);
141 154 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
142 155 break;
143 156 }
144 157
145 158 case QSeries::SeriesTypeStackedBar: {
146 159
147 160 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
148 161 StackedBarPresenter* item = new StackedBarPresenter(stackedBarSeries,m_chart);
149 162 m_chartTheme->decorate(item,stackedBarSeries,m_chartItems.count());
150 163 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
151 164 QObject::connect(stackedBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
152 165 m_chartItems.insert(series,item);
153 166 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
154 167 break;
155 168 }
156 169
157 170 case QSeries::SeriesTypePercentBar: {
158 171
159 172 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
160 173 PercentBarPresenter* item = new PercentBarPresenter(percentBarSeries,m_chart);
161 174 m_chartTheme->decorate(item,percentBarSeries ,m_chartItems.count());
162 175 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
163 176 QObject::connect(percentBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
164 177 m_chartItems.insert(series,item);
165 178 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
166 179 break;
167 180 }
168 181 case QSeries::SeriesTypeScatter: {
169 182 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
170 183 ScatterPresenter *scatterPresenter = new ScatterPresenter(scatterSeries, m_chart);
171 184 QObject::connect(scatterPresenter, SIGNAL(clicked(QPointF)),
172 185 scatterSeries, SIGNAL(clicked(QPointF)));
173 186 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)),
174 187 scatterPresenter, SLOT(handleGeometryChanged(const QRectF&)));
175 188 m_chartTheme->decorate(scatterPresenter, scatterSeries, m_chartItems.count());
176 189 m_chartItems.insert(scatterSeries, scatterPresenter);
177 190 if(m_rect.isValid()) scatterPresenter->handleGeometryChanged(m_rect);
178 191 break;
179 192 }
180 193 case QSeries::SeriesTypePie: {
181 194 QPieSeries *s = qobject_cast<QPieSeries *>(series);
182 195 PiePresenter* pie = new PiePresenter(m_chart, s);
183 196 m_chartTheme->decorate(pie, s, m_chartItems.count());
184 197 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), pie, SLOT(handleGeometryChanged(const QRectF&)));
185 198
186 199 // Hide all from background when there is only piechart
187 200 // TODO: refactor this ugly code... should be one setting for this
188 201 if (m_chartItems.count() == 0) {
189 202 m_chart->axisX()->setAxisVisible(false);
190 203 m_chart->axisY()->setAxisVisible(false);
191 204 m_chart->axisX()->setGridVisible(false);
192 205 m_chart->axisY()->setGridVisible(false);
193 206 m_chart->axisX()->setLabelsVisible(false);
194 207 m_chart->axisY()->setLabelsVisible(false);
195 208 m_chart->axisX()->setShadesVisible(false);
196 209 m_chart->axisY()->setShadesVisible(false);
197 210 m_chart->setChartBackgroundBrush(Qt::transparent);
198 211 }
199 212
200 213 m_chartItems.insert(series, pie);
201 214 pie->handleGeometryChanged(m_rect);
202 215 break;
203 216 }
204 217 case QSeries::SeriesTypeSpline: {
205 218 QSplineSeries* splineSeries = qobject_cast<QSplineSeries*>(series);
206 219 SplinePresenter* splinePresenter = new SplinePresenter(splineSeries, m_chart);
207 220 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), splinePresenter, SLOT(handleGeometryChanged(const QRectF&)));
208 221 m_chartTheme->decorate(splinePresenter, splineSeries, m_chartItems.count());
209 222 m_chartItems.insert(splineSeries, splinePresenter);
210 223 break;
211 224 }
212 225 default: {
213 226 qDebug()<< "Series type" << series->type() << "not implemented.";
214 227 break;
215 228 }
216 229
217 230 }
218 231 }
219 232
220 233 void ChartPresenter::handleSeriesRemoved(QSeries* series)
221 234 {
222 235 ChartItem* item = m_chartItems.take(series);
223 236 delete item;
224 237 }
225 238
226 239 void ChartPresenter::handleSeriesDomainChanged(QSeries* series, const Domain& domain)
227 240 {
228 241 m_chartItems.value(series)->handleDomainChanged(domain);
229 242 }
230 243
231 244 void ChartPresenter::handleAxisRangeChanged(QChartAxis* axis,const QStringList& labels)
232 245 {
233 246 m_axisItems.value(axis)->handleRangeChanged(axis,labels);
234 247 }
235 248
236 249 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
237 250 {
238 251 delete m_chartTheme;
239 252
240 253 m_chartTheme = ChartTheme::createTheme(theme);
241 254
242 255 m_chartTheme->decorate(m_chart);
243 256 QMapIterator<QSeries*,ChartItem*> i(m_chartItems);
244 257
245 258 int index=0;
246 259 while (i.hasNext()) {
247 260 i.next();
248 261 m_chartTheme->decorate(i.value(),i.key(),index);
249 262 index++;
250 263 }
251 264
252 265 QMapIterator<QChartAxis*,AxisItem*> j(m_axisItems);
253 266 while (j.hasNext()) {
254 267 j.next();
255 268 m_chartTheme->decorate(j.key(),j.value());
256 269 }
257 270 }
258 271
259 272 QChart::ChartTheme ChartPresenter::chartTheme()
260 273 {
261 274 return m_chartTheme->id();
262 275 }
263 276
264 277 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
265 278 {
266 279 if(m_options!=options) {
267 280
268 281 m_options=options;
269 282
270 283 //recreate elements
271 284
272 285 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
273 286 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
274 287
275 288 foreach(QChartAxis* axis, axisList) {
276 289 handleAxisRemoved(axis);
277 290 handleAxisAdded(axis);
278 291 }
279 292 foreach(QSeries* series, seriesList) {
280 293 handleSeriesRemoved(series);
281 294 handleSeriesAdded(series);
282 295 }
283 296
284 297 //now reintialize view data
285 298 //TODO: make it more nice
286 299 m_dataset->setDomain(m_dataset->domainIndex());
287 300 }
288 301 }
289 302
290 303 QChart::AnimationOptions ChartPresenter::animationOptions() const
291 304 {
292 305 return m_options;
293 306 }
294 307
295 308
296 309 #include "moc_chartpresenter_p.cpp"
297 310
298 311 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,289 +1,319
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 #include "qsplineseries.h"
16 17
17 18 //items
18 19 #include "axisitem_p.h"
19 20 #include "barpresenter_p.h"
20 21 #include "stackedbarpresenter_p.h"
21 22 #include "percentbarpresenter_p.h"
22 23 #include "linechartitem_p.h"
24 #include "areachartitem_p.h"
23 25 #include "scatterpresenter_p.h"
24 26 #include "piepresenter_p.h"
25 27 #include "splinepresenter_p.h"
26 28
27 29 //themes
28 30 #include "chartthemevanilla_p.h"
29 31 #include "chartthemeicy_p.h"
30 32 #include "chartthemegrayscale_p.h"
31 33 #include "chartthemescientific_p.h"
32 34
33 35
34 36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 37
36 38 /* TODO
37 39 case QChart::ChartThemeUnnamed1:
38 40 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xff3fa9f5)), 2));
39 41 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xff7AC943)), 2));
40 42 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF931E)), 2));
41 43 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF1D25)), 2));
42 44 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF7BAC)), 2));
43 45
44 46 m_gradientStartColor = QColor(QRgb(0xfff3dc9e));
45 47 m_gradientEndColor = QColor(QRgb(0xffafafaf));
46 48 */
47 49
48 50 ChartTheme::ChartTheme(QChart::ChartTheme id)
49 51 {
50 52 m_id = id;
51 53 m_seriesColor.append(QRgb(0xff000000));
52 54 m_seriesColor.append(QRgb(0xff707070));
53 55 m_gradientStartColor = QColor(QRgb(0xffffffff));
54 56 m_gradientEndColor = QColor(QRgb(0xffafafaf));
55 57
56 58 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
57 59 }
58 60
59 61
60 62 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
61 63 {
62 64 switch(theme) {
63 65 case QChart::ChartThemeDefault:
64 return new ChartThemeIcy();
66 return new ChartTheme();
65 67 case QChart::ChartThemeVanilla:
66 68 return new ChartThemeVanilla();
67 69 case QChart::ChartThemeIcy:
68 70 return new ChartThemeIcy();
69 71 case QChart::ChartThemeGrayscale:
70 72 return new ChartThemeGrayscale();
71 73 case QChart::ChartThemeScientific:
72 74 return new ChartThemeScientific();
73 75 }
74 76 }
75 77
76 78 void ChartTheme::decorate(QChart* chart)
77 79 {
78 80 QLinearGradient backgroundGradient;
79 81 backgroundGradient.setColorAt(0.0, m_gradientStartColor);
80 82 backgroundGradient.setColorAt(1.0, m_gradientEndColor);
81 83 backgroundGradient.setCoordinateMode(QGradient::ObjectBoundingMode);
82 84 chart->setChartBackgroundBrush(backgroundGradient);
83 85 }
84 86 //TODO helper to by removed later
85 87 void ChartTheme::decorate(ChartItem* item, QSeries* series,int count)
86 88 {
87 89 switch(series->type())
88 90 {
89 91 case QSeries::SeriesTypeLine: {
90 92 QLineSeries* s = static_cast<QLineSeries*>(series);
91 93 LineChartItem* i = static_cast<LineChartItem*>(item);
92 94 decorate(i,s,count);
93 95 break;
94 96 }
97 case QSeries::SeriesTypeArea: {
98 QAreaSeries* s = static_cast<QAreaSeries*>(series);
99 AreaChartItem* i = static_cast<AreaChartItem*>(item);
100 decorate(i,s,count);
101 break;
102 }
95 103 case QSeries::SeriesTypeBar: {
96 104 QBarSeries* b = static_cast<QBarSeries*>(series);
97 105 BarPresenter* i = static_cast<BarPresenter*>(item);
98 106 decorate(i,b,count);
99 107 break;
100 108 }
101 109 case QSeries::SeriesTypeStackedBar: {
102 110 QStackedBarSeries* s = static_cast<QStackedBarSeries*>(series);
103 111 StackedBarPresenter* i = static_cast<StackedBarPresenter*>(item);
104 112 decorate(i,s,count);
105 113 break;
106 114 }
107 115 case QSeries::SeriesTypePercentBar: {
108 116 QPercentBarSeries* s = static_cast<QPercentBarSeries*>(series);
109 117 PercentBarPresenter* i = static_cast<PercentBarPresenter*>(item);
110 118 decorate(i,s,count);
111 119 break;
112 120 }
113 121 case QSeries::SeriesTypeScatter: {
114 122 QScatterSeries* s = qobject_cast<QScatterSeries*>(series);
115 123 Q_ASSERT(s);
116 124 ScatterPresenter* i = static_cast<ScatterPresenter*>(item);
117 125 Q_ASSERT(i);
118 126 decorate(i, s, count);
119 127 break;
120 128 }
121 129 case QSeries::SeriesTypePie: {
122 130 QPieSeries* s = static_cast<QPieSeries*>(series);
123 131 PiePresenter* i = static_cast<PiePresenter*>(item);
124 132 decorate(i,s,count);
125 133 break;
126 134 }
127 135 default:
128 136 qDebug()<<"Wrong item to be decorated by theme";
129 137 break;
130 138 }
131 139
132 140 }
133 141
142 void ChartTheme::decorate(AreaChartItem* item, QAreaSeries* series,int count)
143 {
144 QPen pen;
145 QBrush brush;
146
147 if(pen != series->pen()){
148 item->setPen(series->pen());
149 }else{
150 pen.setColor(m_seriesColor.at(count%m_seriesColor.size()));
151 pen.setWidthF(2);
152 item->setPen(pen);
153 }
154
155 if(brush != series->brush()){
156 item->setBrush(series->brush());
157 }else{
158 QBrush brush(m_seriesColor.at(count%m_seriesColor.size()));
159 item->setBrush(brush);
160 }
161 }
162
163
134 164 void ChartTheme::decorate(LineChartItem* item, QLineSeries* series,int count)
135 165 {
136 166 QPen pen;
137 167 if(pen != series->pen()){
138 168 item->setPen(series->pen());
139 169 return;
140 170 }
141 171 pen.setColor(m_seriesColor.at(count%m_seriesColor.size()));
142 172 pen.setWidthF(2);
143 173 item->setPen(pen);
144 174 }
145 175
146 176 void ChartTheme::decorate(BarPresenter* item, QBarSeries* series,int count)
147 177 {
148 178 QList<QBarSet*> sets = series->barSets();
149 179 for (int i=0; i<series->barsetCount(); i++) {
150 180 sets.at(i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count())));
151 181 }
152 182 }
153 183
154 184 void ChartTheme::decorate(StackedBarPresenter* item, QStackedBarSeries* series,int count)
155 185 {
156 186 QList<QBarSet*> sets = series->barSets();
157 187 for (int i=0; i<series->barsetCount(); i++) {
158 188 sets.at(i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count())));
159 189 }
160 190 }
161 191
162 192 void ChartTheme::decorate(PercentBarPresenter* item, QPercentBarSeries* series,int count)
163 193 {
164 194 QList<QBarSet*> sets = series->barSets();
165 195 for (int i=0; i<series->barsetCount(); i++) {
166 196 sets.at(i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count())));
167 197 }
168 198 }
169 199
170 200 void ChartTheme::decorate(ScatterPresenter* presenter, QScatterSeries* series, int count)
171 201 {
172 202 Q_ASSERT(presenter);
173 203 Q_ASSERT(series);
174 204
175 205 QColor color = m_seriesColor.at(count % m_seriesColor.size());
176 206 // TODO: define alpha in the theme? or in the series?
177 207 //color.setAlpha(120);
178 208
179 209 QBrush brush(color, Qt::SolidPattern);
180 210 presenter->m_markerBrush = brush;
181 211
182 212 QPen pen(brush, 3);
183 213 pen.setColor(color);
184 214 presenter->m_markerPen = pen;
185 215 }
186 216
187 217 void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int /*count*/)
188 218 {
189 219 // create a list of slice colors based on current theme
190 220 int i = 0;
191 221 QList<QColor> colors;
192 222 while (colors.count() < series->count()) {
193 223
194 224 // get base color
195 225 QColor c = m_seriesColor[i++];
196 226 i = i % m_seriesColor.count();
197 227
198 228 // dont use black colors... looks bad
199 229 if (c == Qt::black)
200 230 continue;
201 231
202 232 // by default use the "raw" theme color
203 233 if (!colors.contains(c)) {
204 234 colors << c;
205 235 continue;
206 236 }
207 237 // ...ok we need to generate something that looks like the same color
208 238 // but different lightness
209 239
210 240 int tryCount = 0;
211 241 while (tryCount++ < 100) {
212 242
213 243 // find maximum value we can raise the lightness
214 244 int lMax = 255;
215 245 if (lMax > 255 - c.red())
216 246 lMax = 255 - c.red();
217 247 if (lMax > 255 - c.green())
218 248 lMax = 255 - c.green();
219 249 if (lMax > 255 - c.blue())
220 250 lMax = 255 - c.blue();
221 251
222 252 // find maximum value we can make it darker
223 253 int dMax = 255;
224 254 if (dMax > c.red())
225 255 dMax = c.red();
226 256 if (dMax > c.green())
227 257 dMax = c.green();
228 258 if (dMax > c.blue())
229 259 dMax = c.blue();
230 260
231 261 int max = dMax + lMax;
232 262 if (max == 0) {
233 263 // no room to make color lighter or darker...
234 264 qDebug() << "cannot generate a color for pie!";
235 265 break;
236 266 }
237 267
238 268 // generate random color
239 269 int r = c.red() - dMax;
240 270 int g = c.green() - dMax;
241 271 int b = c.blue() - dMax;
242 272 int d = qrand() % max;
243 273 c.setRgb(r+d, g+d, b+d);
244 274
245 275 // found a unique color?
246 276 if (!colors.contains(c))
247 277 break;
248 278 }
249 279
250 280 qDebug() << "generated a color for pie" << c;
251 281 colors << c;
252 282 }
253 283
254 284 // finally update colors
255 285 foreach (QPieSlice* s, series->slices()) {
256 286 QColor c = colors.takeFirst();
257 287 s->setPen(c);
258 288 s->setBrush(c);
259 289 }
260 290 }
261 291
262 292
263 293 void ChartTheme::decorate(QChartAxis* axis,AxisItem* item)
264 294 {
265 295 //TODO: dummy defults for now
266 296 axis->setLabelsBrush(Qt::black);
267 297 axis->setLabelsPen(Qt::NoPen);
268 298 axis->setShadesPen(Qt::NoPen);
269 299 axis->setShadesOpacity(0.5);
270 300 }
271 301
272 302 void ChartTheme::decorate(SplinePresenter* presenter, QSplineSeries* series, int count)
273 303 {
274 304 Q_ASSERT(presenter);
275 305 Q_ASSERT(series);
276 306
277 307 // QColor color = m_seriesColor.at(count % m_seriesColor.size());
278 308 // TODO: define alpha in the theme? or in the series?
279 309 //color.setAlpha(120);
280 310
281 311 // QBrush brush(color, Qt::SolidPattern);
282 312 // presenter->m_markerBrush = brush;
283 313
284 314 // QPen pen(brush, 3);
285 315 // pen.setColor(color);
286 316 // presenter->m_markerPen = pen;
287 317 }
288 318
289 319 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,55 +1,58
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 24 class SplinePresenter;
25 25 class QSplineSeries;
26 class AreaChartItem;
27 class QAreaSeries;
26 28
27 29 class ChartTheme
28 30 {
29 31 protected:
30 32 explicit ChartTheme(QChart::ChartTheme id = QChart::ChartThemeDefault);
31 33 public:
32 34 static ChartTheme* createTheme(QChart::ChartTheme theme);
33 35 QChart::ChartTheme id() const {return m_id;}
34 36 void decorate(QChart* chart);
35 37 void decorate(ChartItem* item, QSeries* series,int count);
36 38 void decorate(BarPresenter* item, QBarSeries* series,int count);
37 39 void decorate(StackedBarPresenter* item, QStackedBarSeries* series,int count);
38 40 void decorate(PercentBarPresenter* item, QPercentBarSeries* series,int count);
39 void decorate(LineChartItem* item, QLineSeries*, int count);
41 void decorate(LineChartItem* item, QLineSeries* series,int count);
42 void decorate(AreaChartItem* item, QAreaSeries* series,int count);
40 43 void decorate(ScatterPresenter* presenter, QScatterSeries* series, int count);
41 44 void decorate(PiePresenter* item, QPieSeries* series, int count);
42 45 void decorate(QChartAxis* axis,AxisItem* item);
43 46 void decorate(SplinePresenter* presenter, QSplineSeries* series, int count);
44 47
45 48 protected:
46 49 QChart::ChartTheme m_id;
47 50 QColor m_gradientStartColor;
48 51 QColor m_gradientEndColor;
49 52 QList<QColor> m_seriesColor;
50 53
51 54 };
52 55
53 56 QTCOMMERCIALCHART_END_NAMESPACE
54 57
55 58 #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,91 +1,92
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 include(splinechart/splinechart.pri)
36 37
37 38 THEMES += themes/chartthemeicy_p.h \
38 39 themes/chartthemegrayscale_p.h \
39 40 themes/chartthemescientific_p.h \
40 41 themes/chartthemevanilla_p.h
41 42 HEADERS += $$PUBLIC_HEADERS
42 43 HEADERS += $$PRIVATE_HEADERS
43 44 HEADERS += $$THEMES
44 45 INCLUDEPATH += linechart \
45 46 barchart \
46 47 themes \
47 48 .
48 49 OBJECTS_DIR = $$CHART_BUILD_DIR/lib
49 50 MOC_DIR = $$CHART_BUILD_DIR/lib
50 51 UI_DIR = $$CHART_BUILD_DIR/lib
51 52 RCC_DIR = $$CHART_BUILD_DIR/lib
52 53 DEFINES += QTCOMMERCIALCHART_LIBRARY
53 54 public_headers.path = $$[QT_INSTALL_HEADERS]/QtCommercialChart
54 55 public_headers.files = $$PUBLIC_HEADERS
55 56 target.path = $$[QT_INSTALL_LIBS]
56 57 INSTALLS += target \
57 58 public_headers
58 59 install_build_public_headers.name = bild_public_headers
59 60 install_build_public_headers.output = $$CHART_BUILD_PUBLIC_HEADER_DIR/${QMAKE_FILE_BASE}.h
60 61 install_build_public_headers.input = PUBLIC_HEADERS
61 62 install_build_public_headers.commands = $$QMAKE_COPY \
62 63 ${QMAKE_FILE_NAME} \
63 64 $$CHART_BUILD_PUBLIC_HEADER_DIR
64 65 install_build_public_headers.CONFIG += target_predeps \
65 66 no_link
66 67 install_build_private_headers.name = bild_private_headers
67 68 install_build_private_headers.output = $$CHART_BUILD_PRIVATE_HEADER_DIR/${QMAKE_FILE_BASE}.h
68 69 install_build_private_headers.input = PRIVATE_HEADERS
69 70 install_build_private_headers.commands = $$QMAKE_COPY \
70 71 ${QMAKE_FILE_NAME} \
71 72 $$CHART_BUILD_PRIVATE_HEADER_DIR
72 73 install_build_private_headers.CONFIG += target_predeps \
73 74 no_link
74 75 QMAKE_EXTRA_COMPILERS += install_build_public_headers \
75 76 install_build_private_headers
76 77 chartversion.target = qchartversion_p.h
77 78 chartversion.commands = @echo \
78 79 "build_time" \
79 80 > \
80 81 $$chartversion.target;
81 82 chartversion.depends = $$HEADERS \
82 83 $$SOURCES
83 84 PRE_TARGETDEPS += qchartversion_p.h
84 85 QMAKE_CLEAN += qchartversion_p.h
85 86 QMAKE_EXTRA_TARGETS += chartversion
86 87 unix:QMAKE_DISTCLEAN += -r \
87 88 $$CHART_BUILD_HEADER_DIR \
88 89 $$CHART_BUILD_LIB_DIR
89 90 win32:QMAKE_DISTCLEAN += /Q \
90 91 $$CHART_BUILD_HEADER_DIR \
91 92 $$CHART_BUILD_LIB_DIR
General Comments 0
You need to be logged in to leave comments. Login now