##// END OF EJS Templates
Marek Rosa -
r451:465dafc0e5b7 merge
parent child
Show More
@@ -1,160 +1,152
1 #include <QtGui/QApplication>
1 #include <QtGui/QApplication>
2 #include <QMainWindow>
2 #include <QMainWindow>
3 #include <qchartglobal.h>
3 #include <qchartglobal.h>
4 #include <qchartview.h>
4 #include <qchartview.h>
5 #include <qstackedbarseries.h>
5 #include <qstackedbarseries.h>
6 #include <qbarset.h>
6 #include <qbarset.h>
7 #include <qchartaxis.h>
7 #include <qchartaxis.h>
8 #include <QStringList>
8 #include <QStringList>
9 #include <QDebug>
9 #include <QDebug>
10
10
11 QTCOMMERCIALCHART_USE_NAMESPACE
11 QTCOMMERCIALCHART_USE_NAMESPACE
12
12
13 //! [1]
13 //! [1]
14 class DrilldownBarSeries : public QStackedBarSeries
14 class DrilldownBarSeries : public QStackedBarSeries
15 {
15 {
16 Q_OBJECT
16 Q_OBJECT
17 public:
17 public:
18 DrilldownBarSeries(QStringList categories, QObject* parent = 0) : QStackedBarSeries(categories,parent) {}
18 DrilldownBarSeries(QStringList categories, QObject *parent = 0) : QStackedBarSeries(categories,parent) {}
19
19
20
20 void addDrilldownSeries(QString category, DrilldownBarSeries* drilldownSeries)
21 public Q_SLOTS:
22 void handleRightClick(QBarSet *barset, QString category)
23 {
21 {
24 qDebug() << "DrilldownBarSeries::handleRightClick" << barset->name() << category;
22 mDrilldownSeries[category] = drilldownSeries;
25 // mChart->changeSeries(this);
26 }
23 }
27
24
28 };
29 //! [1]
30
31 //! [2]
32 class DrilldownBarSet : public QBarSet
33 {
34 Q_OBJECT
35 public:
36 DrilldownBarSet(QString name, DrilldownBarSeries* drilldownSeries) : QBarSet(name) , mSeries(drilldownSeries) {}
37
38 DrilldownBarSeries* drilldownSeries(QString category)
25 DrilldownBarSeries* drilldownSeries(QString category)
39 {
26 {
40 return mSeries;
27 // qDebug() << "DrilldownBarSeries::drilldownSeries" << category << mDrilldownSeries[category];
41 }
28 return mDrilldownSeries[category];
29 }
30
31 public Q_SLOTS:
42
32
43 private:
33 private:
44 DrilldownBarSeries* mSeries;
34
35 QMap<QString, DrilldownBarSeries*> mDrilldownSeries;
45 };
36 };
46 //! [2]
37 //! [1]
47
38
48 //! [3]
39 //! [2]
49 class DrilldownChart : public QChartView
40 class DrilldownChart : public QChartView
50 {
41 {
51 Q_OBJECT
42 Q_OBJECT
52 public:
43 public:
53 explicit DrilldownChart(QWidget *parent = 0) : QChartView(parent), m_currentSeries(0) {}
44 explicit DrilldownChart(QWidget *parent = 0) : QChartView(parent), m_currentSeries(0) {}
54
45
55 void changeSeries(QSeries* series)
46 void changeSeries(QSeries* series)
56 {
47 {
57 if (m_currentSeries)
48 if (m_currentSeries)
58 removeSeries(m_currentSeries);
49 removeSeries(m_currentSeries);
59 m_currentSeries = series;
50 m_currentSeries = series;
60 addSeries(series);
51 addSeries(series);
61 setChartTitle(series->title());
52 setChartTitle(series->title());
62 }
53 }
63
54
64 public Q_SLOTS:
55 public Q_SLOTS:
65 void handleRightClick(QBarSet *barset, QString category)
56 void handleRightClick(QBarSet *barset, QString category)
66 {
57 {
67 qDebug() << "DrilldownChart::handleRightClick" << barset->name() << category;
58 qDebug() << "DrilldownChart::handleRightClick" << barset->name() << category;
68 // TODO: continue from here
59 // TODO: continue from here
69 DrilldownBarSet* drilldownBarSet = static_cast<DrilldownBarSet*>(barset);
60 DrilldownBarSeries* series = static_cast<DrilldownBarSeries*> (sender());
70 changeSeries(drilldownBarSet->drilldownSeries(category));
61 changeSeries(series->drilldownSeries(category));
71 }
62 }
72
63
73 private:
64 private:
74 QSeries* m_currentSeries;
65 QSeries* m_currentSeries;
75 };
66 };
76 //! [3]
67 //! [2]
77
68
78 int main(int argc, char *argv[])
69 int main(int argc, char *argv[])
79 {
70 {
80 QApplication a(argc, argv);
71 QApplication a(argc, argv);
81 QMainWindow window;
72 QMainWindow window;
82
73
83 DrilldownChart* drilldownChart = new DrilldownChart(&window);
74 DrilldownChart* drilldownChart = new DrilldownChart(&window);
84 drilldownChart->setChartTheme(QChart::ChartThemeIcy);
75 drilldownChart->setChartTheme(QChart::ChartThemeIcy);
85
76
86 //! [4]
77 //! [3]
87 // Define categories
78 // Define categories
88 QStringList months;
79 QStringList months;
89 months << "Jun" << "Jul" << "Aug" << "Sep";
80 months << "Jun" << "Jul" << "Aug" << "Sep";
90 QStringList weeks;
81 QStringList weeks;
91 weeks << "week 1" << "week 2" << "week 3" << "week 4";
82 weeks << "week 1" << "week 2" << "week 3" << "week 4";
92 QStringList plants;
83 QStringList plants;
93 plants << "Habanero" << "Lemon Drop" << "Starfish" << "Aji Amarillo";
84 plants << "Habanero" << "Lemon Drop" << "Starfish" << "Aji Amarillo";
85 //! [3]
86
94 //! [4]
87 //! [4]
88 // Create drilldown structure
89 DrilldownBarSeries* seasonSeries = new DrilldownBarSeries(months, drilldownChart);
90 seasonSeries->setTitle("Crop by month - Season");
95
91
96 DrilldownBarSeries* monthlySeries = new DrilldownBarSeries(months, drilldownChart);
92 // Each month in season series has drilldown series for weekly data
97 monthlySeries->setTitle("Crop by month - Season");
93 foreach (QString month, months) {
98
94
99 foreach (QString plant, plants) {
95 // Create drilldown series for every week
100 DrilldownBarSeries* weeklySeries = new DrilldownBarSeries(weeks, drilldownChart);
96 DrilldownBarSeries* weeklySeries = new DrilldownBarSeries(weeks, drilldownChart);
101 DrilldownBarSet* monthlyCrop = new DrilldownBarSet(plant,weeklySeries);
97 seasonSeries->addDrilldownSeries(month, weeklySeries);
102 weeklySeries->setTitle("Crop by week - Month");
103
104 foreach(QString month, months) {
105 DrilldownBarSet* weeklyCrop = new DrilldownBarSet(plant,monthlySeries);
106
107 foreach (QString week, weeks ) {
108 *weeklyCrop << (qrand() % 20);
109 }
110
98
111 weeklySeries->addBarSet(weeklyCrop);
99 // Drilling down from weekly data brings us back to season data.
112 weeklySeries->setToolTipEnabled(true);
100 foreach (QString week, weeks) {
113 *monthlyCrop << weeklyCrop->total();
101 weeklySeries->addDrilldownSeries(week, seasonSeries);
114
102 weeklySeries->setTitle(QString("Crop by week - " + month));
115 QObject::connect(weeklyCrop,SIGNAL(clicked(QString)),weeklyCrop,SIGNAL(toggleFloatingValues()));
116 QObject::connect(weeklySeries,SIGNAL(rightClicked(QBarSet*,QString)),drilldownChart,SLOT(handleRightClick(QBarSet*,QString)));
117 }
103 }
118
104
119 QObject::connect(monthlyCrop,SIGNAL(clicked(QString)),monthlyCrop,SIGNAL(toggleFloatingValues()));
105 // Use right click signal to implement drilldown
120 monthlySeries->addBarSet(monthlyCrop);
106 QObject::connect(weeklySeries,SIGNAL(rightClicked(QBarSet*,QString)),drilldownChart,SLOT(handleRightClick(QBarSet*,QString)));
121 }
107 }
108 //! [4]
122
109
123 /*
110 //! [5]
111 // Fill monthly and weekly series with data
124 foreach (QString plant, plants) {
112 foreach (QString plant, plants) {
125 DrilldownBarSeries* weeklySeries = new DrilldownBarSeries(weeks, drilldownChart);
113 QBarSet* monthlyCrop = new QBarSet(plant);
126 DrilldownBarSet* monthlyCrop = new DrilldownBarSet(plant,weeklySeries);
114 foreach (QString month, months) {
127 weeklySeries->setTitle("Crop by week - Month");
115 QBarSet* weeklyCrop = new QBarSet(plant);
128 foreach(QString month, months) {
129 DrilldownBarSet* weeklyCrop = new DrilldownBarSet(plant,monthlySeries);
130 foreach (QString week, weeks ) {
116 foreach (QString week, weeks ) {
131 *weeklyCrop << (qrand() % 20);
117 *weeklyCrop << (qrand() % 20);
132 }
118 }
133 weeklySeries->addBarSet(weeklyCrop);
119 // Get the drilldown series from upper level series and add crop to it.
134 weeklySeries->setToolTipEnabled(true);
120 seasonSeries->drilldownSeries(month)->addBarSet(weeklyCrop);
121 seasonSeries->drilldownSeries(month)->setToolTipEnabled(true);
135 *monthlyCrop << weeklyCrop->total();
122 *monthlyCrop << weeklyCrop->total();
123
136 QObject::connect(weeklyCrop,SIGNAL(clicked(QString)),weeklyCrop,SIGNAL(toggleFloatingValues()));
124 QObject::connect(weeklyCrop,SIGNAL(clicked(QString)),weeklyCrop,SIGNAL(toggleFloatingValues()));
137 QObject::connect(weeklySeries,SIGNAL(rightClicked(QBarSet*,QString)),drilldownChart,SLOT(handleRightClick(QBarSet*,QString)));
138 }
125 }
126 seasonSeries->addBarSet(monthlyCrop);
139 QObject::connect(monthlyCrop,SIGNAL(clicked(QString)),monthlyCrop,SIGNAL(toggleFloatingValues()));
127 QObject::connect(monthlyCrop,SIGNAL(clicked(QString)),monthlyCrop,SIGNAL(toggleFloatingValues()));
140 monthlySeries->addBarSet(monthlyCrop);
141 }
128 }
142 */
129 //! [5]
143 QObject::connect(monthlySeries,SIGNAL(rightClicked(QBarSet*,QString)),drilldownChart,SLOT(handleRightClick(QBarSet*,QString)));
130
131 seasonSeries->setToolTipEnabled(true);
132
133 // Enable drilldown from season series using right click.
134 QObject::connect(seasonSeries,SIGNAL(rightClicked(QBarSet*,QString)),drilldownChart,SLOT(handleRightClick(QBarSet*,QString)));
144
135
145 monthlySeries->setToolTipEnabled(true);
136 // Show season series in initial view
146 drilldownChart->changeSeries(monthlySeries);
137 drilldownChart->changeSeries(seasonSeries);
147 drilldownChart->setChartTitle(monthlySeries->title());
138 drilldownChart->setChartTitle(seasonSeries->title());
148
139
140 // Disable axis, since they don't really apply to bar chart
149 drilldownChart->axisX()->setAxisVisible(false);
141 drilldownChart->axisX()->setAxisVisible(false);
150 drilldownChart->axisX()->setGridVisible(false);
142 drilldownChart->axisX()->setGridVisible(false);
151 drilldownChart->axisX()->setLabelsVisible(false);
143 drilldownChart->axisX()->setLabelsVisible(false);
152
144
153 window.setCentralWidget(drilldownChart);
145 window.setCentralWidget(drilldownChart);
154 window.resize(400, 300);
146 window.resize(400, 300);
155 window.show();
147 window.show();
156
148
157 return a.exec();
149 return a.exec();
158 }
150 }
159
151
160 #include "main.moc"
152 #include "main.moc"
@@ -1,117 +1,116
1 #include "stackedbarpresenter_p.h"
1 #include "stackedbarpresenter_p.h"
2 #include "bar_p.h"
2 #include "bar_p.h"
3 #include "barlabel_p.h"
3 #include "barlabel_p.h"
4 #include "barvalue_p.h"
4 #include "barvalue_p.h"
5 #include "separator_p.h"
5 #include "separator_p.h"
6 #include "qbarset.h"
6 #include "qbarset.h"
7 #include <QDebug>
7 #include <QDebug>
8
8
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10
10
11 StackedBarPresenter::StackedBarPresenter(QBarSeries *series, QGraphicsItem *parent) :
11 StackedBarPresenter::StackedBarPresenter(QBarSeries *series, QGraphicsItem *parent) :
12 BarPresenterBase(series,parent)
12 BarPresenterBase(series,parent)
13 {
13 {
14 }
14 }
15
15
16 StackedBarPresenter::~StackedBarPresenter()
16 StackedBarPresenter::~StackedBarPresenter()
17 {
17 {
18 qDebug() << "StackedBarPresenter deleted";
19 }
18 }
20
19
21
20
22 void StackedBarPresenter::layoutChanged()
21 void StackedBarPresenter::layoutChanged()
23 {
22 {
24 // Scale bars to new layout
23 // Scale bars to new layout
25 // Layout for bars:
24 // Layout for bars:
26 if (mSeries->barsetCount() <= 0) {
25 if (mSeries->barsetCount() <= 0) {
27 qDebug() << "No sets in model!";
26 qDebug() << "No sets in model!";
28 // Nothing to do.
27 // Nothing to do.
29 return;
28 return;
30 }
29 }
31
30
32 if (mSeries->categoryCount() == 0) {
31 if (mSeries->categoryCount() == 0) {
33 qDebug() << "No categories in model!";
32 qDebug() << "No categories in model!";
34 // Nothing to do
33 // Nothing to do
35 return;
34 return;
36 }
35 }
37
36
38 if (childItems().count() == 0) {
37 if (childItems().count() == 0) {
39 qDebug() << "WARNING: StackedBarPresenter::layoutChanged called before graphics items are created!";
38 qDebug() << "WARNING: StackedBarPresenter::layoutChanged called before graphics items are created!";
40 return;
39 return;
41 }
40 }
42
41
43 // TODO: better way to auto-layout
42 // TODO: better way to auto-layout
44 // Use reals for accurancy (we might get some compiler warnings... :)
43 // Use reals for accurancy (we might get some compiler warnings... :)
45 // TODO: use temp variable for category count...
44 // TODO: use temp variable for category count...
46 qreal maxSum = mSeries->maxCategorySum();
45 qreal maxSum = mSeries->maxCategorySum();
47 qreal h = mHeight;
46 qreal h = mHeight;
48 qreal scale = (h / maxSum);
47 qreal scale = (h / maxSum);
49
48
50 int itemIndex(0);
49 int itemIndex(0);
51 int labelIndex(0);
50 int labelIndex(0);
52 qreal tW = mWidth;
51 qreal tW = mWidth;
53 qreal tC = mSeries->categoryCount() + 1;
52 qreal tC = mSeries->categoryCount() + 1;
54 qreal xStep = (tW/tC);
53 qreal xStep = (tW/tC);
55 qreal xPos = ((tW/tC) - mBarDefaultWidth / 2);
54 qreal xPos = ((tW/tC) - mBarDefaultWidth / 2);
56
55
57 for (int category = 0; category < mSeries->categoryCount(); category++) {
56 for (int category = 0; category < mSeries->categoryCount(); category++) {
58 qreal yPos = h;
57 qreal yPos = h;
59 for (int set=0; set < mSeries->barsetCount(); set++) {
58 for (int set=0; set < mSeries->barsetCount(); set++) {
60 qreal barHeight = mSeries->valueAt(set, category) * scale;
59 qreal barHeight = mSeries->valueAt(set, category) * scale;
61 Bar* bar = mBars.at(itemIndex);
60 Bar* bar = mBars.at(itemIndex);
62
61
63 bar->resize(mBarDefaultWidth, barHeight);
62 bar->resize(mBarDefaultWidth, barHeight);
64 bar->setBrush(mSeries->barsetAt(set)->brush());
63 bar->setBrush(mSeries->barsetAt(set)->brush());
65 bar->setPos(xPos, yPos-barHeight);
64 bar->setPos(xPos, yPos-barHeight);
66 itemIndex++;
65 itemIndex++;
67 yPos -= barHeight;
66 yPos -= barHeight;
68 }
67 }
69
68
70 // TODO: Layout for labels, remove magic number
69 // TODO: Layout for labels, remove magic number
71 BarLabel* label = mLabels.at(labelIndex);
70 BarLabel* label = mLabels.at(labelIndex);
72 label->setPos(xPos, mHeight + 20);
71 label->setPos(xPos, mHeight + 20);
73 labelIndex++;
72 labelIndex++;
74 xPos += xStep;
73 xPos += xStep;
75 }
74 }
76
75
77 // Position separators
76 // Position separators
78 xPos = xStep + xStep/2;
77 xPos = xStep + xStep/2;
79 for (int s=0; s < mSeries->categoryCount() - 1; s++) {
78 for (int s=0; s < mSeries->categoryCount() - 1; s++) {
80 Separator* sep = mSeparators.at(s);
79 Separator* sep = mSeparators.at(s);
81 sep->setPos(xPos,0);
80 sep->setPos(xPos,0);
82 sep->setSize(QSizeF(1,mHeight));
81 sep->setSize(QSizeF(1,mHeight));
83 xPos += xStep;
82 xPos += xStep;
84 }
83 }
85
84
86 // Position floating values
85 // Position floating values
87 itemIndex = 0;
86 itemIndex = 0;
88 xPos = ((tW/tC) - mBarDefaultWidth / 2);
87 xPos = ((tW/tC) - mBarDefaultWidth / 2);
89 for (int category=0; category < mSeries->categoryCount(); category++) {
88 for (int category=0; category < mSeries->categoryCount(); category++) {
90 qreal yPos = h;
89 qreal yPos = h;
91 for (int set=0; set < mSeries->barsetCount(); set++) {
90 for (int set=0; set < mSeries->barsetCount(); set++) {
92 qreal barHeight = mSeries->valueAt(set,category) * scale;
91 qreal barHeight = mSeries->valueAt(set,category) * scale;
93 BarValue* value = mFloatingValues.at(itemIndex);
92 BarValue* value = mFloatingValues.at(itemIndex);
94
93
95 // TODO: remove hard coding, apply layout
94 // TODO: remove hard coding, apply layout
96 value->resize(100,50);
95 value->resize(100,50);
97 value->setPos(xPos, yPos-barHeight/2);
96 value->setPos(xPos, yPos-barHeight/2);
98 value->setPen(QPen(QColor(255,255,255,255)));
97 value->setPen(QPen(QColor(255,255,255,255)));
99
98
100 if (mSeries->valueAt(set,category) != 0) {
99 if (mSeries->valueAt(set,category) != 0) {
101 value->setValueString(QString::number(mSeries->valueAt(set,category)));
100 value->setValueString(QString::number(mSeries->valueAt(set,category)));
102 } else {
101 } else {
103 value->setValueString(QString(""));
102 value->setValueString(QString(""));
104 }
103 }
105
104
106 itemIndex++;
105 itemIndex++;
107 yPos -= barHeight;
106 yPos -= barHeight;
108 }
107 }
109 xPos += xStep;
108 xPos += xStep;
110 }
109 }
111
110
112 mLayoutDirty = true;
111 mLayoutDirty = true;
113 }
112 }
114
113
115 #include "moc_stackedbarpresenter_p.cpp"
114 #include "moc_stackedbarpresenter_p.cpp"
116
115
117 QTCOMMERCIALCHART_END_NAMESPACE
116 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,299 +1,307
1 #include "chartdataset_p.h"
1 #include "chartdataset_p.h"
2 #include "qchartaxis.h"
2 #include "qchartaxis.h"
3 //series
3 //series
4 #include "qlineseries.h"
4 #include "qlineseries.h"
5 #include "qareaseries.h"
5 #include "qareaseries.h"
6 #include "qbarseries.h"
6 #include "qbarseries.h"
7 #include "qstackedbarseries.h"
7 #include "qstackedbarseries.h"
8 #include "qpercentbarseries.h"
8 #include "qpercentbarseries.h"
9 #include "qpieseries.h"
9 #include "qpieseries.h"
10 #include "qscatterseries.h"
10 #include "qscatterseries.h"
11 #include "qsplineseries.h"
11 #include "qsplineseries.h"
12
12
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
14
14
15 ChartDataSet::ChartDataSet(QObject *parent):QObject(parent),
15 ChartDataSet::ChartDataSet(QObject *parent):QObject(parent),
16 m_axisX(new QChartAxis(this)),
16 m_axisX(new QChartAxis(this)),
17 m_axisY(new QChartAxis(this)),
17 m_axisY(new QChartAxis(this)),
18 m_domainIndex(0),
18 m_domainIndex(0),
19 m_axisXInitialized(false)
19 m_axisXInitialized(false)
20 {
20 {
21 }
21 }
22
22
23 ChartDataSet::~ChartDataSet()
23 ChartDataSet::~ChartDataSet()
24 {
24 {
25 }
25 }
26
26
27 void ChartDataSet::addSeries(QSeries* series, QChartAxis *axisY)
27 void ChartDataSet::addSeries(QSeries* series, QChartAxis *axisY)
28 {
28 {
29 if(axisY==0) axisY = m_axisY;
29 if(axisY==0) axisY = m_axisY;
30
30
31 QChartAxis* axis = m_seriesAxisMap.value(series);
31 QChartAxis* axis = m_seriesAxisMap.value(series);
32
32
33 if(axis) {
33 if(axis) {
34 qWarning() << "Can not add series. Series already on the chart";
34 qWarning() << "Can not add series. Series already on the chart";
35 return;
35 return;
36 }
36 }
37
37
38 if(!series->parent()){
38 if(!series->parent()){
39 series->setParent(this); // take ownership
39 series->setParent(this); // take ownership
40 };
40 };
41
41
42 if(!axisY->parent()){
42 if(!axisY->parent()){
43 axisY->setParent(this); // take ownership
43 axisY->setParent(this); // take ownership
44 }
44 }
45
45
46 Domain* domain = m_axisDomainMap.value(axisY);
46 Domain* domain = m_axisDomainMap.value(axisY);
47
47
48 if(!domain) {
48 if(!domain) {
49 domain = new Domain();
49 domain = new Domain();
50
50
51 QObject::connect(axisY,SIGNAL(rangeChanged(qreal,qreal)),domain,SLOT(handleAxisRangeXChanged(qreal,qreal)));
51 QObject::connect(axisY,SIGNAL(rangeChanged(qreal,qreal)),domain,SLOT(handleAxisRangeXChanged(qreal,qreal)));
52 QObject::connect(axisX(),SIGNAL(rangeChanged(qreal,qreal)),domain,SLOT(handleAxisRangeYChanged(qreal,qreal)));
52 QObject::connect(axisX(),SIGNAL(rangeChanged(qreal,qreal)),domain,SLOT(handleAxisRangeYChanged(qreal,qreal)));
53 //initialize
53 //initialize
54 m_axisDomainMap.insert(axisY,domain);
54 m_axisDomainMap.insert(axisY,domain);
55 emit axisAdded(axisY,domain);
55 emit axisAdded(axisY,domain);
56 }
56 }
57
57
58 if(!m_axisXInitialized){
58 if(!m_axisXInitialized){
59 emit axisAdded(axisX(),domain);
59 emit axisAdded(axisX(),domain);
60 m_axisXInitialized=true;
60 m_axisXInitialized=true;
61 }
61 }
62
62
63 calculateDomain(series,domain);
63 calculateDomain(series,domain);
64
64
65 m_seriesAxisMap.insert(series,axisY);
65 m_seriesAxisMap.insert(series,axisY);
66 emit seriesAdded(series,domain);
66 emit seriesAdded(series,domain);
67
67
68 }
68 }
69
69
70 void ChartDataSet::removeSeries(QSeries* series)
70 void ChartDataSet::removeSeries(QSeries* series)
71 {
71 {
72
72
73 QChartAxis* axis = m_seriesAxisMap.value(series);
73 QChartAxis* axis = m_seriesAxisMap.value(series);
74
74
75 if(!axis){
75 if(!axis){
76 qWarning()<<"Can not remove series. Series not found on the chart.";
76 qWarning()<<"Can not remove series. Series not found on the chart.";
77 return;
77 return;
78 }
78 }
79 emit seriesRemoved(series);
79 emit seriesRemoved(series);
80 m_seriesAxisMap.remove(series);
80 m_seriesAxisMap.remove(series);
81
81
82 if(series->parent()==this){
82 if(series->parent()==this){
83 delete series;
83 delete series;
84 series=0;
84 series=0;
85 }
85 }
86
86
87 QList<QChartAxis*> axes = m_seriesAxisMap.values();
87 QList<QChartAxis*> axes = m_seriesAxisMap.values();
88
88
89 int i = axes.indexOf(axis);
89 int i = axes.indexOf(axis);
90
90
91 if(i==-1){
91 if(i==-1){
92 Domain* domain = m_axisDomainMap.take(axis);
92 Domain* domain = m_axisDomainMap.take(axis);
93 emit axisRemoved(axis);
93 emit axisRemoved(axis);
94 if(axis!=axisY()){
94 if(axis!=axisY()){
95 if(axis->parent()==this){
95 if(axis->parent()==this){
96 delete axis;
96 delete axis;
97 axis=0;
97 axis=0;
98 }
98 }
99 }
99 }
100 delete domain;
100 delete domain;
101 }
101 }
102
102
103 if(m_seriesAxisMap.values().size()==0)
103 if(m_seriesAxisMap.values().size()==0)
104 {
104 {
105 m_axisXInitialized=false;
105 m_axisXInitialized=false;
106 emit axisRemoved(axisX());
106 emit axisRemoved(axisX());
107 }
107 }
108 }
108 }
109
109
110 void ChartDataSet::removeAllSeries()
110 void ChartDataSet::removeAllSeries()
111 {
111 {
112
112
113 QList<QSeries*> series = m_seriesAxisMap.keys();
113 QList<QSeries*> series = m_seriesAxisMap.keys();
114
114
115 foreach(QSeries* s , series) {
115 foreach(QSeries* s , series) {
116 removeSeries(s);
116 removeSeries(s);
117 }
117 }
118
118
119 Q_ASSERT(m_seriesAxisMap.count()==0);
119 Q_ASSERT(m_seriesAxisMap.count()==0);
120 Q_ASSERT(m_axisDomainMap.count()==0);
120 Q_ASSERT(m_axisDomainMap.count()==0);
121
121
122 }
122 }
123
123
124 //to be removed with PIMPL
124 //to be removed with PIMPL
125 void ChartDataSet::calculateDomain(QSeries* series,Domain* domain) const
125 void ChartDataSet::calculateDomain(QSeries* series,Domain* domain) const
126 {
126 {
127 switch(series->type())
127 switch(series->type())
128 {
128 {
129 case QSeries::SeriesTypeLine: {
129 case QSeries::SeriesTypeLine: {
130
130
131 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
131 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
132
132
133 for (int i = 0; i < lineSeries->count(); i++)
133 for (int i = 0; i < lineSeries->count(); i++)
134 {
134 {
135 qreal x = lineSeries->x(i);
135 qreal x = lineSeries->x(i);
136 qreal y = lineSeries->y(i);
136 qreal y = lineSeries->y(i);
137 domain->setMinX(qMin(domain->minX(),x));
137 domain->setMinX(qMin(domain->minX(),x));
138 domain->setMinY(qMin(domain->minY(),y));
138 domain->setMinY(qMin(domain->minY(),y));
139 domain->setMaxX(qMax(domain->maxX(),x));
139 domain->setMaxX(qMax(domain->maxX(),x));
140 domain->setMaxY(qMax(domain->maxY(),y));
140 domain->setMaxY(qMax(domain->maxY(),y));
141 }
141 }
142 break;
142 break;
143 }
143 }
144 case QSeries::SeriesTypeArea: {
144 case QSeries::SeriesTypeArea: {
145
145
146 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
146 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
147
147
148 QLineSeries* upperSeries = areaSeries->upperSeries();
148 QLineSeries* upperSeries = areaSeries->upperSeries();
149 QLineSeries* lowerSeries = areaSeries->lowerSeries();
149 QLineSeries* lowerSeries = areaSeries->lowerSeries();
150
150
151 for (int i = 0; i < upperSeries->count(); i++)
151 for (int i = 0; i < upperSeries->count(); i++)
152 {
152 {
153 qreal x = upperSeries->x(i);
153 qreal x = upperSeries->x(i);
154 qreal y = upperSeries->y(i);
154 qreal y = upperSeries->y(i);
155 domain->setMinX(qMin(domain->minX(),x));
155 domain->setMinX(qMin(domain->minX(),x));
156 domain->setMinY(qMin(domain->minY(),y));
156 domain->setMinY(qMin(domain->minY(),y));
157 domain->setMaxX(qMax(domain->maxX(),x));
157 domain->setMaxX(qMax(domain->maxX(),x));
158 domain->setMaxY(qMax(domain->maxY(),y));
158 domain->setMaxY(qMax(domain->maxY(),y));
159 }
159 }
160 if(lowerSeries) {
160 if(lowerSeries) {
161 for (int i = 0; i < lowerSeries->count(); i++)
161 for (int i = 0; i < lowerSeries->count(); i++)
162 {
162 {
163 qreal x = lowerSeries->x(i);
163 qreal x = lowerSeries->x(i);
164 qreal y = lowerSeries->y(i);
164 qreal y = lowerSeries->y(i);
165 domain->setMinX(qMin(domain->minX(),x));
165 domain->setMinX(qMin(domain->minX(),x));
166 domain->setMinY(qMin(domain->minY(),y));
166 domain->setMinY(qMin(domain->minY(),y));
167 domain->setMaxX(qMax(domain->maxX(),x));
167 domain->setMaxX(qMax(domain->maxX(),x));
168 domain->setMaxY(qMax(domain->maxY(),y));
168 domain->setMaxY(qMax(domain->maxY(),y));
169 }}
169 }}
170 break;
170 break;
171 }
171 }
172 case QSeries::SeriesTypeBar: {
172 case QSeries::SeriesTypeBar: {
173 qDebug() << "QChartSeries::SeriesTypeBar";
173 qDebug() << "QChartSeries::SeriesTypeBar";
174 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
174 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
175 qreal x = barSeries->categoryCount();
175 qreal x = barSeries->categoryCount();
176 qreal y = barSeries->max();
176 qreal y = barSeries->max();
177 domain->setMinX(qMin(domain->minX(),x));
177 domain->setMinX(qMin(domain->minX(),x));
178 domain->setMinY(qMin(domain->minY(),y));
178 domain->setMinY(qMin(domain->minY(),y));
179 domain->setMaxX(qMax(domain->maxX(),x));
179 domain->setMaxX(qMax(domain->maxX(),x));
180 domain->setMaxY(qMax(domain->maxY(),y));
180 domain->setMaxY(qMax(domain->maxY(),y));
181 break;
181 break;
182 }
182 }
183 case QSeries::SeriesTypeStackedBar: {
183 case QSeries::SeriesTypeStackedBar: {
184 qDebug() << "QChartSeries::SeriesTypeStackedBar";
184 qDebug() << "QChartSeries::SeriesTypeStackedBar";
185
185
186 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
186 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
187 qreal x = stackedBarSeries->categoryCount();
187 qreal x = stackedBarSeries->categoryCount();
188 qreal y = stackedBarSeries->maxCategorySum();
188 qreal y = stackedBarSeries->maxCategorySum();
189 domain->setMinX(qMin(domain->minX(),x));
189 domain->setMinX(qMin(domain->minX(),x));
190 domain->setMinY(qMin(domain->minY(),y));
190 domain->setMinY(qMin(domain->minY(),y));
191 domain->setMaxX(qMax(domain->maxX(),x));
191 domain->setMaxX(qMax(domain->maxX(),x));
192 domain->setMaxY(qMax(domain->maxY(),y));
192 domain->setMaxY(qMax(domain->maxY(),y));
193 break;
193 break;
194 }
194 }
195 case QSeries::SeriesTypePercentBar: {
195 case QSeries::SeriesTypePercentBar: {
196 qDebug() << "QChartSeries::SeriesTypePercentBar";
196 qDebug() << "QChartSeries::SeriesTypePercentBar";
197
197
198 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
198 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
199 qreal x = percentBarSeries->categoryCount();
199 qreal x = percentBarSeries->categoryCount();
200 domain->setMinX(qMin(domain->minX(),x));
200 domain->setMinX(qMin(domain->minX(),x));
201 domain->setMinY(0);
201 domain->setMinY(0);
202 domain->setMaxX(qMax(domain->maxX(),x));
202 domain->setMaxX(qMax(domain->maxX(),x));
203 domain->setMaxY(100);
203 domain->setMaxY(100);
204 break;
204 break;
205 }
205 }
206
206
207 case QSeries::SeriesTypePie: {
207 case QSeries::SeriesTypePie: {
208 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
208 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
209 // TODO: domain stuff
209 // TODO: domain stuff
210 break;
210 break;
211 }
211 }
212
212
213 case QSeries::SeriesTypeScatter: {
213 case QSeries::SeriesTypeScatter: {
214 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
214 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
215 Q_ASSERT(scatterSeries);
215 Q_ASSERT(scatterSeries);
216 qreal minX(domain->minX());
217 qreal minY(domain->minY());
218 qreal maxX(domain->maxX());
219 qreal maxY(domain->maxY());
216 foreach (QPointF point, scatterSeries->data()) {
220 foreach (QPointF point, scatterSeries->data()) {
217 domain->setMinX(qMin(domain->minX(), point.x()));
221 minX = qMin(minX, point.x());
218 domain->setMinY(qMax(domain->maxX(), point.x()));
222 minY = qMin(minY, point.y());
219 domain->setMaxX(qMin(domain->minY(), point.y()));
223 maxX = qMax(maxX, point.x());
220 domain->setMaxY(qMax(domain->maxY(), point.y()));
224 maxY = qMax(maxY, point.y());
221 }
225 }
226 domain->setMinX(minX);
227 domain->setMinY(minY);
228 domain->setMaxX(maxX);
229 domain->setMaxY(maxY);
222 break;
230 break;
223 }
231 }
224
232
225 case QSeries::SeriesTypeSpline: {
233 case QSeries::SeriesTypeSpline: {
226 QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
234 QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
227
235
228 for (int i = 0; i < splineSeries->count(); i++)
236 for (int i = 0; i < splineSeries->count(); i++)
229 {
237 {
230 qreal x = splineSeries->x(i);
238 qreal x = splineSeries->x(i);
231 qreal y = splineSeries->y(i);
239 qreal y = splineSeries->y(i);
232 domain->setMinX(qMin(domain->minX(),x));
240 domain->setMinX(qMin(domain->minX(),x));
233 domain->setMinY(qMin(domain->minY(),y));
241 domain->setMinY(qMin(domain->minY(),y));
234 domain->setMaxX(qMax(domain->maxX(),x));
242 domain->setMaxX(qMax(domain->maxX(),x));
235 domain->setMaxY(qMax(domain->maxY(),y));
243 domain->setMaxY(qMax(domain->maxY(),y));
236 }
244 }
237 break;
245 break;
238 }
246 }
239
247
240 default: {
248 default: {
241 qDebug()<<__FUNCTION__<<"type" << series->type()<<"not supported";
249 qDebug()<<__FUNCTION__<<"type" << series->type()<<"not supported";
242 return;
250 return;
243 break;
251 break;
244 }
252 }
245
253
246 }
254 }
247 }
255 }
248
256
249 void ChartDataSet::zoomInDomain(const QRectF& rect, const QSizeF& size)
257 void ChartDataSet::zoomInDomain(const QRectF& rect, const QSizeF& size)
250 {
258 {
251 QMapIterator<QChartAxis*, Domain*> i( m_axisDomainMap);
259 QMapIterator<QChartAxis*, Domain*> i( m_axisDomainMap);
252 while (i.hasNext()) {
260 while (i.hasNext()) {
253 i.next();
261 i.next();
254 i.value()->zoomIn(rect,size);
262 i.value()->zoomIn(rect,size);
255 }
263 }
256 }
264 }
257
265
258 void ChartDataSet::zoomOutDomain(const QRectF& rect, const QSizeF& size)
266 void ChartDataSet::zoomOutDomain(const QRectF& rect, const QSizeF& size)
259 {
267 {
260 QMapIterator<QChartAxis*, Domain*> i( m_axisDomainMap);
268 QMapIterator<QChartAxis*, Domain*> i( m_axisDomainMap);
261 while (i.hasNext()) {
269 while (i.hasNext()) {
262 i.next();
270 i.next();
263 i.value()->zoomOut(rect,size);
271 i.value()->zoomOut(rect,size);
264 }
272 }
265 }
273 }
266
274
267 QChartAxis* ChartDataSet::axisY(QSeries* series) const
275 QChartAxis* ChartDataSet::axisY(QSeries* series) const
268 {
276 {
269 if(series == 0) return m_axisY;
277 if(series == 0) return m_axisY;
270 return m_seriesAxisMap.value(series);
278 return m_seriesAxisMap.value(series);
271 }
279 }
272
280
273 Domain* ChartDataSet::domain(QSeries* series) const
281 Domain* ChartDataSet::domain(QSeries* series) const
274 {
282 {
275 QChartAxis* axis = m_seriesAxisMap.value(series);
283 QChartAxis* axis = m_seriesAxisMap.value(series);
276 if(axis){
284 if(axis){
277 return m_axisDomainMap.value(axis);
285 return m_axisDomainMap.value(axis);
278 }else
286 }else
279 return 0;
287 return 0;
280 }
288 }
281
289
282 Domain* ChartDataSet::domain(QChartAxis* axis) const
290 Domain* ChartDataSet::domain(QChartAxis* axis) const
283 {
291 {
284 if(axis==axisX()) {
292 if(axis==axisX()) {
285 return m_axisDomainMap.value(axisY());
293 return m_axisDomainMap.value(axisY());
286 }
294 }
287 else {
295 else {
288 return m_axisDomainMap.value(axis);
296 return m_axisDomainMap.value(axis);
289 }
297 }
290 }
298 }
291
299
292 QChartAxis* ChartDataSet::axis(QSeries* series) const
300 QChartAxis* ChartDataSet::axis(QSeries* series) const
293 {
301 {
294 return m_seriesAxisMap.value(series);
302 return m_seriesAxisMap.value(series);
295 }
303 }
296
304
297 #include "moc_chartdataset_p.cpp"
305 #include "moc_chartdataset_p.cpp"
298
306
299 QTCOMMERCIALCHART_END_NAMESPACE
307 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,366 +1,370
1 #include "qchart.h"
1 #include "qchart.h"
2 #include "qchartaxis.h"
2 #include "qchartaxis.h"
3 #include "chartpresenter_p.h"
3 #include "chartpresenter_p.h"
4 #include "chartdataset_p.h"
4 #include "chartdataset_p.h"
5 #include "charttheme_p.h"
5 #include "charttheme_p.h"
6 //series
6 //series
7 #include "qbarseries.h"
7 #include "qbarseries.h"
8 #include "qstackedbarseries.h"
8 #include "qstackedbarseries.h"
9 #include "qpercentbarseries.h"
9 #include "qpercentbarseries.h"
10 #include "qlineseries.h"
10 #include "qlineseries.h"
11 #include "qareaseries.h"
11 #include "qareaseries.h"
12 #include "qpieseries.h"
12 #include "qpieseries.h"
13 #include "qscatterseries.h"
13 #include "qscatterseries.h"
14 #include "qsplineseries.h"
14 #include "qsplineseries.h"
15 //items
15 //items
16 #include "axisitem_p.h"
16 #include "axisitem_p.h"
17 #include "axisanimationitem_p.h"
17 #include "axisanimationitem_p.h"
18 #include "areachartitem_p.h"
18 #include "areachartitem_p.h"
19 #include "barpresenter_p.h"
19 #include "barpresenter_p.h"
20 #include "stackedbarpresenter_p.h"
20 #include "stackedbarpresenter_p.h"
21 #include "percentbarpresenter_p.h"
21 #include "percentbarpresenter_p.h"
22 #include "linechartitem_p.h"
22 #include "linechartitem_p.h"
23 #include "linechartanimationitem_p.h"
23 #include "linechartanimationitem_p.h"
24 #include "piepresenter_p.h"
24 #include "piepresenter_p.h"
25 #include "scatterpresenter_p.h"
25 #include "scatterpresenter_p.h"
26 #include "splinepresenter_p.h"
26 #include "splinepresenter_p.h"
27
27
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29
29
30 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
30 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
31 m_chart(chart),
31 m_chart(chart),
32 m_dataset(dataset),
32 m_dataset(dataset),
33 m_chartTheme(0),
33 m_chartTheme(0),
34 m_zoomIndex(0),
34 m_zoomIndex(0),
35 m_marginSize(0),
35 m_marginSize(0),
36 m_rect(QRectF(QPoint(0,0),m_chart->size())),
36 m_rect(QRectF(QPoint(0,0),m_chart->size())),
37 m_options(QChart::NoAnimation)
37 m_options(QChart::NoAnimation)
38 {
38 {
39 createConnections();
39 createConnections();
40 setChartTheme(QChart::ChartThemeDefault);
40 setChartTheme(QChart::ChartThemeDefault);
41 }
41 }
42
42
43 ChartPresenter::~ChartPresenter()
43 ChartPresenter::~ChartPresenter()
44 {
44 {
45 }
45 }
46
46
47 void ChartPresenter::createConnections()
47 void ChartPresenter::createConnections()
48 {
48 {
49 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
49 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
50 QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),this,SLOT(handleSeriesAdded(QSeries*,Domain*)));
50 QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),this,SLOT(handleSeriesAdded(QSeries*,Domain*)));
51 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),this,SLOT(handleSeriesRemoved(QSeries*)));
51 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),this,SLOT(handleSeriesRemoved(QSeries*)));
52 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*,Domain*)),this,SLOT(handleAxisAdded(QChartAxis*,Domain*)));
52 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*,Domain*)),this,SLOT(handleAxisAdded(QChartAxis*,Domain*)));
53 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
53 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
54 }
54 }
55
55
56
56
57 QRectF ChartPresenter::geometry() const
57 QRectF ChartPresenter::geometry() const
58 {
58 {
59 return m_rect;
59 return m_rect;
60 }
60 }
61
61
62 void ChartPresenter::handleGeometryChanged()
62 void ChartPresenter::handleGeometryChanged()
63 {
63 {
64 QRectF rect(QPoint(0,0),m_chart->size());
64 QRectF rect(QPoint(0,0),m_chart->size());
65 rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize);
65 rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize);
66
66
67 //rewrite zoom stack
67 //rewrite zoom stack
68 for(int i=0;i<m_zoomStack.count();i++){
68 for(int i=0;i<m_zoomStack.count();i++){
69 QRectF r = m_zoomStack[i];
69 QRectF r = m_zoomStack[i];
70 qreal w = rect.width()/m_rect.width();
70 qreal w = rect.width()/m_rect.width();
71 qreal h = rect.height()/m_rect.height();
71 qreal h = rect.height()/m_rect.height();
72 QPointF tl = r.topLeft();
72 QPointF tl = r.topLeft();
73 tl.setX(tl.x()*w);
73 tl.setX(tl.x()*w);
74 tl.setY(tl.y()*h);
74 tl.setY(tl.y()*h);
75 QPointF br = r.bottomRight();
75 QPointF br = r.bottomRight();
76 br.setX(br.x()*w);
76 br.setX(br.x()*w);
77 br.setY(br.y()*h);
77 br.setY(br.y()*h);
78 r.setTopLeft(tl);
78 r.setTopLeft(tl);
79 r.setBottomRight(br);
79 r.setBottomRight(br);
80 m_zoomStack[i]=r;
80 m_zoomStack[i]=r;
81 }
81 }
82
82
83 m_rect = rect;
83 m_rect = rect;
84 Q_ASSERT(m_rect.isValid());
84 Q_ASSERT(m_rect.isValid());
85 emit geometryChanged(m_rect);
85 emit geometryChanged(m_rect);
86 }
86 }
87
87
88 int ChartPresenter::margin() const
88 int ChartPresenter::margin() const
89 {
89 {
90 return m_marginSize;
90 return m_marginSize;
91 }
91 }
92
92
93 void ChartPresenter::setMargin(int margin)
93 void ChartPresenter::setMargin(int margin)
94 {
94 {
95 m_marginSize = margin;
95 m_marginSize = margin;
96 }
96 }
97
97
98 void ChartPresenter::handleAxisAdded(QChartAxis* axis,Domain* domain)
98 void ChartPresenter::handleAxisAdded(QChartAxis* axis,Domain* domain)
99 {
99 {
100
100
101 AxisItem* item ;
101 AxisItem* item ;
102
102
103 if(!m_options.testFlag(QChart::GridAxisAnimations))
103 if(!m_options.testFlag(QChart::GridAxisAnimations))
104 {
104 {
105 item = new AxisItem(axis,axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
105 item = new AxisItem(axis,axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
106 }else{
106 }else{
107 item = new AxisAnimationItem(axis,axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
107 item = new AxisAnimationItem(axis,axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
108 }
108 }
109 if(axis==m_dataset->axisX()){
109 if(axis==m_dataset->axisX()){
110 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal)),item,SLOT(handleRangeChanged(qreal,qreal)));
110 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal)),item,SLOT(handleRangeChanged(qreal,qreal)));
111 //initialize
111 //initialize
112 item->handleRangeChanged(domain->minX(),domain->maxX());
112 item->handleRangeChanged(domain->minX(),domain->maxX());
113 }
113 }
114 else{
114 else{
115 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal)),item,SLOT(handleRangeChanged(qreal,qreal)));
115 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal)),item,SLOT(handleRangeChanged(qreal,qreal)));
116 //initialize
116 //initialize
117 item->handleRangeChanged(domain->minY(),domain->maxY());
117 item->handleRangeChanged(domain->minY(),domain->maxY());
118 }
118 }
119
119
120 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
120 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
121 //initialize
121 //initialize
122 item->handleGeometryChanged(m_rect);
122 item->handleGeometryChanged(m_rect);
123 m_chartTheme->decorate(axis,item);
123 m_chartTheme->decorate(axis,item);
124 m_axisItems.insert(axis,item);
124 m_axisItems.insert(axis,item);
125 }
125 }
126
126
127 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
127 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
128 {
128 {
129 AxisItem* item = m_axisItems.take(axis);
129 AxisItem* item = m_axisItems.take(axis);
130 Q_ASSERT(item);
130 Q_ASSERT(item);
131 delete item;
131 delete item;
132 }
132 }
133
133
134
134
135 void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain)
135 void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain)
136 {
136 {
137 switch(series->type())
137 switch(series->type())
138 {
138 {
139 case QSeries::SeriesTypeLine: {
139 case QSeries::SeriesTypeLine: {
140
140
141 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
141 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
142 LineChartItem* item;
142 LineChartItem* item;
143 if(m_options.testFlag(QChart::SeriesAnimations)){
143 if(m_options.testFlag(QChart::SeriesAnimations)){
144 item = new LineChartAnimationItem(lineSeries,m_chart);
144 item = new LineChartAnimationItem(lineSeries,m_chart);
145 }else{
145 }else{
146 item = new LineChartItem(lineSeries,m_chart);
146 item = new LineChartItem(lineSeries,m_chart);
147 }
147 }
148 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
148 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
149 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
149 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
150 //initialize
150 //initialize
151 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
151 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
152 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
152 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
153 //decorate
153 //decorate
154 m_chartTheme->decorate(item,lineSeries,m_chartItems.count());
154 m_chartTheme->decorate(item,lineSeries,m_chartItems.count());
155 m_chartItems.insert(series,item);
155 m_chartItems.insert(series,item);
156 break;
156 break;
157 }
157 }
158
158
159 case QSeries::SeriesTypeArea: {
159 case QSeries::SeriesTypeArea: {
160
160
161 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
161 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
162 AreaChartItem* item;
162 AreaChartItem* item;
163 if(m_options.testFlag(QChart::SeriesAnimations)) {
163 if(m_options.testFlag(QChart::SeriesAnimations)) {
164 item = new AreaChartItem(areaSeries,m_chart);
164 item = new AreaChartItem(areaSeries,m_chart);
165 }
165 }
166 else {
166 else {
167 item = new AreaChartItem(areaSeries,m_chart);
167 item = new AreaChartItem(areaSeries,m_chart);
168 }
168 }
169 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
169 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
170 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
170 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
171 //initialize
171 //initialize
172 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
172 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
173 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
173 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
174 //decorate
174 //decorate
175 m_chartTheme->decorate(item,areaSeries,m_chartItems.count());
175 m_chartTheme->decorate(item,areaSeries,m_chartItems.count());
176 m_chartItems.insert(series,item);
176 m_chartItems.insert(series,item);
177 break;
177 break;
178 }
178 }
179
179
180 case QSeries::SeriesTypeBar: {
180 case QSeries::SeriesTypeBar: {
181 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
181 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
182 BarPresenter* item = new BarPresenter(barSeries,m_chart);
182 BarPresenter* item = new BarPresenter(barSeries,m_chart);
183 m_chartTheme->decorate(item,barSeries,m_chartItems.count());
183 m_chartTheme->decorate(item,barSeries,m_chartItems.count());
184 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
184 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
185 // QObject::connect(barSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
185 // QObject::connect(barSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
186 m_chartItems.insert(series,item);
186 m_chartItems.insert(series,item);
187 // m_axisXItem->setVisible(false);
187 // m_axisXItem->setVisible(false);
188 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
188 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
189 break;
189 break;
190 }
190 }
191
191
192 case QSeries::SeriesTypeStackedBar: {
192 case QSeries::SeriesTypeStackedBar: {
193
193
194 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
194 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
195 StackedBarPresenter* item = new StackedBarPresenter(stackedBarSeries,m_chart);
195 StackedBarPresenter* item = new StackedBarPresenter(stackedBarSeries,m_chart);
196 m_chartTheme->decorate(item,stackedBarSeries,m_chartItems.count());
196 m_chartTheme->decorate(item,stackedBarSeries,m_chartItems.count());
197 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
197 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
198 // QObject::connect(stackedBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
198 // QObject::connect(stackedBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
199 m_chartItems.insert(series,item);
199 m_chartItems.insert(series,item);
200 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
200 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
201 break;
201 break;
202 }
202 }
203
203
204 case QSeries::SeriesTypePercentBar: {
204 case QSeries::SeriesTypePercentBar: {
205
205
206 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
206 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
207 PercentBarPresenter* item = new PercentBarPresenter(percentBarSeries,m_chart);
207 PercentBarPresenter* item = new PercentBarPresenter(percentBarSeries,m_chart);
208 m_chartTheme->decorate(item,percentBarSeries ,m_chartItems.count());
208 m_chartTheme->decorate(item,percentBarSeries ,m_chartItems.count());
209 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
209 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
210 // QObject::connect(percentBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
210 // QObject::connect(percentBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
211 m_chartItems.insert(series,item);
211 m_chartItems.insert(series,item);
212 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
212 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
213 break;
213 break;
214 }
214 }
215 case QSeries::SeriesTypeScatter: {
215 case QSeries::SeriesTypeScatter: {
216 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
216 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
217 ScatterPresenter *scatterPresenter = new ScatterPresenter(scatterSeries, m_chart);
217 ScatterPresenter *scatterPresenter = new ScatterPresenter(scatterSeries, m_chart);
218 QObject::connect(scatterPresenter, SIGNAL(clicked(QPointF)),
218 QObject::connect(scatterPresenter, SIGNAL(clicked(QPointF)),
219 scatterSeries, SIGNAL(clicked(QPointF)));
219 scatterSeries, SIGNAL(clicked(QPointF)));
220 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)),
220 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)),
221 scatterPresenter, SLOT(handleGeometryChanged(const QRectF&)));
221 scatterPresenter, SLOT(handleGeometryChanged(const QRectF&)));
222 QObject::connect(domain, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),
223 scatterPresenter, SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
222 m_chartTheme->decorate(scatterPresenter, scatterSeries, m_chartItems.count());
224 m_chartTheme->decorate(scatterPresenter, scatterSeries, m_chartItems.count());
223 m_chartItems.insert(scatterSeries, scatterPresenter);
225 m_chartItems.insert(scatterSeries, scatterPresenter);
224 if(m_rect.isValid()) scatterPresenter->handleGeometryChanged(m_rect);
226 if (m_rect.isValid())
227 scatterPresenter->handleGeometryChanged(m_rect);
228 scatterPresenter->handleDomainChanged(domain->minX(), domain->maxX(), domain->minY(), domain->maxY());
225 break;
229 break;
226 }
230 }
227 case QSeries::SeriesTypePie: {
231 case QSeries::SeriesTypePie: {
228 QPieSeries *s = qobject_cast<QPieSeries *>(series);
232 QPieSeries *s = qobject_cast<QPieSeries *>(series);
229 PiePresenter* pie = new PiePresenter(m_chart, s);
233 PiePresenter* pie = new PiePresenter(m_chart, s);
230 m_chartTheme->decorate(pie, s, m_chartItems.count());
234 m_chartTheme->decorate(pie, s, m_chartItems.count());
231 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), pie, SLOT(handleGeometryChanged(const QRectF&)));
235 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), pie, SLOT(handleGeometryChanged(const QRectF&)));
232
236
233 // Hide all from background when there is only piechart
237 // Hide all from background when there is only piechart
234 // TODO: refactor this ugly code... should be one setting for this
238 // TODO: refactor this ugly code... should be one setting for this
235 if (m_chartItems.count() == 0) {
239 if (m_chartItems.count() == 0) {
236 m_chart->axisX()->setAxisVisible(false);
240 m_chart->axisX()->setAxisVisible(false);
237 m_chart->axisY()->setAxisVisible(false);
241 m_chart->axisY()->setAxisVisible(false);
238 m_chart->axisX()->setGridVisible(false);
242 m_chart->axisX()->setGridVisible(false);
239 m_chart->axisY()->setGridVisible(false);
243 m_chart->axisY()->setGridVisible(false);
240 m_chart->axisX()->setLabelsVisible(false);
244 m_chart->axisX()->setLabelsVisible(false);
241 m_chart->axisY()->setLabelsVisible(false);
245 m_chart->axisY()->setLabelsVisible(false);
242 m_chart->axisX()->setShadesVisible(false);
246 m_chart->axisX()->setShadesVisible(false);
243 m_chart->axisY()->setShadesVisible(false);
247 m_chart->axisY()->setShadesVisible(false);
244 m_chart->setChartBackgroundBrush(Qt::transparent);
248 m_chart->setChartBackgroundBrush(Qt::transparent);
245 }
249 }
246
250
247 m_chartItems.insert(series, pie);
251 m_chartItems.insert(series, pie);
248 pie->handleGeometryChanged(m_rect);
252 pie->handleGeometryChanged(m_rect);
249 break;
253 break;
250 }
254 }
251
255
252 case QSeries::SeriesTypeSpline: {
256 case QSeries::SeriesTypeSpline: {
253 QSplineSeries* splineSeries = qobject_cast<QSplineSeries*>(series);
257 QSplineSeries* splineSeries = qobject_cast<QSplineSeries*>(series);
254 SplinePresenter* splinePresenter = new SplinePresenter(splineSeries, m_chart);
258 SplinePresenter* splinePresenter = new SplinePresenter(splineSeries, m_chart);
255 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), splinePresenter, SLOT(handleGeometryChanged(const QRectF&)));
259 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), splinePresenter, SLOT(handleGeometryChanged(const QRectF&)));
256 //initialize
260 //initialize
257 splinePresenter->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
261 splinePresenter->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
258 m_chartTheme->decorate(splinePresenter, splineSeries, m_chartItems.count());
262 m_chartTheme->decorate(splinePresenter, splineSeries, m_chartItems.count());
259 m_chartItems.insert(splineSeries, splinePresenter);
263 m_chartItems.insert(splineSeries, splinePresenter);
260 break;
264 break;
261 }
265 }
262 default: {
266 default: {
263 qDebug()<< "Series type" << series->type() << "not implemented.";
267 qDebug()<< "Series type" << series->type() << "not implemented.";
264 break;
268 break;
265 }
269 }
266 }
270 }
267
271
268 zoomReset();
272 zoomReset();
269 }
273 }
270
274
271 void ChartPresenter::handleSeriesRemoved(QSeries* series)
275 void ChartPresenter::handleSeriesRemoved(QSeries* series)
272 {
276 {
273 ChartItem* item = m_chartItems.take(series);
277 ChartItem* item = m_chartItems.take(series);
274 delete item;
278 delete item;
275 }
279 }
276
280
277 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
281 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
278 {
282 {
279 delete m_chartTheme;
283 delete m_chartTheme;
280
284
281 m_chartTheme = ChartTheme::createTheme(theme);
285 m_chartTheme = ChartTheme::createTheme(theme);
282
286
283 m_chartTheme->decorate(m_chart);
287 m_chartTheme->decorate(m_chart);
284 QMapIterator<QSeries*,ChartItem*> i(m_chartItems);
288 QMapIterator<QSeries*,ChartItem*> i(m_chartItems);
285
289
286 int index=0;
290 int index=0;
287 while (i.hasNext()) {
291 while (i.hasNext()) {
288 i.next();
292 i.next();
289 m_chartTheme->decorate(i.value(),i.key(),index);
293 m_chartTheme->decorate(i.value(),i.key(),index);
290 index++;
294 index++;
291 }
295 }
292
296
293 QMapIterator<QChartAxis*,AxisItem*> j(m_axisItems);
297 QMapIterator<QChartAxis*,AxisItem*> j(m_axisItems);
294 while (j.hasNext()) {
298 while (j.hasNext()) {
295 j.next();
299 j.next();
296 m_chartTheme->decorate(j.key(),j.value());
300 m_chartTheme->decorate(j.key(),j.value());
297 }
301 }
298 }
302 }
299
303
300 QChart::ChartTheme ChartPresenter::chartTheme()
304 QChart::ChartTheme ChartPresenter::chartTheme()
301 {
305 {
302 return m_chartTheme->id();
306 return m_chartTheme->id();
303 }
307 }
304
308
305 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
309 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
306 {
310 {
307 if(m_options!=options) {
311 if(m_options!=options) {
308
312
309 m_options=options;
313 m_options=options;
310
314
311 //recreate elements
315 //recreate elements
312 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
316 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
313 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
317 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
314
318
315 foreach(QChartAxis* axis, axisList) {
319 foreach(QChartAxis* axis, axisList) {
316 handleAxisRemoved(axis);
320 handleAxisRemoved(axis);
317 handleAxisAdded(axis,m_dataset->domain(axis));
321 handleAxisAdded(axis,m_dataset->domain(axis));
318 }
322 }
319 foreach(QSeries* series, seriesList) {
323 foreach(QSeries* series, seriesList) {
320 handleSeriesRemoved(series);
324 handleSeriesRemoved(series);
321 handleSeriesAdded(series,m_dataset->domain(series));
325 handleSeriesAdded(series,m_dataset->domain(series));
322 }
326 }
323 }
327 }
324 }
328 }
325
329
326 void ChartPresenter::zoomIn()
330 void ChartPresenter::zoomIn()
327 {
331 {
328 QRectF rect = geometry();
332 QRectF rect = geometry();
329 rect.setWidth(rect.width()/2);
333 rect.setWidth(rect.width()/2);
330 rect.setHeight(rect.height()/2);
334 rect.setHeight(rect.height()/2);
331 rect.moveCenter(geometry().center());
335 rect.moveCenter(geometry().center());
332 zoomIn(rect);
336 zoomIn(rect);
333 }
337 }
334
338
335 void ChartPresenter::zoomIn(const QRectF& rect)
339 void ChartPresenter::zoomIn(const QRectF& rect)
336 {
340 {
337 QRectF r = rect.normalized();
341 QRectF r = rect.normalized();
338 r.translate(-m_marginSize, -m_marginSize);
342 r.translate(-m_marginSize, -m_marginSize);
339 m_dataset->zoomInDomain(r,geometry().size());
343 m_dataset->zoomInDomain(r,geometry().size());
340 m_zoomStack<<r;
344 m_zoomStack<<r;
341 m_zoomIndex++;
345 m_zoomIndex++;
342 }
346 }
343
347
344 void ChartPresenter::zoomOut()
348 void ChartPresenter::zoomOut()
345 {
349 {
346 if(m_zoomIndex==0) return;
350 if(m_zoomIndex==0) return;
347 m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
351 m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
348 m_zoomIndex--;
352 m_zoomIndex--;
349 m_zoomStack.resize(m_zoomIndex);
353 m_zoomStack.resize(m_zoomIndex);
350 }
354 }
351
355
352 void ChartPresenter::zoomReset()
356 void ChartPresenter::zoomReset()
353 {
357 {
354 m_zoomIndex=0;
358 m_zoomIndex=0;
355 m_zoomStack.resize(m_zoomIndex);
359 m_zoomStack.resize(m_zoomIndex);
356 }
360 }
357
361
358 QChart::AnimationOptions ChartPresenter::animationOptions() const
362 QChart::AnimationOptions ChartPresenter::animationOptions() const
359 {
363 {
360 return m_options;
364 return m_options;
361 }
365 }
362
366
363
367
364 #include "moc_chartpresenter_p.cpp"
368 #include "moc_chartpresenter_p.cpp"
365
369
366 QTCOMMERCIALCHART_END_NAMESPACE
370 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,33 +1,33
1 #ifndef QCHARTAXISCATEGORIES_H_
1 #ifndef QCHARTAXISCATEGORIES_H_
2 #define QCHARTAXISCATEGORIES_H_
2 #define QCHARTAXISCATEGORIES_H_
3 #include "qchartglobal.h"
3 #include "qchartglobal.h"
4
4
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6
6
7 class QChartAxisCategories : public QObject
7 class QTCOMMERCIALCHART_EXPORT QChartAxisCategories : public QObject
8 {
8 {
9 Q_OBJECT
9 Q_OBJECT
10 private:
10 private:
11 QChartAxisCategories();
11 QChartAxisCategories();
12 public:
12 public:
13 ~QChartAxisCategories();
13 ~QChartAxisCategories();
14
14
15 void insert(qreal value,QString label);
15 void insert(qreal value,QString label);
16 void remove(qreal value);
16 void remove(qreal value);
17 void clear();
17 void clear();
18 int count();
18 int count();
19
19
20 //internal signal
20 //internal signal
21 signals:
21 signals:
22 void updated();
22 void updated();
23
23
24 private:
24 private:
25 QMap<qreal,QString> m_map;
25 QMap<qreal,QString> m_map;
26
26
27 friend class QChartAxis;
27 friend class QChartAxis;
28 };
28 };
29
29
30
30
31 QTCOMMERCIALCHART_END_NAMESPACE
31 QTCOMMERCIALCHART_END_NAMESPACE
32
32
33 #endif /* QCHARTAXISCATEGORIES_H_ */
33 #endif /* QCHARTAXISCATEGORIES_H_ */
@@ -1,156 +1,156
1 #include "scatterpresenter_p.h"
1 #include "scatterpresenter_p.h"
2 #include "qscatterseries.h"
2 #include "qscatterseries.h"
3 #include "chartpresenter_p.h"
3 #include "chartpresenter_p.h"
4 #include <QPen>
4 #include <QPen>
5 #include <QPainter>
5 #include <QPainter>
6 #include <QGraphicsScene>
6 #include <QGraphicsScene>
7 #include <QGraphicsSceneMouseEvent>
7 #include <QGraphicsSceneMouseEvent>
8 #include <QGraphicsDropShadowEffect>
8 #include <QGraphicsDropShadowEffect>
9 #include <QDebug>
9 #include <QDebug>
10 #include <QTime>
10 #include <QTime>
11
11
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13
13
14 ScatterPresenter::ScatterPresenter(QScatterSeries *series, QGraphicsObject *parent) :
14 ScatterPresenter::ScatterPresenter(QScatterSeries *series, QGraphicsObject *parent) :
15 ChartItem(parent),
15 ChartItem(parent),
16 m_minX(0),
16 m_minX(0),
17 m_maxX(0),
17 m_maxX(0),
18 m_minY(0),
18 m_minY(0),
19 m_maxY(0),
19 m_maxY(0),
20 m_series(series),
20 m_series(series),
21 m_boundingRect()
21 m_clippingRect()
22 {
22 {
23 if (parent)
23 if (parent)
24 m_boundingRect = parent->boundingRect();
24 m_clippingRect = parent->boundingRect();
25
25
26 if (series) {
26 if (series) {
27 connect(series, SIGNAL(changed()), this, SLOT(handleModelChanged()));
27 connect(series, SIGNAL(changed()), this, SLOT(handleModelChanged()));
28 }
28 }
29
29
30 setZValue(ChartPresenter::ScatterSeriesZValue);
30 setZValue(ChartPresenter::ScatterSeriesZValue);
31
31
32 // TODO: how to draw a drop shadow?
32 // TODO: how to draw a drop shadow?
33 // QGraphicsDropShadowEffect *dropShadow = new QGraphicsDropShadowEffect();
33 // QGraphicsDropShadowEffect *dropShadow = new QGraphicsDropShadowEffect();
34 // dropShadow->setOffset(2.0);
34 // dropShadow->setOffset(2.0);
35 // dropShadow->setBlurRadius(2.0);
35 // dropShadow->setBlurRadius(2.0);
36 // setGraphicsEffect(dropShadow);
36 // setGraphicsEffect(dropShadow);
37 }
37 }
38
38
39 void ScatterPresenter::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
39 void ScatterPresenter::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
40 {
40 {
41 m_minX=minX;
41 m_minX = minX;
42 m_maxX=maxX;
42 m_maxX = maxX;
43 m_minY=minY;
43 m_minY = minY;
44 m_maxY=maxY;
44 m_maxY = maxY;
45 changeGeometry();
45 changeGeometry();
46 }
46 }
47
47
48 void ScatterPresenter::handleGeometryChanged(const QRectF& rect)
48 void ScatterPresenter::handleGeometryChanged(const QRectF& rect)
49 {
49 {
50 m_boundingRect = rect.translated(-rect.topLeft());
50 m_clippingRect = rect.translated(-rect.topLeft());
51 changeGeometry();
51 changeGeometry();
52 setPos(rect.topLeft());
52 setPos(rect.topLeft());
53 }
53 }
54
54
55 void ScatterPresenter::handleModelChanged()
55 void ScatterPresenter::handleModelChanged()
56 {
56 {
57 // TODO: more fine grained modelChanged signaling
57 // TODO: more fine grained modelChanged signaling
58 changeGeometry();
58 changeGeometry();
59 }
59 }
60
60
61 void ScatterPresenter::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
61 void ScatterPresenter::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
62 {
62 {
63 painter->save();
63 painter->save();
64 painter->setClipRect(m_boundingRect);
64 painter->setClipRect(m_clippingRect);
65
65
66 // TODO: how to draw a drop shadow?
66 // TODO: how to draw a drop shadow?
67 // Now using a custom implementation for drop shadow instead of QGraphicsDropShadowEffect.
67 // Now using a custom implementation for drop shadow instead of QGraphicsDropShadowEffect.
68 // It seems QGraphicsDropShadowEffect is quite heavy, at least on windows without open gl.
68 // It seems QGraphicsDropShadowEffect is quite heavy, at least on windows without open gl.
69 QPen dropShadowPen(QColor(0, 0, 0, 70));
69 QPen dropShadowPen(QColor(0, 0, 0, 70));
70 dropShadowPen.setWidth(3);
70 dropShadowPen.setWidth(3);
71 painter->setPen(dropShadowPen);
71 painter->setPen(dropShadowPen);
72 painter->setBrush(dropShadowPen.color());
72 painter->setBrush(dropShadowPen.color());
73 // painter->setRenderHint(QPainter::Antialiasing);
73 // painter->setRenderHint(QPainter::Antialiasing);
74 painter->drawPath(m_path.translated(2, 2));
74 painter->drawPath(m_path.translated(2, 2));
75
75
76 // Paint the shape
76 // Paint the shape
77 // The custom settings in series override those defined by the theme
77 // The custom settings in series override those defined by the theme
78 QPen pen = m_markerPen;
78 QPen pen = m_markerPen;
79 if (m_series->pen().color().isValid())
79 if (m_series->pen().color().isValid())
80 pen = m_series->pen();
80 pen = m_series->pen();
81 painter->setPen(pen);
81 painter->setPen(pen);
82 if (m_series->brush().color().isValid())
82 if (m_series->brush().color().isValid())
83 painter->setBrush(m_series->brush());
83 painter->setBrush(m_series->brush());
84 else
84 else
85 painter->setBrush(m_markerBrush);
85 painter->setBrush(m_markerBrush);
86
86
87 // If either pen or brush is opaque, we need to draw the polygons one-by-one
87 // If either pen or brush is opaque, we need to draw the polygons one-by-one
88 if (painter->pen().color().alpha() < 255 || painter->brush().color().alpha() < 255) {
88 if (painter->pen().color().alpha() < 255 || painter->brush().color().alpha() < 255) {
89 foreach (QPolygonF pol, m_path.toSubpathPolygons())
89 foreach (QPolygonF pol, m_path.toSubpathPolygons())
90 painter->drawPolygon(pol);
90 painter->drawPolygon(pol);
91 } else {
91 } else {
92 painter->drawPath(m_path);
92 painter->drawPath(m_path);
93 }
93 }
94
94
95 painter->restore();
95 painter->restore();
96 }
96 }
97
97
98 void ScatterPresenter::mousePressEvent(QGraphicsSceneMouseEvent *event)
98 void ScatterPresenter::mousePressEvent(QGraphicsSceneMouseEvent *event)
99 {
99 {
100 // Empty implementation to grab mouse release events for this item
100 // Empty implementation to grab mouse release events for this item
101 Q_UNUSED(event)
101 Q_UNUSED(event)
102 }
102 }
103
103
104 void ScatterPresenter::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
104 void ScatterPresenter::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
105 {
105 {
106 QPointF clickedPoint(
106 QPointF clickedPoint(
107 m_minX + (event->lastPos().x() / m_boundingRect.width()) * (m_maxX-m_minX),
107 m_minX + (event->lastPos().x() / m_clippingRect.width()) * (m_maxX-m_minX),
108 m_maxY - (event->lastPos().y() / m_boundingRect.height()) * (m_maxY-m_minY));
108 m_maxY - (event->lastPos().y() / m_clippingRect.height()) * (m_maxY-m_minY));
109 emit clicked(clickedPoint);
109 emit clicked(clickedPoint);
110 }
110 }
111
111
112 void ScatterPresenter::changeGeometry()
112 void ScatterPresenter::changeGeometry()
113 {
113 {
114 if (m_boundingRect.isValid()) {
114 if (m_clippingRect.isValid()) {
115 prepareGeometryChange();
115 prepareGeometryChange();
116 qreal scalex = m_boundingRect.width() / (m_maxX-m_minX);
116 qreal scalex = m_clippingRect.width() / (m_maxX - m_minX);
117 qreal scaley = m_boundingRect.height() / (m_maxY-m_minY);
117 qreal scaley = m_clippingRect.height() / (m_maxY - m_minY);
118
118
119 int shape = m_series->shape();
119 int shape = m_series->shape();
120 m_path = QPainterPath();
120 m_path = QPainterPath();
121 m_path.setFillRule(Qt::WindingFill);
121 m_path.setFillRule(Qt::WindingFill);
122 const qreal size = m_series->size();
122 const qreal size = m_series->size();
123
123
124 foreach (QPointF point, m_series->data()) {
124 foreach (QPointF point, m_series->data()) {
125 // Convert relative coordinates to absolute pixel coordinates that can be used for drawing
125 // Convert relative coordinates to absolute pixel coordinates that can be used for drawing
126 qreal x = point.x() * scalex - m_minX * scalex - size / 2;
126 qreal x = point.x() * scalex - m_minX * scalex - size / 2;
127 qreal y = m_boundingRect.height() - point.y() * scaley + m_minY * scaley - size / 2;
127 qreal y = m_clippingRect.height() - point.y() * scaley + m_minY * scaley - size / 2;
128
128
129 if (x < scene()->width() && y < scene()->height()) {
129 if (x < scene()->width() && y < scene()->height()) {
130 switch (shape) {
130 switch (shape) {
131 case QScatterSeries::MarkerShapeDefault:
131 case QScatterSeries::MarkerShapeDefault:
132 // Fallthrough, defaults to circle
132 // Fallthrough, defaults to circle
133 case QScatterSeries::MarkerShapeCircle:
133 case QScatterSeries::MarkerShapeCircle:
134 m_path.addEllipse(x, y, size, size);
134 m_path.addEllipse(x, y, size, size);
135 break;
135 break;
136 case QScatterSeries::MarkerShapeRectangle:
136 case QScatterSeries::MarkerShapeRectangle:
137 m_path.addRect(x, y, size, size);
137 m_path.addRect(x, y, size, size);
138 break;
138 break;
139 case QScatterSeries::MarkerShapeTiltedRectangle: {
139 case QScatterSeries::MarkerShapeTiltedRectangle: {
140 // TODO: tilt the rectangle
140 // TODO: tilt the rectangle
141 m_path.addRect(x, y, size, size);
141 m_path.addRect(x, y, size, size);
142 break;
142 break;
143 }
143 }
144 default:
144 default:
145 // TODO: implement the rest of the shapes
145 // TODO: implement the rest of the shapes
146 Q_ASSERT(false);
146 Q_ASSERT(false);
147 break;
147 break;
148 }
148 }
149 }
149 }
150 }
150 }
151 }
151 }
152 }
152 }
153
153
154 #include "moc_scatterpresenter_p.cpp"
154 #include "moc_scatterpresenter_p.cpp"
155
155
156 QTCOMMERCIALCHART_END_NAMESPACE
156 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,51 +1,51
1 #ifndef SCATTERPRESENTER_H
1 #ifndef SCATTERPRESENTER_H
2 #define SCATTERPRESENTER_H
2 #define SCATTERPRESENTER_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include "chartitem_p.h"
5 #include "chartitem_p.h"
6 #include <QObject>
6 #include <QObject>
7 #include <QPen>
7 #include <QPen>
8
8
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10
10
11 class QScatterSeries;
11 class QScatterSeries;
12
12
13 class ScatterPresenter : public QObject, public ChartItem
13 class ScatterPresenter : public QObject, public ChartItem
14 {
14 {
15 Q_OBJECT
15 Q_OBJECT
16 public:
16 public:
17 explicit ScatterPresenter(QScatterSeries *series, QGraphicsObject *parent = 0);
17 explicit ScatterPresenter(QScatterSeries *series, QGraphicsObject *parent = 0);
18
18
19 public: // from ChartItem
19 public: // from ChartItem
20 QRectF boundingRect() const { return m_path.controlPointRect(); }
20 QRectF boundingRect() const { return m_path.controlPointRect(); }
21 QPainterPath shape() const { return m_path; }
21 QPainterPath shape() const { return m_path; }
22 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
22 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
23 void mousePressEvent (QGraphicsSceneMouseEvent * event);
23 void mousePressEvent (QGraphicsSceneMouseEvent * event);
24 void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
24 void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
25
25
26 Q_SIGNALS:
26 Q_SIGNALS:
27 void clicked(QPointF coordinates);
27 void clicked(QPointF coordinates);
28
28
29 public Q_SLOTS:
29 public Q_SLOTS:
30 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
30 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
31 void handleGeometryChanged(const QRectF& rect);
31 void handleGeometryChanged(const QRectF& rect);
32 void handleModelChanged();
32 void handleModelChanged();
33
33
34 public:
34 public:
35 void changeGeometry();
35 void changeGeometry();
36
36
37 qreal m_minX;
37 qreal m_minX;
38 qreal m_maxX;
38 qreal m_maxX;
39 qreal m_minY;
39 qreal m_minY;
40 qreal m_maxY;
40 qreal m_maxY;
41 QScatterSeries *m_series;
41 QScatterSeries *m_series;
42 QRectF m_boundingRect;
42 QRectF m_clippingRect;
43 QPen m_markerPen;
43 QPen m_markerPen;
44 QBrush m_markerBrush;
44 QBrush m_markerBrush;
45 QPainterPath m_path;
45 QPainterPath m_path;
46
46
47 };
47 };
48
48
49 QTCOMMERCIALCHART_END_NAMESPACE
49 QTCOMMERCIALCHART_END_NAMESPACE
50
50
51 #endif // SCATTERPRESENTER_H
51 #endif // SCATTERPRESENTER_H
@@ -1,392 +1,342
1 #include "mainwidget.h"
1 #include "mainwidget.h"
2 #include "dataseriedialog.h"
2 #include "dataseriedialog.h"
3 #include "qpieseries.h"
3 #include "qpieseries.h"
4 #include "qscatterseries.h"
4 #include "qscatterseries.h"
5 #include <qlineseries.h>
5 #include <qlineseries.h>
6 #include <qbarset.h>
6 #include <qbarset.h>
7 #include <qbarseries.h>
7 #include <qbarseries.h>
8 #include <qstackedbarseries.h>
8 #include <qstackedbarseries.h>
9 #include <qpercentbarseries.h>
9 #include <qpercentbarseries.h>
10 #include <QPushButton>
10 #include <QPushButton>
11 #include <QComboBox>
11 #include <QComboBox>
12 #include <QSpinBox>
12 #include <QSpinBox>
13 #include <QCheckBox>
13 #include <QCheckBox>
14 #include <QGridLayout>
14 #include <QGridLayout>
15 #include <QHBoxLayout>
15 #include <QHBoxLayout>
16 #include <QLabel>
16 #include <QLabel>
17 #include <QSpacerItem>
17 #include <QSpacerItem>
18 #include <QMessageBox>
18 #include <QMessageBox>
19 #include <cmath>
19 #include <cmath>
20 #include <QDebug>
20 #include <QDebug>
21 #include <QStandardItemModel>
21 #include <QStandardItemModel>
22
22
23
23
24 QTCOMMERCIALCHART_USE_NAMESPACE
24 QTCOMMERCIALCHART_USE_NAMESPACE
25
25
26 MainWidget::MainWidget(QWidget *parent) :
26 MainWidget::MainWidget(QWidget *parent) :
27 QWidget(parent),
27 QWidget(parent),
28 m_addSerieDialog(0),
28 m_addSerieDialog(0),
29 m_chartView(0)
29 m_chartView(0)
30 {
30 {
31 m_chartView = new QChartView(this);
31 m_chartView = new QChartView(this);
32 m_chartView->setRubberBandPolicy(QChartView::HorizonalRubberBand);
32 m_chartView->setRubberBandPolicy(QChartView::HorizonalRubberBand);
33
33
34 // Grid layout for the controls for configuring the chart widget
34 // Grid layout for the controls for configuring the chart widget
35 QGridLayout *grid = new QGridLayout();
35 QGridLayout *grid = new QGridLayout();
36 QPushButton *addSeriesButton = new QPushButton("Add series");
36 QPushButton *addSeriesButton = new QPushButton("Add series");
37 connect(addSeriesButton, SIGNAL(clicked()), this, SLOT(addSeries()));
37 connect(addSeriesButton, SIGNAL(clicked()), this, SLOT(addSeries()));
38 grid->addWidget(addSeriesButton, 0, 1);
38 grid->addWidget(addSeriesButton, 0, 1);
39 initBackroundCombo(grid);
39 initBackroundCombo(grid);
40 initScaleControls(grid);
40 initScaleControls(grid);
41 initThemeCombo(grid);
41 initThemeCombo(grid);
42 initCheckboxes(grid);
42 initCheckboxes(grid);
43
43
44 // add row with empty label to make all the other rows static
44 // add row with empty label to make all the other rows static
45 grid->addWidget(new QLabel(""), grid->rowCount(), 0);
45 grid->addWidget(new QLabel(""), grid->rowCount(), 0);
46 grid->setRowStretch(grid->rowCount() - 1, 1);
46 grid->setRowStretch(grid->rowCount() - 1, 1);
47
47
48 // Another grid layout as a main layout
48 // Another grid layout as a main layout
49 QGridLayout *mainLayout = new QGridLayout();
49 QGridLayout *mainLayout = new QGridLayout();
50 mainLayout->addLayout(grid, 0, 0);
50 mainLayout->addLayout(grid, 0, 0);
51
51
52 // Init series type specific controls
53 initPieControls();
54 mainLayout->addLayout(m_pieLayout, 2, 0);
55 // Scatter series specific settings
56 // m_scatterLayout = new QGridLayout();
57 // m_scatterLayout->addWidget(new QLabel("scatter"), 0, 0);
58 // m_scatterLayout->setEnabled(false);
59 // mainLayout->addLayout(m_scatterLayout, 1, 0);
60
61 // Add layouts and the chart widget to the main layout
52 // Add layouts and the chart widget to the main layout
62 mainLayout->addWidget(m_chartView, 0, 1, 3, 1);
53 mainLayout->addWidget(m_chartView, 0, 1, 3, 1);
63 setLayout(mainLayout);
54 setLayout(mainLayout);
64 }
55 }
65
56
66 // Combo box for selecting the chart's background
57 // Combo box for selecting the chart's background
67 void MainWidget::initBackroundCombo(QGridLayout *grid)
58 void MainWidget::initBackroundCombo(QGridLayout *grid)
68 {
59 {
69 QComboBox *backgroundCombo = new QComboBox(this);
60 QComboBox *backgroundCombo = new QComboBox(this);
70 backgroundCombo->addItem("Color");
61 backgroundCombo->addItem("Color");
71 backgroundCombo->addItem("Gradient");
62 backgroundCombo->addItem("Gradient");
72 backgroundCombo->addItem("Image");
63 backgroundCombo->addItem("Image");
73 connect(backgroundCombo, SIGNAL(currentIndexChanged(int)),
64 connect(backgroundCombo, SIGNAL(currentIndexChanged(int)),
74 this, SLOT(backgroundChanged(int)));
65 this, SLOT(backgroundChanged(int)));
75
66
76 grid->addWidget(new QLabel("Background:"), grid->rowCount(), 0);
67 grid->addWidget(new QLabel("Background:"), grid->rowCount(), 0);
77 grid->addWidget(backgroundCombo, grid->rowCount() - 1, 1);
68 grid->addWidget(backgroundCombo, grid->rowCount() - 1, 1);
78 }
69 }
79
70
80 // Scale related controls (auto-scale vs. manual min-max values)
71 // Scale related controls (auto-scale vs. manual min-max values)
81 void MainWidget::initScaleControls(QGridLayout *grid)
72 void MainWidget::initScaleControls(QGridLayout *grid)
82 {
73 {
83 m_autoScaleCheck = new QCheckBox("Automatic scaling");
74 m_autoScaleCheck = new QCheckBox("Automatic scaling");
84 connect(m_autoScaleCheck, SIGNAL(stateChanged(int)), this, SLOT(autoScaleChanged(int)));
75 connect(m_autoScaleCheck, SIGNAL(stateChanged(int)), this, SLOT(autoScaleChanged(int)));
85 // Allow setting also non-sense values (like -2147483648 and 2147483647)
76 // Allow setting also non-sense values (like -2147483648 and 2147483647)
86 m_xMinSpin = new QSpinBox();
77 m_xMinSpin = new QSpinBox();
87 m_xMinSpin->setMinimum(INT_MIN);
78 m_xMinSpin->setMinimum(INT_MIN);
88 m_xMinSpin->setMaximum(INT_MAX);
79 m_xMinSpin->setMaximum(INT_MAX);
89 m_xMinSpin->setValue(0);
80 m_xMinSpin->setValue(0);
90 connect(m_xMinSpin, SIGNAL(valueChanged(int)), this, SLOT(xMinChanged(int)));
81 connect(m_xMinSpin, SIGNAL(valueChanged(int)), this, SLOT(xMinChanged(int)));
91 m_xMaxSpin = new QSpinBox();
82 m_xMaxSpin = new QSpinBox();
92 m_xMaxSpin->setMinimum(INT_MIN);
83 m_xMaxSpin->setMinimum(INT_MIN);
93 m_xMaxSpin->setMaximum(INT_MAX);
84 m_xMaxSpin->setMaximum(INT_MAX);
94 m_xMaxSpin->setValue(10);
85 m_xMaxSpin->setValue(10);
95 connect(m_xMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(xMaxChanged(int)));
86 connect(m_xMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(xMaxChanged(int)));
96 m_yMinSpin = new QSpinBox();
87 m_yMinSpin = new QSpinBox();
97 m_yMinSpin->setMinimum(INT_MIN);
88 m_yMinSpin->setMinimum(INT_MIN);
98 m_yMinSpin->setMaximum(INT_MAX);
89 m_yMinSpin->setMaximum(INT_MAX);
99 m_yMinSpin->setValue(0);
90 m_yMinSpin->setValue(0);
100 connect(m_yMinSpin, SIGNAL(valueChanged(int)), this, SLOT(yMinChanged(int)));
91 connect(m_yMinSpin, SIGNAL(valueChanged(int)), this, SLOT(yMinChanged(int)));
101 m_yMaxSpin = new QSpinBox();
92 m_yMaxSpin = new QSpinBox();
102 m_yMaxSpin->setMinimum(INT_MIN);
93 m_yMaxSpin->setMinimum(INT_MIN);
103 m_yMaxSpin->setMaximum(INT_MAX);
94 m_yMaxSpin->setMaximum(INT_MAX);
104 m_yMaxSpin->setValue(10);
95 m_yMaxSpin->setValue(10);
105 connect(m_yMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(yMaxChanged(int)));
96 connect(m_yMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(yMaxChanged(int)));
106
97
107 grid->addWidget(m_autoScaleCheck, grid->rowCount(), 0);
98 grid->addWidget(m_autoScaleCheck, grid->rowCount(), 0);
108 grid->addWidget(new QLabel("x min:"), grid->rowCount(), 0);
99 grid->addWidget(new QLabel("x min:"), grid->rowCount(), 0);
109 grid->addWidget(m_xMinSpin, grid->rowCount() - 1, 1);
100 grid->addWidget(m_xMinSpin, grid->rowCount() - 1, 1);
110 grid->addWidget(new QLabel("x max:"), grid->rowCount(), 0);
101 grid->addWidget(new QLabel("x max:"), grid->rowCount(), 0);
111 grid->addWidget(m_xMaxSpin, grid->rowCount() - 1, 1);
102 grid->addWidget(m_xMaxSpin, grid->rowCount() - 1, 1);
112 grid->addWidget(new QLabel("y min:"), grid->rowCount(), 0);
103 grid->addWidget(new QLabel("y min:"), grid->rowCount(), 0);
113 grid->addWidget(m_yMinSpin, grid->rowCount() - 1, 1);
104 grid->addWidget(m_yMinSpin, grid->rowCount() - 1, 1);
114 grid->addWidget(new QLabel("y max:"), grid->rowCount(), 0);
105 grid->addWidget(new QLabel("y max:"), grid->rowCount(), 0);
115 grid->addWidget(m_yMaxSpin, grid->rowCount() - 1, 1);
106 grid->addWidget(m_yMaxSpin, grid->rowCount() - 1, 1);
116
107
117 m_autoScaleCheck->setChecked(true);
108 m_autoScaleCheck->setChecked(true);
118 }
109 }
119
110
120 // Combo box for selecting theme
111 // Combo box for selecting theme
121 void MainWidget::initThemeCombo(QGridLayout *grid)
112 void MainWidget::initThemeCombo(QGridLayout *grid)
122 {
113 {
123 QComboBox *chartTheme = new QComboBox();
114 QComboBox *chartTheme = new QComboBox();
124 chartTheme->addItem("Default");
115 chartTheme->addItem("Default");
125 chartTheme->addItem("Vanilla");
116 chartTheme->addItem("Vanilla");
126 chartTheme->addItem("Icy");
117 chartTheme->addItem("Icy");
127 chartTheme->addItem("Grayscale");
118 chartTheme->addItem("Grayscale");
128 chartTheme->addItem("Scientific");
119 chartTheme->addItem("Scientific");
129 chartTheme->addItem("Unnamed1");
120 chartTheme->addItem("Unnamed1");
130 connect(chartTheme, SIGNAL(currentIndexChanged(int)),
121 connect(chartTheme, SIGNAL(currentIndexChanged(int)),
131 this, SLOT(changeChartTheme(int)));
122 this, SLOT(changeChartTheme(int)));
132 grid->addWidget(new QLabel("Chart theme:"), 8, 0);
123 grid->addWidget(new QLabel("Chart theme:"), 8, 0);
133 grid->addWidget(chartTheme, 8, 1);
124 grid->addWidget(chartTheme, 8, 1);
134 }
125 }
135
126
136 // Different check boxes for customizing chart
127 // Different check boxes for customizing chart
137 void MainWidget::initCheckboxes(QGridLayout *grid)
128 void MainWidget::initCheckboxes(QGridLayout *grid)
138 {
129 {
139 // TODO: setZoomEnabled slot has been removed from QChartView -> Re-implement zoom on/off
130 // TODO: setZoomEnabled slot has been removed from QChartView -> Re-implement zoom on/off
140 QCheckBox *zoomCheckBox = new QCheckBox("Drag'n drop Zoom");
131 QCheckBox *zoomCheckBox = new QCheckBox("Drag'n drop Zoom");
141 connect(zoomCheckBox, SIGNAL(toggled(bool)), m_chartView, SLOT(setZoomEnabled(bool)));
132 connect(zoomCheckBox, SIGNAL(toggled(bool)), m_chartView, SLOT(setZoomEnabled(bool)));
142 zoomCheckBox->setChecked(true);
133 zoomCheckBox->setChecked(true);
143 grid->addWidget(zoomCheckBox, grid->rowCount(), 0);
134 grid->addWidget(zoomCheckBox, grid->rowCount(), 0);
144
135
145 QCheckBox *aliasCheckBox = new QCheckBox("Anti-alias");
136 QCheckBox *aliasCheckBox = new QCheckBox("Anti-alias");
146 connect(aliasCheckBox, SIGNAL(toggled(bool)), this, SLOT(antiAliasToggled(bool)));
137 connect(aliasCheckBox, SIGNAL(toggled(bool)), this, SLOT(antiAliasToggled(bool)));
147 aliasCheckBox->setChecked(false);
138 aliasCheckBox->setChecked(false);
148 grid->addWidget(aliasCheckBox, grid->rowCount(), 0);
139 grid->addWidget(aliasCheckBox, grid->rowCount(), 0);
149 }
140 }
150
141
151 void MainWidget::antiAliasToggled(bool enabled)
142 void MainWidget::antiAliasToggled(bool enabled)
152 {
143 {
153 m_chartView->setRenderHint(QPainter::Antialiasing, enabled);
144 m_chartView->setRenderHint(QPainter::Antialiasing, enabled);
154 }
145 }
155
146
156 void MainWidget::initPieControls()
157 {
158 // Pie series specific settings
159 // Pie size factory
160 QDoubleSpinBox *pieSizeSpin = new QDoubleSpinBox();
161 pieSizeSpin->setMinimum(LONG_MIN);
162 pieSizeSpin->setMaximum(LONG_MAX);
163 pieSizeSpin->setValue(1.0);
164 pieSizeSpin->setSingleStep(0.1);
165 connect(pieSizeSpin, SIGNAL(valueChanged(double)), this, SLOT(setPieSizeFactor(double)));
166 // Pie position
167 QComboBox *piePosCombo = new QComboBox(this);
168 piePosCombo->addItem("Maximized");
169 piePosCombo->addItem("Top left");
170 piePosCombo->addItem("Top right");
171 piePosCombo->addItem("Bottom left");
172 piePosCombo->addItem("Bottom right");
173 connect(piePosCombo, SIGNAL(currentIndexChanged(int)),
174 this, SLOT(setPiePosition(int)));
175 m_pieLayout = new QGridLayout();
176 m_pieLayout->setEnabled(false);
177 m_pieLayout->addWidget(new QLabel("Pie size factor"), 0, 0);
178 m_pieLayout->addWidget(pieSizeSpin, 0, 1);
179 m_pieLayout->addWidget(new QLabel("Pie position"), 1, 0);
180 m_pieLayout->addWidget(piePosCombo, 1, 1);
181 }
182
183 void MainWidget::addSeries()
147 void MainWidget::addSeries()
184 {
148 {
185 if (!m_addSerieDialog) {
149 if (!m_addSerieDialog) {
186 m_addSerieDialog = new DataSerieDialog(this);
150 m_addSerieDialog = new DataSerieDialog(this);
187 connect(m_addSerieDialog, SIGNAL(accepted(QString, int, int, QString, bool)),
151 connect(m_addSerieDialog, SIGNAL(accepted(QString, int, int, QString, bool)),
188 this, SLOT(addSeries(QString, int, int, QString, bool)));
152 this, SLOT(addSeries(QString, int, int, QString, bool)));
189 }
153 }
190 m_addSerieDialog->exec();
154 m_addSerieDialog->exec();
191 }
155 }
192
156
193 QList<RealList> MainWidget::generateTestData(int columnCount, int rowCount, QString dataCharacteristics)
157 QList<RealList> MainWidget::generateTestData(int columnCount, int rowCount, QString dataCharacteristics)
194 {
158 {
195 // TODO: dataCharacteristics
159 // TODO: dataCharacteristics
196 QList<RealList> testData;
160 QList<RealList> testData;
197 for (int j(0); j < columnCount; j++) {
161 for (int j(0); j < columnCount; j++) {
198 QList <qreal> newColumn;
162 QList <qreal> newColumn;
199 for (int i(0); i < rowCount; i++) {
163 for (int i(0); i < rowCount; i++) {
200 if (dataCharacteristics == "Sin") {
164 if (dataCharacteristics == "Sin") {
201 newColumn.append(abs(sin(3.14159265358979 / 50 * i) * 100));
165 newColumn.append(abs(sin(3.14159265358979 / 50 * i) * 100));
202 } else if (dataCharacteristics == "Sin + random") {
166 } else if (dataCharacteristics == "Sin + random") {
203 newColumn.append(abs(sin(3.14159265358979 / 50 * i) * 100) + (rand() % 5));
167 newColumn.append(abs(sin(3.14159265358979 / 50 * i) * 100) + (rand() % 5));
204 } else if (dataCharacteristics == "Random") {
168 } else if (dataCharacteristics == "Random") {
205 newColumn.append(rand() % 5);
169 newColumn.append(rand() % 5);
206 } else if (dataCharacteristics == "Linear") {
170 } else if (dataCharacteristics == "Linear") {
207 //newColumn.append(i * (j + 1.0));
171 //newColumn.append(i * (j + 1.0));
208 // TODO: temporary hack to make pie work; prevent zero values:
172 // TODO: temporary hack to make pie work; prevent zero values:
209 newColumn.append(i * (j + 1.0) + 0.1);
173 newColumn.append(i * (j + 1.0) + 0.1);
210 } else { // "constant"
174 } else { // "constant"
211 newColumn.append((j + 1.0));
175 newColumn.append((j + 1.0));
212 }
176 }
213 }
177 }
214 testData.append(newColumn);
178 testData.append(newColumn);
215 }
179 }
216 return testData;
180 return testData;
217 }
181 }
218
182
219 QStringList MainWidget::generateLabels(int count)
183 QStringList MainWidget::generateLabels(int count)
220 {
184 {
221 QStringList result;
185 QStringList result;
222 for (int i(0); i < count; i++)
186 for (int i(0); i < count; i++)
223 result.append("label" + QString::number(i));
187 result.append("label" + QString::number(i));
224 return result;
188 return result;
225 }
189 }
226
190
227 void MainWidget::addSeries(QString seriesName, int columnCount, int rowCount, QString dataCharacteristics, bool labelsEnabled)
191 void MainWidget::addSeries(QString seriesName, int columnCount, int rowCount, QString dataCharacteristics, bool labelsEnabled)
228 {
192 {
229 qDebug() << "addSeries: " << seriesName
193 qDebug() << "addSeries: " << seriesName
230 << " columnCount: " << columnCount
194 << " columnCount: " << columnCount
231 << " rowCount: " << rowCount
195 << " rowCount: " << rowCount
232 << " dataCharacteristics: " << dataCharacteristics
196 << " dataCharacteristics: " << dataCharacteristics
233 << " labels enabled: " << labelsEnabled;
197 << " labels enabled: " << labelsEnabled;
234 m_defaultSeriesName = seriesName;
198 m_defaultSeriesName = seriesName;
235
199
236 QList<RealList> data = generateTestData(columnCount, rowCount, dataCharacteristics);
200 QList<RealList> data = generateTestData(columnCount, rowCount, dataCharacteristics);
237
201
238 // Line series and scatter series use similar data
202 // Line series and scatter series use similar data
239 if (seriesName.contains("line", Qt::CaseInsensitive)) {
203 if (seriesName.contains("line", Qt::CaseInsensitive)) {
240 for (int j(0); j < data.count(); j ++) {
204 for (int j(0); j < data.count(); j ++) {
241 QList<qreal> column = data.at(j);
205 QList<qreal> column = data.at(j);
242 QLineSeries *series = new QLineSeries();
206 QLineSeries *series = new QLineSeries();
243 for (int i(0); i < column.count(); i++) {
207 for (int i(0); i < column.count(); i++) {
244 series->add(i, column.at(i));
208 series->add(i, column.at(i));
245 }
209 }
246 m_chartView->addSeries(series);
210 m_chartView->addSeries(series);
247 setCurrentSeries(series);
211 setCurrentSeries(series);
248 }
212 }
249 } else if (seriesName.contains("scatter", Qt::CaseInsensitive)) {
213 } else if (seriesName.contains("scatter", Qt::CaseInsensitive)) {
250 for (int j(0); j < data.count(); j++) {
214 for (int j(0); j < data.count(); j++) {
251 QList<qreal> column = data.at(j);
215 QList<qreal> column = data.at(j);
252 QScatterSeries *series = new QScatterSeries();
216 QScatterSeries *series = new QScatterSeries();
253 for (int i(0); i < column.count(); i++) {
217 for (int i(0); i < column.count(); i++) {
254 (*series) << QPointF(i, column.at(i));
218 (*series) << QPointF(i, column.at(i));
255 }
219 }
256 m_chartView->addSeries(series);
220 m_chartView->addSeries(series);
257 setCurrentSeries(series);
221 setCurrentSeries(series);
258 }
222 }
259 } else if (seriesName.contains("pie", Qt::CaseInsensitive)) {
223 } else if (seriesName.contains("pie", Qt::CaseInsensitive)) {
260 QStringList labels = generateLabels(rowCount);
224 QStringList labels = generateLabels(rowCount);
261 for (int j(0); j < data.count(); j++) {
225 for (int j(0); j < data.count(); j++) {
262 QPieSeries *series = new QPieSeries();
226 QPieSeries *series = new QPieSeries();
263 QList<qreal> column = data.at(j);
227 QList<qreal> column = data.at(j);
264 for (int i(0); i < column.count(); i++) {
228 for (int i(0); i < column.count(); i++) {
265 series->add(column.at(i), labels.at(i));
229 series->add(column.at(i), labels.at(i));
266 }
230 }
267 m_chartView->addSeries(series);
231 m_chartView->addSeries(series);
268 setCurrentSeries(series);
232 setCurrentSeries(series);
269 }
233 }
270 } else if (seriesName == "Bar"
234 } else if (seriesName == "Bar"
271 || seriesName == "Stacked bar"
235 || seriesName == "Stacked bar"
272 || seriesName == "Percent bar") {
236 || seriesName == "Percent bar") {
273 QStringList category;
237 QStringList category;
274 QStringList labels = generateLabels(rowCount);
238 QStringList labels = generateLabels(rowCount);
275 foreach(QString label, labels)
239 foreach(QString label, labels)
276 category << label;
240 category << label;
277 QBarSeries* series = 0;
241 QBarSeries* series = 0;
278 if (seriesName == "Bar")
242 if (seriesName == "Bar")
279 series = new QBarSeries(category, this);
243 series = new QBarSeries(category, this);
280 else if (seriesName == "Stacked bar")
244 else if (seriesName == "Stacked bar")
281 series = new QStackedBarSeries(category, this);
245 series = new QStackedBarSeries(category, this);
282 else
246 else
283 series = new QPercentBarSeries(category, this);
247 series = new QPercentBarSeries(category, this);
284
248
285 for (int j(0); j < data.count(); j++) {
249 for (int j(0); j < data.count(); j++) {
286 QList<qreal> column = data.at(j);
250 QList<qreal> column = data.at(j);
287 QBarSet *set = new QBarSet("set" + QString::number(j));
251 QBarSet *set = new QBarSet("set" + QString::number(j));
288 for (int i(0); i < column.count(); i++) {
252 for (int i(0); i < column.count(); i++) {
289 *set << column.at(i);
253 *set << column.at(i);
290 }
254 }
291 series->addBarSet(set);
255 series->addBarSet(set);
292 }
256 }
293 // TODO: new implementation of setFloatingValuesEnabled with signals
257 // TODO: new implementation of setFloatingValuesEnabled with signals
294 //series->setFloatingValuesEnabled(true);
258 //series->setFloatingValuesEnabled(true);
295 series->setToolTipEnabled(true);
259 series->setToolTipEnabled(true);
296 series->setSeparatorsEnabled(false);
260 series->setSeparatorsEnabled(false);
297 m_chartView->addSeries(series);
261 m_chartView->addSeries(series);
298 setCurrentSeries(series);
262 setCurrentSeries(series);
299 }
263 }
300
264
301 // TODO: spline and area
265 // TODO: spline and area
302 }
266 }
303
267
304 void MainWidget::setCurrentSeries(QSeries *series)
268 void MainWidget::setCurrentSeries(QSeries *series)
305 {
269 {
306 if (series) {
270 if (series) {
307 m_currentSeries = series;
271 m_currentSeries = series;
308 switch (m_currentSeries->type()) {
272 switch (m_currentSeries->type()) {
309 case QSeries::SeriesTypeLine:
273 case QSeries::SeriesTypeLine:
310 break;
274 break;
311 case QSeries::SeriesTypeScatter:
275 case QSeries::SeriesTypeScatter:
312 break;
276 break;
313 case QSeries::SeriesTypePie:
277 case QSeries::SeriesTypePie:
314 break;
278 break;
315 case QSeries::SeriesTypeBar:
279 case QSeries::SeriesTypeBar:
316 qDebug() << "setCurrentSeries (bar)";
280 qDebug() << "setCurrentSeries (bar)";
317 break;
281 break;
318 case QSeries::SeriesTypeStackedBar:
282 case QSeries::SeriesTypeStackedBar:
319 qDebug() << "setCurrentSeries (Stackedbar)";
283 qDebug() << "setCurrentSeries (Stackedbar)";
320 break;
284 break;
321 case QSeries::SeriesTypePercentBar:
285 case QSeries::SeriesTypePercentBar:
322 qDebug() << "setCurrentSeries (Percentbar)";
286 qDebug() << "setCurrentSeries (Percentbar)";
323 break;
287 break;
324 default:
288 default:
325 Q_ASSERT(false);
289 Q_ASSERT(false);
326 break;
290 break;
327 }
291 }
328 }
292 }
329 }
293 }
330
294
331 void MainWidget::backgroundChanged(int itemIndex)
295 void MainWidget::backgroundChanged(int itemIndex)
332 {
296 {
333 qDebug() << "backgroundChanged: " << itemIndex;
297 qDebug() << "backgroundChanged: " << itemIndex;
334 }
298 }
335
299
336 void MainWidget::autoScaleChanged(int value)
300 void MainWidget::autoScaleChanged(int value)
337 {
301 {
338 if (value) {
302 if (value) {
339 // TODO: enable auto scaling
303 // TODO: enable auto scaling
340 } else {
304 } else {
341 // TODO: set scaling manually (and disable auto scaling)
305 // TODO: set scaling manually (and disable auto scaling)
342 }
306 }
343
307
344 m_xMinSpin->setEnabled(!value);
308 m_xMinSpin->setEnabled(!value);
345 m_xMaxSpin->setEnabled(!value);
309 m_xMaxSpin->setEnabled(!value);
346 m_yMinSpin->setEnabled(!value);
310 m_yMinSpin->setEnabled(!value);
347 m_yMaxSpin->setEnabled(!value);
311 m_yMaxSpin->setEnabled(!value);
348 }
312 }
349
313
350 void MainWidget::xMinChanged(int value)
314 void MainWidget::xMinChanged(int value)
351 {
315 {
352 qDebug() << "xMinChanged: " << value;
316 qDebug() << "xMinChanged: " << value;
353 }
317 }
354
318
355 void MainWidget::xMaxChanged(int value)
319 void MainWidget::xMaxChanged(int value)
356 {
320 {
357 qDebug() << "xMaxChanged: " << value;
321 qDebug() << "xMaxChanged: " << value;
358 }
322 }
359
323
360 void MainWidget::yMinChanged(int value)
324 void MainWidget::yMinChanged(int value)
361 {
325 {
362 qDebug() << "yMinChanged: " << value;
326 qDebug() << "yMinChanged: " << value;
363 }
327 }
364
328
365 void MainWidget::yMaxChanged(int value)
329 void MainWidget::yMaxChanged(int value)
366 {
330 {
367 qDebug() << "yMaxChanged: " << value;
331 qDebug() << "yMaxChanged: " << value;
368 }
332 }
369
333
370 void MainWidget::changeChartTheme(int themeIndex)
334 void MainWidget::changeChartTheme(int themeIndex)
371 {
335 {
372 qDebug() << "changeChartTheme: " << themeIndex;
336 qDebug() << "changeChartTheme: " << themeIndex;
373 m_chartView->setChartTheme((QChart::ChartTheme) themeIndex);
337 m_chartView->setChartTheme((QChart::ChartTheme) themeIndex);
374 //TODO: remove this hack. This is just to make it so that theme change is seen immediately.
338 //TODO: remove this hack. This is just to make it so that theme change is seen immediately.
375 QSize s = size();
339 QSize s = size();
376 s.setWidth(s.width()+1);
340 s.setWidth(s.width()+1);
377 resize(s);
341 resize(s);
378 }
342 }
379
380 void MainWidget::setPieSizeFactor(double size)
381 {
382 QPieSeries *pie = qobject_cast<QPieSeries *>(m_currentSeries);
383 if (pie)
384 pie->setSizeFactor(qreal(size));
385 }
386
387 void MainWidget::setPiePosition(int position)
388 {
389 QPieSeries *pie = qobject_cast<QPieSeries *>(m_currentSeries);
390 if (pie)
391 pie->setPosition((QPieSeries::PiePosition) position);
392 }
@@ -1,63 +1,59
1 #ifndef MAINWIDGET_H
1 #ifndef MAINWIDGET_H
2 #define MAINWIDGET_H
2 #define MAINWIDGET_H
3
3
4 #include <qchartglobal.h>
4 #include <qchartglobal.h>
5 #include <qchartview.h>
5 #include <qchartview.h>
6 #include <QWidget>
6 #include <QWidget>
7
7
8 class QSpinBox;
8 class QSpinBox;
9 class QCheckBox;
9 class QCheckBox;
10 class QGridLayout;
10 class QGridLayout;
11
11
12 QTCOMMERCIALCHART_USE_NAMESPACE
12 QTCOMMERCIALCHART_USE_NAMESPACE
13
13
14 #define RealList QList<qreal>
14 #define RealList QList<qreal>
15 class DataSerieDialog;
15 class DataSerieDialog;
16
16
17 class MainWidget : public QWidget
17 class MainWidget : public QWidget
18 {
18 {
19 Q_OBJECT
19 Q_OBJECT
20 public:
20 public:
21 explicit MainWidget(QWidget *parent = 0);
21 explicit MainWidget(QWidget *parent = 0);
22
22
23 signals:
23 signals:
24
24
25 private:
25 private:
26 void initBackroundCombo(QGridLayout *grid);
26 void initBackroundCombo(QGridLayout *grid);
27 void initScaleControls(QGridLayout *grid);
27 void initScaleControls(QGridLayout *grid);
28 void initThemeCombo(QGridLayout *grid);
28 void initThemeCombo(QGridLayout *grid);
29 void initCheckboxes(QGridLayout *grid);
29 void initCheckboxes(QGridLayout *grid);
30 void initPieControls();
31
30
32 private slots:
31 private slots:
33 void addSeries();
32 void addSeries();
34 void addSeries(QString series, int columnCount, int rowCount, QString dataCharacteristics, bool labelsEnabled);
33 void addSeries(QString series, int columnCount, int rowCount, QString dataCharacteristics, bool labelsEnabled);
35 void backgroundChanged(int itemIndex);
34 void backgroundChanged(int itemIndex);
36 void autoScaleChanged(int value);
35 void autoScaleChanged(int value);
37 void xMinChanged(int value);
36 void xMinChanged(int value);
38 void xMaxChanged(int value);
37 void xMaxChanged(int value);
39 void yMinChanged(int value);
38 void yMinChanged(int value);
40 void yMaxChanged(int value);
39 void yMaxChanged(int value);
41 void antiAliasToggled(bool enabled);
40 void antiAliasToggled(bool enabled);
42 void setCurrentSeries(QSeries *series);
41 void setCurrentSeries(QSeries *series);
43 void changeChartTheme(int themeIndex);
42 void changeChartTheme(int themeIndex);
44 void setPieSizeFactor(double margin);
45 void setPiePosition(int position);
46 QList<RealList> generateTestData(int columnCount, int rowCount, QString dataCharacteristics);
43 QList<RealList> generateTestData(int columnCount, int rowCount, QString dataCharacteristics);
47 QStringList generateLabels(int count);
44 QStringList generateLabels(int count);
48
45
49 private:
46 private:
50 DataSerieDialog *m_addSerieDialog;
47 DataSerieDialog *m_addSerieDialog;
51 QChartView *m_chartView;
48 QChartView *m_chartView;
52 QCheckBox *m_autoScaleCheck;
49 QCheckBox *m_autoScaleCheck;
53 QSpinBox *m_xMinSpin;
50 QSpinBox *m_xMinSpin;
54 QSpinBox *m_xMaxSpin;
51 QSpinBox *m_xMaxSpin;
55 QSpinBox *m_yMinSpin;
52 QSpinBox *m_yMinSpin;
56 QSpinBox *m_yMaxSpin;
53 QSpinBox *m_yMaxSpin;
57 QString m_defaultSeriesName;
54 QString m_defaultSeriesName;
58 QSeries *m_currentSeries;
55 QSeries *m_currentSeries;
59 QGridLayout *m_scatterLayout;
56 QGridLayout *m_scatterLayout;
60 QGridLayout *m_pieLayout;
61 };
57 };
62
58
63 #endif // MAINWIDGET_H
59 #endif // MAINWIDGET_H
General Comments 0
You need to be logged in to leave comments. Login now