##// END OF EJS Templates
better use of gradients in barcharts
sauimone -
r512:db1a02a52a65
parent child
Show More
@@ -1,82 +1,83
1 #include <QApplication>
1 #include <QApplication>
2 #include <QMainWindow>
2 #include <QMainWindow>
3 #include <QStandardItemModel>
3 #include <QStandardItemModel>
4 #include <qpercentbarseries.h>
4 #include <qpercentbarseries.h>
5 #include <qchartview.h>
5 #include <qchartview.h>
6 #include <qbarset.h>
6 #include <qbarset.h>
7 #include <qchartaxis.h>
7 #include <qchartaxis.h>
8 #include <QStringList>
8 #include <QStringList>
9
9
10 QTCOMMERCIALCHART_USE_NAMESPACE
10 QTCOMMERCIALCHART_USE_NAMESPACE
11
11
12 int main(int argc, char *argv[])
12 int main(int argc, char *argv[])
13 {
13 {
14 QApplication a(argc, argv);
14 QApplication a(argc, argv);
15 QMainWindow window;
15 QMainWindow window;
16
16
17 //! [1]
17 //! [1]
18 // Define categories
18 // Define categories
19 QStringList categories;
19 QStringList categories;
20 categories << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "Jun";
20 categories << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "Jun";
21 //! [1]
21 //! [1]
22
22
23 //! [2]
23 //! [2]
24 // Create some test sets for chat
24 // Create some test sets for chat
25 QBarSet *set0 = new QBarSet("Bub");
25 QBarSet *set0 = new QBarSet("Bub");
26 QBarSet *set1 = new QBarSet("Bob");
26 QBarSet *set1 = new QBarSet("Bob");
27 QBarSet *set2 = new QBarSet("Guybrush");
27 QBarSet *set2 = new QBarSet("Guybrush");
28 QBarSet *set3 = new QBarSet("Larry");
28 QBarSet *set3 = new QBarSet("Larry");
29 QBarSet *set4 = new QBarSet("Zak");
29 QBarSet *set4 = new QBarSet("Zak");
30
30
31 *set0 << 1 << 2 << 3 << 4 << 5 << 6;
31 *set0 << 1 << 2 << 3 << 4 << 5 << 6;
32 *set1 << 5 << 0 << 0 << 4 << 0 << 7;
32 *set1 << 5 << 0 << 0 << 4 << 0 << 7;
33 *set2 << 3 << 5 << 8 << 13 << 8 << 5;
33 *set2 << 3 << 5 << 8 << 13 << 8 << 5;
34 *set3 << 5 << 6 << 7 << 3 << 4 << 5;
34 *set3 << 5 << 6 << 7 << 3 << 4 << 5;
35 *set4 << 9 << 7 << 5 << 3 << 1 << 2;
35 *set4 << 9 << 7 << 5 << 3 << 1 << 2;
36 //! [2]
36 //! [2]
37
37
38 //! [3]
38 //! [3]
39 // Create series and add sets to it
39 // Create series and add sets to it
40 QPercentBarSeries* series = new QPercentBarSeries(categories);
40 QPercentBarSeries* series = new QPercentBarSeries(categories);
41
41
42 series->addBarSet(set0);
42 series->addBarSet(set0);
43 series->addBarSet(set1);
43 series->addBarSet(set1);
44 series->addBarSet(set2);
44 series->addBarSet(set2);
45 series->addBarSet(set3);
45 series->addBarSet(set3);
46 series->addBarSet(set4);
46 series->addBarSet(set4);
47 //! [3]
47 //! [3]
48
48
49 //! [4]
49 //! [4]
50 // Enable tooltip
50 // Enable tooltip
51 series->setToolTipEnabled();
51 series->setToolTipEnabled();
52
52
53 // Connect clicked signal of set to toggle floating values of set.
53 // Connect clicked signal of set to toggle floating values of set.
54 // Note that we leave QBarset "Zak" unconnected here, so clicking on it doesn't toggle values.
54 // Note that we leave QBarset "Zak" unconnected here, so clicking on it doesn't toggle values.
55 QObject::connect(set0,SIGNAL(clicked(QString)),set0,SIGNAL(toggleFloatingValues()));
55 QObject::connect(set0,SIGNAL(clicked(QString)),set0,SIGNAL(toggleFloatingValues()));
56 QObject::connect(set1,SIGNAL(clicked(QString)),set1,SIGNAL(toggleFloatingValues()));
56 QObject::connect(set1,SIGNAL(clicked(QString)),set1,SIGNAL(toggleFloatingValues()));
57 QObject::connect(set2,SIGNAL(clicked(QString)),set2,SIGNAL(toggleFloatingValues()));
57 QObject::connect(set2,SIGNAL(clicked(QString)),set2,SIGNAL(toggleFloatingValues()));
58 QObject::connect(set3,SIGNAL(clicked(QString)),set3,SIGNAL(toggleFloatingValues()));
58 QObject::connect(set3,SIGNAL(clicked(QString)),set3,SIGNAL(toggleFloatingValues()));
59 QObject::connect(set4,SIGNAL(clicked(QString)),set4,SIGNAL(toggleFloatingValues()));
59 //! [4]
60 //! [4]
60
61
61 //! [5]
62 //! [5]
62 // Create view for chart and add series to it. Apply theme.
63 // Create view for chart and add series to it. Apply theme.
63
64
64 QChartView* chartView = new QChartView(&window);
65 QChartView* chartView = new QChartView(&window);
65 chartView->addSeries(series);
66 chartView->addSeries(series);
66 chartView->setChartTitle("simple percent barchart");
67 chartView->setChartTitle("simple percent barchart");
67 chartView->setChartTheme(QChart::ChartThemeIcy);
68 chartView->setChartTheme(QChart::ChartThemeIcy);
68 //! [5]
69 //! [5]
69
70
70 //! [6]
71 //! [6]
71 chartView->axisX()->setAxisVisible(false);
72 chartView->axisX()->setAxisVisible(false);
72 chartView->axisX()->setGridVisible(false);
73 chartView->axisX()->setGridVisible(false);
73 chartView->axisX()->setLabelsVisible(false);
74 chartView->axisX()->setLabelsVisible(false);
74 //! [6]
75 //! [6]
75
76
76 window.setCentralWidget(chartView);
77 window.setCentralWidget(chartView);
77 window.resize(400, 300);
78 window.resize(400, 300);
78 window.show();
79 window.show();
79
80
80 return a.exec();
81 return a.exec();
81 }
82 }
82
83
@@ -1,95 +1,96
1 #include "barpresenter_p.h"
1 #include "barpresenter_p.h"
2 #include "bar_p.h"
2 #include "bar_p.h"
3 #include "barvalue_p.h"
3 #include "barvalue_p.h"
4 #include "separator_p.h"
4 #include "separator_p.h"
5 #include "qbarset.h"
5 #include "qbarset.h"
6 #include <QDebug>
6 #include <QDebug>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 BarPresenter::BarPresenter(QBarSeries *series, QChart *parent) :
10 BarPresenter::BarPresenter(QBarSeries *series, QChart *parent) :
11 BarPresenterBase(series, parent)
11 BarPresenterBase(series, parent)
12 {
12 {
13 }
13 }
14
14
15 void BarPresenter::layoutChanged()
15 void BarPresenter::layoutChanged()
16 {
16 {
17 // Scale bars to new layout
17 // Scale bars to new layout
18 // Layout for bars:
18 // Layout for bars:
19 if (mSeries->barsetCount() <= 0) {
19 if (mSeries->barsetCount() <= 0) {
20 qDebug() << "No sets in model!";
20 qDebug() << "No sets in model!";
21 return;
21 return;
22 }
22 }
23
23
24 if (childItems().count() == 0) {
24 if (childItems().count() == 0) {
25 qDebug() << "WARNING: BarPresenter::layoutChanged called before graphics items are created!";
25 qDebug() << "WARNING: BarPresenter::layoutChanged called before graphics items are created!";
26 return;
26 return;
27 }
27 }
28
28
29 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
29 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
30 int categoryCount = mSeries->categoryCount();
30 int categoryCount = mSeries->categoryCount();
31 int setCount = mSeries->barsetCount();
31 int setCount = mSeries->barsetCount();
32
32
33 qreal tW = mWidth;
33 qreal tW = mWidth;
34 qreal tH = mHeight;
34 qreal tH = mHeight;
35 qreal tM = mSeries->max();
35 qreal tM = mSeries->max();
36 qreal scale = (tH/tM);
36 qreal scale = (tH/tM);
37 qreal tC = categoryCount + 1;
37 qreal tC = categoryCount + 1;
38 qreal categoryWidth = tW/tC;
38 qreal categoryWidth = tW/tC;
39 mBarWidth = categoryWidth / (setCount+1);
39 mBarWidth = categoryWidth / (setCount+1);
40
40
41 int itemIndex(0);
41 int itemIndex(0);
42 for (int category=0; category < categoryCount; category++) {
42 for (int category=0; category < categoryCount; category++) {
43 qreal xPos = categoryWidth * category + categoryWidth /2;
43 qreal xPos = categoryWidth * category + categoryWidth /2;
44 qreal yPos = mHeight;
44 qreal yPos = mHeight;
45 for (int set = 0; set < setCount; set++) {
45 for (int set = 0; set < setCount; set++) {
46 qreal barHeight = mSeries->valueAt(set,category) * scale;
46 qreal barHeight = mSeries->valueAt(set,category) * scale;
47 Bar* bar = mBars.at(itemIndex);
47 Bar* bar = mBars.at(itemIndex);
48
48
49 // TODO: width settable per bar?
49 // TODO: width settable per bar?
50 bar->resize(mBarWidth, barHeight);
50 bar->resize(mBarWidth, barHeight);
51 bar->setBrush(mSeries->barsetAt(set)->brush());
51 bar->setBrush(mSeries->barsetAt(set)->brush());
52 bar->setPos(xPos, yPos-barHeight);
52 bar->setPos(xPos, yPos-barHeight);
53 itemIndex++;
53 itemIndex++;
54 xPos += mBarWidth;
54 xPos += mBarWidth;
55 }
55 }
56 }
56 }
57
57
58 // Position separators
58 // Position separators
59 qreal xPos = categoryWidth + categoryWidth/2 - mBarWidth /2;
59 qreal xPos = categoryWidth + categoryWidth/2 - mBarWidth /2;
60 for (int s=0; s < mSeparators.count(); s++) {
60 for (int s=0; s < mSeparators.count(); s++) {
61 Separator* sep = mSeparators.at(s);
61 Separator* sep = mSeparators.at(s);
62 sep->setPos(xPos,0);
62 sep->setPos(xPos,0);
63 sep->setSize(QSizeF(1,mHeight));
63 sep->setSize(QSizeF(1,mHeight));
64 sep->setColor(QColor(255,0,0,255)); // TODO: color for separations from theme
64 xPos += categoryWidth;
65 xPos += categoryWidth;
65 }
66 }
66
67
67 // Position floating values
68 // Position floating values
68 itemIndex = 0;
69 itemIndex = 0;
69 for (int category=0; category < mSeries->categoryCount(); category++) {
70 for (int category=0; category < mSeries->categoryCount(); category++) {
70 qreal xPos = categoryWidth * category + categoryWidth/2 + mBarWidth/2;
71 qreal xPos = categoryWidth * category + categoryWidth/2 + mBarWidth/2;
71 qreal yPos = mHeight;
72 qreal yPos = mHeight;
72 for (int set=0; set < mSeries->barsetCount(); set++) {
73 for (int set=0; set < mSeries->barsetCount(); set++) {
73 qreal barHeight = mSeries->valueAt(set,category) * scale;
74 qreal barHeight = mSeries->valueAt(set,category) * scale;
74 BarValue* value = mFloatingValues.at(itemIndex);
75 BarValue* value = mFloatingValues.at(itemIndex);
75
76
76 // TODO: remove hard coding, apply layout
77 QBarSet* barSet = mSeries->barsetAt(set);
77 value->resize(100,50);
78 value->resize(100,50); // TODO: proper layout for this.
78 value->setPos(xPos, yPos-barHeight/2);
79 value->setPos(xPos, yPos-barHeight/2);
79 value->setPen(QPen(QColor(255,255,255,255)));
80 value->setPen(barSet->floatingValuePen());
80
81
81 if (mSeries->valueAt(set,category) != 0) {
82 if (mSeries->valueAt(set,category) != 0) {
82 value->setValueString(QString::number(mSeries->valueAt(set,category)));
83 value->setValueString(QString::number(mSeries->valueAt(set,category)));
83 } else {
84 } else {
84 value->setValueString(QString(""));
85 value->setValueString(QString(""));
85 }
86 }
86
87
87 itemIndex++;
88 itemIndex++;
88 xPos += mBarWidth;
89 xPos += mBarWidth;
89 }
90 }
90 }
91 }
91 }
92 }
92
93
93 #include "moc_barpresenter_p.cpp"
94 #include "moc_barpresenter_p.cpp"
94
95
95 QTCOMMERCIALCHART_END_NAMESPACE
96 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,179 +1,178
1 #include "barpresenterbase_p.h"
1 #include "barpresenterbase_p.h"
2 #include "bar_p.h"
2 #include "bar_p.h"
3 #include "barvalue_p.h"
3 #include "barvalue_p.h"
4 #include "separator_p.h"
4 #include "separator_p.h"
5 #include "qbarset.h"
5 #include "qbarset.h"
6 #include "qbarseries.h"
6 #include "qbarseries.h"
7 #include "qchart.h"
7 #include "qchart.h"
8 #include "qchartaxis.h"
8 #include "qchartaxis.h"
9 #include "qchartaxiscategories.h"
9 #include "qchartaxiscategories.h"
10 #include <QDebug>
10 #include <QDebug>
11 #include <QToolTip>
11 #include <QToolTip>
12
12
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
14
14
15 BarPresenterBase::BarPresenterBase(QBarSeries *series, QChart *parent)
15 BarPresenterBase::BarPresenterBase(QBarSeries *series, QChart *parent)
16 : ChartItem(parent)
16 : ChartItem(parent)
17 ,mLayoutSet(false)
17 ,mLayoutSet(false)
18 ,mSeries(series)
18 ,mSeries(series)
19 ,mChart(parent)
19 ,mChart(parent)
20 {
20 {
21 connect(series,SIGNAL(showToolTip(QPoint,QString)),this,SLOT(showToolTip(QPoint,QString)));
21 connect(series,SIGNAL(showToolTip(QPoint,QString)),this,SLOT(showToolTip(QPoint,QString)));
22 connect(series,SIGNAL(enableSeparators(bool)),this,SLOT(enableSeparators(bool)));
22 connect(series,SIGNAL(enableSeparators(bool)),this,SLOT(enableSeparators(bool)));
23 enableSeparators(series->separatorsVisible());
23 enableSeparators(series->separatorsVisible());
24 initAxisLabels();
24 initAxisLabels();
25 dataChanged();
25 dataChanged();
26 }
26 }
27
27
28 BarPresenterBase::~BarPresenterBase()
28 BarPresenterBase::~BarPresenterBase()
29 {
29 {
30 disconnect(this,SLOT(showToolTip(QPoint,QString)));
30 disconnect(this,SLOT(showToolTip(QPoint,QString)));
31 disconnect(this,SLOT(enableSeparators(bool)));
31 disconnect(this,SLOT(enableSeparators(bool)));
32 }
32 }
33
33
34 void BarPresenterBase::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
34 void BarPresenterBase::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
35 {
35 {
36 if (!mLayoutSet) {
36 if (!mLayoutSet) {
37 qDebug() << "BarPresenterBase::paint called without layout set. Aborting.";
37 qDebug() << "BarPresenterBase::paint called without layout set. Aborting.";
38 return;
38 return;
39 }
39 }
40 foreach(QGraphicsItem* i, childItems()) {
40 foreach(QGraphicsItem* i, childItems()) {
41 i->paint(painter,option,widget);
41 i->paint(painter,option,widget);
42 }
42 }
43 }
43 }
44
44
45 QRectF BarPresenterBase::boundingRect() const
45 QRectF BarPresenterBase::boundingRect() const
46 {
46 {
47 return QRectF(0,0,mWidth,mHeight);
47 return QRectF(0,0,mWidth,mHeight);
48 }
48 }
49
49
50 void BarPresenterBase::dataChanged()
50 void BarPresenterBase::dataChanged()
51 {
51 {
52 // TODO: performance optimizations. Do we really need to delete and create items every time data is changed or can we reuse them?
52 // TODO: performance optimizations. Do we really need to delete and create items every time data is changed or can we reuse them?
53 // Delete old bars
53 // Delete old bars
54 foreach (QGraphicsItem* item, childItems()) {
54 foreach (QGraphicsItem* item, childItems()) {
55 delete item;
55 delete item;
56 }
56 }
57
57
58 mBars.clear();
58 mBars.clear();
59 mSeparators.clear();
59 mSeparators.clear();
60 mFloatingValues.clear();
60 mFloatingValues.clear();
61
61
62 // Create new graphic items for bars
62 // Create new graphic items for bars
63 for (int c=0; c<mSeries->categoryCount(); c++) {
63 for (int c=0; c<mSeries->categoryCount(); c++) {
64 QString category = mSeries->categoryName(c);
64 QString category = mSeries->categoryName(c);
65 for (int s=0; s<mSeries->barsetCount(); s++) {
65 for (int s=0; s<mSeries->barsetCount(); s++) {
66 QBarSet *set = mSeries->barsetAt(s);
66 QBarSet *set = mSeries->barsetAt(s);
67 Bar *bar = new Bar(category,this);
67 Bar *bar = new Bar(category,this);
68 childItems().append(bar);
68 childItems().append(bar);
69 mBars.append(bar);
69 mBars.append(bar);
70 connect(bar,SIGNAL(clicked(QString)),set,SIGNAL(clicked(QString)));
70 connect(bar,SIGNAL(clicked(QString)),set,SIGNAL(clicked(QString)));
71 connect(bar,SIGNAL(rightClicked(QString)),set,SIGNAL(rightClicked(QString)));
71 connect(bar,SIGNAL(rightClicked(QString)),set,SIGNAL(rightClicked(QString)));
72 connect(bar,SIGNAL(hoverEntered(QPoint)),set,SLOT(barHoverEnterEvent(QPoint)));
72 connect(bar,SIGNAL(hoverEntered(QPoint)),set,SLOT(barHoverEnterEvent(QPoint)));
73 connect(bar,SIGNAL(hoverLeaved()),set,SLOT(barHoverLeaveEvent()));
73 connect(bar,SIGNAL(hoverLeaved()),set,SLOT(barHoverLeaveEvent()));
74 }
74 }
75 }
75 }
76
76
77 // Create separators
77 // Create separators
78 int count = mSeries->categoryCount() - 1; // There is one less separator than columns
78 int count = mSeries->categoryCount() - 1; // There is one less separator than columns
79 for (int i=0; i<count; i++) {
79 for (int i=0; i<count; i++) {
80 Separator* sep = new Separator(this);
80 Separator* sep = new Separator(this);
81 sep->setColor(QColor(255,0,0,255)); // TODO: color for separations from theme
82 sep->setVisible(mSeries->separatorsVisible());
81 sep->setVisible(mSeries->separatorsVisible());
83 childItems().append(sep);
82 childItems().append(sep);
84 mSeparators.append(sep);
83 mSeparators.append(sep);
85 }
84 }
86
85
87 // Create floating values
86 // Create floating values
88 for (int category=0; category<mSeries->categoryCount(); category++) {
87 for (int category=0; category<mSeries->categoryCount(); category++) {
89 for (int s=0; s<mSeries->barsetCount(); s++) {
88 for (int s=0; s<mSeries->barsetCount(); s++) {
90 QBarSet *set = mSeries->barsetAt(s);
89 QBarSet *set = mSeries->barsetAt(s);
91 BarValue *value = new BarValue(*set, this);
90 BarValue *value = new BarValue(*set, this);
92 childItems().append(value);
91 childItems().append(value);
93 mFloatingValues.append(value);
92 mFloatingValues.append(value);
94 connect(set,SIGNAL(toggleFloatingValues()),value,SLOT(toggleVisible()));
93 connect(set,SIGNAL(toggleFloatingValues()),value,SLOT(toggleVisible()));
95 }
94 }
96 }
95 }
97 }
96 }
98
97
99 void BarPresenterBase::initAxisLabels()
98 void BarPresenterBase::initAxisLabels()
100 {
99 {
101 int count = mSeries->categoryCount();
100 int count = mSeries->categoryCount();
102 if (0 == count) {
101 if (0 == count) {
103 return;
102 return;
104 }
103 }
105
104
106 mChart->axisX()->setTicksCount(count+2);
105 mChart->axisX()->setTicksCount(count+2);
107
106
108 qreal min = 0;
107 qreal min = 0;
109 qreal max = count+1;
108 qreal max = count+1;
110
109
111 mChart->axisX()->setMin(min);
110 mChart->axisX()->setMin(min);
112 mChart->axisX()->setMax(max);
111 mChart->axisX()->setMax(max);
113
112
114 QChartAxisCategories* categories = mChart->axisX()->categories();
113 QChartAxisCategories* categories = mChart->axisX()->categories();
115 categories->clear();
114 categories->clear();
116 for (int i=0; i<count; i++) {
115 for (int i=0; i<count; i++) {
117 categories->insert(i+1,mSeries->categoryName(i));
116 categories->insert(i+1,mSeries->categoryName(i));
118 }
117 }
119
118
120
119
121
120
122 mChart->axisX()->setLabelsVisible(true);
121 mChart->axisX()->setLabelsVisible(true);
123 }
122 }
124
123
125 //handlers
124 //handlers
126
125
127 void BarPresenterBase::handleModelChanged(int index)
126 void BarPresenterBase::handleModelChanged(int index)
128 {
127 {
129 // qDebug() << "BarPresenterBase::handleModelChanged" << index;
128 // qDebug() << "BarPresenterBase::handleModelChanged" << index;
130 dataChanged();
129 dataChanged();
131 }
130 }
132
131
133 void BarPresenterBase::handleDomainChanged(const Domain& domain)
132 void BarPresenterBase::handleDomainChanged(const Domain& domain)
134 {
133 {
135 qDebug() << "BarPresenterBase::handleDomainChanged";
134 qDebug() << "BarPresenterBase::handleDomainChanged";
136 /*
135 /*
137 int count = mSeries->categoryCount();
136 int count = mSeries->categoryCount();
138 if (0 == count) {
137 if (0 == count) {
139 return;
138 return;
140 }
139 }
141
140
142 // Position labels to domain
141 // Position labels to domain
143 qreal min = domain.minX();
142 qreal min = domain.minX();
144 qreal max = domain.maxX();
143 qreal max = domain.maxX();
145 qreal step = (max-min)/count;
144 qreal step = (max-min)/count;
146 QChartAxisCategories& categories = mChart->axisX()->categories();
145 QChartAxisCategories& categories = mChart->axisX()->categories();
147 categories.clear();
146 categories.clear();
148 for (int i=0; i<count; i++) {
147 for (int i=0; i<count; i++) {
149 categories.insert(min,mSeries->categoryName(i));
148 categories.insert(min,mSeries->categoryName(i));
150 min += step;
149 min += step;
151 }
150 }
152 */
151 */
153 }
152 }
154
153
155 void BarPresenterBase::handleGeometryChanged(const QRectF& rect)
154 void BarPresenterBase::handleGeometryChanged(const QRectF& rect)
156 {
155 {
157 mWidth = rect.width();
156 mWidth = rect.width();
158 mHeight = rect.height();
157 mHeight = rect.height();
159 layoutChanged();
158 layoutChanged();
160 mLayoutSet = true;
159 mLayoutSet = true;
161 setPos(rect.topLeft());
160 setPos(rect.topLeft());
162 }
161 }
163
162
164 void BarPresenterBase::showToolTip(QPoint pos, QString tip)
163 void BarPresenterBase::showToolTip(QPoint pos, QString tip)
165 {
164 {
166 // TODO: cool tooltip instead of default
165 // TODO: cool tooltip instead of default
167 QToolTip::showText(pos,tip);
166 QToolTip::showText(pos,tip);
168 }
167 }
169
168
170 void BarPresenterBase::enableSeparators(bool enabled)
169 void BarPresenterBase::enableSeparators(bool enabled)
171 {
170 {
172 for (int i=0; i<mSeparators.count(); i++) {
171 for (int i=0; i<mSeparators.count(); i++) {
173 mSeparators.at(i)->setVisible(enabled);
172 mSeparators.at(i)->setVisible(enabled);
174 }
173 }
175 }
174 }
176
175
177 #include "moc_barpresenterbase_p.cpp"
176 #include "moc_barpresenterbase_p.cpp"
178
177
179 QTCOMMERCIALCHART_END_NAMESPACE
178 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,103 +1,103
1 #include "percentbarpresenter_p.h"
1 #include "percentbarpresenter_p.h"
2 #include "bar_p.h"
2 #include "bar_p.h"
3 #include "barvalue_p.h"
3 #include "barvalue_p.h"
4 #include "separator_p.h"
4 #include "separator_p.h"
5 #include "qbarset.h"
5 #include "qbarset.h"
6 #include <QDebug>
6 #include <QDebug>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10
10
11 PercentBarPresenter::PercentBarPresenter(QBarSeries *series, QChart *parent) :
11 PercentBarPresenter::PercentBarPresenter(QBarSeries *series, QChart *parent) :
12 BarPresenterBase(series, parent)
12 BarPresenterBase(series, parent)
13 {
13 {
14 }
14 }
15
15
16 void PercentBarPresenter::layoutChanged()
16 void PercentBarPresenter::layoutChanged()
17 {
17 {
18 // Scale bars to new layout
18 // Scale bars to new layout
19 // Layout for bars:
19 // Layout for bars:
20 if (mSeries->barsetCount() <= 0) {
20 if (mSeries->barsetCount() <= 0) {
21 qDebug() << "No sets in model!";
21 qDebug() << "No sets in model!";
22 // Nothing to do.
22 // Nothing to do.
23 return;
23 return;
24 }
24 }
25
25
26 if (childItems().count() == 0) {
26 if (childItems().count() == 0) {
27 qDebug() << "WARNING: PercentBarPresenter::layoutChanged called before graphics items are created!";
27 qDebug() << "WARNING: PercentBarPresenter::layoutChanged called before graphics items are created!";
28 return;
28 return;
29 }
29 }
30
30
31 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
31 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
32 qreal tW = mWidth;
32 qreal tW = mWidth;
33 qreal tC = mSeries->categoryCount() + 1;
33 qreal tC = mSeries->categoryCount() + 1;
34 qreal cC = mSeries->categoryCount() * 2 + 1;
34 qreal cC = mSeries->categoryCount() * 2 + 1;
35 mBarWidth = tW / cC;
35 mBarWidth = tW / cC;
36 qreal xStep = (tW/tC);
36 qreal xStep = (tW/tC);
37 qreal xPos = ((tW/tC) - mBarWidth / 2);
37 qreal xPos = ((tW/tC) - mBarWidth / 2);
38 qreal h = mHeight;
38 qreal h = mHeight;
39
39
40 int itemIndex(0);
40 int itemIndex(0);
41 for (int category = 0; category < mSeries->categoryCount(); category++) {
41 for (int category = 0; category < mSeries->categoryCount(); category++) {
42 qreal colSum = mSeries->categorySum(category);
42 qreal colSum = mSeries->categorySum(category);
43 qreal scale = (h / colSum);
43 qreal scale = (h / colSum);
44 qreal yPos = h;
44 qreal yPos = h;
45 for (int set=0; set < mSeries->barsetCount(); set++) {
45 for (int set=0; set < mSeries->barsetCount(); set++) {
46 qreal barHeight = mSeries->valueAt(set, category) * scale;
46 qreal barHeight = mSeries->valueAt(set, category) * scale;
47 Bar* bar = mBars.at(itemIndex);
47 Bar* bar = mBars.at(itemIndex);
48
48
49 // TODO: width settable per bar?
49 // TODO: width settable per bar?
50 bar->resize(mBarWidth, barHeight);
50 bar->resize(mBarWidth, barHeight);
51 bar->setBrush(mSeries->barsetAt(set)->brush());
51 bar->setBrush(mSeries->barsetAt(set)->brush());
52 bar->setPos(xPos, yPos-barHeight);
52 bar->setPos(xPos, yPos-barHeight);
53 itemIndex++;
53 itemIndex++;
54 yPos -= barHeight;
54 yPos -= barHeight;
55 }
55 }
56 xPos += xStep;
56 xPos += xStep;
57 }
57 }
58
58
59 // Position separators
59 // Position separators
60 xPos = xStep + xStep/2;
60 xPos = xStep + xStep/2;
61 for (int s=0; s < mSeries->categoryCount() - 1; s++) {
61 for (int s=0; s < mSeries->categoryCount() - 1; s++) {
62 Separator* sep = mSeparators.at(s);
62 Separator* sep = mSeparators.at(s);
63 sep->setPos(xPos,0);
63 sep->setPos(xPos,0);
64 sep->setSize(QSizeF(1,mHeight));
64 sep->setSize(QSizeF(1,mHeight));
65 xPos += xStep;
65 xPos += xStep;
66 }
66 }
67
67
68 // Position floating values
68 // Position floating values
69 itemIndex = 0;
69 itemIndex = 0;
70 xPos = (tW/tC);
70 xPos = (tW/tC);
71 for (int category=0; category < mSeries->categoryCount(); category++) {
71 for (int category=0; category < mSeries->categoryCount(); category++) {
72 qreal yPos = h;
72 qreal yPos = h;
73 qreal colSum = mSeries->categorySum(category);
73 qreal colSum = mSeries->categorySum(category);
74 qreal scale = (h / colSum);
74 qreal scale = (h / colSum);
75 for (int set=0; set < mSeries->barsetCount(); set++) {
75 for (int set=0; set < mSeries->barsetCount(); set++) {
76 qreal barHeight = mSeries->valueAt(set,category) * scale;
76 qreal barHeight = mSeries->valueAt(set,category) * scale;
77 BarValue* value = mFloatingValues.at(itemIndex);
77 BarValue* value = mFloatingValues.at(itemIndex);
78
78
79 // TODO: remove hard coding, apply layout
79 QBarSet* barSet = mSeries->barsetAt(set);
80 value->resize(100,50);
80 value->resize(100,50); // TODO: proper layout for this.
81 value->setPos(xPos, yPos-barHeight/2);
81 value->setPos(xPos, yPos-barHeight/2);
82 value->setPen(QPen(QColor(255,255,255,255)));
82 value->setPen(barSet->floatingValuePen());
83
83
84 if (mSeries->valueAt(set,category) != 0) {
84 if (mSeries->valueAt(set,category) != 0) {
85 int p = mSeries->percentageAt(set,category) * 100;
85 int p = mSeries->percentageAt(set,category) * 100;
86 QString vString(QString::number(p));
86 QString vString(QString::number(p));
87 vString.truncate(3);
87 vString.truncate(3);
88 vString.append("%");
88 vString.append("%");
89 value->setValueString(vString);
89 value->setValueString(vString);
90 } else {
90 } else {
91 value->setValueString(QString(""));
91 value->setValueString(QString(""));
92 }
92 }
93
93
94 itemIndex++;
94 itemIndex++;
95 yPos -= barHeight;
95 yPos -= barHeight;
96 }
96 }
97 xPos += xStep;
97 xPos += xStep;
98 }
98 }
99 }
99 }
100
100
101 #include "moc_percentbarpresenter_p.cpp"
101 #include "moc_percentbarpresenter_p.cpp"
102
102
103 QTCOMMERCIALCHART_END_NAMESPACE
103 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,175 +1,191
1 #include "qbarset.h"
1 #include "qbarset.h"
2 #include <QDebug>
2 #include <QDebug>
3 #include <QToolTip>
3 #include <QToolTip>
4
4
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6
6
7 /*!
7 /*!
8 \class QBarSet
8 \class QBarSet
9 \brief part of QtCommercial chart API.
9 \brief part of QtCommercial chart API.
10
10
11 QBarSet represents one set of bars. Set of bars contains one data value for each category.
11 QBarSet represents one set of bars. Set of bars contains one data value for each category.
12 First value of set is assumed to belong to first category, second to second category and so on.
12 First value of set is assumed to belong to first category, second to second category and so on.
13 If set has fewer values than there are categories, then the missing values are assumed to be
13 If set has fewer values than there are categories, then the missing values are assumed to be
14 at the end of set. For missing values in middle of a set, numerical value of zero is used.
14 at the end of set. For missing values in middle of a set, numerical value of zero is used.
15
15
16 \mainclass
16 \mainclass
17
17
18 \sa QBarSeries, QStackedBarSeries, QPercentBarSeries
18 \sa QBarSeries, QStackedBarSeries, QPercentBarSeries
19 */
19 */
20
20
21 /*!
21 /*!
22 \fn void QBarSet::clicked(QString category)
22 \fn void QBarSet::clicked(QString category)
23 \brief signals that set has been clicked
23 \brief signals that set has been clicked
24 Parameter \a category describes on which category was clicked
24 Parameter \a category describes on which category was clicked
25 */
25 */
26
26
27 /*!
27 /*!
28 \fn void QBarSet::rightClicked(QString category)
28 \fn void QBarSet::rightClicked(QString category)
29 \brief signals that set has been clicked with right mouse button
29 \brief signals that set has been clicked with right mouse button
30 Parameter \a category describes on which category was clicked
30 Parameter \a category describes on which category was clicked
31 */
31 */
32
32
33 /*!
33 /*!
34 \fn void QBarSet::hoverEnter(QPoint pos)
34 \fn void QBarSet::hoverEnter(QPoint pos)
35 \brief signals that mouse has entered over the set at position \a pos.
35 \brief signals that mouse has entered over the set at position \a pos.
36 */
36 */
37
37
38 /*!
38 /*!
39 \fn void QBarSet::hoverLeave()
39 \fn void QBarSet::hoverLeave()
40 \brief signals that mouse has left from the set.
40 \brief signals that mouse has left from the set.
41 */
41 */
42
42
43 /*!
43 /*!
44 \fn void QBarSet::toggleFloatingValues()
44 \fn void QBarSet::toggleFloatingValues()
45 \brief \internal
45 \brief \internal
46 */
46 */
47
47
48 /*!
48 /*!
49 \fn void QBarSet::showToolTip(QPoint pos, QString tip)
49 \fn void QBarSet::showToolTip(QPoint pos, QString tip)
50 \brief \internal \a pos \a tip
50 \brief \internal \a pos \a tip
51 */
51 */
52
52
53
53
54 /*!
54 /*!
55 Constructs QBarSet with a name of \a name and with parent of \a parent
55 Constructs QBarSet with a name of \a name and with parent of \a parent
56 */
56 */
57 QBarSet::QBarSet(QString name, QObject *parent)
57 QBarSet::QBarSet(QString name, QObject *parent)
58 : QObject(parent)
58 : QObject(parent)
59 ,mName(name)
59 ,mName(name)
60 {
60 {
61 }
61 }
62
62
63 /*!
63 /*!
64 Sets new \a name for set.
64 Sets new \a name for set.
65 */
65 */
66 void QBarSet::setName(QString name)
66 void QBarSet::setName(QString name)
67 {
67 {
68 mName = name;
68 mName = name;
69 }
69 }
70
70
71 /*!
71 /*!
72 Returns name of the set.
72 Returns name of the set.
73 */
73 */
74 QString QBarSet::name()
74 QString QBarSet::name()
75 {
75 {
76 return mName;
76 return mName;
77 }
77 }
78
78
79 /*!
79 /*!
80 Appends new value \a value to the end of set.
80 Appends new value \a value to the end of set.
81 */
81 */
82 QBarSet& QBarSet::operator << (const qreal &value)
82 QBarSet& QBarSet::operator << (const qreal &value)
83 {
83 {
84 mValues.append(value);
84 mValues.append(value);
85 return *this;
85 return *this;
86 }
86 }
87
87
88 /*!
88 /*!
89 Returns count of values in set.
89 Returns count of values in set.
90 */
90 */
91 int QBarSet::count()
91 int QBarSet::count()
92 {
92 {
93 return mValues.count();
93 return mValues.count();
94 }
94 }
95
95
96 /*!
96 /*!
97 Returns value of set indexed by \a index
97 Returns value of set indexed by \a index
98 */
98 */
99 qreal QBarSet::valueAt(int index)
99 qreal QBarSet::valueAt(int index)
100 {
100 {
101 return mValues.at(index);
101 return mValues.at(index);
102 }
102 }
103
103
104 /*!
104 /*!
105 Sets a new value \a value to set, indexed by \a index
105 Sets a new value \a value to set, indexed by \a index
106 */
106 */
107 void QBarSet::setValue(int index, qreal value)
107 void QBarSet::setValue(int index, qreal value)
108 {
108 {
109 mValues.replace(index,value);
109 mValues.replace(index,value);
110 }
110 }
111
111
112 /*!
112 /*!
113 Returns total sum of all values in barset.
113 Returns total sum of all values in barset.
114 */
114 */
115 qreal QBarSet::total()
115 qreal QBarSet::total()
116 {
116 {
117 qreal total(0);
117 qreal total(0);
118 for (int i=0; i<mValues.count(); i++) {
118 for (int i=0; i<mValues.count(); i++) {
119 total += mValues.at(i);
119 total += mValues.at(i);
120 }
120 }
121 return total;
121 return total;
122 }
122 }
123
123
124 /*!
124 /*!
125 Sets pen for set. Bars of this set are drawn using \a pen
125 Sets pen for set. Bars of this set are drawn using \a pen
126 */
126 */
127 void QBarSet::setPen(const QPen pen)
127 void QBarSet::setPen(const QPen pen)
128 {
128 {
129 mPen = pen;
129 mPen = pen;
130 }
130 }
131
131
132 /*!
132 /*!
133 Returns pen of the set.
133 Returns pen of the set.
134 */
134 */
135 QPen QBarSet::pen() const
135 QPen QBarSet::pen() const
136 {
136 {
137 return mPen;
137 return mPen;
138 }
138 }
139
139
140 /*!
140 /*!
141 Sets brush for the set. Bars of this set are drawn using \a brush
141 Sets brush for the set. Bars of this set are drawn using \a brush
142 */
142 */
143 void QBarSet::setBrush(const QBrush brush)
143 void QBarSet::setBrush(const QBrush brush)
144 {
144 {
145 mBrush = brush;
145 mBrush = brush;
146 }
146 }
147
147
148 /*!
148 /*!
149 Returns brush of the set.
149 Returns brush of the set.
150 */
150 */
151 QBrush QBarSet::brush() const
151 QBrush QBarSet::brush() const
152 {
152 {
153 return mBrush;
153 return mBrush;
154 }
154 }
155
155
156 /*!
156 /*!
157 Sets the pen for floating values that are drawn on top of this set
158 */
159 void QBarSet::setFloatingValuePen(const QPen pen)
160 {
161 mFloatingValuePen = pen;
162 }
163
164 /*!
165 Returns the pen for floating values that are drawn on top of this set
166 */
167 QPen QBarSet::floatingValuePen() const
168 {
169 return mFloatingValuePen;
170 }
171
172 /*!
157 \internal \a pos
173 \internal \a pos
158 */
174 */
159 void QBarSet::barHoverEnterEvent(QPoint pos)
175 void QBarSet::barHoverEnterEvent(QPoint pos)
160 {
176 {
161 emit showToolTip(pos, mName);
177 emit showToolTip(pos, mName);
162 emit hoverEnter(pos);
178 emit hoverEnter(pos);
163 }
179 }
164
180
165 /*!
181 /*!
166 \internal
182 \internal
167 */
183 */
168 void QBarSet::barHoverLeaveEvent()
184 void QBarSet::barHoverLeaveEvent()
169 {
185 {
170 // Emit signal to user of charts
186 // Emit signal to user of charts
171 emit hoverLeave();
187 emit hoverLeave();
172 }
188 }
173
189
174 #include "moc_qbarset.cpp"
190 #include "moc_qbarset.cpp"
175 QTCOMMERCIALCHART_END_NAMESPACE
191 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,67 +1,70
1 #ifndef QBARSET_H
1 #ifndef QBARSET_H
2 #define QBARSET_H
2 #define QBARSET_H
3
3
4 #include <qchartglobal.h>
4 #include <qchartglobal.h>
5 #include <QPen>
5 #include <QPen>
6 #include <QBrush>
6 #include <QBrush>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 class QTCOMMERCIALCHART_EXPORT QBarSet : public QObject
10 class QTCOMMERCIALCHART_EXPORT QBarSet : public QObject
11 {
11 {
12 Q_OBJECT
12 Q_OBJECT
13 public:
13 public:
14 QBarSet(QString name, QObject *parent = 0);
14 QBarSet(QString name, QObject *parent = 0);
15
15
16 void setName(QString name);
16 void setName(QString name);
17 QString name();
17 QString name();
18 QBarSet& operator << (const qreal &value); // appends new value to set
18 QBarSet& operator << (const qreal &value); // appends new value to set
19
19
20 // TODO: remove indices eventually. Use as internal?
20 // TODO: remove indices eventually. Use as internal?
21 int count(); // count of values in set
21 int count(); // count of values in set
22 qreal valueAt(int index); // for modifying individual values
22 qreal valueAt(int index); // for modifying individual values
23 void setValue(int index, qreal value); // setter for individual value
23 void setValue(int index, qreal value); // setter for individual value
24 qreal total(); // total values in the set
24 qreal total(); // total values in the set
25
25
26 // TODO:
26 // TODO:
27 //qreal value(QString category);
27 //qreal value(QString category);
28 //void setValue(QString category, qreal value);
28 //void setValue(QString category, qreal value);
29
29
30 void setPen(const QPen pen);
30 void setPen(const QPen pen);
31 QPen pen() const;
31 QPen pen() const;
32
32
33 void setBrush(const QBrush brush);
33 void setBrush(const QBrush brush);
34 QBrush brush() const;
34 QBrush brush() const;
35
35
36 void setFloatingValuePen(const QPen pen);
37 QPen floatingValuePen() const;
38
36 Q_SIGNALS:
39 Q_SIGNALS:
37 void clicked(QString category); // Clicked and hover signals exposed to user
40 void clicked(QString category); // Clicked and hover signals exposed to user
38 void rightClicked(QString category);
41 void rightClicked(QString category);
39 void toggleFloatingValues();
42 void toggleFloatingValues();
40
43
41 // TODO: Expose this to user or not?
44 // TODO: Expose this to user or not?
42 // TODO: TO PIMPL --->
45 // TODO: TO PIMPL --->
43 void hoverEnter(QPoint pos);
46 void hoverEnter(QPoint pos);
44 void hoverLeave();
47 void hoverLeave();
45 void showToolTip(QPoint pos, QString tip); // Private signal
48 void showToolTip(QPoint pos, QString tip); // Private signal
46 // <--- TO PIMPL
49 // <--- TO PIMPL
47
50
48 public Q_SLOTS:
51 public Q_SLOTS:
49 // These are for internal communication
52 // These are for internal communication
50 // TODO: TO PIMPL --->
53 // TODO: TO PIMPL --->
51 void barHoverEnterEvent(QPoint pos);
54 void barHoverEnterEvent(QPoint pos);
52 void barHoverLeaveEvent();
55 void barHoverLeaveEvent();
53 // <--- TO PIMPL
56 // <--- TO PIMPL
54
57
55 private:
58 private:
56
59
57 QString mName;
60 QString mName;
58 QList<qreal> mValues; // TODO: replace with map (category, value)
61 QList<qreal> mValues; // TODO: replace with map (category, value)
59 QMap<QString,qreal> mMappedValues;
62 QMap<QString,qreal> mMappedValues;
60 QPen mPen;
63 QPen mPen;
61 QBrush mBrush;
64 QBrush mBrush;
62
65 QPen mFloatingValuePen;
63 };
66 };
64
67
65 QTCOMMERCIALCHART_END_NAMESPACE
68 QTCOMMERCIALCHART_END_NAMESPACE
66
69
67 #endif // QBARSET_H
70 #endif // QBARSET_H
@@ -1,106 +1,106
1 #include "stackedbarpresenter_p.h"
1 #include "stackedbarpresenter_p.h"
2 #include "bar_p.h"
2 #include "bar_p.h"
3 #include "barvalue_p.h"
3 #include "barvalue_p.h"
4 #include "separator_p.h"
4 #include "separator_p.h"
5 #include "qbarset.h"
5 #include "qbarset.h"
6 #include <QDebug>
6 #include <QDebug>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 StackedBarPresenter::StackedBarPresenter(QBarSeries *series, QChart *parent) :
10 StackedBarPresenter::StackedBarPresenter(QBarSeries *series, QChart *parent) :
11 BarPresenterBase(series,parent)
11 BarPresenterBase(series,parent)
12 {
12 {
13 }
13 }
14
14
15 StackedBarPresenter::~StackedBarPresenter()
15 StackedBarPresenter::~StackedBarPresenter()
16 {
16 {
17 }
17 }
18
18
19
19
20 void StackedBarPresenter::layoutChanged()
20 void StackedBarPresenter::layoutChanged()
21 {
21 {
22 // Scale bars to new layout
22 // Scale bars to new layout
23 // Layout for bars:
23 // Layout for bars:
24 if (mSeries->barsetCount() <= 0) {
24 if (mSeries->barsetCount() <= 0) {
25 qDebug() << "No sets in model!";
25 qDebug() << "No sets in model!";
26 // Nothing to do.
26 // Nothing to do.
27 return;
27 return;
28 }
28 }
29
29
30 if (mSeries->categoryCount() == 0) {
30 if (mSeries->categoryCount() == 0) {
31 qDebug() << "No categories in model!";
31 qDebug() << "No categories in model!";
32 // Nothing to do
32 // Nothing to do
33 return;
33 return;
34 }
34 }
35
35
36 if (childItems().count() == 0) {
36 if (childItems().count() == 0) {
37 qDebug() << "WARNING: StackedBarPresenter::layoutChanged called before graphics items are created!";
37 qDebug() << "WARNING: StackedBarPresenter::layoutChanged called before graphics items are created!";
38 return;
38 return;
39 }
39 }
40
40
41 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
41 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
42 qreal maxSum = mSeries->maxCategorySum();
42 qreal maxSum = mSeries->maxCategorySum();
43 qreal h = mHeight;
43 qreal h = mHeight;
44 qreal scale = (h / maxSum);
44 qreal scale = (h / maxSum);
45 qreal tW = mWidth;
45 qreal tW = mWidth;
46 qreal tC = mSeries->categoryCount() + 1;
46 qreal tC = mSeries->categoryCount() + 1;
47 qreal cC = mSeries->categoryCount() * 2 + 1;
47 qreal cC = mSeries->categoryCount() * 2 + 1;
48 mBarWidth = tW / cC;
48 mBarWidth = tW / cC;
49 qreal xStep = (tW/tC);
49 qreal xStep = (tW/tC);
50 qreal xPos = ((tW/tC) - mBarWidth / 2);
50 qreal xPos = ((tW/tC) - mBarWidth / 2);
51
51
52 int itemIndex(0);
52 int itemIndex(0);
53 for (int category = 0; category < mSeries->categoryCount(); category++) {
53 for (int category = 0; category < mSeries->categoryCount(); category++) {
54 qreal yPos = h;
54 qreal yPos = h;
55 for (int set=0; set < mSeries->barsetCount(); set++) {
55 for (int set=0; set < mSeries->barsetCount(); set++) {
56 qreal barHeight = mSeries->valueAt(set, category) * scale;
56 qreal barHeight = mSeries->valueAt(set, category) * scale;
57 Bar* bar = mBars.at(itemIndex);
57 Bar* bar = mBars.at(itemIndex);
58
58
59 bar->resize(mBarWidth, barHeight);
59 bar->resize(mBarWidth, barHeight);
60 bar->setBrush(mSeries->barsetAt(set)->brush());
60 bar->setBrush(mSeries->barsetAt(set)->brush());
61 bar->setPos(xPos, yPos-barHeight);
61 bar->setPos(xPos, yPos-barHeight);
62 itemIndex++;
62 itemIndex++;
63 yPos -= barHeight;
63 yPos -= barHeight;
64 }
64 }
65 xPos += xStep;
65 xPos += xStep;
66 }
66 }
67
67
68 // Position separators
68 // Position separators
69 xPos = xStep + xStep/2;
69 xPos = xStep + xStep/2;
70 for (int s=0; s < mSeries->categoryCount() - 1; s++) {
70 for (int s=0; s < mSeries->categoryCount() - 1; s++) {
71 Separator* sep = mSeparators.at(s);
71 Separator* sep = mSeparators.at(s);
72 sep->setPos(xPos,0);
72 sep->setPos(xPos,0);
73 sep->setSize(QSizeF(1,mHeight));
73 sep->setSize(QSizeF(1,mHeight));
74 xPos += xStep;
74 xPos += xStep;
75 }
75 }
76
76
77 // Position floating values
77 // Position floating values
78 itemIndex = 0;
78 itemIndex = 0;
79 xPos = (tW/tC);
79 xPos = (tW/tC);
80 for (int category=0; category < mSeries->categoryCount(); category++) {
80 for (int category=0; category < mSeries->categoryCount(); category++) {
81 qreal yPos = h;
81 qreal yPos = h;
82 for (int set=0; set < mSeries->barsetCount(); set++) {
82 for (int set=0; set < mSeries->barsetCount(); set++) {
83 qreal barHeight = mSeries->valueAt(set,category) * scale;
83 qreal barHeight = mSeries->valueAt(set,category) * scale;
84 BarValue* value = mFloatingValues.at(itemIndex);
84 BarValue* value = mFloatingValues.at(itemIndex);
85
85
86 // TODO: remove hard coding, apply layout
86 QBarSet* barSet = mSeries->barsetAt(set);
87 value->resize(100,50);
87 value->resize(100,50); // TODO: proper layout for this.
88 value->setPos(xPos, yPos-barHeight/2);
88 value->setPos(xPos, yPos-barHeight/2);
89 value->setPen(QPen(QColor(255,255,255,255)));
89 value->setPen(barSet->floatingValuePen());
90
90
91 if (mSeries->valueAt(set,category) != 0) {
91 if (mSeries->valueAt(set,category) != 0) {
92 value->setValueString(QString::number(mSeries->valueAt(set,category)));
92 value->setValueString(QString::number(mSeries->valueAt(set,category)));
93 } else {
93 } else {
94 value->setValueString(QString(""));
94 value->setValueString(QString(""));
95 }
95 }
96
96
97 itemIndex++;
97 itemIndex++;
98 yPos -= barHeight;
98 yPos -= barHeight;
99 }
99 }
100 xPos += xStep;
100 xPos += xStep;
101 }
101 }
102 }
102 }
103
103
104 #include "moc_stackedbarpresenter_p.cpp"
104 #include "moc_stackedbarpresenter_p.cpp"
105
105
106 QTCOMMERCIALCHART_END_NAMESPACE
106 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,332 +1,356
1 #include "charttheme_p.h"
1 #include "charttheme_p.h"
2 #include "qchart.h"
2 #include "qchart.h"
3 #include "qchartaxis.h"
3 #include "qchartaxis.h"
4 #include <QTime>
4 #include <QTime>
5
5
6 //series
6 //series
7 #include "qbarset.h"
7 #include "qbarset.h"
8 #include "qbarseries.h"
8 #include "qbarseries.h"
9 #include "qstackedbarseries.h"
9 #include "qstackedbarseries.h"
10 #include "qpercentbarseries.h"
10 #include "qpercentbarseries.h"
11 #include "qlineseries.h"
11 #include "qlineseries.h"
12 #include "qareaseries.h"
12 #include "qareaseries.h"
13 #include "qscatterseries.h"
13 #include "qscatterseries.h"
14 #include "qpieseries.h"
14 #include "qpieseries.h"
15 #include "qpieslice.h"
15 #include "qpieslice.h"
16 #include "qsplineseries.h"
16 #include "qsplineseries.h"
17
17
18 //items
18 //items
19 #include "axisitem_p.h"
19 #include "axisitem_p.h"
20 #include "barpresenter_p.h"
20 #include "barpresenter_p.h"
21 #include "stackedbarpresenter_p.h"
21 #include "stackedbarpresenter_p.h"
22 #include "percentbarpresenter_p.h"
22 #include "percentbarpresenter_p.h"
23 #include "linechartitem_p.h"
23 #include "linechartitem_p.h"
24 #include "areachartitem_p.h"
24 #include "areachartitem_p.h"
25 #include "scatterchartitem_p.h"
25 #include "scatterchartitem_p.h"
26 #include "piepresenter_p.h"
26 #include "piepresenter_p.h"
27 #include "splinechartitem_p.h"
27 #include "splinechartitem_p.h"
28
28
29 //themes
29 //themes
30 #include "chartthemedefault_p.h"
30 #include "chartthemedefault_p.h"
31 #include "chartthemevanilla_p.h"
31 #include "chartthemevanilla_p.h"
32 #include "chartthemeicy_p.h"
32 #include "chartthemeicy_p.h"
33 #include "chartthemegrayscale_p.h"
33 #include "chartthemegrayscale_p.h"
34 #include "chartthemescientific_p.h"
34 #include "chartthemescientific_p.h"
35
35
36
36
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38
38
39 ChartTheme::ChartTheme(QChart::ChartTheme id)
39 ChartTheme::ChartTheme(QChart::ChartTheme id)
40 {
40 {
41 m_id = id;
41 m_id = id;
42 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
42 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
43 }
43 }
44
44
45
45
46 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
46 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
47 {
47 {
48 switch(theme) {
48 switch(theme) {
49 case QChart::ChartThemeVanilla:
49 case QChart::ChartThemeVanilla:
50 return new ChartThemeVanilla();
50 return new ChartThemeVanilla();
51 case QChart::ChartThemeIcy:
51 case QChart::ChartThemeIcy:
52 return new ChartThemeIcy();
52 return new ChartThemeIcy();
53 case QChart::ChartThemeGrayscale:
53 case QChart::ChartThemeGrayscale:
54 return new ChartThemeGrayscale();
54 return new ChartThemeGrayscale();
55 case QChart::ChartThemeScientific:
55 case QChart::ChartThemeScientific:
56 return new ChartThemeScientific();
56 return new ChartThemeScientific();
57 default:
57 default:
58 return new ChartThemeDefault();
58 return new ChartThemeDefault();
59 }
59 }
60 }
60 }
61
61
62 void ChartTheme::decorate(QChart* chart)
62 void ChartTheme::decorate(QChart* chart)
63 {
63 {
64 chart->setChartBackgroundBrush(m_backgroundGradient);
64 chart->setChartBackgroundBrush(m_backgroundGradient);
65 }
65 }
66 //TODO helper to by removed later
66 //TODO helper to by removed later
67 void ChartTheme::decorate(ChartItem* item, QSeries* series,int count)
67 void ChartTheme::decorate(ChartItem* item, QSeries* series,int count)
68 {
68 {
69 switch(series->type())
69 switch(series->type())
70 {
70 {
71 case QSeries::SeriesTypeLine: {
71 case QSeries::SeriesTypeLine: {
72 QLineSeries* s = static_cast<QLineSeries*>(series);
72 QLineSeries* s = static_cast<QLineSeries*>(series);
73 LineChartItem* i = static_cast<LineChartItem*>(item);
73 LineChartItem* i = static_cast<LineChartItem*>(item);
74 decorate(i,s,count);
74 decorate(i,s,count);
75 break;
75 break;
76 }
76 }
77 case QSeries::SeriesTypeArea: {
77 case QSeries::SeriesTypeArea: {
78 QAreaSeries* s = static_cast<QAreaSeries*>(series);
78 QAreaSeries* s = static_cast<QAreaSeries*>(series);
79 AreaChartItem* i = static_cast<AreaChartItem*>(item);
79 AreaChartItem* i = static_cast<AreaChartItem*>(item);
80 decorate(i,s,count);
80 decorate(i,s,count);
81 break;
81 break;
82 }
82 }
83 case QSeries::SeriesTypeBar: {
83 case QSeries::SeriesTypeBar: {
84 QBarSeries* b = static_cast<QBarSeries*>(series);
84 QBarSeries* b = static_cast<QBarSeries*>(series);
85 BarPresenter* i = static_cast<BarPresenter*>(item);
85 BarPresenter* i = static_cast<BarPresenter*>(item);
86 decorate(i,b,count);
86 decorate(i,b,count);
87 break;
87 break;
88 }
88 }
89 case QSeries::SeriesTypeStackedBar: {
89 case QSeries::SeriesTypeStackedBar: {
90 QStackedBarSeries* s = static_cast<QStackedBarSeries*>(series);
90 QStackedBarSeries* s = static_cast<QStackedBarSeries*>(series);
91 StackedBarPresenter* i = static_cast<StackedBarPresenter*>(item);
91 StackedBarPresenter* i = static_cast<StackedBarPresenter*>(item);
92 decorate(i,s,count);
92 decorate(i,s,count);
93 break;
93 break;
94 }
94 }
95 case QSeries::SeriesTypePercentBar: {
95 case QSeries::SeriesTypePercentBar: {
96 QPercentBarSeries* s = static_cast<QPercentBarSeries*>(series);
96 QPercentBarSeries* s = static_cast<QPercentBarSeries*>(series);
97 PercentBarPresenter* i = static_cast<PercentBarPresenter*>(item);
97 PercentBarPresenter* i = static_cast<PercentBarPresenter*>(item);
98 decorate(i,s,count);
98 decorate(i,s,count);
99 break;
99 break;
100 }
100 }
101 case QSeries::SeriesTypeScatter: {
101 case QSeries::SeriesTypeScatter: {
102 QScatterSeries* s = qobject_cast<QScatterSeries*>(series);
102 QScatterSeries* s = qobject_cast<QScatterSeries*>(series);
103 Q_ASSERT(s);
103 Q_ASSERT(s);
104 ScatterChartItem* i = static_cast<ScatterChartItem*>(item);
104 ScatterChartItem* i = static_cast<ScatterChartItem*>(item);
105 Q_ASSERT(i);
105 Q_ASSERT(i);
106 decorate(i, s, count);
106 decorate(i, s, count);
107 break;
107 break;
108 }
108 }
109 case QSeries::SeriesTypePie: {
109 case QSeries::SeriesTypePie: {
110 QPieSeries* s = static_cast<QPieSeries*>(series);
110 QPieSeries* s = static_cast<QPieSeries*>(series);
111 PiePresenter* i = static_cast<PiePresenter*>(item);
111 PiePresenter* i = static_cast<PiePresenter*>(item);
112 decorate(i,s,count);
112 decorate(i,s,count);
113 break;
113 break;
114 }
114 }
115 default:
115 default:
116 qDebug()<<"Wrong item to be decorated by theme";
116 qDebug()<<"Wrong item to be decorated by theme";
117 break;
117 break;
118 }
118 }
119
119
120 }
120 }
121
121
122 void ChartTheme::decorate(AreaChartItem* item, QAreaSeries* series,int count)
122 void ChartTheme::decorate(AreaChartItem* item, QAreaSeries* series,int count)
123 {
123 {
124 QPen pen;
124 QPen pen;
125 QBrush brush;
125 QBrush brush;
126
126
127 if(pen != series->pen()){
127 if(pen != series->pen()){
128 item->setPen(series->pen());
128 item->setPen(series->pen());
129 }else{
129 }else{
130 pen.setColor(m_seriesColors.at(count%m_seriesColors.size()));
130 pen.setColor(m_seriesColors.at(count%m_seriesColors.size()));
131 pen.setWidthF(2);
131 pen.setWidthF(2);
132 item->setPen(pen);
132 item->setPen(pen);
133 }
133 }
134
134
135 if(brush != series->brush()){
135 if(brush != series->brush()){
136 item->setBrush(series->brush());
136 item->setBrush(series->brush());
137 }else{
137 }else{
138 QBrush brush(m_seriesColors.at(count%m_seriesColors.size()));
138 QBrush brush(m_seriesColors.at(count%m_seriesColors.size()));
139 item->setBrush(brush);
139 item->setBrush(brush);
140 }
140 }
141 }
141 }
142
142
143
143
144 void ChartTheme::decorate(LineChartItem* item, QLineSeries* series,int count)
144 void ChartTheme::decorate(LineChartItem* item, QLineSeries* series,int count)
145 {
145 {
146 QPen pen;
146 QPen pen;
147 if(pen != series->pen()){
147 if(pen != series->pen()){
148 item->setLinePen(series->pen());
148 item->setLinePen(series->pen());
149 return;
149 return;
150 }
150 }
151 pen.setColor(m_seriesColors.at(count%m_seriesColors.size()));
151 pen.setColor(m_seriesColors.at(count%m_seriesColors.size()));
152 pen.setWidthF(2);
152 pen.setWidthF(2);
153 item->setLinePen(pen);
153 item->setLinePen(pen);
154 }
154 }
155
155
156 void ChartTheme::decorate(BarPresenter* item, QBarSeries* series,int count)
156 void ChartTheme::decorate(BarPresenter* item, QBarSeries* series,int count)
157 {
157 {
158 QList<QBarSet*> sets = series->barSets();
158 QList<QBarSet*> sets = series->barSets();
159 for (int i=0; i<sets.count(); i++) {
159 for (int i=0; i<sets.count(); i++) {
160 qreal pos = (qreal) i / (qreal) sets.count();
160 qreal pos = (qreal) i / (qreal) sets.count();
161 QColor c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), pos);
161 QColor c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), pos);
162 sets.at(i)->setBrush(QBrush(c));
162 sets.at(i)->setBrush(QBrush(c));
163
164 // Pick label color as far as possible from bar color (within gradient).
165 // 0.3 is magic number that was picked as value that gave enough contrast with icy theme gradient :)
166 // TODO: better picking of label color?
167 if (pos < 0.3) {
168 c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), 1);
169 } else {
170 c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), 0);
171 }
172 sets.at(i)->setFloatingValuePen(QPen(c));
163 }
173 }
164 }
174 }
165
175
166 void ChartTheme::decorate(StackedBarPresenter* item, QStackedBarSeries* series,int count)
176 void ChartTheme::decorate(StackedBarPresenter* item, QStackedBarSeries* series,int count)
167 {
177 {
168 QList<QBarSet*> sets = series->barSets();
178 QList<QBarSet*> sets = series->barSets();
169 for (int i=0; i<sets.count(); i++) {
179 for (int i=0; i<sets.count(); i++) {
170 qreal pos = (qreal) i / (qreal) sets.count();
180 qreal pos = (qreal) i / (qreal) sets.count();
171 QColor c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), pos);
181 QColor c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), pos);
172 sets.at(i)->setBrush(QBrush(c));
182 sets.at(i)->setBrush(QBrush(c));
183
184 if (pos < 0.3) {
185 c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), 1);
186 } else {
187 c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), 0);
188 }
189 sets.at(i)->setFloatingValuePen(QPen(c));
173 }
190 }
174 }
191 }
175
192
176 void ChartTheme::decorate(PercentBarPresenter* item, QPercentBarSeries* series,int count)
193 void ChartTheme::decorate(PercentBarPresenter* item, QPercentBarSeries* series,int count)
177 {
194 {
178 QList<QBarSet*> sets = series->barSets();
195 QList<QBarSet*> sets = series->barSets();
179 for (int i=0; i<sets.count(); i++) {
196 for (int i=0; i<sets.count(); i++) {
180 qreal pos = (qreal) i / (qreal) sets.count();
197 qreal pos = (qreal) i / (qreal) sets.count();
181 QColor c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), pos);
198 QColor c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), pos);
182 sets.at(i)->setBrush(QBrush(c));
199 sets.at(i)->setBrush(QBrush(c));
200
201 if (pos < 0.3) {
202 c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), 1);
203 } else {
204 c = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), 0);
205 }
206 sets.at(i)->setFloatingValuePen(QPen(c));
183 }
207 }
184 }
208 }
185
209
186 void ChartTheme::decorate(ScatterChartItem* item, QScatterSeries* series, int count)
210 void ChartTheme::decorate(ScatterChartItem* item, QScatterSeries* series, int count)
187 {
211 {
188 Q_ASSERT(item);
212 Q_ASSERT(item);
189 Q_ASSERT(series);
213 Q_ASSERT(series);
190
214
191 QColor color = m_seriesColors.at(count % m_seriesColors.size());
215 QColor color = m_seriesColors.at(count % m_seriesColors.size());
192 // TODO: define alpha in the theme? or in the series?
216 // TODO: define alpha in the theme? or in the series?
193 //color.setAlpha(120);
217 //color.setAlpha(120);
194
218
195 QBrush brush(color, Qt::SolidPattern);
219 QBrush brush(color, Qt::SolidPattern);
196 item->setBrush(Qt::blue);
220 item->setBrush(Qt::blue);
197
221
198 QPen pen(brush, 3);
222 QPen pen(brush, 3);
199 pen.setColor(color);
223 pen.setColor(color);
200 item->setPen(pen);
224 item->setPen(pen);
201 }
225 }
202
226
203 void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int count)
227 void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int count)
204 {
228 {
205 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
229 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
206 for (int i(0); i < series->slices().count(); i++) {
230 for (int i(0); i < series->slices().count(); i++) {
207 qreal pos = (qreal) i / (qreal) series->count();
231 qreal pos = (qreal) i / (qreal) series->count();
208 QColor penColor = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), 0.1);
232 QColor penColor = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), 0.1);
209 series->slices().at(i)->setSlicePen(penColor);
233 series->slices().at(i)->setSlicePen(penColor);
210 QColor brushColor = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), pos);
234 QColor brushColor = colorAt(m_seriesGradients.at(count % m_seriesGradients.size()), pos);
211 series->slices().at(i)->setSliceBrush(brushColor);
235 series->slices().at(i)->setSliceBrush(brushColor);
212 }
236 }
213 }
237 }
214
238
215
239
216 void ChartTheme::decorate(QChartAxis* axis, AxisItem* item)
240 void ChartTheme::decorate(QChartAxis* axis, AxisItem* item)
217 {
241 {
218 //TODO: dummy defults for now
242 //TODO: dummy defults for now
219 axis->setLabelsBrush(Qt::black);
243 axis->setLabelsBrush(Qt::black);
220 axis->setLabelsPen(Qt::NoPen);
244 axis->setLabelsPen(Qt::NoPen);
221 axis->setShadesPen(Qt::NoPen);
245 axis->setShadesPen(Qt::NoPen);
222 axis->setShadesOpacity(0.5);
246 axis->setShadesOpacity(0.5);
223 }
247 }
224
248
225 void ChartTheme::decorate(SplineChartItem* item, QSplineSeries* series, int count)
249 void ChartTheme::decorate(SplineChartItem* item, QSplineSeries* series, int count)
226 {
250 {
227 Q_ASSERT(item);
251 Q_ASSERT(item);
228 Q_ASSERT(series);
252 Q_ASSERT(series);
229
253
230 QPen pen;
254 QPen pen;
231
255
232 if(pen != series->pen()){
256 if(pen != series->pen()){
233 item->setLinePen(series->pen());
257 item->setLinePen(series->pen());
234 }else{
258 }else{
235 pen.setColor(m_seriesColors.at(count%m_seriesColors.size()));
259 pen.setColor(m_seriesColors.at(count%m_seriesColors.size()));
236 pen.setWidthF(series->pen().widthF());
260 pen.setWidthF(series->pen().widthF());
237 item->setLinePen(series->pen());
261 item->setLinePen(series->pen());
238 }
262 }
239
263
240 // QColor color = m_seriesColors.at(count % m_seriesColors.size());
264 // QColor color = m_seriesColors.at(count % m_seriesColors.size());
241 // TODO: define alpha in the theme? or in the series?
265 // TODO: define alpha in the theme? or in the series?
242 //color.setAlpha(120);
266 //color.setAlpha(120);
243
267
244 // QBrush brush(color, Qt::SolidPattern);
268 // QBrush brush(color, Qt::SolidPattern);
245 // presenter->m_markerBrush = brush;
269 // presenter->m_markerBrush = brush;
246
270
247 // QPen pen(brush, 3);
271 // QPen pen(brush, 3);
248 // pen.setColor(color);
272 // pen.setColor(color);
249 // presenter->m_markerPen = pen;
273 // presenter->m_markerPen = pen;
250 }
274 }
251
275
252 void ChartTheme::generateSeriesGradients()
276 void ChartTheme::generateSeriesGradients()
253 {
277 {
254 // Generate gradients in HSV color space
278 // Generate gradients in HSV color space
255 foreach (QColor color, m_seriesColors) {
279 foreach (QColor color, m_seriesColors) {
256 QLinearGradient g;
280 QLinearGradient g;
257 qreal h = color.hsvHueF();
281 qreal h = color.hsvHueF();
258 qreal s = color.hsvSaturationF();
282 qreal s = color.hsvSaturationF();
259
283
260 // TODO: tune the algorithm to give nice results with most base colors defined in
284 // TODO: tune the algorithm to give nice results with most base colors defined in
261 // most themes. The rest of the gradients we can define manually in theme specific
285 // most themes. The rest of the gradients we can define manually in theme specific
262 // implementation.
286 // implementation.
263 QColor start = color;
287 QColor start = color;
264 start.setHsvF(h, 0.05, 0.95);
288 start.setHsvF(h, 0.05, 0.95);
265 g.setColorAt(0.0, start);
289 g.setColorAt(0.0, start);
266
290
267 g.setColorAt(0.5, color);
291 g.setColorAt(0.5, color);
268
292
269 QColor end = color;
293 QColor end = color;
270 end.setHsvF(h, s, 0.25);
294 end.setHsvF(h, s, 0.25);
271 g.setColorAt(1.0, end);
295 g.setColorAt(1.0, end);
272
296
273 m_seriesGradients << g;
297 m_seriesGradients << g;
274 }
298 }
275 }
299 }
276
300
277
301
278 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
302 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
279 {
303 {
280 Q_ASSERT(pos >=0.0 && pos <= 1.0);
304 Q_ASSERT(pos >=0.0 && pos <= 1.0);
281 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
305 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
282 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
306 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
283 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
307 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
284 QColor c;
308 QColor c;
285 c.setRgbF(r, g, b);
309 c.setRgbF(r, g, b);
286 return c;
310 return c;
287 }
311 }
288
312
289 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
313 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
290 {
314 {
291 Q_ASSERT(pos >=0 && pos <= 1.0);
315 Q_ASSERT(pos >=0 && pos <= 1.0);
292
316
293 // another possibility:
317 // another possibility:
294 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
318 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
295
319
296 QGradientStops stops = gradient.stops();
320 QGradientStops stops = gradient.stops();
297 int count = stops.count();
321 int count = stops.count();
298
322
299 // find previous stop relative to position
323 // find previous stop relative to position
300 QGradientStop prev = stops.first();
324 QGradientStop prev = stops.first();
301 for (int i=0; i<count; i++) {
325 for (int i=0; i<count; i++) {
302 QGradientStop stop = stops.at(i);
326 QGradientStop stop = stops.at(i);
303 if (pos > stop.first)
327 if (pos > stop.first)
304 prev = stop;
328 prev = stop;
305
329
306 // given position is actually a stop position?
330 // given position is actually a stop position?
307 if (pos == stop.first) {
331 if (pos == stop.first) {
308 //qDebug() << "stop color" << pos;
332 //qDebug() << "stop color" << pos;
309 return stop.second;
333 return stop.second;
310 }
334 }
311 }
335 }
312
336
313 // find next stop relative to position
337 // find next stop relative to position
314 QGradientStop next = stops.last();
338 QGradientStop next = stops.last();
315 for (int i=count-1; i>=0; i--) {
339 for (int i=count-1; i>=0; i--) {
316 QGradientStop stop = stops.at(i);
340 QGradientStop stop = stops.at(i);
317 if (pos < stop.first)
341 if (pos < stop.first)
318 next = stop;
342 next = stop;
319 }
343 }
320
344
321 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
345 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
322
346
323 qreal range = next.first - prev.first;
347 qreal range = next.first - prev.first;
324 qreal posDelta = pos - prev.first;
348 qreal posDelta = pos - prev.first;
325 qreal relativePos = posDelta / range;
349 qreal relativePos = posDelta / range;
326
350
327 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
351 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
328
352
329 return colorAt(prev.second, next.second, relativePos);
353 return colorAt(prev.second, next.second, relativePos);
330 }
354 }
331
355
332 QTCOMMERCIALCHART_END_NAMESPACE
356 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now