##// END OF EJS Templates
Bar series to use theme base colors. Pie brush minor fix....
Tero Ahola -
r661:4756f59398b8
parent child
Show More
@@ -1,243 +1,247
1 1 #include <QtGui/QApplication>
2 2 #include <QMainWindow>
3 3 #include <qchartglobal.h>
4 4 #include <qchartview.h>
5 5 #include <qpieseries.h>
6 6 #include <qpieslice.h>
7 #include <qbarseries.h>
7 8 #include <qpercentbarseries.h>
9 #include <qstackedbarseries.h>
8 10 #include <qbarset.h>
9 11 #include <QGridLayout>
10 12 #include <QFormLayout>
11 13 #include <QComboBox>
12 14 #include <QSpinBox>
13 15 #include <QCheckBox>
14 16 #include <QGroupBox>
15 17 #include <QLabel>
16 18 #include <QTime>
17 19 #include <qlineseries.h>
18 20 #include <qsplineseries.h>
19 21 #include <qscatterseries.h>
20 22 #include <qareaseries.h>
21 23
22 24 QTCOMMERCIALCHART_USE_NAMESPACE
23 25
24 26 typedef QPair<QPointF, QString> Data;
25 27 typedef QList<Data> DataList;
26 28 typedef QList<DataList> DataTable;
27 29
28 30
29 31 class MainWidget : public QWidget
30 32 {
31 33 Q_OBJECT
32 34
33 35 public:
34 36 explicit MainWidget(QWidget* parent = 0)
35 37 :QWidget(parent)
36 38 {
37 39 // set seed for random stuff
38 40 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
39 41
40 42 // generate random data
41 43 int listCount = 3;
42 44 int valueMax = 100;
43 45 int valueCount = 11;
44 46 for (int i(0); i < listCount; i++) {
45 47 DataList dataList;
46 48 for (int j(0); j < valueCount; j++) {
47 49 QPointF value(j + (qreal) rand() / (qreal) RAND_MAX, qrand() % valueMax);
48 50 QString label = QString::number(i) + ":" + QString::number(j);
49 51 dataList << Data(value, label);
50 52 }
51 53 m_dataTable << dataList;
52 54 }
53 55
54 56 // create layout
55 57 QGridLayout* baseLayout = new QGridLayout();
56 58
57 59 // settings layout
58 60 m_themeComboBox = new QComboBox();
59 61 m_themeComboBox->addItem("Default", QChart::ChartThemeDefault);
60 62 m_themeComboBox->addItem("Light", QChart::ChartThemeLight);
61 63 m_themeComboBox->addItem("Blue Cerulean", QChart::ChartThemeBlueCerulean);
62 64 m_themeComboBox->addItem("Dark", QChart::ChartThemeDark);
63 65 m_themeComboBox->addItem("Brown Sand", QChart::ChartThemeBrownSand);
64 66 m_themeComboBox->addItem("Blue NCS", QChart::ChartThemeBlueNcs);
65 67 m_themeComboBox->addItem("Vanilla", QChart::ChartThemeVanilla);
66 68 m_themeComboBox->addItem("Icy", QChart::ChartThemeIcy);
67 69 m_themeComboBox->addItem("Grayscale", QChart::ChartThemeGrayscale);
68 70 m_themeComboBox->addItem("Scientific", QChart::ChartThemeScientific);
69 71 connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this ,SLOT(updateTheme()));
70 72 QCheckBox *antialiasCheckBox = new QCheckBox("Anti aliasing");
71 73 connect(antialiasCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateAntialiasing(bool)));
72 74 QCheckBox *animatedCheckBox = new QCheckBox("Animated");
73 75 connect(animatedCheckBox, SIGNAL(toggled(bool)), this ,SLOT(updateAnimations(bool)));
74 76 QHBoxLayout *settingsLayout = new QHBoxLayout();
75 77 settingsLayout->addWidget(new QLabel("Theme:"));
76 78 settingsLayout->addWidget(m_themeComboBox);
77 79 settingsLayout->addWidget(antialiasCheckBox);
78 80 settingsLayout->addWidget(animatedCheckBox);
79 81 settingsLayout->addStretch();
80 82 baseLayout->addLayout(settingsLayout, 0, 0, 1, 3);
81 83
82 84 // area chart
83 85 QChartView *chart = new QChartView();
84 86 chart->setChartTitle("Area chart");
85 87 baseLayout->addWidget(chart, 1, 0);
86 88 {
87 89 for (int i(0); i < m_dataTable.count(); i++) {
88 90 QLineSeries *series1 = new QLineSeries(chart);
89 91 QLineSeries *series2 = new QLineSeries(chart);
90 92 foreach (Data data, m_dataTable[i]) {
91 93 series1->add(data.first);
92 94 series2->add(QPointF(data.first.x(), 0.0));
93 95 }
94 96 QAreaSeries *area = new QAreaSeries(series1, series2);
95 97 chart->addSeries(area);
96 98 }
97 99 }
98 100 m_charts << chart;
99 101
100 102 // bar chart
101 103 chart = new QChartView();
102 104 chart->setChartTitle("bar chart");
103 105 baseLayout->addWidget(chart, 1, 1);
104 106 {
105 107 QStringList categories;
106 108 // TODO: categories
107 109 for (int i(0); i < valueCount; i++)
108 110 categories << QString::number(i);
109 QPercentBarSeries* series = new QPercentBarSeries(categories, chart);
111 // QBarSeries* series = new QBarSeries(categories, chart);
112 // QPercentBarSeries* series = new QPercentBarSeries(categories, chart);
113 QStackedBarSeries* series = new QStackedBarSeries(categories, chart);
110 114 for (int i(0); i < m_dataTable.count(); i++) {
111 115 QBarSet *set = new QBarSet("Set" + QString::number(i));
112 116 foreach (Data data, m_dataTable[i])
113 117 *set << data.first.y();
114 118 series->addBarSet(set);
115 119 }
116 120 chart->addSeries(series);
117 121 }
118 122 m_charts << chart;
119 123
120 124 // line chart
121 125 chart = new QChartView();
122 126 chart->setChartTitle("line chart");
123 127 baseLayout->addWidget(chart, 1, 2);
124 128 foreach (DataList list, m_dataTable) {
125 129 QLineSeries *series = new QLineSeries(chart);
126 130 foreach (Data data, list)
127 131 series->add(data.first);
128 132 chart->addSeries(series);
129 133 }
130 134 m_charts << chart;
131 135
132 136 // pie chart
133 137 chart = new QChartView();
134 138 chart->setChartTitle("pie chart");
135 139 baseLayout->addWidget(chart, 2, 0);
136 140 qreal pieSize = 1.0 / m_dataTable.count();
137 141 for (int i=0; i<m_dataTable.count(); i++) {
138 142 QPieSeries *series = new QPieSeries(chart);
139 143 foreach (Data data, m_dataTable[i])
140 144 series->add(data.first.y(), data.second);
141 145 qreal hPos = (pieSize / 2) + (i / (qreal) m_dataTable.count());
142 146 series->setPieSize(pieSize);
143 147 series->setPiePosition(hPos, 0.5);
144 148 chart->addSeries(series);
145 149 }
146 150 m_charts << chart;
147 151
148 152 // spine chart
149 153 chart = new QChartView();
150 154 chart->setChartTitle("spline chart");
151 155 baseLayout->addWidget(chart, 2, 1);
152 156 foreach (DataList list, m_dataTable) {
153 157 QSplineSeries *series = new QSplineSeries(chart);
154 158 foreach (Data data, list)
155 159 series->add(data.first);
156 160 chart->addSeries(series);
157 161 }
158 162 m_charts << chart;
159 163
160 164 // scatter chart
161 165 chart = new QChartView();
162 166 chart->setChartTitle("scatter chart");
163 167 baseLayout->addWidget(chart, 2, 2);
164 168 foreach (DataList list, m_dataTable) {
165 169 QScatterSeries *series = new QScatterSeries(chart);
166 170 foreach (Data data, list)
167 171 series->add(data.first);
168 172 chart->addSeries(series);
169 173 }
170 174 m_charts << chart;
171 175
172 176 setLayout(baseLayout);
173 177 }
174 178
175 179 public Q_SLOTS:
176 180
177 181 void updateTheme()
178 182 {
179 183 QChart::ChartTheme theme = (QChart::ChartTheme) m_themeComboBox->itemData(m_themeComboBox->currentIndex()).toInt();
180 184 foreach (QChartView *chart, m_charts)
181 185 chart->setChartTheme(theme);
182 186
183 187 QPalette pal = window()->palette();
184 188 if (theme == QChart::ChartThemeLight) {
185 189 pal.setColor(QPalette::Window, QRgb(0xf0f0f0));
186 190 pal.setColor(QPalette::WindowText, QRgb(0x404044));
187 191 } else if (theme == QChart::ChartThemeDark) {
188 192 pal.setColor(QPalette::Window, QRgb(0x121218));
189 193 pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6));
190 194 } else if (theme == QChart::ChartThemeBlueCerulean) {
191 195 pal.setColor(QPalette::Window, QRgb(0x40434a));
192 196 pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6));
193 197 } else if (theme == QChart::ChartThemeBrownSand) {
194 198 pal.setColor(QPalette::Window, QRgb(0x9e8965));
195 199 pal.setColor(QPalette::WindowText, QRgb(0x404044));
196 200 } else if (theme == QChart::ChartThemeBlueNcs) {
197 201 pal.setColor(QPalette::Window, QRgb(0x018bba));
198 202 pal.setColor(QPalette::WindowText, QRgb(0x404044));
199 203 } else {
200 204 pal.setColor(QPalette::Window, QRgb(0xf0f0f0));
201 205 pal.setColor(QPalette::WindowText, QRgb(0x404044));
202 206 }
203 207 window()->setPalette(pal);
204 208 }
205 209
206 210 void updateAntialiasing(bool enabled)
207 211 {
208 212 foreach (QChartView *chart, m_charts)
209 213 chart->setRenderHint(QPainter::Antialiasing, enabled);
210 214 }
211 215
212 216 void updateAnimations(bool animated)
213 217 {
214 218 QChart::AnimationOptions options = QChart::NoAnimation;
215 219 if (animated)
216 220 options = QChart::AllAnimations;
217 221
218 222 foreach (QChartView *chart, m_charts)
219 223 chart->setAnimationOptions(options);
220 224 }
221 225
222 226 private:
223 227 QList<QChartView*> m_charts;
224 228 QComboBox *m_themeComboBox;
225 229 DataTable m_dataTable;
226 230 };
227 231
228 232 int main(int argc, char *argv[])
229 233 {
230 234 QApplication a(argc, argv);
231 235
232 236 QMainWindow window;
233 237
234 238 MainWidget* widget = new MainWidget();
235 239
236 240 window.setCentralWidget(widget);
237 241 window.resize(900, 600);
238 242 window.show();
239 243
240 244 return a.exec();
241 245 }
242 246
243 247 #include "main.moc"
@@ -1,87 +1,88
1 1 #include "barpresenter_p.h"
2 2 #include "bar_p.h"
3 3 #include "barvalue_p.h"
4 4 #include "qbarset.h"
5 5 #include <QDebug>
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 9 BarPresenter::BarPresenter(QBarSeries *series, QChart *parent) :
10 10 BarPresenterBase(series, parent)
11 11 {
12 12 connect(series, SIGNAL(updatedBars()), this, SLOT(layoutChanged()));
13 13 }
14 14
15 15 void BarPresenter::layoutChanged()
16 16 {
17 17 // Scale bars to new layout
18 18 // Layout for bars:
19 19 if (mSeries->barsetCount() <= 0) {
20 20 qDebug() << "No sets in model!";
21 21 return;
22 22 }
23 23
24 24 if (childItems().count() == 0) {
25 25 qDebug() << "WARNING: BarPresenter::layoutChanged called before graphics items are created!";
26 26 return;
27 27 }
28 28
29 29 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
30 30 int categoryCount = mSeries->categoryCount();
31 31 int setCount = mSeries->barsetCount();
32 32
33 33 qreal tW = mWidth;
34 34 qreal tH = mHeight;
35 35 qreal tM = mSeries->max();
36 36 qreal scale = (tH/tM);
37 37 qreal tC = categoryCount + 1;
38 38 qreal categoryWidth = tW/tC;
39 39 mBarWidth = categoryWidth / (setCount+1);
40 40
41 41 int itemIndex(0);
42 42 for (int category=0; category < categoryCount; category++) {
43 43 qreal xPos = categoryWidth * category + categoryWidth /2 + mBarWidth/2;
44 44 qreal yPos = mHeight;
45 45 for (int set = 0; set < setCount; set++) {
46 46 qreal barHeight = mSeries->valueAt(set,category) * scale;
47 47 Bar* bar = mBars.at(itemIndex);
48 48
49 49 // TODO: width settable per bar?
50 50 bar->resize(mBarWidth, barHeight);
51 bar->setPen(mSeries->barsetAt(set)->pen());
51 52 bar->setBrush(mSeries->barsetAt(set)->brush());
52 53 bar->setPos(xPos, yPos-barHeight);
53 54 itemIndex++;
54 55 xPos += mBarWidth;
55 56 }
56 57 }
57 58
58 59 // Position floating values
59 60 itemIndex = 0;
60 61 for (int category=0; category < mSeries->categoryCount(); category++) {
61 62 qreal xPos = categoryWidth * category + categoryWidth/2 + mBarWidth;
62 63 qreal yPos = mHeight;
63 64 for (int set=0; set < mSeries->barsetCount(); set++) {
64 65 qreal barHeight = mSeries->valueAt(set,category) * scale;
65 66 BarValue* value = mFloatingValues.at(itemIndex);
66 67
67 68 QBarSet* barSet = mSeries->barsetAt(set);
68 69 value->resize(100,50); // TODO: proper layout for this.
69 70 value->setPos(xPos, yPos-barHeight/2);
70 71 value->setPen(barSet->floatingValuePen());
71 72
72 73 if (mSeries->valueAt(set,category) != 0) {
73 74 value->setValueString(QString::number(mSeries->valueAt(set,category)));
74 75 } else {
75 76 value->setValueString(QString(""));
76 77 }
77 78
78 79 itemIndex++;
79 80 xPos += mBarWidth;
80 81 }
81 82 }
82 83 update();
83 84 }
84 85
85 86 #include "moc_barpresenter_p.cpp"
86 87
87 88 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,96 +1,97
1 1 #include "stackedbarpresenter_p.h"
2 2 #include "bar_p.h"
3 3 #include "barvalue_p.h"
4 4 #include "qbarset.h"
5 5 #include <QDebug>
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 9 StackedBarPresenter::StackedBarPresenter(QBarSeries *series, QChart *parent) :
10 10 BarPresenterBase(series,parent)
11 11 {
12 12 }
13 13
14 14 StackedBarPresenter::~StackedBarPresenter()
15 15 {
16 16 }
17 17
18 18
19 19 void StackedBarPresenter::layoutChanged()
20 20 {
21 21 // Scale bars to new layout
22 22 // Layout for bars:
23 23 if (mSeries->barsetCount() <= 0) {
24 24 qDebug() << "No sets in model!";
25 25 // Nothing to do.
26 26 return;
27 27 }
28 28
29 29 if (mSeries->categoryCount() == 0) {
30 30 qDebug() << "No categories in model!";
31 31 // Nothing to do
32 32 return;
33 33 }
34 34
35 35 if (childItems().count() == 0) {
36 36 qDebug() << "WARNING: StackedBarPresenter::layoutChanged called before graphics items are created!";
37 37 return;
38 38 }
39 39
40 40 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
41 41 qreal maxSum = mSeries->maxCategorySum();
42 42 qreal h = mHeight;
43 43 qreal scale = (h / maxSum);
44 44 qreal tW = mWidth;
45 45 qreal tC = mSeries->categoryCount() + 1;
46 46 qreal cC = mSeries->categoryCount() * 2 + 1;
47 47 mBarWidth = tW / cC;
48 48 qreal xStep = (tW/tC);
49 49 qreal xPos = ((tW/tC) - mBarWidth / 2);
50 50
51 51 int itemIndex(0);
52 52 for (int category = 0; category < mSeries->categoryCount(); category++) {
53 53 qreal yPos = h;
54 54 for (int set=0; set < mSeries->barsetCount(); set++) {
55 55 qreal barHeight = mSeries->valueAt(set, category) * scale;
56 56 Bar* bar = mBars.at(itemIndex);
57 57
58 58 bar->resize(mBarWidth, barHeight);
59 bar->setPen(mSeries->barsetAt(set)->pen());
59 60 bar->setBrush(mSeries->barsetAt(set)->brush());
60 61 bar->setPos(xPos, yPos-barHeight);
61 62 itemIndex++;
62 63 yPos -= barHeight;
63 64 }
64 65 xPos += xStep;
65 66 }
66 67
67 68 // Position floating values
68 69 itemIndex = 0;
69 70 xPos = (tW/tC);
70 71 for (int category=0; category < mSeries->categoryCount(); category++) {
71 72 qreal yPos = h;
72 73 for (int set=0; set < mSeries->barsetCount(); set++) {
73 74 qreal barHeight = mSeries->valueAt(set,category) * scale;
74 75 BarValue* value = mFloatingValues.at(itemIndex);
75 76
76 77 QBarSet* barSet = mSeries->barsetAt(set);
77 78 value->resize(100,50); // TODO: proper layout for this.
78 79 value->setPos(xPos, yPos-barHeight/2);
79 80 value->setPen(barSet->floatingValuePen());
80 81
81 82 if (mSeries->valueAt(set,category) != 0) {
82 83 value->setValueString(QString::number(mSeries->valueAt(set,category)));
83 84 } else {
84 85 value->setValueString(QString(""));
85 86 }
86 87
87 88 itemIndex++;
88 89 yPos -= barHeight;
89 90 }
90 91 xPos += xStep;
91 92 }
92 93 }
93 94
94 95 #include "moc_stackedbarpresenter_p.cpp"
95 96
96 97 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,352 +1,365
1 1 #include "charttheme_p.h"
2 2 #include "qchart.h"
3 3 #include "qchartview.h"
4 4 #include "qlegend.h"
5 5 #include "qchartaxis.h"
6 6 #include <QTime>
7 7
8 8 //series
9 9 #include "qbarset.h"
10 10 #include "qbarseries.h"
11 11 #include "qstackedbarseries.h"
12 12 #include "qpercentbarseries.h"
13 13 #include "qlineseries.h"
14 14 #include "qareaseries.h"
15 15 #include "qscatterseries.h"
16 16 #include "qpieseries.h"
17 17 #include "qpieslice.h"
18 18 #include "qsplineseries.h"
19 19
20 20 //items
21 21 #include "axisitem_p.h"
22 22 #include "barpresenter_p.h"
23 23 #include "stackedbarpresenter_p.h"
24 24 #include "percentbarpresenter_p.h"
25 25 #include "linechartitem_p.h"
26 26 #include "areachartitem_p.h"
27 27 #include "scatterchartitem_p.h"
28 28 #include "piechartitem_p.h"
29 29 #include "splinechartitem_p.h"
30 30
31 31 //themes
32 32 #include "chartthemedefault_p.h"
33 33 #include "chartthemelight_p.h"
34 34 #include "chartthemebluecerulean_p.h"
35 35 #include "chartthemedark_p.h"
36 36 #include "chartthemebrownsand_p.h"
37 37 #include "chartthemebluencs_p.h"
38 38 #include "chartthemevanilla_p.h"
39 39 #include "chartthemeicy_p.h"
40 40 #include "chartthemegrayscale_p.h"
41 41 #include "chartthemescientific_p.h"
42 42
43 43 QTCOMMERCIALCHART_BEGIN_NAMESPACE
44 44
45 45 ChartTheme::ChartTheme(QChart::ChartTheme id) :
46 46 m_masterFont(QFont()),
47 47 m_titleBrush(QColor(QRgb(0x000000))),
48 48 m_axisLinePen(QPen(QRgb(0x000000))),
49 49 m_axisLabelBrush(QColor(QRgb(0x000000))),
50 50 m_backgroundShadesPen(Qt::NoPen),
51 51 m_backgroundShadesBrush(Qt::NoBrush),
52 52 m_backgroundShades(BackgroundShadesNone),
53 53 m_gridLinePen(QPen(QRgb(0x000000)))
54 54 {
55 55 m_id = id;
56 56 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
57 57 }
58 58
59 59
60 60 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
61 61 {
62 62 switch(theme) {
63 63 case QChart::ChartThemeLight:
64 64 return new ChartThemeLight();
65 65 case QChart::ChartThemeBlueCerulean:
66 66 return new ChartThemeBlueCerulean();
67 67 case QChart::ChartThemeDark:
68 68 return new ChartThemeDark();
69 69 case QChart::ChartThemeBrownSand:
70 70 return new ChartThemeBrownSand();
71 71 case QChart::ChartThemeBlueNcs:
72 72 return new ChartThemeBlueNcs();
73 73 case QChart::ChartThemeVanilla:
74 74 return new ChartThemeVanilla();
75 75 case QChart::ChartThemeIcy:
76 76 return new ChartThemeIcy();
77 77 case QChart::ChartThemeGrayscale:
78 78 return new ChartThemeGrayscale();
79 79 case QChart::ChartThemeScientific:
80 80 return new ChartThemeScientific();
81 81 default:
82 82 return new ChartThemeDefault();
83 83 }
84 84 }
85 85
86 86 void ChartTheme::decorate(QChart* chart,bool force)
87 87 {
88 88 QPen pen;
89 89 QBrush brush;
90 90
91 91 if(brush == chart->backgroundBrush() || force)
92 92 {
93 93 if (m_backgroundShades == BackgroundShadesNone) {
94 94 chart->setBackgroundBrush(m_chartBackgroundGradient);
95 95 }
96 96 else {
97 97 chart->setBackgroundBrush(Qt::NoBrush);
98 98 }
99 99 }
100 100 chart->setTitleFont(m_masterFont);
101 101 chart->setTitleBrush(m_titleBrush);
102 102 }
103 103
104 104 void ChartTheme::decorate(QLegend* legend,bool force)
105 105 {
106 106 QPen pen;
107 107 QBrush brush;
108 108
109 109 if (pen == legend->pen() || force){
110 110 //TODO:: legend->setPen();
111 111 }
112 112
113 113
114 114 if (brush == legend->brush() || force) {
115 115 legend->setBrush(m_chartBackgroundGradient);
116 116 }
117 117 }
118 118
119 119 void ChartTheme::decorate(QAreaSeries* series, int index,bool force)
120 120 {
121 121 QPen pen;
122 122 QBrush brush;
123 123
124 124 if (pen == series->pen() || force){
125 125 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
126 126 pen.setWidthF(2);
127 127 series->setPen(pen);
128 128 }
129 129
130 130 if (brush == series->brush() || force) {
131 131 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
132 132 series->setBrush(brush);
133 133 }
134 134 }
135 135
136 136
137 137 void ChartTheme::decorate(QLineSeries* series,int index,bool force)
138 138 {
139 139 QPen pen;
140 140 if(pen == series->pen() || force ){
141 141 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
142 142 pen.setWidthF(2);
143 143 series->setPen(pen);
144 144 }
145 145 }
146 146
147 147 void ChartTheme::decorate(QBarSeries* series, int index, bool force)
148 148 {
149 149 QBrush brush;
150 150 QPen pen;
151 151 QList<QBarSet*> sets = series->barSets();
152 152
153 for (int i(0); i < sets.count(); i++) {
154 qreal pos = 0.5;
155 if (sets.count() > 1)
156 pos = (qreal) i / (qreal) (sets.count() - 1);
157
158 if (brush == sets.at(i)->brush() || force ) {
159 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
160 sets.at(i)->setBrush(QBrush(c));
153 qreal takeAtPos = 0.5;
154 qreal step = 0.2;
155 if (sets.count() > 1 ) {
156 step = 1.0 / (qreal) sets.count();
157 if (sets.count() % m_seriesGradients.count())
158 step *= m_seriesGradients.count();
159 else
160 step *= (m_seriesGradients.count() - 1);
161 161 }
162 162
163 for (int i(0); i < sets.count(); i++) {
164 int colorIndex = (index + i) % m_seriesGradients.count();
165 if (i > 0 && i % m_seriesGradients.count() == 0) {
166 // There is no dedicated base color for each sets, generate more colors
167 takeAtPos += step;
168 if (takeAtPos == 1.0)
169 takeAtPos += step;
170 takeAtPos -= (int) takeAtPos;
171 }
172 qDebug() << "pos:" << takeAtPos;
173 if (brush == sets.at(i)->brush() || force )
174 sets.at(i)->setBrush(colorAt(m_seriesGradients.at(colorIndex), takeAtPos));
175
163 176 // Pick label color from the opposite end of the gradient.
164 177 // 0.3 as a boundary seems to work well.
165 if (pos < 0.3)
178 if (takeAtPos < 0.3)
166 179 sets.at(i)->setFloatingValuePen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1));
167 180 else
168 181 sets.at(i)->setFloatingValuePen(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0));
169 182
170 183 if (pen == sets.at(i)->pen() || force) {
171 184 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
172 185 sets.at(i)->setPen(c);
173 186 }
174 187 }
175 188 }
176 189
177 190 void ChartTheme::decorate(QScatterSeries* series, int index,bool force)
178 191 {
179 192 QPen pen;
180 193 QBrush brush;
181 194
182 195 if (pen == series->pen() || force) {
183 196 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
184 197 pen.setWidthF(2);
185 198 series->setPen(pen);
186 199 }
187 200
188 201 if (brush == series->brush() || force) {
189 202 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
190 203 series->setBrush(brush);
191 204 }
192 205 }
193 206
194 207 void ChartTheme::decorate(QPieSeries* series, int index, bool force)
195 208 {
196 209 QPen pen;
197 210 QBrush brush;
198 211
199 212 for (int i(0); i < series->slices().count(); i++) {
200 213 if (pen == series->slices().at(i)->slicePen() || force) {
201 214 QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
202 215 series->slices().at(i)->setSlicePen(penColor);
203 216 }
204 217
205 218 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
206 qreal pos = (qreal) i / (qreal) series->count();
219 qreal pos = (qreal) (i + 1) / (qreal) series->count();
207 220 if (brush == series->slices().at(i)->sliceBrush() || force) {
208 221 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
209 222 series->slices().at(i)->setSliceBrush(brushColor);
210 223 }
211 224 }
212 225 }
213 226
214 227 void ChartTheme::decorate(QSplineSeries* series, int index, bool force)
215 228 {
216 229 QPen pen;
217 230 if(pen == series->pen() || force){
218 231 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
219 232 pen.setWidthF(2);
220 233 series->setPen(pen);
221 234 }
222 235 }
223 236
224 237 void ChartTheme::decorate(QChartAxis* axis,bool axisX, bool force)
225 238 {
226 239 QPen pen;
227 240 QBrush brush;
228 241 QFont font;
229 242
230 243 if (axis->isAxisVisible()) {
231 244
232 245 if(brush == axis->labelsBrush() || force){
233 246 axis->setLabelsBrush(m_axisLabelBrush);
234 247 }
235 248 if(pen == axis->labelsPen() || force){
236 249 axis->setLabelsPen(Qt::NoPen); // NoPen for performance reasons
237 250 }
238 251
239 252
240 253 if (axis->shadesVisible() || force) {
241 254
242 255 if(brush == axis->shadesBrush() || force){
243 256 axis->setShadesBrush(m_backgroundShadesBrush);
244 257 }
245 258
246 259 if(pen == axis->shadesPen() || force){
247 260 axis->setShadesPen(m_backgroundShadesPen);
248 261 }
249 262
250 263 if(force && (m_backgroundShades == BackgroundShadesBoth
251 264 || (m_backgroundShades == BackgroundShadesVertical && axisX)
252 265 || (m_backgroundShades == BackgroundShadesHorizontal && !axisX))){
253 266 axis->setShadesVisible(true);
254 267
255 268 }
256 269 }
257 270
258 271 if(pen == axis->axisPen() || force){
259 272 axis->setAxisPen(m_axisLinePen);
260 273 }
261 274
262 275 if(pen == axis->gridLinePen() || force){
263 276 axis->setGridLinePen(m_gridLinePen);
264 277 }
265 278
266 279 if(font == axis->labelsFont() || force){
267 280 axis->setLabelsFont(m_masterFont);
268 281 }
269 282 }
270 283 }
271 284
272 285 void ChartTheme::generateSeriesGradients()
273 286 {
274 287 // Generate gradients in HSV color space
275 288 foreach (QColor color, m_seriesColors) {
276 289 QLinearGradient g;
277 290 qreal h = color.hsvHueF();
278 291 qreal s = color.hsvSaturationF();
279 292
280 293 // TODO: tune the algorithm to give nice results with most base colors defined in
281 294 // most themes. The rest of the gradients we can define manually in theme specific
282 295 // implementation.
283 296 QColor start = color;
284 297 start.setHsvF(h, 0.0, 1.0);
285 298 g.setColorAt(0.0, start);
286 299
287 300 g.setColorAt(0.5, color);
288 301
289 302 QColor end = color;
290 303 end.setHsvF(h, s, 0.25);
291 304 g.setColorAt(1.0, end);
292 305
293 306 m_seriesGradients << g;
294 307 }
295 308 }
296 309
297 310
298 311 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
299 312 {
300 313 Q_ASSERT(pos >=0.0 && pos <= 1.0);
301 314 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
302 315 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
303 316 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
304 317 QColor c;
305 318 c.setRgbF(r, g, b);
306 319 return c;
307 320 }
308 321
309 322 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
310 323 {
311 324 Q_ASSERT(pos >=0 && pos <= 1.0);
312 325
313 326 // another possibility:
314 327 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
315 328
316 329 QGradientStops stops = gradient.stops();
317 330 int count = stops.count();
318 331
319 332 // find previous stop relative to position
320 333 QGradientStop prev = stops.first();
321 334 for (int i=0; i<count; i++) {
322 335 QGradientStop stop = stops.at(i);
323 336 if (pos > stop.first)
324 337 prev = stop;
325 338
326 339 // given position is actually a stop position?
327 340 if (pos == stop.first) {
328 341 //qDebug() << "stop color" << pos;
329 342 return stop.second;
330 343 }
331 344 }
332 345
333 346 // find next stop relative to position
334 347 QGradientStop next = stops.last();
335 348 for (int i=count-1; i>=0; i--) {
336 349 QGradientStop stop = stops.at(i);
337 350 if (pos < stop.first)
338 351 next = stop;
339 352 }
340 353
341 354 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
342 355
343 356 qreal range = next.first - prev.first;
344 357 qreal posDelta = pos - prev.first;
345 358 qreal relativePos = posDelta / range;
346 359
347 360 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
348 361
349 362 return colorAt(prev.second, next.second, relativePos);
350 363 }
351 364
352 365 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,165 +1,168
1 1 #include "dataseriedialog.h"
2 2 #include <QDialogButtonBox>
3 3 #include <QGridLayout>
4 4 #include <QCheckBox>
5 5 #include <QPushButton>
6 6 #include <QGroupBox>
7 7 #include <QRadioButton>
8 8 #include <QLabel>
9 9 #include <QDebug>
10 10
11 11 DataSerieDialog::DataSerieDialog(QWidget *parent) :
12 12 QDialog(parent)
13 13 {
14 14 QDialogButtonBox *addSeriesBox = new QDialogButtonBox(Qt::Horizontal);
15 15 QPushButton *b = addSeriesBox->addButton(QDialogButtonBox::Ok);
16 16 connect(b, SIGNAL(clicked()), this, SLOT(accept()));
17 17 b = addSeriesBox->addButton(QDialogButtonBox::Cancel);
18 18 connect(b, SIGNAL(clicked()), this, SLOT(reject()));
19 19
20 20 QGridLayout *grid = new QGridLayout();
21 21
22 22 m_seriesTypeSelector = seriesTypeSelector();
23 23 m_columnCountSelector = columnCountSelector();
24 24 m_rowCountSelector = rowCountSelector();
25 25 m_dataCharacteristicsSelector = dataCharacteristicsSelector();
26 26
27 27 grid->addWidget(m_seriesTypeSelector, 0, 0);
28 28 grid->addWidget(m_columnCountSelector, 0, 1);
29 29 grid->addWidget(m_rowCountSelector, 1, 1);
30 30 grid->addWidget(m_dataCharacteristicsSelector, 1, 0);
31 31 m_labelsSelector = new QCheckBox("Labels defined");
32 32 m_labelsSelector->setChecked(true);
33 33 grid->addWidget(m_labelsSelector, 2, 0);
34 34 grid->addWidget(addSeriesBox, 3, 1);
35 35
36 36 setLayout(grid);
37 37 }
38 38
39 39 QGroupBox *DataSerieDialog::seriesTypeSelector()
40 40 {
41 41 QVBoxLayout *layout = new QVBoxLayout();
42 42
43 43 QRadioButton *line = new QRadioButton("Line");
44 44 line->setChecked(true);
45 45 layout->addWidget(line);
46 46 layout->addWidget(new QRadioButton("Area"));
47 47 layout->addWidget(new QRadioButton("Pie"));
48 48 layout->addWidget(new QRadioButton("Bar"));
49 49 layout->addWidget(new QRadioButton("Stacked bar"));
50 50 layout->addWidget(new QRadioButton("Percent bar"));
51 51 layout->addWidget(new QRadioButton("Scatter"));
52 52 layout->addWidget(new QRadioButton("Spline"));
53 53
54 54 QGroupBox *groupBox = new QGroupBox("Series type");
55 55 groupBox->setLayout(layout);
56 56 selectRadio(groupBox, 0);
57 57
58 58 return groupBox;
59 59 }
60 60
61 61 QGroupBox *DataSerieDialog::columnCountSelector()
62 62 {
63 63 QVBoxLayout *layout = new QVBoxLayout();
64 64
65 65 QRadioButton *radio = new QRadioButton("1");
66 66 radio->setChecked(true);
67 67 layout->addWidget(radio);
68 68 layout->addWidget(new QRadioButton("2"));
69 69 layout->addWidget(new QRadioButton("3"));
70 layout->addWidget(new QRadioButton("4"));
70 71 layout->addWidget(new QRadioButton("5"));
72 layout->addWidget(new QRadioButton("8"));
71 73 layout->addWidget(new QRadioButton("10"));
72 74 layout->addWidget(new QRadioButton("100"));
73 75
74 76 QGroupBox *groupBox = new QGroupBox("Column count");
75 77 groupBox->setLayout(layout);
76 78 selectRadio(groupBox, 0);
77 79
78 80 return groupBox;
79 81 }
80 82
81 83 QGroupBox *DataSerieDialog::rowCountSelector()
82 84 {
83 85 QVBoxLayout *layout = new QVBoxLayout();
84 86
85 87 layout->addWidget(new QRadioButton("1"));
86 88 QRadioButton *radio = new QRadioButton("10");
87 89 radio->setChecked(true);
88 90 layout->addWidget(radio);
89 91 layout->addWidget(new QRadioButton("50"));
90 92 layout->addWidget(new QRadioButton("100"));
91 93 layout->addWidget(new QRadioButton("10000"));
94 layout->addWidget(new QRadioButton("100000"));
92 95 layout->addWidget(new QRadioButton("1000000"));
93 96
94 97 QGroupBox *groupBox = new QGroupBox("Row count");
95 98 groupBox->setLayout(layout);
96 99 selectRadio(groupBox, 0);
97 100
98 101 return groupBox;
99 102 }
100 103
101 104 QGroupBox *DataSerieDialog::dataCharacteristicsSelector()
102 105 {
103 106 QVBoxLayout *layout = new QVBoxLayout();
104 107
105 108 layout->addWidget(new QRadioButton("Linear"));
106 109 layout->addWidget(new QRadioButton("Constant"));
107 110 layout->addWidget(new QRadioButton("Random"));
108 111 layout->addWidget(new QRadioButton("Sin"));
109 112 layout->addWidget(new QRadioButton("Sin + random"));
110 113
111 114 QGroupBox *groupBox = new QGroupBox("Data Characteristics");
112 115 groupBox->setLayout(layout);
113 116 selectRadio(groupBox, 0);
114 117
115 118 return groupBox;
116 119 }
117 120
118 121 void DataSerieDialog::accept()
119 122 {
120 123 accepted(radioSelection(m_seriesTypeSelector),
121 124 radioSelection(m_columnCountSelector).toInt(),
122 125 radioSelection(m_rowCountSelector).toInt(),
123 126 radioSelection(m_dataCharacteristicsSelector),
124 127 m_labelsSelector->isChecked());
125 128 QDialog::accept();
126 129 }
127 130
128 131 void DataSerieDialog::selectRadio(QGroupBox *groupBox, int defaultSelection)
129 132 {
130 133 QVBoxLayout *layout = qobject_cast<QVBoxLayout *>(groupBox->layout());
131 134 Q_ASSERT(layout);
132 135 Q_ASSERT(layout->count());
133 136
134 137 QLayoutItem *item = 0;
135 138 if (defaultSelection == -1) {
136 139 item = layout->itemAt(0);
137 140 } else if (layout->count() > defaultSelection) {
138 141 item = layout->itemAt(defaultSelection);
139 142 }
140 143 Q_ASSERT(item);
141 144 QRadioButton *radio = qobject_cast<QRadioButton *>(item->widget());
142 145 Q_ASSERT(radio);
143 146 radio->setChecked(true);
144 147 }
145 148
146 149 QString DataSerieDialog::radioSelection(QGroupBox *groupBox)
147 150 {
148 151 QString selection;
149 152 QVBoxLayout *layout = qobject_cast<QVBoxLayout *>(groupBox->layout());
150 153 Q_ASSERT(layout);
151 154
152 155 for (int i(0); i < layout->count(); i++) {
153 156 QLayoutItem *item = layout->itemAt(i);
154 157 Q_ASSERT(item);
155 158 QRadioButton *radio = qobject_cast<QRadioButton *>(item->widget());
156 159 Q_ASSERT(radio);
157 160 if (radio->isChecked()) {
158 161 selection = radio->text();
159 162 break;
160 163 }
161 164 }
162 165
163 166 qDebug() << "radioSelection: " << selection;
164 167 return selection;
165 168 }
General Comments 0
You need to be logged in to leave comments. Login now