##// END OF EJS Templates
Marek Rosa -
r207:1bc0eafcd96e merge
parent child
Show More
@@ -0,0 +1,18
1 #include <QtGui/QApplication>
2 #include <QMainWindow>
3 #include "multichartwidget.h"
4
5 int main(int argc, char *argv[])
6 {
7 QApplication a(argc, argv);
8
9 MultiChartWidget *multi = new MultiChartWidget();
10
11 // Use the chart widget as the central widget
12 QMainWindow w;
13 w.resize(640, 480);
14 w.setCentralWidget(multi);
15 w.show();
16
17 return a.exec();
18 }
@@ -0,0 +1,21
1 !include( ../../common.pri ) {
2 error( "Couldn't find the common.pri file!" )
3 }
4 !include( ../../integrated.pri ) {
5 error( "Couldn't find the integrated.pri file !")
6 }
7
8 QT += core gui
9
10 TARGET = multichart
11 TEMPLATE = app
12
13 SOURCES += main.cpp \
14 multichartwidget.cpp
15
16 HEADERS += \
17 multichartwidget.h
18
19
20
21
@@ -0,0 +1,35
1 #include "multichartwidget.h"
2 #include <QVBoxLayout>
3 #include <qchartglobal.h>
4 #include <qchartview.h>
5 #include <qscatterseries.h>
6 #include <qpieseries.h>
7
8 QTCOMMERCIALCHART_USE_NAMESPACE
9
10 MultiChartWidget::MultiChartWidget(QWidget *parent) :
11 QWidget(parent)
12 {
13 QVBoxLayout *l = new QVBoxLayout(this);
14
15 // Create chart 1 and add a simple pie series onto it
16 QChartView *chartView1 = new QChartView();
17 l->addWidget(chartView1);
18 QPieSeries *pie = new QPieSeries();
19 pie->add(1.1, "label1");
20 pie->add(1.2, "label2");
21 chartView1->addSeries(pie);
22
23 // Create chart 2 and add a simple scatter series onto it
24 QChartView *chartView2 = new QChartView();
25 l->addWidget(chartView2);
26 QScatterSeries *scatter = new QScatterSeries();
27 *scatter << QPointF(0.5, 5.0)
28 << QPointF(1.0, 4.5)
29 << QPointF(1.0, 5.5)
30 << QPointF(1.5, 5.0)
31 << QPointF(2.0, 4.5)
32 << QPointF(2.0, 5.5)
33 << QPointF(2.5, 5.0);
34 chartView2->addSeries(scatter);
35 }
@@ -0,0 +1,18
1 #ifndef MULTICHARTWIDGET_H
2 #define MULTICHARTWIDGET_H
3
4 #include <QWidget>
5
6 class MultiChartWidget : public QWidget
7 {
8 Q_OBJECT
9 public:
10 explicit MultiChartWidget(QWidget *parent = 0);
11
12 signals:
13
14 public slots:
15
16 };
17
18 #endif // MULTICHARTWIDGET_H
@@ -0,0 +1,20
1 #include "customslice.h"
2
3 CustomSlice::CustomSlice(qreal value, QObject* parent)
4 :QPieSlice(parent)
5 {
6 setValue(value);
7 connect(this, SIGNAL(changed()), this, SLOT(updateLabel()));
8 connect(this, SIGNAL(hoverEnter()), this, SLOT(toggleExploded()));
9 connect(this, SIGNAL(hoverLeave()), this, SLOT(toggleExploded()));
10 }
11
12 void CustomSlice::updateLabel()
13 {
14 setLabel(QString::number(this->percentage()));
15 }
16
17 void CustomSlice::toggleExploded()
18 {
19 setExploded(!isExploded());
20 }
@@ -0,0 +1,15
1 #include <qpieslice.h>
2
3 QTCOMMERCIALCHART_USE_NAMESPACE
4
5 class CustomSlice : public QPieSlice
6 {
7 Q_OBJECT
8
9 public:
10 CustomSlice(qreal value, QObject* parent = 0);
11
12 public Q_SLOTS:
13 void updateLabel();
14 void toggleExploded();
15 };
@@ -0,0 +1,69
1 #include "declarativescatterseries.h"
2 #include "declarativechart.h"
3 #include "qchart.h"
4 #include "qscatterseries.h"
5 #include <cmath>
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
9 DeclarativeScatterSeries::DeclarativeScatterSeries(QDeclarativeItem *parent) :
10 QDeclarativeItem(parent),
11 m_chart(0),
12 m_series(0)
13 {
14 setFlag(QGraphicsItem::ItemHasNoContents, false);
15 connect(this, SIGNAL(parentChanged()),
16 this, SLOT(setParentForSeries()));
17 }
18
19 void DeclarativeScatterSeries::setParentForSeries()
20 {
21 if (!m_series)
22 initSeries();
23 }
24
25 void DeclarativeScatterSeries::initSeries()
26 {
27 Q_ASSERT(!m_series);
28 DeclarativeChart *declarativeChart = qobject_cast<DeclarativeChart *>(parent());
29
30 if (declarativeChart) {
31 QChart *chart = qobject_cast<QChart *>(declarativeChart->m_chart);
32 qDebug() << "creating scatter series for chart: " << chart;
33 Q_ASSERT(chart);
34
35 m_series = new QScatterSeries();
36 Q_ASSERT(m_series);
37 for (int i(0); i < m_data.count(); i++) {
38 ScatterElement *element = m_data.at(i);
39 *m_series << QPointF(element->x(), element->y());
40 }
41 chart->addSeries(m_series);
42 }
43 }
44
45 QDeclarativeListProperty<ScatterElement> DeclarativeScatterSeries::data()
46 {
47 return QDeclarativeListProperty<ScatterElement>(this, 0,
48 &DeclarativeScatterSeries::appendData);
49 }
50
51 void DeclarativeScatterSeries::appendData(QDeclarativeListProperty<ScatterElement> *list,
52 ScatterElement *element)
53 {
54 DeclarativeScatterSeries *series = qobject_cast<DeclarativeScatterSeries *>(list->object);
55 qDebug() << "appendData: " << series;
56 qDebug() << "appendData: " << element;
57 qDebug() << "appendData: " << element->x();
58 qDebug() << "appendData: " << element->y();
59 qDebug() << "appendData: " << series->m_series;
60 if (series) {
61 series->m_data.append(element);
62 if (series->m_series)
63 series->m_series->addData(QPointF(element->x(), element->y()));
64 }
65 }
66
67 #include "moc_declarativescatterseries.cpp"
68
69 QTCOMMERCIALCHART_END_NAMESPACE
@@ -0,0 +1,42
1 #ifndef DECLARATIVESCATTERSERIES_H
2 #define DECLARATIVESCATTERSERIES_H
3
4 #include "qchartglobal.h"
5 #include "scatterelement.h"
6 #include <QDeclarativeItem>
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
10 class QChart;
11 class QScatterSeries;
12
13 class DeclarativeScatterSeries : public QDeclarativeItem
14 {
15 Q_OBJECT
16 Q_PROPERTY(QDeclarativeListProperty<ScatterElement> data READ data)
17
18 public:
19 explicit DeclarativeScatterSeries(QDeclarativeItem *parent = 0);
20 QDeclarativeListProperty<ScatterElement> data();
21
22 signals:
23
24 public slots:
25 static void appendData(QDeclarativeListProperty<ScatterElement> *list,
26 ScatterElement *element);
27 // void append(ScatterElement element);
28
29 private slots:
30 void setParentForSeries();
31
32 public:
33 void initSeries();
34
35 QChart *m_chart;
36 QScatterSeries *m_series;
37 QList<ScatterElement *> m_data;
38 };
39
40 QTCOMMERCIALCHART_END_NAMESPACE
41
42 #endif // DECLARATIVESCATTERSERIES_H
@@ -0,0 +1,12
1 #include "scatterelement.h"
2
3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4
5 ScatterElement::ScatterElement(QObject *parent) :
6 QObject(parent)
7 {
8 }
9
10 #include "moc_scatterelement.cpp"
11
12 QTCOMMERCIALCHART_END_NAMESPACE
@@ -0,0 +1,30
1 #ifndef SCATTERELEMENT_H
2 #define SCATTERELEMENT_H
3
4 #include "qchartglobal.h"
5 #include <QObject>
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
9 class ScatterElement : public QObject
10 {
11 Q_OBJECT
12 Q_PROPERTY(qreal x READ x WRITE setX /*NOTIFY dataXChanged*/)
13 Q_PROPERTY(qreal y READ y WRITE setY /*NOTIFY dataYChanged*/)
14
15 public:
16 explicit ScatterElement(QObject *parent = 0);
17
18 void setX(qreal x) {m_x = x;}
19 qreal x() {return m_x;}
20 void setY(qreal y) {m_y = y;}
21 qreal y() {return m_y;}
22
23 public:
24 qreal m_x;
25 qreal m_y;
26 };
27
28 QTCOMMERCIALCHART_END_NAMESPACE
29
30 #endif // SCATTERELEMENT_H
@@ -0,0 +1,181
1 #include "qpieslice.h"
2
3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4
5 #define DEFAULT_PEN_COLOR Qt::black
6 #define DEFAULT_BRUSH_COLOR Qt::white
7 #define DEFAULT_LABEL_ARM_LENGTH 50
8
9 QPieSlice::QPieSlice(QObject *parent)
10 :QObject(parent),
11 m_value(0),
12 m_isLabelVisible(true),
13 m_isExploded(false),
14 m_percentage(0),
15 m_angle(0),
16 m_span(0),
17 m_pen(DEFAULT_PEN_COLOR),
18 m_brush(DEFAULT_BRUSH_COLOR),
19 m_labelPen(DEFAULT_PEN_COLOR),
20 m_labelArmLength(DEFAULT_LABEL_ARM_LENGTH)
21 {
22
23 }
24
25 QPieSlice::QPieSlice(qreal value, QString label, bool labelVisible, QObject *parent)
26 :QObject(parent),
27 m_value(value),
28 m_label(label),
29 m_isLabelVisible(labelVisible),
30 m_isExploded(false),
31 m_percentage(0),
32 m_angle(0),
33 m_span(0),
34 m_pen(DEFAULT_PEN_COLOR),
35 m_brush(DEFAULT_BRUSH_COLOR),
36 m_labelPen(DEFAULT_PEN_COLOR),
37 m_labelArmLength(DEFAULT_LABEL_ARM_LENGTH)
38 {
39
40 }
41
42 QPieSlice::~QPieSlice()
43 {
44
45 }
46
47 qreal QPieSlice::value() const
48 {
49 return m_value;
50 }
51
52 QString QPieSlice::label() const
53 {
54 return m_label;
55 }
56
57 bool QPieSlice::isLabelVisible() const
58 {
59 return m_isLabelVisible;
60 }
61
62 bool QPieSlice::isExploded() const
63 {
64 return m_isExploded;
65 }
66
67 qreal QPieSlice::percentage() const
68 {
69 return m_percentage;
70 }
71
72 qreal QPieSlice::angle() const
73 {
74 return m_angle;
75 }
76
77 qreal QPieSlice::span() const
78 {
79 return m_span;
80 }
81
82 QPen QPieSlice::pen() const
83 {
84 return m_pen;
85 }
86
87 QBrush QPieSlice::brush() const
88 {
89 return m_brush;
90 }
91
92 QPen QPieSlice::labelPen() const
93 {
94 return m_labelPen;
95 }
96
97 QFont QPieSlice::labelFont() const
98 {
99 return m_labelFont;
100 }
101
102 qreal QPieSlice::labelArmLenght() const
103 {
104 return m_labelArmLength;
105 }
106
107 void QPieSlice::setValue(qreal value)
108 {
109 if (m_value != value) {
110 m_value = value;
111 emit changed();
112 }
113 }
114
115 void QPieSlice::setLabel(QString label)
116 {
117 if (m_label != label) {
118 m_label = label;
119 emit changed();
120 }
121 }
122
123 void QPieSlice::setLabelVisible(bool visible)
124 {
125 if (m_isLabelVisible != visible) {
126 m_isLabelVisible = visible;
127 emit changed();
128 }
129 }
130
131 void QPieSlice::setExploded(bool exploded)
132 {
133 if (m_isExploded != exploded) {
134 m_isExploded = exploded;
135 emit changed();
136 }
137 }
138
139 void QPieSlice::setPen(QPen pen)
140 {
141 if (m_pen != pen) {
142 m_pen = pen;
143 emit changed();
144 }
145 }
146
147 void QPieSlice::setBrush(QBrush brush)
148 {
149 if (m_brush != brush) {
150 m_brush = brush;
151 emit changed();
152 }
153 }
154
155 void QPieSlice::setLabelFont(QFont font)
156 {
157 if (m_labelFont != font) {
158 m_labelFont = font;
159 emit changed();
160 }
161 }
162
163 void QPieSlice::setLabelPen(QPen pen)
164 {
165 if (m_labelPen != pen) {
166 m_labelPen = pen;
167 emit changed();
168 }
169 }
170
171 void QPieSlice::setLabelArmLength(qreal len)
172 {
173 if (m_labelArmLength != len) {
174 m_labelArmLength = len;
175 emit changed();
176 }
177 }
178
179 #include "moc_qpieslice.cpp"
180
181 QTCOMMERCIALCHART_END_NAMESPACE
@@ -0,0 +1,86
1 #ifndef QPIESLICE_H
2 #define QPIESLICE_H
3
4 #include <qchartglobal.h>
5 #include <QObject>
6 #include <QPen>
7 #include <QBrush>
8 #include <QFont>
9
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11
12 class QTCOMMERCIALCHART_EXPORT QPieSlice : public QObject
13 {
14 Q_OBJECT
15
16 public:
17 QPieSlice(QObject *parent = 0);
18 QPieSlice(qreal value, QString label, bool labelVisible = true, QObject *parent = 0);
19 virtual ~QPieSlice();
20
21 // data
22 qreal value() const;
23 QString label() const;
24 bool isLabelVisible() const;
25 bool isExploded() const;
26
27 // generated data
28 qreal percentage() const;
29 qreal angle() const;
30 qreal span() const;
31
32 // customization
33 QPen pen() const;
34 QBrush brush() const;
35 QPen labelPen() const;
36 QFont labelFont() const;
37 qreal labelArmLenght() const;
38
39 Q_SIGNALS:
40 void clicked();
41 void hoverEnter();
42 void hoverLeave();
43 void changed();
44
45 public Q_SLOTS:
46
47 // data
48 void setLabel(QString label);
49 void setLabelVisible(bool visible);
50 void setValue(qreal value);
51 void setExploded(bool exploded);
52
53 // customization
54 void setPen(QPen pen);
55 void setBrush(QBrush brush);
56 void setLabelFont(QFont font);
57 void setLabelPen(QPen pen);
58 void setLabelArmLength(qreal len);
59
60 private:
61
62 // TODO: use private class
63 friend class QPieSeries;
64
65 // data
66 qreal m_value;
67 QString m_label;
68 bool m_isLabelVisible;
69 bool m_isExploded;
70
71 // generated data
72 qreal m_percentage;
73 qreal m_angle;
74 qreal m_span;
75
76 // customization
77 QPen m_pen;
78 QBrush m_brush;
79 QPen m_labelPen;
80 QFont m_labelFont;
81 qreal m_labelArmLength;
82 };
83
84 QTCOMMERCIALCHART_END_NAMESPACE
85
86 #endif // QPIESLICE_H
@@ -0,0 +1,13
1 INCLUDEPATH += $$PWD
2 DEPENDPATH += $$PWD
3
4 SOURCES += \
5 $$PWD/qscatterseries.cpp \
6 $$PWD/scatterpresenter.cpp
7
8 PRIVATE_HEADERS += \
9 $$PWD/scatterpresenter_p.h \
10 $$PWD/scatterseries_p.h
11
12 PUBLIC_HEADERS += \
13 $$PWD/qscatterseries.h
@@ -3,7 +3,14
3 3 }
4 4
5 5 TEMPLATE = subdirs
6 SUBDIRS += src qmlplugin example test
6 SUBDIRS += src example test qmlplugin
7
8 integrated_build:{
9 message('Configured for integrated build')
10 } else {
11 message('Please build example test and qmlplugin after installing library.')
12 }
13
7 14 CONFIG += ordered
8 15 QMAKE_CXXFLAGS += -g -Wall
9 16 unix:QMAKE_DISTCLEAN += -r build bin
@@ -1,13 +1,15
1 1 CONFIG+=integrated_build #remove if you want to build against installed libs
2 2
3 CHART_BUILD_HEADER_DIR = $$PWD/include
3 CHART_BUILD_PUBLIC_HEADER_DIR = $$PWD/include
4 CHART_BUILD_PRIVATE_HEADER_DIR = $$CHART_BUILD_PUBLIC_HEADER_DIR/private
4 5 CHART_BUILD_LIB_DIR = $$PWD/lib
5 6 CHART_BUILD_DIR = $$PWD/build
6 7 CHART_BUILD_BIN_DIR = $$PWD/bin
7 8
8 9 # hack to fix windows builds
9 10 win32:{
10 CHART_BUILD_HEADER_DIR = $$replace(CHART_BUILD_HEADER_DIR, "/","\\")
11 CHART_BUILD_PUBLIC_HEADER_DIR = $$replace(CHART_BUILD_PUBLIC_HEADER_DIR, "/","\\")
12 CHART_BUILD_PRIVATE_HEADER_DIR = $$replace(CHART_BUILD_PRIVATE_HEADER_DIR, "/","\\")
11 13 CHART_BUILD_LIB_DIR = $$replace(CHART_BUILD_LIB_DIR, "/","\\")
12 14 CHART_BUILD_BUILD_DIR = $$replace(CHART_BUILD_BUILD_DIR, "/","\\")
13 15 CHART_BUILD_BIN_DIR = $$replace(CHART_BUILD_BIN_DIR, "/","\\")
@@ -9,4 +9,5 SUBDIRS += linechart \
9 9 piechart \
10 10 dynamiclinechart \
11 11 axischart\
12 gdpbarchart
12 gdpbarchart\
13 multichart
@@ -1,9 +1,10
1 1 #include <QtGui/QApplication>
2 2 #include <QMainWindow>
3 #include <cmath>
4 3 #include <qchartglobal.h>
5 4 #include <qchartview.h>
6 5 #include <qpieseries.h>
6 #include <qpieslice.h>
7 #include "customslice.h"
7 8
8 9 QTCOMMERCIALCHART_USE_NAMESPACE
9 10
@@ -11,23 +12,31 int main(int argc, char *argv[])
11 12 {
12 13 QApplication a(argc, argv);
13 14
14 // Create widget and scatter series
15 QChartView *chartWidget = new QChartView();
16 QPieSeries *series = qobject_cast<QPieSeries *>(chartWidget->createSeries(QChartSeries::SeriesTypePie));
17 Q_ASSERT(series);
18
19 // Add test data to the series
20 series->add(QPieSlice(1, "test1", true, true, QPen(Qt::red, 2), QBrush(Qt::red)));
21 series->add(QPieSlice(2, "test2"));
22 series->add(QPieSlice(3, "test3"));
23 series->add(QPieSlice(4, "test4"));
24 series->add(QPieSlice(5, "test5"));
25
26 // Use the chart widget as the central widget
27 QMainWindow w;
28 w.resize(640, 480);
29 w.setCentralWidget(chartWidget);
30 w.show();
15 QMainWindow window;
16
17 QPieSeries *series = new QPieSeries();
18 series->add(5, "Slice 1");
19 series->add(2, "Slice 2");
20 series->add(3, "Slice 3");
21 series->add(4, "Slice 4");
22 series->add(5, "Slice 5");
23 series->add(6, "Slice 6");
24 series->add(7, "Slice 7");
25 series->add(new CustomSlice(8));
26 series->enableClickExplodes(true);
27 series->enableHoverHighlight(true);
28
29 foreach (QPieSlice*s, series->slices())
30 qDebug() << s->angle() << s->span() << s->percentage();
31
32 QChartView* chartView = new QChartView(&window);
33 chartView->addSeries(series);
34 chartView->setChartTitle("simple piechart");
35 chartView->setChartTheme(QChart::ChartThemeIcy);
36
37 window.setCentralWidget(chartView);
38 window.resize(600, 600);
39 window.show();
31 40
32 41 return a.exec();
33 42 }
@@ -10,8 +10,10 QT += core gui
10 10 TARGET = piechart
11 11 TEMPLATE = app
12 12
13 SOURCES += main.cpp
13 SOURCES += main.cpp customslice.cpp
14 HEADERS += customslice.h
14 15
15 HEADERS +=
16 OBJECTS_DIR = tmp
17 MOC_DIR = tmp
16 18
17 19
@@ -14,20 +14,38 int main(int argc, char *argv[])
14 14 // Create chart widget
15 15 QChartView *chartWidget = new QChartView();
16 16
17 // Create scatter series with simple test data
17 // Add scatter series with simple test data
18 18 QScatterSeries *scatter = new QScatterSeries();
19 *scatter << QPointF(0.5, 2.0)
20 << QPointF(1.0, 2.5)
21 << QPointF(1.5, 2.0)
22 << QPointF(2.0, 2.5);
19 *scatter << QPointF(0.5, 5.0)
20 << QPointF(1.0, 4.5)
21 << QPointF(1.0, 5.5)
22 << QPointF(1.5, 5.0)
23 << QPointF(2.0, 4.5)
24 << QPointF(2.0, 5.5)
25 << QPointF(2.5, 5.0);
23 26 chartWidget->addSeries(scatter);
24 27
25 // Add another scatter series with more complex data with random component
28 // Add another scatter series
29 // - more data with random component
26 30 QScatterSeries *scatter2 = new QScatterSeries();
27 for (qreal i(0.0); i < 20; i += 0.5)
31 for (qreal i(0.0); i < 20; i += 0.05) {
28 32 (*scatter2) << QPointF(i + (qreal)(rand() % 100) / 100.0,
29 33 i + (qreal)(rand() % 100) / 100.0);
34 }
30 35 chartWidget->addSeries(scatter2);
36 // Custom pen and brush (not those defined by the chart theme)
37 // - uses opaque color
38 QColor color("#2685BF");
39 color.setAlpha(80);
40 QBrush brush(Qt::SolidPattern);
41 brush.setColor(color);
42 scatter2->setMarkerBrush(brush);
43 QPen pen;
44 pen.setColor(color);
45 pen.setWidth(2);
46 scatter2->setMarkerPen(pen);
47 // use a rectangle as the marker shape
48 scatter2->setMarkerShape(QScatterSeries::MarkerShapeRectangle);
31 49
32 50 // Use the chart widget as the central widget
33 51 QMainWindow w;
@@ -1,12 +1,18
1 1 integrated_build:{
2 message('Internal build within charts core source tree')
3 INCLUDEPATH += $$CHART_BUILD_HEADER_DIR
2 message('Running integrated build against local libs...')
3 INCLUDEPATH += $$CHART_BUILD_PUBLIC_HEADER_DIR
4 4
5 5 !win32: {
6 6 LIBS += -L $$CHART_BUILD_LIB_DIR -Wl,-rpath,$$CHART_BUILD_LIB_DIR
7 7 }else{
8 win32-msvc*: {
9 # hack fix for error:
10 # "LINK : fatal error LNK1146: no argument specified with option '/LIBPATH:'"
11 QMAKE_LIBDIR += $$CHART_BUILD_LIB_DIR
12 }else{
8 13 LIBS += -L $$CHART_BUILD_LIB_DIR
9 14 }
15 }
10 16
11 17 DESTDIR = $$CHART_BUILD_BIN_DIR
12 18
@@ -45,5 +51,6 integrated_build:{
45 51 }
46 52
47 53 } else {
54 message('Running build aginst system libs...')
48 55 CONFIG+=qtcommercialchart
49 56 }
@@ -7,7 +7,6 DeclarativeChart::DeclarativeChart(QDeclarativeItem *parent)
7 7 m_chart(new QChart(this))
8 8 {
9 9 setFlag(QGraphicsItem::ItemHasNoContents, false);
10 // m_chart->setMargin(50); // TODO: should not be needed?
11 10 }
12 11
13 12 DeclarativeChart::ChartTheme DeclarativeChart::theme()
@@ -18,8 +17,21 DeclarativeChart::ChartTheme DeclarativeChart::theme()
18 17
19 18 void DeclarativeChart::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
20 19 {
21 if (newGeometry.isValid())
20 qDebug() << "geometryChanged " << this << " old geometry: " << oldGeometry;
21 if (newGeometry.isValid()) {
22 if (newGeometry.width() > 0 && newGeometry.height() > 0) {
23 // TODO: setting margin should not be needed to make axis visible?
24 const int margin = 30;
25 if (m_chart->margin() == 0
26 && newGeometry.width() > (margin * 2)
27 && newGeometry.height() > (margin * 2)) {
28 m_chart->setMargin(margin);
22 29 m_chart->resize(newGeometry.width(), newGeometry.height());
30 } else {
31 m_chart->resize(newGeometry.width(), newGeometry.height());
32 }
33 }
34 }
23 35 }
24 36
25 37 #include "moc_declarativechart.cpp"
@@ -86,15 +86,6 void DeclarativeSeries::initSeries()
86 86 }
87 87 }
88 88
89 QVariant DeclarativeSeries::itemChange(GraphicsItemChange change,
90 const QVariant &value)
91 {
92 // For debugging purposes only:
93 // qDebug() << QString::number(change) << " : " << value.toString();
94 return QGraphicsItem::itemChange(change, value);
95 }
96
97
98 89 #include "moc_declarativeseries.cpp"
99 90
100 91 QTCOMMERCIALCHART_END_NAMESPACE
@@ -34,9 +34,6 signals:
34 34 public slots:
35 35 void setParentForSeries();
36 36
37 public: // from QDeclarativeItem
38 QVariant itemChange(GraphicsItemChange, const QVariant &);
39
40 37 public:
41 38 void setSeriesType(SeriesType type);
42 39 SeriesType seriesType() { return m_seriesType; }
@@ -2,6 +2,8
2 2 #include <QtDeclarative/qdeclarative.h>
3 3 #include "declarativechart.h"
4 4 #include "declarativeseries.h"
5 #include "scatterelement.h"
6 #include "declarativescatterseries.h"
5 7
6 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 9
@@ -14,7 +16,8 public:
14 16 Q_ASSERT(QLatin1String(uri) == QLatin1String("QtCommercial.Chart"));
15 17 qmlRegisterType<DeclarativeChart>(uri, 1, 0, "Chart");
16 18 qmlRegisterType<DeclarativeSeries>(uri, 1, 0, "Series");
17 //qmlRegisterUncreatableType<QChartSeries::SeriesTypeBar>(uri, 1, 0, "Series.Se", QLatin1String("Do not create objects of this type."));
19 qmlRegisterType<DeclarativeScatterSeries>(uri, 1, 0, "ScatterSeries");
20 qmlRegisterType<ScatterElement>(uri, 1, 0, "ScatterElement");
18 21 }
19 22 };
20 23
@@ -24,10 +24,14 RCC_DIR = $$CHART_BUILD_DIR/lib
24 24 SOURCES += \
25 25 plugin.cpp \
26 26 declarativechart.cpp \
27 declarativeseries.cpp
27 declarativeseries.cpp \
28 declarativescatterseries.cpp \
29 scatterelement.cpp
28 30 HEADERS += \
29 31 declarativechart.h \
30 declarativeseries.h
32 declarativeseries.h \
33 declarativescatterseries.h \
34 scatterelement.h
31 35
32 36 TARGETPATH = QtCommercial/Chart
33 37 target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
@@ -37,3 +41,17 qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
37 41 INSTALLS += target qmldir
38 42
39 43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
@@ -29,6 +29,7 void ChartDataSet::addSeries(QChartSeries* series)
29 29 {
30 30 // TODO: we should check the series not already added
31 31 m_chartSeries << series;
32 series->setParent(this); // take ownership
32 33 m_domainIndex = 0;
33 34 m_domains.resize(1);
34 35
@@ -18,7 +18,7
18 18 #include "percentbargroup.h"
19 19 #include "linechartanimationitem_p.h"
20 20 #include "piepresenter.h"
21 #include "scatterpresenter.h"
21 #include "scatterpresenter_p.h"
22 22
23 23 QTCOMMERCIALCHART_BEGIN_NAMESPACE
24 24
@@ -127,9 +127,6 void ChartPresenter::handleSeriesAdded(QChartSeries* series)
127 127 QObject::connect(m_dataset, SIGNAL(domainChanged(const Domain&)),
128 128 scatterPresenter, SLOT(handleDomainChanged(const Domain&)));
129 129 m_chartTheme->decorate(scatterPresenter, scatterSeries, m_chartItems.count());
130 // scatterSeries->d->m_theme = m_chartTheme->themeForSeries();
131 // scatterSeries->d->setParentItem(this);
132 // scatterSeries->d->m_boundingRect = m_rect.adjusted(margin(),margin(), -margin(), -margin());
133 130 m_chartItems.insert(scatterSeries, scatterPresenter);
134 131 break;
135 132 }
@@ -10,6 +10,7
10 10 #include "qlinechartseries.h"
11 11 #include "qscatterseries.h"
12 12 #include "qpieseries.h"
13 #include "qpieslice.h"
13 14
14 15 //items
15 16 #include "axisitem_p.h"
@@ -17,7 +18,7
17 18 #include "stackedbargroup.h"
18 19 #include "linechartitem_p.h"
19 20 #include "percentbargroup.h"
20 #include "scatterpresenter.h"
21 #include "scatterpresenter_p.h"
21 22 #include "piepresenter.h"
22 23
23 24 //themes
@@ -104,6 +105,14 void ChartTheme::decorate(ChartItem* item, QChartSeries* series,int count)
104 105 decorate(i,s,count);
105 106 break;
106 107 }
108 case QChartSeries::SeriesTypeScatter: {
109 QScatterSeries* s = qobject_cast<QScatterSeries*>(series);
110 Q_ASSERT(s);
111 ScatterPresenter* i = static_cast<ScatterPresenter*>(item);
112 Q_ASSERT(i);
113 decorate(i, s, count);
114 break;
115 }
107 116 case QChartSeries::SeriesTypePie: {
108 117 QPieSeries* s = static_cast<QPieSeries*>(series);
109 118 PiePresenter* i = static_cast<PiePresenter*>(item);
@@ -179,16 +188,16 void ChartTheme::decorate(ScatterPresenter* presenter, QScatterSeries* series, i
179 188 Q_ASSERT(presenter);
180 189 Q_ASSERT(series);
181 190
182 presenter->m_markerPen.setColor(m_seriesColor.at(count % m_seriesColor.size()));
191 QColor color = m_seriesColor.at(count % m_seriesColor.size());
192 // TODO: define alpha in the theme? or in the series?
193 color.setAlpha(120);
194
195 QBrush brush(color, Qt::SolidPattern);
196 presenter->m_markerBrush = brush;
183 197
184 // QPen pen;
185 // if(pen != series->pen()){
186 // item->setPen(series->pen());
187 // return;
188 // }
189 // pen.setColor(m_seriesColor.at(count%m_seriesColor.size()));
190 // pen.setWidthF(2);
191 // item->setPen(pen);
198 QPen pen(brush, 1);
199 pen.setColor(color);
200 presenter->m_markerPen = pen;
192 201 }
193 202
194 203 void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int /*count*/)
@@ -224,11 +233,9 void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int /*count*/)
224 233 }
225 234
226 235 // finally update colors
227 foreach (QPieSliceId id, series->ids()) {
228 QPieSlice s = series->slice(id);
229 s.setPen(QPen(Qt::black)); // TODO: get from theme
230 s.setBrush(colors.takeFirst());
231 series->update(s);
236 foreach (QPieSlice* s, series->slices()) {
237 s->setPen(QPen(Qt::black)); // TODO: get from theme
238 s->setBrush(colors.takeFirst());
232 239 }
233 240 }
234 241
@@ -5,7 +5,8 SOURCES += \
5 5 $$PWD/qpieseries.cpp \
6 6 $$PWD/pieslice.cpp \
7 7 $$PWD/piepresenter.cpp \
8 $$PWD/pieslicelabel.cpp
8 $$PWD/pieslicelabel.cpp \
9 $$PWD/qpieslice.cpp
9 10
10 11 PRIVATE_HEADERS += \
11 12 $$PWD/piepresenter.h \
@@ -13,4 +14,5 PRIVATE_HEADERS += \
13 14 $$PWD/pieslicelabel.h
14 15
15 16 PUBLIC_HEADERS += \
16 $$PWD/qpieseries.h
17 $$PWD/qpieseries.h \
18 $$PWD/qpieslice.h
@@ -1,6 +1,7
1 1
2 2 #include "piepresenter.h"
3 3 #include "pieslice.h"
4 #include "qpieslice.h"
4 5 #include <QDebug>
5 6 #include <QTime>
6 7
@@ -29,140 +30,124 void PiePresenter::paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *
29 30
30 31 void PiePresenter::handleSeriesChanged(const QPieSeries::ChangeSet& changeSet)
31 32 {
32 qDebug() << "PiePresenter::handleSeriesChanged()";
33 qDebug() << " added : " << changeSet.m_added;
34 qDebug() << " changed: " << changeSet.m_changed;
35 qDebug() << " removed: " << changeSet.m_removed;
33 //qDebug() << "PiePresenter::handleSeriesChanged()";
34 //qDebug() << " added : " << changeSet.added();
35 //qDebug() << " changed: " << changeSet.changed();
36 //qDebug() << " removed: " << changeSet.removed();
36 37
37 38 // ignore changeset when there are no visual slices
38 39 // changeset might not be valid about the added slices
39 40 if (m_slices.count() == 0) {
40 foreach (QPieSliceId id, m_series->m_slices.keys())
41 addSlice(id);
41 foreach (QPieSlice* s, m_series->m_slices)
42 addSlice(s);
42 43 return;
43 44 }
44 45
45 foreach (QPieSliceId id, changeSet.m_removed)
46 deleteSlice(id);
46 foreach (QPieSlice* s, changeSet.removed())
47 deleteSlice(s);
47 48
48 foreach (QPieSliceId id, changeSet.m_changed)
49 updateSlice(id);
49 foreach (QPieSlice* s, changeSet.added())
50 addSlice(s);
51 }
50 52
51 foreach (QPieSliceId id, changeSet.m_added)
52 addSlice(id);
53 void PiePresenter::handleDomainChanged(const Domain& domain)
54 {
55 // TODO
56 }
57
58 void PiePresenter::handleGeometryChanged(const QRectF& rect)
59 {
60 m_rect = rect;
61 updateGeometry();
53 62 }
54 63
55 64 void PiePresenter::updateGeometry()
56 65 {
57 66 prepareGeometryChange();
58 67
59 m_pieRect = m_rect;
68 QRectF pieRect = m_rect;
60 69
61 if (m_pieRect.width() < m_pieRect.height()) {
62 m_pieRect.setWidth(m_pieRect.width() * m_series->sizeFactor());
63 m_pieRect.setHeight(m_pieRect.width());
64 m_pieRect.moveCenter(m_rect.center());
70 if (pieRect.width() < pieRect.height()) {
71 pieRect.setWidth(pieRect.width() * m_series->sizeFactor());
72 pieRect.setHeight(pieRect.width());
73 pieRect.moveCenter(m_rect.center());
65 74 } else {
66 m_pieRect.setHeight(m_pieRect.height() * m_series->sizeFactor());
67 m_pieRect.setWidth(m_pieRect.height());
68 m_pieRect.moveCenter(m_rect.center());
75 pieRect.setHeight(pieRect.height() * m_series->sizeFactor());
76 pieRect.setWidth(pieRect.height());
77 pieRect.moveCenter(m_rect.center());
69 78 }
70 79
71 80 switch (m_series->position()) {
72 81 case QPieSeries::PiePositionTopLeft: {
73 m_pieRect.setHeight(m_pieRect.height() / 2);
74 m_pieRect.setWidth(m_pieRect.height());
75 m_pieRect.moveCenter(QPointF(m_rect.center().x() / 2, m_rect.center().y() / 2));
82 pieRect.setHeight(pieRect.height() / 2);
83 pieRect.setWidth(pieRect.height());
84 pieRect.moveCenter(QPointF(m_rect.center().x() / 2, m_rect.center().y() / 2));
76 85 break;
77 86 }
78 87 case QPieSeries::PiePositionTopRight: {
79 m_pieRect.setHeight(m_pieRect.height() / 2);
80 m_pieRect.setWidth(m_pieRect.height());
81 m_pieRect.moveCenter(QPointF((m_rect.center().x() / 2) * 3, m_rect.center().y() / 2));
88 pieRect.setHeight(pieRect.height() / 2);
89 pieRect.setWidth(pieRect.height());
90 pieRect.moveCenter(QPointF((m_rect.center().x() / 2) * 3, m_rect.center().y() / 2));
82 91 break;
83 92 }
84 93 case QPieSeries::PiePositionBottomLeft: {
85 m_pieRect.setHeight(m_pieRect.height() / 2);
86 m_pieRect.setWidth(m_pieRect.height());
87 m_pieRect.moveCenter(QPointF(m_rect.center().x() / 2, (m_rect.center().y() / 2) * 3));
94 pieRect.setHeight(pieRect.height() / 2);
95 pieRect.setWidth(pieRect.height());
96 pieRect.moveCenter(QPointF(m_rect.center().x() / 2, (m_rect.center().y() / 2) * 3));
88 97 break;
89 98 }
90 99 case QPieSeries::PiePositionBottomRight: {
91 m_pieRect.setHeight(m_pieRect.height() / 2);
92 m_pieRect.setWidth(m_pieRect.height());
93 m_pieRect.moveCenter(QPointF((m_rect.center().x() / 2) * 3, (m_rect.center().y() / 2) * 3));
100 pieRect.setHeight(pieRect.height() / 2);
101 pieRect.setWidth(pieRect.height());
102 pieRect.moveCenter(QPointF((m_rect.center().x() / 2) * 3, (m_rect.center().y() / 2) * 3));
94 103 break;
95 104 }
96 105 default:
97 106 break;
98 107 }
99 108
100 // update slice geometry
101 const qreal fullPie = 360;
102 qreal angle = 0;
103 foreach (QPieSliceId id, m_slices.keys()) {
104 qreal span = fullPie * m_series->slice(id).percentage();
105 m_slices[id]->updateGeometry(m_pieRect, angle, span);
106 angle += span;
107 }
108
109 //qDebug() << "PiePresenter::updateGeometry" << m_rect << m_pieRect;
109 if (m_pieRect != pieRect) {
110 m_pieRect = pieRect;
111 //qDebug() << "PiePresenter::updateGeometry()" << m_pieRect;
112 foreach (PieSlice* s, m_slices.values()) {
113 s->setPieRect(m_pieRect);
114 s->updateGeometry();
110 115 }
111
112 void PiePresenter::handleDomainChanged(const Domain& domain)
113 {
114 // TODO
115 116 }
116
117 void PiePresenter::handleGeometryChanged(const QRectF& rect)
118 {
119 m_rect = rect;
120 updateGeometry();
121 117 }
122 118
123 void PiePresenter::addSlice(QPieSliceId id)
119 void PiePresenter::addSlice(QPieSlice* sliceData)
124 120 {
125 qDebug() << "PiePresenter::addSlice()" << id;
121 //qDebug() << "PiePresenter::addSlice()" << sliceData;
126 122
127 if (m_slices.contains(id)) {
128 qWarning() << "PiePresenter::addSlice(): slice already exists!" << id;
129 updateSlice(id);
123 if (m_slices.keys().contains(sliceData)) {
124 //qWarning() << "PiePresenter::addSlice(): slice already exists!" << sliceData;
125 Q_ASSERT(0);
130 126 return;
131 127 }
132 128
133 129 // create slice
134 PieSlice *slice = new PieSlice(id, m_series, this);
135 m_slices.insert(id, slice);
130 PieSlice *slice = new PieSlice(this);
131 slice->updateData(sliceData);
132 m_slices.insert(sliceData, slice);
136 133
137 updateGeometry();
134 // connect signals
135 connect(sliceData, SIGNAL(changed()), slice, SLOT(handleSliceDataChanged()));
136 connect(slice, SIGNAL(clicked()), sliceData, SIGNAL(clicked()));
137 connect(slice, SIGNAL(hoverEnter()), sliceData, SIGNAL(hoverEnter()));
138 connect(slice, SIGNAL(hoverLeave()), sliceData, SIGNAL(hoverLeave()));
138 139 }
139 140
140 void PiePresenter::updateSlice(QPieSliceId id)
141 void PiePresenter::deleteSlice(QPieSlice* sliceData)
141 142 {
142 qDebug() << "PiePresenter::updateSlice()" << id;
143 //qDebug() << "PiePresenter::deleteSlice()" << sliceData;
143 144
144 // TODO: animation
145 if (m_slices.contains(id))
146 m_slices.value(id)->updateData();
145 if (m_slices.contains(sliceData))
146 delete m_slices.take(sliceData);
147 147 else {
148 qWarning() << "PiePresenter::updateSlice(): slice does not exist!" << id;
149 addSlice(id);
148 // nothing to remove
149 Q_ASSERT(0); // TODO: remove before release
150 150 }
151
152 updateGeometry();
153 }
154
155 void PiePresenter::deleteSlice(QPieSliceId id)
156 {
157 qDebug() << "PiePresenter::deleteSlice()" << id;
158
159 // TODO: animation
160 if (m_slices.contains(id))
161 delete m_slices.take(id);
162 else
163 qWarning() << "PiePresenter::deleteSlice(): slice does not exist!" << id;
164
165 updateGeometry();
166 151 }
167 152
168 153 #include "moc_piepresenter.cpp"
@@ -32,13 +32,12 public Q_SLOTS:
32 32 void updateGeometry();
33 33
34 34 private:
35 void addSlice(QPieSliceId id);
36 void updateSlice(QPieSliceId id);
37 void deleteSlice(QPieSliceId id);
35 void addSlice(QPieSlice* sliceData);
36 void deleteSlice(QPieSlice* sliceData);
38 37
39 38 private:
40 39 friend class PieSlice;
41 QHash<QPieSliceId, PieSlice*> m_slices;
40 QHash<QPieSlice*, PieSlice*> m_slices;
42 41 QPieSeries *m_series;
43 42 QRectF m_rect;
44 43 QRectF m_pieRect;
@@ -2,6 +2,7
2 2 #include "pieslicelabel.h"
3 3 #include "piepresenter.h"
4 4 #include "qpieseries.h"
5 #include "qpieslice.h"
5 6 #include <QPainter>
6 7 #include <QDebug>
7 8 #include <qmath.h>
@@ -20,27 +21,25 QPointF offset(qreal angle, qreal length)
20 21 return QPointF(dx, -dy);
21 22 }
22 23
23 PieSlice::PieSlice(QPieSliceId id, QPieSeries *series, QGraphicsItem* parent)
24 PieSlice::PieSlice(QGraphicsItem* parent)
24 25 :QGraphicsObject(parent),
25 m_id(id),
26 m_series(series),
27 26 m_slicelabel(new PieSliceLabel(this)),
28 m_isHovering(false)
27 m_angle(0),
28 m_span(0),
29 m_isExploded(false)
29 30 {
30 Q_ASSERT(series);
31 31 setAcceptHoverEvents(true);
32 32 setAcceptedMouseButtons(Qt::LeftButton);
33 updateData();
34 33 }
35 34
36 35 PieSlice::~PieSlice()
37 36 {
38 qDebug() << "~PieSlice()" << m_id;
37
39 38 }
40 39
41 40 QRectF PieSlice::boundingRect() const
42 41 {
43 return m_rect;
42 return m_path.boundingRect();
44 43 }
45 44
46 45 QPainterPath PieSlice::shape() const
@@ -50,50 +49,43 QPainterPath PieSlice::shape() const
50 49
51 50 void PieSlice::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
52 51 {
53 // set hover brush
54 // TODO: what if we are using gradients...
55 QBrush brush = m_data.brush();
56 if (m_isHovering)
57 brush.setColor(brush.color().lighter());
58
59 52 painter->setRenderHint(QPainter::Antialiasing);
60 painter->setPen(m_data.pen());
61 painter->setBrush(brush);
53 painter->setPen(m_pen);
54 painter->setBrush(m_brush);
62 55 painter->drawPath(m_path);
63 56 }
64 57
65 58 void PieSlice::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
66 59 {
67 m_isHovering = true;
68 update();
69 // TODO: emit hoverEnter()
60 emit hoverEnter();
70 61 }
71 62
72 63 void PieSlice::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
73 64 {
74 m_isHovering = false;
75 update();
76 // TODO: emit hoverLeave()
65 emit hoverLeave();
77 66 }
78 67
79 68 void PieSlice::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/)
80 69 {
81 // TODO: emit clicked
82 // TODO: should we let the user decide if this can be exploded?
83 m_data.setExploded(!m_data.isExploded());
84 m_series->update(m_data);
70 emit clicked();
71 }
72
73 void PieSlice::setPieRect(QRectF rect)
74 {
75 m_pieRect = rect;
85 76 }
86 77
87 void PieSlice::updateGeometry(QRectF rect, qreal startAngle, qreal span)
78 void PieSlice::updateGeometry()
88 79 {
89 80 prepareGeometryChange();
90 81
91 82 // calculate center angle
92 qreal centerAngle = startAngle + (span/2);
83 qreal centerAngle = m_angle + (m_span/2);
93 84
94 85 // adjust rect for exploding
86 QRectF rect = m_pieRect;
95 87 rect.adjust(EXPLODE_OFFSET, EXPLODE_OFFSET, -EXPLODE_OFFSET ,-EXPLODE_OFFSET);
96 if (m_data.isExploded()) {
88 if (m_isExploded) {
97 89 QPointF d = offset((centerAngle), EXPLODE_OFFSET);
98 90 rect.translate(d.x(), d.y());
99 91 }
@@ -102,9 +94,9 void PieSlice::updateGeometry(QRectF rect, qreal startAngle, qreal span)
102 94 // TODO: draw the shape so that it might have a hole in the center
103 95 QPainterPath path;
104 96 path.moveTo(rect.center());
105 path.arcTo(rect, -startAngle + 90, -span);
97 path.arcTo(rect, -m_angle + 90, -m_span);
98 path.closeSubpath();
106 99 m_path = path;
107 m_rect = path.boundingRect();
108 100
109 101 // update label position
110 102 qreal radius = rect.height() / 2;
@@ -112,27 +104,36 void PieSlice::updateGeometry(QRectF rect, qreal startAngle, qreal span)
112 104
113 105 m_slicelabel->setArmStartPoint(edgeCenter);
114 106 m_slicelabel->setArmAngle(centerAngle);
115 m_slicelabel->setArmLength(50);
116 107 m_slicelabel->updateGeometry();
117 108
118 //qDebug() << "PieSlice::updateGeometry" << m_rect;
109 //qDebug() << "PieSlice::updateGeometry" << m_slicelabel->text() << boundingRect() << m_angle << m_span;
110 }
111
112 void PieSlice::handleSliceDataChanged()
113 {
114 QPieSlice *slice = qobject_cast<QPieSlice*>(sender());
115 Q_ASSERT(slice);
116 updateData(slice);
119 117 }
120 118
121 void PieSlice::updateData()
119 void PieSlice::updateData(const QPieSlice* sliceData)
122 120 {
123 if (!m_series->m_slices.contains(m_id))
124 qWarning() << "PieSlice::updateData(): cannot find slice data!" << m_id;
121 // TODO: compare what has changes to avoid unneccesary geometry updates
125 122
126 QPieSlice data = m_series->slice(m_id);
127 // TODO: find out what has changed and trigger some animation
128 m_data = data;
123 m_angle = sliceData->angle();
124 m_span = sliceData->span();
125 m_isExploded = sliceData->isExploded();
126 m_pen = sliceData->pen();
127 m_brush = sliceData->brush();
129 128
129 updateGeometry();
130 130 update();
131 131
132 m_slicelabel->setVisible(m_data.isLabelVisible());
133 m_slicelabel->setText(m_data.label());
134 //m_slicelabel->setPen(m_data.labelPen());
135 //m_slicelabel->setFont(m_data.labelFont());
132 m_slicelabel->setVisible(sliceData->isLabelVisible());
133 m_slicelabel->setText(sliceData->label());
134 m_slicelabel->setPen(sliceData->labelPen());
135 m_slicelabel->setFont(sliceData->labelFont());
136 m_slicelabel->setArmLength(sliceData->labelArmLenght());
136 137 m_slicelabel->updateGeometry(); // text size & font modifies the geometry
137 138 m_slicelabel->update();
138 139 }
@@ -12,13 +12,14
12 12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13 13 class PiePresenter;
14 14 class PieSliceLabel;
15 class QPieSlice;
15 16
16 17 class PieSlice : public QGraphicsObject
17 18 {
18 19 Q_OBJECT
19 20
20 21 public:
21 PieSlice(QPieSliceId id, QPieSeries *series, QGraphicsItem* parent = 0);
22 PieSlice(QGraphicsItem* parent = 0);
22 23 ~PieSlice();
23 24
24 25 public: // from QGraphicsItem
@@ -31,19 +32,27 public: // from QGraphicsItem
31 32
32 33 Q_SIGNALS:
33 34 void clicked();
35 void hoverEnter();
36 void hoverLeave();
34 37
35 public:
36 void updateGeometry(QRectF rect, qreal startAngle, qreal span);
37 void updateData();
38 public Q_SLOTS:
39 void handleSliceDataChanged();
40 void setPieRect(QRectF rect);
41 void updateGeometry();
42 void updateData(const QPieSlice *sliceData);
38 43
39 44 private:
40 QPieSliceId m_id;
41 QPieSeries* m_series;
42 QPieSlice m_data;
43 45 PieSliceLabel* m_slicelabel;
46
47 QRectF m_pieRect;
44 48 QPainterPath m_path;
45 QRectF m_rect;
46 bool m_isHovering;
49
50 qreal m_angle;
51 qreal m_span;
52 bool m_isExploded;
53
54 QPen m_pen;
55 QBrush m_brush;
47 56 };
48 57
49 58 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,112 +1,146
1 1 #include "qpieseries.h"
2 #include "qpieslice.h"
2 3 #include "piepresenter.h"
3 4 #include "pieslice.h"
4 5 #include <QDebug>
5 6
6 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 8
8 QPieSeries::QPieSeries(QObject *parent) :
9 QChartSeries(parent),
10 m_sizeFactor(1.0),
11 m_position(PiePositionMaximized),
12 m_sliceIdSeed(0)
9 void QPieSeries::ChangeSet::appendAdded(QPieSlice* slice)
13 10 {
11 if (!m_added.contains(slice))
12 m_added << slice;
14 13 }
15 14
16 QPieSeries::~QPieSeries()
15 void QPieSeries::ChangeSet::appendChanged(QPieSlice* slice)
17 16 {
17 if (!m_changed.contains(slice))
18 m_changed << slice;
19 }
18 20
21 void QPieSeries::ChangeSet::appendRemoved(QPieSlice* slice)
22 {
23 if (!m_removed.contains(slice))
24 m_removed << slice;
19 25 }
20 26
21 bool QPieSeries::setData(QList<qreal> data)
27 QList<QPieSlice*> QPieSeries::ChangeSet::added() const
22 28 {
23 // TODO: remove this function
24 QList<QPieSlice> slices;
25 foreach (int value, data)
26 slices << QPieSlice(value, QString::number(value));
27 return set(slices);
29 return m_added;
28 30 }
29 31
30 bool QPieSeries::set(const QList<QPieSlice>& slices)
32 QList<QPieSlice*> QPieSeries::ChangeSet::changed() const
31 33 {
32 if (!slices.count())
33 return false;
34 return m_changed;
35 }
34 36
35 ChangeSet changeSet;
37 QList<QPieSlice*> QPieSeries::ChangeSet::removed() const
38 {
39 return m_removed;
40 }
41
42 bool QPieSeries::ChangeSet::isEmpty() const
43 {
44 if (m_added.count() || m_changed.count() || m_removed.count())
45 return false;
46 return true;
47 }
36 48
37 foreach (QPieSlice s, m_slices.values())
38 changeSet.m_removed << s.id();
39 49
40 m_slices.clear();
50 QPieSeries::QPieSeries(QObject *parent) :
51 QChartSeries(parent),
52 m_sizeFactor(1.0),
53 m_position(PiePositionMaximized),
54 m_pieStartAngle(0),
55 m_pieSpan(360)
56 {
41 57
42 foreach (QPieSlice s, slices) {
43 s.m_id = generateSliceId();
44 m_slices.insert(s.id(), s);
45 changeSet.m_added << s.id();
46 58 }
47 59
48 updateDerivativeData();
49 emit changed(changeSet);
60 QPieSeries::~QPieSeries()
61 {
62
63 }
50 64
65 bool QPieSeries::setData(QList<qreal> data)
66 {
67 // TODO: remove this function
68 QList<QPieSlice*> slices;
69 foreach (int value, data)
70 slices << new QPieSlice(value, QString::number(value));
71 set(slices);
51 72 return true;
52 73 }
53 74
54 bool QPieSeries::add(const QList<QPieSlice>& slices)
75 void QPieSeries::set(QList<QPieSlice*> slices)
55 76 {
56 if (!slices.count())
57 return false;
77 clear();
78 add(slices);
79 }
58 80
81 void QPieSeries::add(QList<QPieSlice*> slices)
82 {
59 83 ChangeSet changeSet;
60 foreach (QPieSlice s, slices) {
61 s.m_id = generateSliceId();
62 m_slices.insert(s.id(), s);
63 changeSet.m_added << s.id();
84 foreach (QPieSlice* s, slices) {
85 s->setParent(this);
86 m_slices << s;
87 changeSet.appendAdded(s);
64 88 }
65 89
66 90 updateDerivativeData();
67 emit changed(changeSet);
68 91
69 return true;
92 foreach (QPieSlice* s, slices) {
93 connect(s, SIGNAL(changed()), this, SLOT(sliceChanged()));
94 connect(s, SIGNAL(clicked()), this, SLOT(sliceClicked()));
95 connect(s, SIGNAL(hoverEnter()), this, SLOT(sliceHoverEnter()));
96 connect(s, SIGNAL(hoverLeave()), this, SLOT(sliceHoverLeave()));
97 }
98
99 emit changed(changeSet);
70 100 }
71 101
72 bool QPieSeries::add(const QPieSlice& slice)
102 void QPieSeries::add(QPieSlice* slice)
73 103 {
74 return add(QList<QPieSlice>() << slice);
104 add(QList<QPieSlice*>() << slice);
75 105 }
76 106
77 bool QPieSeries::update(const QPieSlice& slice)
107 QPieSlice* QPieSeries::add(qreal value, QString name)
78 108 {
79 if (!m_slices.contains(slice.id()))
80 return false; // series does not contain this slice
109 QPieSlice* slice = new QPieSlice(value, name);
110 add(slice);
111 return slice;
112 }
81 113
82 m_slices[slice.id()] = slice;
114 void QPieSeries::remove(QPieSlice* slice)
115 {
116 if (!m_slices.removeOne(slice)) {
117 Q_ASSERT(0); // TODO: remove before release
118 return;
119 }
83 120
84 121 ChangeSet changeSet;
85 changeSet.m_changed << slice.id();
86 updateDerivativeData();
122 changeSet.appendRemoved(slice);
87 123 emit changed(changeSet);
88 124
89 return true;
125 delete slice;
126 slice = NULL;
127
128 updateDerivativeData();
90 129 }
91 130
92 bool QPieSeries::remove(QPieSliceId id)
131 void QPieSeries::clear()
93 132 {
94 if (!m_slices.contains(id))
95 return false; // series does not contain this slice
96
97 m_slices.remove(id);
133 if (m_slices.count() == 0)
134 return;
98 135
99 136 ChangeSet changeSet;
100 changeSet.m_removed << id;
101 updateDerivativeData();
102 emit changed(changeSet);
103
104 return true;
137 foreach (QPieSlice* s, m_slices) {
138 changeSet.appendRemoved(s);
139 m_slices.removeOne(s);
140 delete s;
105 141 }
106
107 QPieSlice QPieSeries::slice(QPieSliceId id) const
108 {
109 return m_slices.value(id);
142 emit changed(changeSet);
143 updateDerivativeData();
110 144 }
111 145
112 146 void QPieSeries::setSizeFactor(qreal factor)
@@ -128,23 +162,136 void QPieSeries::setPosition(PiePosition position)
128 162 }
129 163 }
130 164
131 QPieSliceId QPieSeries::generateSliceId()
165 void QPieSeries::setSpan(qreal startAngle, qreal span)
166 {
167 if (startAngle >= 0 && startAngle < 360 &&
168 span > 0 && span <= 360) {
169 m_pieStartAngle = startAngle;
170 m_pieSpan = span;
171 updateDerivativeData();
172 }
173 }
174
175 void QPieSeries::setLabelsVisible(bool visible)
176 {
177 foreach (QPieSlice* s, m_slices)
178 s->setLabelVisible(visible);
179 }
180
181 void QPieSeries::enableClickExplodes(bool enable)
182 {
183 if (enable)
184 connect(this, SIGNAL(clicked(QPieSlice*)), this, SLOT(toggleExploded(QPieSlice*)));
185 else
186 disconnect(this, SLOT(toggleExploded(QPieSlice*)));
187 }
188
189 void QPieSeries::enableHoverHighlight(bool enable)
190 {
191 if (enable) {
192 connect(this, SIGNAL(hoverEnter(QPieSlice*)), this, SLOT(highlightOn(QPieSlice*)));
193 connect(this, SIGNAL(hoverLeave(QPieSlice*)), this, SLOT(highlightOff(QPieSlice*)));
194 } else {
195 disconnect(this, SLOT(hoverEnter(QPieSlice*)));
196 disconnect(this, SLOT(hoverLeave(QPieSlice*)));
197 }
198 }
199
200 void QPieSeries::sliceChanged()
201 {
202 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
203 Q_ASSERT(m_slices.contains(slice));
204
205 ChangeSet changeSet;
206 changeSet.appendChanged(slice);
207 emit changed(changeSet);
208
209 updateDerivativeData();
210 }
211
212 void QPieSeries::sliceClicked()
132 213 {
133 // Id is quint64 so it should be enough for us.
134 // Note that id is not unique between pie series.
135 return m_sliceIdSeed++;
214 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
215 Q_ASSERT(m_slices.contains(slice));
216 emit clicked(slice);
217 }
218
219 void QPieSeries::sliceHoverEnter()
220 {
221 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
222 Q_ASSERT(m_slices.contains(slice));
223 emit hoverEnter(slice);
224 }
225
226 void QPieSeries::sliceHoverLeave()
227 {
228 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
229 Q_ASSERT(m_slices.contains(slice));
230 emit hoverLeave(slice);
231 }
232
233 void QPieSeries::toggleExploded(QPieSlice* slice)
234 {
235 Q_ASSERT(slice);
236 slice->setExploded(!slice->isExploded());
237 }
238
239 void QPieSeries::highlightOn(QPieSlice* slice)
240 {
241 Q_ASSERT(slice);
242 QColor c = slice->brush().color().lighter();
243 slice->setBrush(c);
244 }
245
246 void QPieSeries::highlightOff(QPieSlice* slice)
247 {
248 Q_ASSERT(slice);
249 QColor c = slice->brush().color().darker(150);
250 slice->setBrush(c);
136 251 }
137 252
138 253 void QPieSeries::updateDerivativeData()
139 254 {
140 255 m_total = 0;
141 foreach (const QPieSlice& s, m_slices.values())
142 m_total += s.value();
143 256
144 Q_ASSERT(m_total > 0); // TODO: remove this before release
257 // nothing to do?
258 if (m_slices.count() == 0)
259 return;
260
261 // calculate total
262 foreach (QPieSlice* s, m_slices)
263 m_total += s->value();
264
265 // we must have some values
266 Q_ASSERT(m_total > 0); // TODO
145 267
146 foreach (QPieSliceId id, m_slices.keys())
147 m_slices[id].m_percentage = m_slices.value(id).value() / m_total;
268 // update slice attributes
269 qreal sliceAngle = m_pieStartAngle;
270 foreach (QPieSlice* s, m_slices) {
271
272 bool changed = false;
273
274 qreal percentage = s->value() / m_total;
275 if (s->m_percentage != percentage) {
276 s->m_percentage = percentage;
277 changed = true;
278 }
279
280 qreal sliceSpan = m_pieSpan * percentage;
281 if (s->m_span != sliceSpan) {
282 s->m_span = sliceSpan;
283 changed = true;
284 }
285
286 if (s->m_angle != sliceAngle) {
287 s->m_angle = sliceAngle;
288 changed = true;
289 }
290 sliceAngle += sliceSpan;
291
292 if (changed)
293 emit s->changed();
294 }
148 295 }
149 296
150 297 #include "moc_qpieseries.cpp"
@@ -7,69 +7,13
7 7 #include <QColor>
8 8 #include <QPen>
9 9 #include <QBrush>
10 #include <QSignalMapper>
10 11
11 12 class QGraphicsObject;
12 13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13 14 class PiePresenter;
14 15 class PieSlice;
15
16 typedef quint64 QPieSliceId;
17
18 class QPieSlice
19 {
20 public:
21 QPieSlice()
22 :m_id(-1), m_value(0), m_isLabelVisible(true), m_isExploded(false), m_percentage(0) {}
23
24 QPieSlice(qreal value, QString label = QString(), bool labelVisible = true, bool exploded = false, QPen pen = QPen(), QBrush brush = QBrush())
25 :m_id(-1), m_value(value), m_label(label), m_isLabelVisible(labelVisible), m_isExploded(exploded), m_pen(pen), m_brush(brush), m_percentage(0) {}
26
27 QPieSliceId id() const { return m_id; }
28
29 void setValue(qreal value) { m_value = value; }
30 qreal value() const { return m_value; }
31
32 void setLabel(QString label) { m_label = label; }
33 QString label() const { return m_label; }
34
35 void setLabelVisible(bool visible) { m_isLabelVisible = visible; }
36 bool isLabelVisible() const { return m_isLabelVisible; }
37
38 // TODO:
39 //void setLabelPen(QPen pen) {};
40 //QPen labelPen() const {};
41 //void setLabelFont(QFont font);
42 //QFont labelFont() const;
43 //void setLabelArmLenght(qreal len) {};
44 //qreal labelArmLenght() const {};
45
46 void setExploded(bool exploded) { m_isExploded = exploded; }
47 bool isExploded() const { return m_isExploded; }
48
49 void setPen(QPen pen) { m_pen = pen; }
50 QPen pen() const { return m_pen; }
51
52 void setBrush(QBrush brush) { m_brush = brush; }
53 QBrush brush() const { return m_brush; }
54
55 qreal percentage() const { return m_percentage; }
56
57 private:
58
59 // TODO: use private class
60 friend class QPieSeries;
61
62 QPieSliceId m_id;
63 qreal m_value;
64 QString m_label;
65 bool m_isLabelVisible;
66 bool m_isExploded;
67
68 QPen m_pen;
69 QBrush m_brush;
70
71 qreal m_percentage; // generated content
72 };
16 class QPieSlice;
73 17
74 18 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QChartSeries
75 19 {
@@ -87,42 +31,48 public:
87 31 class ChangeSet
88 32 {
89 33 public:
90 QList<QPieSliceId> m_added;
91 QList<QPieSliceId> m_removed;
92 QList<QPieSliceId> m_changed;
34 void appendAdded(QPieSlice* slice);
35 void appendChanged(QPieSlice* slice);
36 void appendRemoved(QPieSlice* slice);
37
38 QList<QPieSlice*> added() const;
39 QList<QPieSlice*> changed() const;
40 QList<QPieSlice*> removed() const;
41
42 bool isEmpty() const;
43
44 private:
45 QList<QPieSlice*> m_added;
46 QList<QPieSlice*> m_changed;
47 QList<QPieSlice*> m_removed;
93 48 };
94 49
95 50 public:
96 51 QPieSeries(QObject *parent = 0);
97 ~QPieSeries();
52 virtual ~QPieSeries();
98 53
99 54 public: // from QChartSeries
100 55 QChartSeriesType type() const { return QChartSeries::SeriesTypePie; }
101 56 virtual bool setData(QList<qreal> data); // TODO: remove this
102 57
103 58 public:
104 // TODO: should we return id/bool or what?
105 // TODO: should we prefer passing a modifiable reference?
106 bool set(const QList<QPieSlice>& slices);
107 bool add(const QList<QPieSlice>& slices);
108 bool add(const QPieSlice& slice);
109 bool update(const QPieSlice& slice);
110 bool remove(QPieSliceId id);
59 void set(QList<QPieSlice*> slices);
60 void add(QList<QPieSlice*> slices);
61 void add(QPieSlice* slice);
62 QPieSlice* add(qreal value, QString name);
63 void remove(QPieSlice* slice);
64 void clear();
111 65
112 66 int count() const { return m_slices.count(); }
113 67
114 QList<QPieSlice> slices() const { return m_slices.values(); }
115 QList<QPieSliceId> ids() const { return m_slices.keys(); }
116 QPieSlice slice(QPieSliceId id) const;
68 QList<QPieSlice*> slices() const { return m_slices; }
117 69
118 // TODO: sorting?
70 // TODO: find slices?
71 // QList<QPieSlice*> findByValue(qreal value);
72 // ...
119 73
120 // TODO: convenience functions?
121 //void setValue(QPieSliceId id, qreal value);
122 //void setLabel(QPieSliceId id, QString label);
123 //void setPen(QPieSliceId id, QPen pen);
124 //void setBrush(QPieSliceId id, QBrush brush);
125 //void setExploded(QPieSliceId id, bool exploded);
74 // TODO: sorting slices?
75 // void sort(QPieSeries::SortByValue)
126 76
127 77 void setSizeFactor(qreal sizeFactor);
128 78 qreal sizeFactor() const { return m_sizeFactor; }
@@ -130,18 +80,31 public:
130 80 void setPosition(PiePosition position);
131 81 PiePosition position() const { return m_position; }
132 82
83 void setSpan(qreal startAngle, qreal span);
84
85 void setLabelsVisible(bool visible);
86 void enableClickExplodes(bool enable);
87 void enableHoverHighlight(bool enable);
88
133 89 Q_SIGNALS:
134 90 void changed(const QPieSeries::ChangeSet& changeSet);
91 void clicked(QPieSlice* slice);
92 void hoverEnter(QPieSlice* slice);
93 void hoverLeave(QPieSlice* slice);
135 94 void sizeFactorChanged();
136 95 void positionChanged();
137 96
138 // TODO:
139 //void sliceClicked(QPieSliceId id);
140 // ?? void sliceHoverEnter(QPieSliceId id);
141 // ?? void sliceHoverLeave(QPieSliceId id);
97 private Q_SLOTS: // should be private and not in the interface
98 void sliceChanged();
99 void sliceClicked();
100 void sliceHoverEnter();
101 void sliceHoverLeave();
102
103 void toggleExploded(QPieSlice* slice);
104 void highlightOn(QPieSlice* slice);
105 void highlightOff(QPieSlice* slice);
142 106
143 107 private:
144 QPieSliceId generateSliceId();
145 108 void updateDerivativeData();
146 109
147 110 private:
@@ -151,11 +114,12 private:
151 114 friend class PiePresenter;
152 115 friend class PieSlice;
153 116
154 QHash<QPieSliceId, QPieSlice> m_slices;
117 QList<QPieSlice*> m_slices;
155 118 qreal m_sizeFactor;
156 119 PiePosition m_position;
157 120 qreal m_total;
158 QPieSliceId m_sliceIdSeed;
121 qreal m_pieStartAngle;
122 qreal m_pieSpan;
159 123 };
160 124
161 125 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,7 +1,4
1 1 #include "qchart.h"
2 #include "qscatterseries.h"
3 #include "qscatterseries_p.h"
4 #include "qpieseries.h"
5 2 #include "qchartaxis.h"
6 3 #include "chartpresenter_p.h"
7 4 #include "chartdataset_p.h"
@@ -11,6 +8,9
11 8 #include "stackedbarchartseries.h"
12 9 #include "percentbarchartseries.h"
13 10 #include "qlinechartseries.h"
11 #include "qscatterseries.h"
12 //#include "scatterseries_p.h"
13 #include "qpieseries.h"
14 14
15 15 #include <QGraphicsScene>
16 16 #include <QGraphicsSceneResizeEvent>
@@ -11,7 +11,7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 11
12 12 QChartView::QChartView(QWidget *parent) :
13 13 QGraphicsView(parent),
14 m_scene(new QGraphicsScene()),
14 m_scene(new QGraphicsScene(this)),
15 15 m_chart(new QChart()),
16 16 m_rubberBand(0),
17 17 m_verticalRubberBand(false),
@@ -24,7 +24,7 public:
24 24 //implement from QWidget
25 25 void resizeEvent(QResizeEvent *event);
26 26
27 void addSeries(QChartSeries* series);
27 void addSeries(QChartSeries* series); // takes ownership
28 28
29 29 // Convenience function
30 30 QChartSeries* createSeries(QChartSeries::QChartSeriesType type);
@@ -1,12 +1,18
1 1 #include "qscatterseries.h"
2 #include "qscatterseries_p.h"
2 #include "scatterseries_p.h"
3 3 #include "qchart.h"
4 4
5 5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 6
7 7 QScatterSeriesPrivate::QScatterSeriesPrivate() :
8 m_data(QList<QPointF>())
8 m_data(QList<QPointF>()),
9 m_markerPen(QPen()),
10 m_markerBrush(QBrush()),
11 m_markerShape(QScatterSeries::MarkerShapeDefault)
9 12 {
13 // Initialize pen color to invalid to use a theme color by default
14 m_markerPen.setColor(QColor::Invalid);
15 m_markerBrush.setColor(QColor::Invalid);
10 16 }
11 17
12 18 QScatterSeries::QScatterSeries(QObject *parent) :
@@ -54,6 +60,26 QPen QScatterSeries::markerPen()
54 60 return d->m_markerPen;
55 61 }
56 62
63 void QScatterSeries::setMarkerBrush(QBrush brush)
64 {
65 d->m_markerBrush = brush;
66 }
67
68 QBrush QScatterSeries::markerBrush()
69 {
70 return d->m_markerBrush;
71 }
72
73 void QScatterSeries::setMarkerShape(MarkerShape shape)
74 {
75 d->m_markerShape = shape;
76 }
77
78 QScatterSeries::MarkerShape QScatterSeries::markerShape()
79 {
80 return (QScatterSeries::MarkerShape) d->m_markerShape;
81 }
82
57 83 #include "moc_qscatterseries.cpp"
58 84
59 85 QTCOMMERCIALCHART_END_NAMESPACE
@@ -11,8 +11,21 class QScatterSeriesPrivate;
11 11 class QTCOMMERCIALCHART_EXPORT QScatterSeries : public QChartSeries
12 12 {
13 13 Q_OBJECT
14
15 public:
16 enum MarkerShape {
17 // TODO: to be defined by the graphics design
18 // TODO: marker shapes: "x", star, rectangle, tilted rect, triangle, circle, dot
19 MarkerShapeDefault = 0,
20 MarkerShapePoint,
21 MarkerShapeX,
22 MarkerShapeRectangle,
23 MarkerShapeTiltedRectangle,
24 MarkerShapeTriangle,
25 MarkerShapeCircle
26 };
27
14 28 public:
15 //QScatterSeries(QSeriesData *data, QObject *chart);
16 29 QScatterSeries(QObject *parent = 0);
17 30 ~QScatterSeries();
18 31
@@ -25,17 +38,20 public:
25 38 QScatterSeries& operator << (const QPointF &value);
26 39 void setData(QList<QPointF> data);
27 40 QList<QPointF> data();
28
29 //TODO? void insertData(int index, QPointF data);
41 //TODO: insertData?
30 42
31 43 void setMarkerPen(QPen pen);
32 44 QPen markerPen();
33 // TODO: marker shapes: "x", star, rectangle, tilted rect, triangle, circle, dot
34 //void setMarkerShape(MarkerShape shape);
45 void setMarkerBrush(QBrush brush);
46 QBrush markerBrush();
47 void setMarkerShape(MarkerShape shape);
48 MarkerShape markerShape();
49 // TODO: marker size?
35 50
36 51 Q_SIGNALS:
37 // TODO: move to PIMPL?
52 // TODO: move to PIMPL for simplicity or does the user ever need these signals?
38 53 // TODO: more finegrained signaling for performance reasons
54 // (check QPieSeries implementation with change sets)
39 55 void changed();
40 56
41 57 //public Q_SLOTS:
@@ -1,4 +1,4
1 #include "scatterpresenter.h"
1 #include "scatterpresenter_p.h"
2 2 #include "qscatterseries.h"
3 3 #include <QPen>
4 4 #include <QPainter>
@@ -43,31 +43,49 void ScatterPresenter::handleModelChanged()
43 43
44 44 void ScatterPresenter::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
45 45 {
46 // TODO: The opacity should be user definable?
47 //brush.setColor(QColor(255, 82, 0, 100));
48 //if (m_series->markerPen().isValid()) {
49 if (false) {
50 QPen pen = painter->pen();
51 QBrush brush = pen.brush();
52 brush.setColor(m_series->markerPen().color());
53 pen.setBrush(brush);
54 pen.setWidth(4);
55 painter->setPen(pen);
56 }
57 else {
58 // TODO: fix this
59 QPen pen = painter->pen();
60 QBrush brush = pen.brush();
61 brush.setColor(m_markerPen.color());
62 pen.setBrush(brush);
63 pen.setWidth(4);
64 painter->setPen(pen);
46 // TODO: Optimization: avoid setting on every paint method call?
47 // The custom settings in series override those defined by the theme
48 if (m_series->markerPen().color().isValid()) {
49 painter->setPen(m_series->markerPen());
50 painter->setBrush(m_series->markerBrush());
51 } else {
52 painter->setPen(m_markerPen);
53 painter->setBrush(m_markerBrush);
65 54 }
66 55
56 int shape = m_series->markerShape();
57
67 58 for (int i(0); i < m_scenex.count() && i < m_sceney.count(); i++) {
68 59 if (scene()->width() > m_scenex.at(i) && scene()->height() > m_sceney.at(i))
69 //painter->drawArc(m_scenex.at(i), m_sceney.at(i), 2, 2, 0, 5760);
60 // Paint a shape
61 switch (shape) {
62 case QScatterSeries::MarkerShapeDefault:
63 // Fallthrough, defaults to circle
64 case QScatterSeries::MarkerShapeCircle:
65 painter->drawChord(m_scenex.at(i), m_sceney.at(i), 9, 9, 0, 5760);
66 break;
67 case QScatterSeries::MarkerShapePoint:
70 68 painter->drawPoint(m_scenex.at(i), m_sceney.at(i));
69 break;
70 case QScatterSeries::MarkerShapeRectangle:
71 painter->drawRect(m_scenex.at(i), m_sceney.at(i), 9, 9);
72 break;
73 case QScatterSeries::MarkerShapeTiltedRectangle: {
74 // TODO:
75 static const QPointF points[4] = {
76 QPointF(-1.0 + m_scenex.at(i), 0.0 + m_sceney.at(i)),
77 QPointF(0.0 + m_scenex.at(i), 1.0 + m_sceney.at(i)),
78 QPointF(1.0 + m_scenex.at(i), 0.0 + m_sceney.at(i)),
79 QPointF(0.0 + m_scenex.at(i), -1.0 + m_sceney.at(i))
80 };
81 painter->drawPolygon(points, 4);
82 }
83 break;
84 default:
85 // TODO: implement the rest of the shapes
86 Q_ASSERT(false);
87 break;
88 }
71 89 }
72 90 }
73 91
@@ -89,6 +107,6 void ScatterPresenter::changeGeometry()
89 107 }
90 108 }
91 109
92 #include "moc_scatterpresenter.cpp"
110 #include "moc_scatterpresenter_p.cpp"
93 111
94 112 QTCOMMERCIALCHART_END_NAMESPACE
@@ -40,6 +40,7 public:
40 40 QList<qreal> m_sceney;
41 41 Domain m_visibleChartArea;
42 42 QPen m_markerPen;
43 QBrush m_markerBrush;
43 44 };
44 45
45 46 QTCOMMERCIALCHART_END_NAMESPACE
@@ -18,6 +18,8 public:
18 18 public:
19 19 QList<QPointF> m_data;
20 20 QPen m_markerPen;
21 QBrush m_markerBrush;
22 int m_markerShape;
21 23 };
22 24
23 25 QTCOMMERCIALCHART_END_NAMESPACE
@@ -22,8 +22,6 SOURCES += barchart/barchartseries.cpp \
22 22 linechart/linechartanimationitem.cpp \
23 23 linechart/linechartitem.cpp \
24 24 linechart/qlinechartseries.cpp \
25 qscatterseries.cpp \
26 #scatterpresentation.cpp \
27 25 qchart.cpp \
28 26 axisitem.cpp \
29 27 qchartview.cpp \
@@ -32,16 +30,13 SOURCES += barchart/barchartseries.cpp \
32 30 charttheme.cpp \
33 31 chartdataset.cpp \
34 32 chartpresenter.cpp \
35 domain.cpp \
36 scatterpresenter.cpp
33 domain.cpp
37 34 PRIVATE_HEADERS += linechart/linechartitem_p.h \
38 35 linechart/linechartanimationitem_p.h \
39 36 barchart/barlabel_p.h \
40 37 barchart/bar_p.h \
41 38 barchart/separator_p.h \
42 39 barchart/barchartmodel_p.h \
43 qscatterseries_p.h \
44 #scatterpresentation.h \
45 40 axisitem_p.h \
46 41 chartitem_p.h \
47 42 charttheme_p.h \
@@ -59,20 +54,19 PUBLIC_HEADERS += linechart/qlinechartseries.h \
59 54 barchart/qbarset.h \
60 55 barchart/qbarcategory.h \
61 56 qchartseries.h \
62 qscatterseries.h \
63 57 qchart.h \
64 58 qchartglobal.h \
65 59 qchartview.h \
66 60 qchartaxis.h
67 61
68 62 include(piechart/piechart.pri)
63 include(scatterseries/scatter.pri)
69 64
70 65 THEMES += themes/chartthemeicy_p.h \
71 66 themes/chartthemegrayscale_p.h \
72 67 themes/chartthemescientific_p.h \
73 68 themes/chartthemevanilla_p.h
74 HEADERS += $$PUBLIC_HEADERS \
75 scatterpresenter.h
69 HEADERS += $$PUBLIC_HEADERS
76 70 HEADERS += $$PRIVATE_HEADERS
77 71 HEADERS += $$THEMES
78 72 INCLUDEPATH += linechart \
@@ -89,15 +83,23 public_headers.files = $$PUBLIC_HEADERS
89 83 target.path = $$[QT_INSTALL_LIBS]
90 84 INSTALLS += target \
91 85 public_headers
92 install_build_headers.name = bild_headers
93 install_build_headers.output = $$CHART_BUILD_HEADER_DIR/${QMAKE_FILE_BASE}.h
94 install_build_headers.input = PUBLIC_HEADERS
95 install_build_headers.commands = $$QMAKE_COPY \
86 install_build_public_headers.name = bild_public_headers
87 install_build_public_headers.output = $$CHART_BUILD_PUBLIC_HEADER_DIR/${QMAKE_FILE_BASE}.h
88 install_build_public_headers.input = PUBLIC_HEADERS
89 install_build_public_headers.commands = $$QMAKE_COPY \
96 90 ${QMAKE_FILE_NAME} \
97 $$CHART_BUILD_HEADER_DIR
98 install_build_headers.CONFIG += target_predeps \
91 $$CHART_BUILD_PUBLIC_HEADER_DIR
92 install_build_public_headers.CONFIG += target_predeps \
99 93 no_link
100 QMAKE_EXTRA_COMPILERS += install_build_headers
94 install_build_private_headers.name = bild_private_headers
95 install_build_private_headers.output = $$CHART_BUILD_PRIVATE_HEADER_DIR/${QMAKE_FILE_BASE}.h
96 install_build_private_headers.input = PRIVATE_HEADERS
97 install_build_private_headers.commands = $$QMAKE_COPY \
98 ${QMAKE_FILE_NAME} \
99 $$CHART_BUILD_PRIVATE_HEADER_DIR
100 install_build_private_headers.CONFIG += target_predeps \
101 no_link
102 QMAKE_EXTRA_COMPILERS += install_build_public_headers install_build_private_headers
101 103 chartversion.target = qchartversion_p.h
102 104 chartversion.commands = @echo \
103 105 "build_time" \
@@ -114,3 +116,4 unix:QMAKE_DISTCLEAN += -r \
114 116 win32:QMAKE_DISTCLEAN += /Q \
115 117 $$CHART_BUILD_HEADER_DIR \
116 118 $$CHART_BUILD_LIB_DIR
119
@@ -4,114 +4,93 import QtCommercial.Chart 1.0
4 4 Rectangle {
5 5 width: 360
6 6 height: 360
7 Text {
8 text: qsTr("Hello World")
9 anchors.centerIn: parent
10 }
11 7
8 // Another option for QML data api:
12 9 // ListModel {
13 10 // id: listModelForPie
14 11 // // PieDataElement
15 12 // ListElement {
16 13 // label: "Apple"
17 // value: 40.3
18 // }
19 // ListElement {
20 // label: "Pumpkin"
21 // value: 10.1
14 // value: 4.3
22 15 // }
23 16 // ListElement {
24 // label: "Raspberry"
17 // label: "Blackberry"
25 18 // value: 15.1
26 19 // }
27 // ListElement {
28 // label: "Strawberry"
29 // value: 29.9
30 // }
31 20 // }
32 21
33 // ChartModel {
34 // id: chartModel
35 // ListElement {
36 // label: "dada"
37 // x: 1.1
38 // y: 3.2
39 // }
40 // }
41
42 // ChartModel {
43 // ScatterElement {x: 1.1; y: 1.2}
44 // ScatterElement {x: 1.3; y: 1.9}
45 // ScatterElement {x: 1.1; y: 1.2}
46 // }
47
48 ListModel {
49 id: listModelScatter
50 ListElement {
51 height: 154
52 weight: 54
53 }
54 ListElement {
55 height: 166
56 weight: 64
57 }
58 ListElement {
59 height: 199
60 weight: 97
61 }
22 Component.onCompleted: {
23 // console.log("Component.onCompleted: " + scatterElement.x);
24 // console.log("Component.onCompleted: " + scatterElement.y);
25 // console.log("Component.onCompleted: " + scatterElement.dataX);
26 // console.log("Component.onCompleted: " + scatterElement.dataY);
27 //console.log("Component.onCompleted: " + chartModel.get(0).x);
28 //console.log("Component.onCompleted: " + chartModel.scatterElements);
29 // console.log("Component.onCompleted: " + elementt.dataX);
30 // console.log("Component.onCompleted: " + chartModel.get(0).dataX);
62 31 }
63 32
64 // Chart {
65 // anchors.fill: parent
66 // theme: Chart.ThemeIcy
67 // ScatterSeries {
68 // model: listModelScatter
69 // name: "scatter"
70 // xValue: x
71 // yValue: y
72 // }
73 // }
74
75 33 Chart {
76 anchors.fill: parent
34 id: chart1
35 anchors.top: parent.top
36 anchors.left: parent.left
37 anchors.right: parent.right
38 height: parent.height / 2
77 39 theme: Chart.ThemeIcy
40 // opacity: 0.3
78 41
79 // PieSeries {
80 // labels: ["point1", "point2", "point3", "point4", "point5"]
81 // datax: [2, 1.5, 3, 3, 3]
82 // }
83 // PieSeries {
84 // name: "raspberry pie"
85 // seriesLabels: ["point1", "point2", "point3", "point4", "point5"]
86 // seriesData: [2, 1.5, 3, 3, 3]
87 // }
88 // ScatterSeries {
89 // name: "scatter1"
90 // datax: [2, 1.5, 3, 3, 3]
91 // datay: [2, 1.5, 3, 3, 3]
92 // }
93 // Series {
94 // labels: ["point1", "point2", "point3", "point4", "point5"]
95 // datax: [2, 1.5, 3, 3, 3]
96 // seriesType: Series.SeriesTypePie
97 // }
98 42 Series {
99 43 seriesType: Series.SeriesTypePie
100 //model: listModelForPie
101 //seriesData: {11.0, 6.4, 12.6, 22.4}
102 //seriesLabels: {"Strawberry", "Blackberry", "Apple", "Pumpkin"}
103 44 }
104 45
105 Series {
106 // data: {[1.2], "y":2.2 }
107 seriesType: Series.SeriesTypeScatter
108 }
109 Series {
110 seriesType: Series.SeriesTypeLine
111 }
46 // TODO: a bug: drawing order affects the drawing; if you draw chart1 first (by changing the
47 // z-order), then chart2 is not shown at all. By drawing chart2 first, both are visible.
48 // Also, if you don't draw line series on chart1 (only pie), both charts are visible.
49 // Series {
50 // seriesType: Series.SeriesTypeLine
51 // }
112 52 // TODO:
113 53 // Series {
114 54 // seriesType: Series.SeriesTypeBar
115 55 // }
116 56 }
57
58
59 Chart {
60 id: chart2
61 anchors.top: chart1.bottom
62 anchors.bottom: parent.bottom
63 anchors.left: parent.left
64 anchors.right: parent.right
65 theme: Chart.ThemeScientific
66
67 ScatterSeries {
68 data: [
69 ScatterElement { x: 1.1; y: 2.1 },
70 ScatterElement { x: 1.2; y: 2.0 },
71 ScatterElement { x: 1.4; y: 2.3 }
72 ]
73 }
74 ScatterSeries {
75 data: [
76 ScatterElement { x: 1.2; y: 2.2 },
77 ScatterElement { x: 1.3; y: 2.2 },
78 ScatterElement { x: 1.7; y: 2.6 }
79 ]
80 }
81 ScatterSeries {
82 data: [
83 ScatterElement { x: 1.3; y: 2.3 },
84 ScatterElement { x: 1.5; y: 2.4 },
85 ScatterElement { x: 2.0; y: 2.9 }
86 ]
87 }
88 ScatterSeries {
89 data: [
90 ScatterElement { x: 1.4; y: 2.4 },
91 ScatterElement { x: 1.8; y: 2.7 },
92 ScatterElement { x: 2.5; y: 3.2 }
93 ]
94 }
95 }
117 96 }
General Comments 0
You need to be logged in to leave comments. Login now