##// END OF EJS Templates
Fix color generation for pie
Jani Honkonen -
r324:405c1f0ce037
parent child
Show More
@@ -1,229 +1,263
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
4 #include <QTime>
5
5
6 //series
6 //series
7 #include "qbarset.h"
7 #include "qbarset.h"
8 #include "qbarchartseries.h"
8 #include "qbarchartseries.h"
9 #include "qstackedbarchartseries.h"
9 #include "qstackedbarchartseries.h"
10 #include "qpercentbarchartseries.h"
10 #include "qpercentbarchartseries.h"
11 #include "qlinechartseries.h"
11 #include "qlinechartseries.h"
12 #include "qscatterseries.h"
12 #include "qscatterseries.h"
13 #include "qpieseries.h"
13 #include "qpieseries.h"
14 #include "qpieslice.h"
14 #include "qpieslice.h"
15
15
16 //items
16 //items
17 #include "axisitem_p.h"
17 #include "axisitem_p.h"
18 #include "barpresenter.h"
18 #include "barpresenter.h"
19 #include "stackedbarpresenter.h"
19 #include "stackedbarpresenter.h"
20 #include "linechartitem_p.h"
20 #include "linechartitem_p.h"
21 #include "percentbarpresenter.h"
21 #include "percentbarpresenter.h"
22 #include "scatterpresenter_p.h"
22 #include "scatterpresenter_p.h"
23 #include "piepresenter.h"
23 #include "piepresenter.h"
24
24
25 //themes
25 //themes
26 #include "chartthemevanilla_p.h"
26 #include "chartthemevanilla_p.h"
27 #include "chartthemeicy_p.h"
27 #include "chartthemeicy_p.h"
28 #include "chartthemegrayscale_p.h"
28 #include "chartthemegrayscale_p.h"
29 #include "chartthemescientific_p.h"
29 #include "chartthemescientific_p.h"
30
30
31
31
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33
33
34 /* TODO
34 /* TODO
35 case QChart::ChartThemeUnnamed1:
35 case QChart::ChartThemeUnnamed1:
36 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xff3fa9f5)), 2));
36 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xff3fa9f5)), 2));
37 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xff7AC943)), 2));
37 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xff7AC943)), 2));
38 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF931E)), 2));
38 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF931E)), 2));
39 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF1D25)), 2));
39 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF1D25)), 2));
40 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF7BAC)), 2));
40 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF7BAC)), 2));
41
41
42 m_gradientStartColor = QColor(QRgb(0xfff3dc9e));
42 m_gradientStartColor = QColor(QRgb(0xfff3dc9e));
43 m_gradientEndColor = QColor(QRgb(0xffafafaf));
43 m_gradientEndColor = QColor(QRgb(0xffafafaf));
44 */
44 */
45
45
46 ChartTheme::ChartTheme(QChart::ChartTheme id)
46 ChartTheme::ChartTheme(QChart::ChartTheme id)
47 {
47 {
48 m_id = id;
48 m_id = id;
49 m_seriesColor.append(QRgb(0xff000000));
49 m_seriesColor.append(QRgb(0xff000000));
50 m_seriesColor.append(QRgb(0xff707070));
50 m_seriesColor.append(QRgb(0xff707070));
51 m_gradientStartColor = QColor(QRgb(0xffffffff));
51 m_gradientStartColor = QColor(QRgb(0xffffffff));
52 m_gradientEndColor = QColor(QRgb(0xffafafaf));
52 m_gradientEndColor = QColor(QRgb(0xffafafaf));
53
54 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
53 }
55 }
54
56
55
57
56 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
58 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
57 {
59 {
58 switch(theme) {
60 switch(theme) {
59 case QChart::ChartThemeDefault:
61 case QChart::ChartThemeDefault:
60 return new ChartThemeIcy();
62 return new ChartThemeIcy();
61 case QChart::ChartThemeVanilla:
63 case QChart::ChartThemeVanilla:
62 return new ChartThemeVanilla();
64 return new ChartThemeVanilla();
63 case QChart::ChartThemeIcy:
65 case QChart::ChartThemeIcy:
64 return new ChartThemeIcy();
66 return new ChartThemeIcy();
65 case QChart::ChartThemeGrayscale:
67 case QChart::ChartThemeGrayscale:
66 return new ChartThemeGrayscale();
68 return new ChartThemeGrayscale();
67 case QChart::ChartThemeScientific:
69 case QChart::ChartThemeScientific:
68 return new ChartThemeScientific();
70 return new ChartThemeScientific();
69 }
71 }
70 }
72 }
71
73
72 void ChartTheme::decorate(QChart* chart)
74 void ChartTheme::decorate(QChart* chart)
73 {
75 {
74 QLinearGradient backgroundGradient;
76 QLinearGradient backgroundGradient;
75 backgroundGradient.setColorAt(0.0, m_gradientStartColor);
77 backgroundGradient.setColorAt(0.0, m_gradientStartColor);
76 backgroundGradient.setColorAt(1.0, m_gradientEndColor);
78 backgroundGradient.setColorAt(1.0, m_gradientEndColor);
77 backgroundGradient.setCoordinateMode(QGradient::ObjectBoundingMode);
79 backgroundGradient.setCoordinateMode(QGradient::ObjectBoundingMode);
78 chart->setChartBackgroundBrush(backgroundGradient);
80 chart->setChartBackgroundBrush(backgroundGradient);
79 }
81 }
80 //TODO helper to by removed later
82 //TODO helper to by removed later
81 void ChartTheme::decorate(ChartItem* item, QChartSeries* series,int count)
83 void ChartTheme::decorate(ChartItem* item, QChartSeries* series,int count)
82 {
84 {
83 switch(series->type())
85 switch(series->type())
84 {
86 {
85 case QChartSeries::SeriesTypeLine: {
87 case QChartSeries::SeriesTypeLine: {
86 QLineChartSeries* s = static_cast<QLineChartSeries*>(series);
88 QLineChartSeries* s = static_cast<QLineChartSeries*>(series);
87 LineChartItem* i = static_cast<LineChartItem*>(item);
89 LineChartItem* i = static_cast<LineChartItem*>(item);
88 decorate(i,s,count);
90 decorate(i,s,count);
89 break;
91 break;
90 }
92 }
91 case QChartSeries::SeriesTypeBar: {
93 case QChartSeries::SeriesTypeBar: {
92 QBarChartSeries* b = static_cast<QBarChartSeries*>(series);
94 QBarChartSeries* b = static_cast<QBarChartSeries*>(series);
93 BarPresenter* i = static_cast<BarPresenter*>(item);
95 BarPresenter* i = static_cast<BarPresenter*>(item);
94 decorate(i,b,count);
96 decorate(i,b,count);
95 break;
97 break;
96 }
98 }
97 case QChartSeries::SeriesTypeStackedBar: {
99 case QChartSeries::SeriesTypeStackedBar: {
98 QStackedBarChartSeries* s = static_cast<QStackedBarChartSeries*>(series);
100 QStackedBarChartSeries* s = static_cast<QStackedBarChartSeries*>(series);
99 StackedBarPresenter* i = static_cast<StackedBarPresenter*>(item);
101 StackedBarPresenter* i = static_cast<StackedBarPresenter*>(item);
100 decorate(i,s,count);
102 decorate(i,s,count);
101 break;
103 break;
102 }
104 }
103 case QChartSeries::SeriesTypePercentBar: {
105 case QChartSeries::SeriesTypePercentBar: {
104 QPercentBarChartSeries* s = static_cast<QPercentBarChartSeries*>(series);
106 QPercentBarChartSeries* s = static_cast<QPercentBarChartSeries*>(series);
105 PercentBarPresenter* i = static_cast<PercentBarPresenter*>(item);
107 PercentBarPresenter* i = static_cast<PercentBarPresenter*>(item);
106 decorate(i,s,count);
108 decorate(i,s,count);
107 break;
109 break;
108 }
110 }
109 case QChartSeries::SeriesTypeScatter: {
111 case QChartSeries::SeriesTypeScatter: {
110 QScatterSeries* s = qobject_cast<QScatterSeries*>(series);
112 QScatterSeries* s = qobject_cast<QScatterSeries*>(series);
111 Q_ASSERT(s);
113 Q_ASSERT(s);
112 ScatterPresenter* i = static_cast<ScatterPresenter*>(item);
114 ScatterPresenter* i = static_cast<ScatterPresenter*>(item);
113 Q_ASSERT(i);
115 Q_ASSERT(i);
114 decorate(i, s, count);
116 decorate(i, s, count);
115 break;
117 break;
116 }
118 }
117 case QChartSeries::SeriesTypePie: {
119 case QChartSeries::SeriesTypePie: {
118 QPieSeries* s = static_cast<QPieSeries*>(series);
120 QPieSeries* s = static_cast<QPieSeries*>(series);
119 PiePresenter* i = static_cast<PiePresenter*>(item);
121 PiePresenter* i = static_cast<PiePresenter*>(item);
120 decorate(i,s,count);
122 decorate(i,s,count);
121 break;
123 break;
122 }
124 }
123 default:
125 default:
124 qDebug()<<"Wrong item to be decorated by theme";
126 qDebug()<<"Wrong item to be decorated by theme";
125 break;
127 break;
126 }
128 }
127
129
128 }
130 }
129
131
130 void ChartTheme::decorate(LineChartItem* item, QLineChartSeries* series,int count)
132 void ChartTheme::decorate(LineChartItem* item, QLineChartSeries* series,int count)
131 {
133 {
132 QPen pen;
134 QPen pen;
133 if(pen != series->pen()){
135 if(pen != series->pen()){
134 item->setPen(series->pen());
136 item->setPen(series->pen());
135 return;
137 return;
136 }
138 }
137 pen.setColor(m_seriesColor.at(count%m_seriesColor.size()));
139 pen.setColor(m_seriesColor.at(count%m_seriesColor.size()));
138 pen.setWidthF(2);
140 pen.setWidthF(2);
139 item->setPen(pen);
141 item->setPen(pen);
140 }
142 }
141
143
142 void ChartTheme::decorate(BarPresenter* item, QBarChartSeries* series,int count)
144 void ChartTheme::decorate(BarPresenter* item, QBarChartSeries* series,int count)
143 {
145 {
144 for (int i=0; i<series->countSets(); i++) {
146 for (int i=0; i<series->countSets(); i++) {
145 series->nextSet(0==i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count())));
147 series->nextSet(0==i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count())));
146 }
148 }
147 }
149 }
148
150
149 void ChartTheme::decorate(StackedBarPresenter* item, QStackedBarChartSeries* series,int count)
151 void ChartTheme::decorate(StackedBarPresenter* item, QStackedBarChartSeries* series,int count)
150 {
152 {
151 for (int i=0; i<series->countSets(); i++) {
153 for (int i=0; i<series->countSets(); i++) {
152 series->nextSet(0==i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count())));
154 series->nextSet(0==i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count())));
153 }
155 }
154 }
156 }
155
157
156 void ChartTheme::decorate(PercentBarPresenter* item, QPercentBarChartSeries* series,int count)
158 void ChartTheme::decorate(PercentBarPresenter* item, QPercentBarChartSeries* series,int count)
157 {
159 {
158 for (int i=0; i<series->countSets(); i++) {
160 for (int i=0; i<series->countSets(); i++) {
159 series->nextSet(0==i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count())));
161 series->nextSet(0==i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count())));
160 }
162 }
161 }
163 }
162
164
163 void ChartTheme::decorate(ScatterPresenter* presenter, QScatterSeries* series, int count)
165 void ChartTheme::decorate(ScatterPresenter* presenter, QScatterSeries* series, int count)
164 {
166 {
165 Q_ASSERT(presenter);
167 Q_ASSERT(presenter);
166 Q_ASSERT(series);
168 Q_ASSERT(series);
167
169
168 QColor color = m_seriesColor.at(count % m_seriesColor.size());
170 QColor color = m_seriesColor.at(count % m_seriesColor.size());
169 // TODO: define alpha in the theme? or in the series?
171 // TODO: define alpha in the theme? or in the series?
170 //color.setAlpha(120);
172 //color.setAlpha(120);
171
173
172 QBrush brush(color, Qt::SolidPattern);
174 QBrush brush(color, Qt::SolidPattern);
173 presenter->m_markerBrush = brush;
175 presenter->m_markerBrush = brush;
174
176
175 QPen pen(brush, 3);
177 QPen pen(brush, 3);
176 pen.setColor(color);
178 pen.setColor(color);
177 presenter->m_markerPen = pen;
179 presenter->m_markerPen = pen;
178 }
180 }
179
181
180 void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int /*count*/)
182 void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int /*count*/)
181 {
183 {
182 // create a list of slice colors based on current theme
184 // create a list of slice colors based on current theme
183 int i = 0;
185 int i = 0;
184 QList<QColor> colors;
186 QList<QColor> colors;
185 while (colors.count() < series->count()) {
187 while (colors.count() < series->count()) {
186
188
187 // get base color
189 // get base color
188 QColor c = m_seriesColor[i++];
190 QColor c = m_seriesColor[i++];
189 i = i % m_seriesColor.count();
191 i = i % m_seriesColor.count();
190
192
191 // -1 means achromatic color -> cannot manipulate lightness
193 // by default use the "raw" theme color
192 // TODO: find a better way to randomize lightness
194 if (!colors.contains(c)) {
193 if (c.toHsv().hue() == -1)
195 colors << c;
194 qWarning() << "ChartTheme::decorate() warning: achromatic theme color";
196 continue;
197 }
198 // ...ok we need to generate something that looks like the same color
199 // but different lightness
200
201 int tryCount = 0;
202 while (tryCount++ < 100) {
195
203
196 // randomize lightness
204 // find maximum value we can raise the lightness
197 qreal f = 50 + (qrand() % 100); // 50 is 50% darker, 100 is the same, 150 is 50% lighter
205 int lMax = 255;
198 c = c.lighter(f);
206 if (lMax > 255 - c.red())
207 lMax = 255 - c.red();
208 if (lMax > 255 - c.green())
209 lMax = 255 - c.green();
210 if (lMax > 255 - c.blue())
211 lMax = 255 - c.blue();
199
212
200 // find duplicates
213 // find maximum value we can make it darker
201 bool isUnique = true;
214 int dMax = 255;
202 foreach (QColor color, colors) {
215 if (dMax > c.red())
203 if (c == color)
216 dMax = c.red();
204 isUnique = false;
217 if (dMax > c.green())
218 dMax = c.green();
219 if (dMax > c.blue())
220 dMax = c.blue();
221
222 int max = dMax + lMax;
223 if (max == 0) {
224 // no room to make color lighter or darker...
225 qDebug() << "cannot generate a color for pie!";
226 break;
227 }
228
229 // generate random color
230 int r = c.red() - dMax;
231 int g = c.green() - dMax;
232 int b = c.blue() - dMax;
233 int d = qrand() % max;
234 c.setRgb(r+d, g+d, b+d);
235
236 // found a unique color?
237 if (!colors.contains(c))
238 break;
205 }
239 }
206
240
207 // add to array if unique
241 qDebug() << "generated a color for pie" << c;
208 //if (isUnique)
242 colors << c;
209 colors << c;
210 }
243 }
211
244
212 // finally update colors
245 // finally update colors
213 foreach (QPieSlice* s, series->slices()) {
246 foreach (QPieSlice* s, series->slices()) {
214 s->setPen(QPen(Qt::black)); // TODO: get from theme
247 QColor c = colors.takeFirst();
215 s->setBrush(colors.takeFirst());
248 s->setPen(c);
249 s->setBrush(c);
216 }
250 }
217 }
251 }
218
252
219
253
220 void ChartTheme::decorate(QChartAxis* axis,AxisItem* item)
254 void ChartTheme::decorate(QChartAxis* axis,AxisItem* item)
221 {
255 {
222 //TODO: dummy defults for now
256 //TODO: dummy defults for now
223 axis->setLabelsBrush(Qt::black);
257 axis->setLabelsBrush(Qt::black);
224 axis->setLabelsPen(Qt::NoPen);
258 axis->setLabelsPen(Qt::NoPen);
225 axis->setShadesPen(Qt::NoPen);
259 axis->setShadesPen(Qt::NoPen);
226 axis->setShadesOpacity(0.5);
260 axis->setShadesOpacity(0.5);
227 }
261 }
228
262
229 QTCOMMERCIALCHART_END_NAMESPACE
263 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now