##// END OF EJS Templates
Drafting pie theme stuff
Jani Honkonen -
r166:340263587b9e
parent child
Show More
@@ -1,263 +1,264
1 1 #include "qchart.h"
2 2 #include "qchartaxis.h"
3 3 #include "chartpresenter_p.h"
4 4 #include "chartdataset_p.h"
5 5 #include "charttheme_p.h"
6 6 //series
7 7 #include "barchartseries.h"
8 8 #include "stackedbarchartseries.h"
9 9 #include "percentbarchartseries.h"
10 10 #include "qlinechartseries.h"
11 11 #include "qpieseries.h"
12 12 #include "qscatterseries.h"
13 13 //items
14 14 #include "axisitem_p.h"
15 15 #include "bargroup.h"
16 16 #include "stackedbargroup.h"
17 17 #include "linechartitem_p.h"
18 18 #include "percentbargroup.h"
19 19 #include "linechartanimationitem_p.h"
20 20 #include "piepresenter.h"
21 21 #include "scatterpresenter.h"
22 22
23 23 QTCOMMERCIALCHART_BEGIN_NAMESPACE
24 24
25 25 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
26 26 m_chart(chart),
27 27 m_dataset(dataset),
28 28 m_chartTheme(0),
29 29 m_domainIndex(0),
30 30 m_marginSize(0),
31 31 m_axisX(new QChartAxis(this)),
32 32 m_axisY(new QChartAxis(this)),
33 33 m_rect(QRectF(QPoint(0,0),m_chart->size()))
34 34 {
35 35 setChartTheme(QChart::ChartThemeDefault);
36 36 m_axisItems[m_axisX] = new AxisItem(m_axisX,AxisItem::X_AXIS,m_chart);
37 37 m_axisItems[m_axisY] = new AxisItem(m_axisY,AxisItem::Y_AXIS,m_chart);
38 38 createConnections();
39 39 }
40 40
41 41 ChartPresenter::~ChartPresenter()
42 42 {
43 43 }
44 44
45 45 void ChartPresenter::createConnections()
46 46 {
47 47 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
48 48 QObject::connect(m_dataset,SIGNAL(seriesAdded(QChartSeries*)),this,SLOT(handleSeriesAdded(QChartSeries*)));
49 49
50 50 QMapIterator<QChartAxis*,AxisItem*> i(m_axisItems);
51 51
52 52 while (i.hasNext()) {
53 53 i.next();
54 54 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),i.value(),SLOT(handleGeometryChanged(const QRectF&)));
55 55 QObject::connect(m_dataset,SIGNAL(domainChanged(const Domain&)),i.value(),SLOT(handleDomainChanged(const Domain&)));
56 56 }
57 57 }
58 58
59 59 void ChartPresenter::handleGeometryChanged()
60 60 {
61 61 m_rect = QRectF(QPoint(0,0),m_chart->size());
62 62 m_rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize);
63 63 Q_ASSERT(m_rect.isValid());
64 64 emit geometryChanged(m_rect);
65 65 }
66 66
67 67 int ChartPresenter::margin() const
68 68 {
69 69 return m_marginSize;
70 70 }
71 71
72 72 void ChartPresenter::setMargin(int margin)
73 73 {
74 74 m_marginSize = margin;
75 75 }
76 76
77 77 void ChartPresenter::handleSeriesAdded(QChartSeries* series)
78 78 {
79 79 switch(series->type())
80 80 {
81 81 case QChartSeries::SeriesTypeLine: {
82 82 QLineChartSeries* lineSeries = static_cast<QLineChartSeries*>(series);
83 83 LineChartItem* item = new LineChartAnimationItem(this,lineSeries,m_chart);
84 84 m_chartTheme->decorate(item,lineSeries,m_chartItems.count());
85 85 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
86 86 QObject::connect(m_dataset,SIGNAL(domainChanged(const Domain&)),item,SLOT(handleDomainChanged(const Domain&)));
87 87 QObject::connect(lineSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
88 88 m_chartItems.insert(series,item);
89 89 break;
90 90 }
91 91
92 92 case QChartSeries::SeriesTypeBar: {
93 93 BarChartSeries* barSeries = static_cast<BarChartSeries*>(series);
94 94 BarGroup* item = new BarGroup(*barSeries,m_chart);
95 95 m_chartTheme->decorate(item,barSeries,m_chartItems.count());
96 96 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
97 97 QObject::connect(m_dataset,SIGNAL(domainChanged(const Domain&)),item,SLOT(handleDomainChanged(const Domain&)));
98 98 QObject::connect(barSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
99 99 m_chartItems.insert(series,item);
100 100 // m_axisXItem->setVisible(false);
101 101 break;
102 102 }
103 103
104 104 case QChartSeries::SeriesTypeStackedBar: {
105 105
106 106 StackedBarChartSeries* stackedBarSeries = static_cast<StackedBarChartSeries*>(series);
107 107 StackedBarGroup* item = new StackedBarGroup(*stackedBarSeries,m_chart);
108 108 m_chartTheme->decorate(item,stackedBarSeries,m_chartItems.count());
109 109 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
110 110 QObject::connect(m_dataset,SIGNAL(domainChanged(const Domain&)),item,SLOT(handleDomainChanged(const Domain&)));
111 111 QObject::connect(stackedBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
112 112 m_chartItems.insert(series,item);
113 113 break;
114 114 }
115 115
116 116 case QChartSeries::SeriesTypePercentBar: {
117 117
118 118 PercentBarChartSeries* percentBarSeries = static_cast<PercentBarChartSeries*>(series);
119 119 PercentBarGroup* item = new PercentBarGroup(*percentBarSeries,m_chart);
120 120 m_chartTheme->decorate(item,percentBarSeries ,m_chartItems.count());
121 121 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
122 122 QObject::connect(m_dataset,SIGNAL(domainChanged(const Domain&)),item,SLOT(handleDomainChanged(const Domain&)));
123 123 QObject::connect(percentBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
124 124 m_chartItems.insert(series,item);
125 125 break;
126 126 }
127 127 case QChartSeries::SeriesTypeScatter: {
128 128 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
129 129 ScatterPresenter *scatterPresenter = new ScatterPresenter(scatterSeries, m_chart);
130 130 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)),
131 131 scatterPresenter, SLOT(handleGeometryChanged(const QRectF&)));
132 132 QObject::connect(m_dataset, SIGNAL(domainChanged(const Domain&)),
133 133 scatterPresenter, SLOT(handleDomainChanged(const Domain&)));
134 134 // scatterSeries->d->m_theme = m_chartTheme->themeForSeries();
135 135 // scatterSeries->d->setParentItem(this);
136 136 // scatterSeries->d->m_boundingRect = m_rect.adjusted(margin(),margin(), -margin(), -margin());
137 137 m_chartItems.insert(scatterSeries, scatterPresenter);
138 138 break;
139 139 }
140 140 case QChartSeries::SeriesTypePie: {
141 141 QPieSeries *s = qobject_cast<QPieSeries *>(series);
142 142 PiePresenter* pie = new PiePresenter(m_chart, s);
143 m_chartTheme->decorate(pie, s, m_chartItems.count());
143 144 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), pie, SLOT(handleGeometryChanged(const QRectF&)));
144 145 QObject::connect(m_dataset, SIGNAL(domainChanged(const Domain&)), pie, SLOT(handleDomainChanged(const Domain&)));
145 146 m_chartItems.insert(series, pie);
146 147 break;
147 148 }
148 149 default: {
149 150 qDebug()<< "Series type" << series->type() << "not implemented.";
150 151 break;
151 152 }
152 153 }
153 154
154 155 if(m_rect.isValid()) emit geometryChanged(m_rect);
155 156 }
156 157
157 158 void ChartPresenter::handleSeriesChanged(QChartSeries* series)
158 159 {
159 160 //TODO:
160 161 }
161 162
162 163 void ChartPresenter::zoomInToRect(const QRectF& rect)
163 164 {
164 165 if(!rect.isValid()) return;
165 166 QRectF r = rect.normalized();
166 167 r.translate(-m_marginSize, -m_marginSize);
167 168 Domain domain (m_dataset->domain().subDomain(r,m_rect.width(),m_rect.height()));
168 169 m_dataset->addDomain(domain);
169 170 }
170 171
171 172 void ChartPresenter::zoomIn()
172 173 {
173 174 if (!m_dataset->nextDomain()) {
174 175 QRectF rect = m_rect;
175 176 rect.setWidth(rect.width()/2);
176 177 rect.setHeight(rect.height()/2);
177 178 rect.moveCenter(m_rect.center());
178 179 Domain domain (m_dataset->domain().subDomain(rect,m_rect.width(),m_rect.height()));
179 180 m_dataset->addDomain(domain);
180 181 }
181 182 }
182 183
183 184 void ChartPresenter::zoomOut()
184 185 {
185 186 m_dataset->previousDomain();
186 187 }
187 188
188 189 void ChartPresenter::zoomReset()
189 190 {
190 191 m_dataset->clearDomains();
191 192 }
192 193
193 194 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
194 195 {
195 196 delete m_chartTheme;
196 197
197 198 m_chartTheme = ChartTheme::createTheme(theme);
198 199
199 200 m_chartTheme->decorate(m_chart);
200 201 QMapIterator<QChartSeries*,ChartItem*> i(m_chartItems);
201 202
202 203 int index=0;
203 204 while (i.hasNext()) {
204 205 i.next();
205 206 index++;
206 207 m_chartTheme->decorate(i.value(),i.key(),index);
207 208 }
208 209 }
209 210
210 211
211 212 QChart::ChartTheme ChartPresenter::chartTheme()
212 213 {
213 214 return m_chartTheme->id();
214 215 }
215 216
216 217 QChartAxis* ChartPresenter::axisX()
217 218 {
218 219 return m_axisX;
219 220 }
220 221
221 222 QChartAxis* ChartPresenter::axisY()
222 223 {
223 224 return m_axisY;
224 225 }
225 226
226 227 QChartAxis* ChartPresenter::addAxisX()
227 228 {
228 229 //only one axis
229 230 if(m_axisX==0){
230 231 m_axisX = new QChartAxis(this);
231 232 m_axisItems[m_axisX] = new AxisItem(m_axisX,AxisItem::X_AXIS,m_chart);
232 233 }
233 234 return m_axisX;
234 235 }
235 236
236 237 QChartAxis* ChartPresenter::addAxisY()
237 238 {
238 239 if(m_axisY==0){
239 240 m_axisY = new QChartAxis(this);
240 241 m_axisItems[m_axisY] = new AxisItem(m_axisY,AxisItem::Y_AXIS,m_chart);
241 242 return m_axisY;
242 243 }
243 244
244 245 QChartAxis* axis = new QChartAxis(this);
245 246 m_axisItems[axis] = new AxisItem(axis,AxisItem::Y_AXIS,m_chart);
246 247 return axis;
247 248 }
248 249
249 250 void ChartPresenter::removeAxis(QChartAxis* axis)
250 251 {
251 252 AxisItem* item = m_axisItems.take(axis);
252 253 if(item){
253 254 delete item;
254 255 delete axis;
255 256 }
256 257 //reset pointers to default ones
257 258 if(axis == m_axisX) m_axisX=0;
258 259 else if(axis == m_axisY) m_axisY=0;
259 260 }
260 261
261 262 #include "moc_chartpresenter_p.cpp"
262 263
263 264 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,177 +1,209
1 1 #include "charttheme_p.h"
2 2 #include "qchart.h"
3 3
4 4
5 5 //series
6 6 #include "barchartseries.h"
7 7 #include "stackedbarchartseries.h"
8 8 #include "percentbarchartseries.h"
9 9 #include "qlinechartseries.h"
10 10 #include "qpieseries.h"
11 11
12 12 //items
13 13 #include "axisitem_p.h"
14 14 #include "bargroup.h"
15 15 #include "stackedbargroup.h"
16 16 #include "linechartitem_p.h"
17 17 #include "percentbargroup.h"
18 18 #include "piepresenter.h"
19 19
20 20 //themes
21 21 #include "chartthemevanilla_p.h"
22 22 #include "chartthemeicy_p.h"
23 23 #include "chartthemegrayscale_p.h"
24 24 #include "chartthemescientific_p.h"
25 25
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 /* TODO
30 30 case QChart::ChartThemeUnnamed1:
31 31 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xff3fa9f5)), 2));
32 32 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xff7AC943)), 2));
33 33 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF931E)), 2));
34 34 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF1D25)), 2));
35 35 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF7BAC)), 2));
36 36
37 37 m_gradientStartColor = QColor(QRgb(0xfff3dc9e));
38 38 m_gradientEndColor = QColor(QRgb(0xffafafaf));
39 39 */
40 40
41 41 ChartTheme::ChartTheme(QChart::ChartTheme id)
42 42 {
43 43 m_id = id;
44 44 m_seriesColor.append(QRgb(0xff000000));
45 45 m_seriesColor.append(QRgb(0xff707070));
46 46 m_gradientStartColor = QColor(QRgb(0xffffffff));
47 47 m_gradientEndColor = QColor(QRgb(0xffafafaf));
48 48 }
49 49
50 50
51 51 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
52 52 {
53 53 switch(theme) {
54 54 case QChart::ChartThemeDefault:
55 55 return new ChartTheme();
56 56 case QChart::ChartThemeVanilla:
57 57 return new ChartThemeVanilla();
58 58 case QChart::ChartThemeIcy:
59 59 return new ChartThemeIcy();
60 60 case QChart::ChartThemeGrayscale:
61 61 return new ChartThemeGrayscale();
62 62 case QChart::ChartThemeScientific:
63 63 return new ChartThemeScientific();
64 64 }
65 65 }
66 66
67 67 void ChartTheme::decorate(QChart* chart)
68 68 {
69 69 QLinearGradient backgroundGradient;
70 70 backgroundGradient.setColorAt(0.0, m_gradientStartColor);
71 71 backgroundGradient.setColorAt(1.0, m_gradientEndColor);
72 72 backgroundGradient.setCoordinateMode(QGradient::ObjectBoundingMode);
73 73 chart->setChartBackgroundBrush(backgroundGradient);
74 74 }
75 75 //TODO helper to by removed later
76 76 void ChartTheme::decorate(ChartItem* item, QChartSeries* series,int count)
77 77 {
78 78 switch(series->type())
79 79 {
80 80 case QChartSeries::SeriesTypeLine: {
81 81 QLineChartSeries* s = static_cast<QLineChartSeries*>(series);
82 82 LineChartItem* i = static_cast<LineChartItem*>(item);
83 83 decorate(i,s,count);
84 84 break;
85 85 }
86 86 case QChartSeries::SeriesTypeBar: {
87 87 BarChartSeries* b = static_cast<BarChartSeries*>(series);
88 88 BarGroup* i = static_cast<BarGroup*>(item);
89 89 decorate(i,b,count);
90 90 break;
91 91 }
92 92 case QChartSeries::SeriesTypeStackedBar: {
93 93 StackedBarChartSeries* s = static_cast<StackedBarChartSeries*>(series);
94 94 StackedBarGroup* i = static_cast<StackedBarGroup*>(item);
95 95 decorate(i,s,count);
96 96 break;
97 97 }
98 98 case QChartSeries::SeriesTypePercentBar: {
99 99 PercentBarChartSeries* s = static_cast<PercentBarChartSeries*>(series);
100 100 PercentBarGroup* i = static_cast<PercentBarGroup*>(item);
101 101 decorate(i,s,count);
102 102 break;
103 103 }
104 104 case QChartSeries::SeriesTypePie: {
105 105 QPieSeries* s = static_cast<QPieSeries*>(series);
106 106 PiePresenter* i = static_cast<PiePresenter*>(item);
107 107 decorate(i,s,count);
108 108 break;
109 109 }
110 110 default:
111 111 qDebug()<<"Wrong item to be decorated by theme";
112 112 break;
113 113 }
114 114
115 115 }
116 116
117 117 void ChartTheme::decorate(LineChartItem* item, QLineChartSeries* series,int count)
118 118 {
119 119 QPen pen;
120 120 if(pen != series->pen()){
121 121 item->setPen(series->pen());
122 122 return;
123 123 }
124 124 pen.setColor(m_seriesColor.at(count%m_seriesColor.size()));
125 125 pen.setWidthF(2);
126 126 item->setPen(pen);
127 127 }
128 128
129 129 void ChartTheme::decorate(BarGroup* item, BarChartSeries* series,int count)
130 130 {
131 131 for (int i=0; i< m_seriesColor.count(); i++) {
132 132 item->addColor(m_seriesColor.at(i));
133 133 }
134 134 item->addColor(QColor(255,0,0,128));
135 135 item->addColor(QColor(255,255,0,128));
136 136 item->addColor(QColor(0,255,0,128));
137 137 item->addColor(QColor(0,0,255,128));
138 138 item->addColor(QColor(255,128,0,128));
139 139 }
140 140
141 141 void ChartTheme::decorate(StackedBarGroup* item, StackedBarChartSeries* series,int count)
142 142 {
143 143 for (int i=0; i< m_seriesColor.count(); i++) {
144 144 item->addColor(m_seriesColor.at(i));
145 145 }
146 146 item->addColor(QColor(255,0,0,128));
147 147 item->addColor(QColor(255,255,0,128));
148 148 item->addColor(QColor(0,255,0,128));
149 149 item->addColor(QColor(0,0,255,128));
150 150 item->addColor(QColor(255,128,0,128));
151 151 }
152 152
153 153 void ChartTheme::decorate(PercentBarGroup* item, PercentBarChartSeries* series,int count)
154 154 {
155 155 for (int i=0; i< m_seriesColor.count(); i++) {
156 156 item->addColor(m_seriesColor.at(i));
157 157 }
158 158 item->addColor(QColor(255,0,0,128));
159 159 item->addColor(QColor(255,255,0,128));
160 160 item->addColor(QColor(0,255,0,128));
161 161 item->addColor(QColor(0,0,255,128));
162 162 item->addColor(QColor(255,128,0,128));
163 163 }
164 164
165 165 void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int /*count*/)
166 166 {
167 // TODO: Does not work well. We need to generate enough different colors
168 // based on available theme and not use the same color twice.
167 // create a list of slice colors based on current theme
168 int i = 0;
169 QList<QColor> colors;
170 while (colors.count() < series->count()) {
171
172 // get base color
173 QColor c = m_seriesColor[i++];
174 i = i % m_seriesColor.count();
175
176 // -1 means achromatic color -> cannot manipulate lightness
177 // TODO: find a better way to randomize lightness
178 if (c.toHsv().hue() == -1)
179 qWarning() << "ChartTheme::decorate() warning: achromatic theme color";
180
181 // randomize lightness
182 qreal f = 50 + (qrand() % 100); // 50 is 50% darker, 100 is the same, 150 is 50% lighter
183 c = c.lighter(f);
184
185 // find duplicates
186 bool isUnique = true;
187 foreach (QColor color, colors) {
188 if (c == color)
189 isUnique = false;
190 }
191
192 // add to array if unique
193 //if (isUnique)
194 colors << c;
195 }
196
197 // finally update colors
198 QList<QPieSlice> slices;
169 199 for (int i=0; i<series->count(); i++) {
170 200 QPieSlice slice = series->slice(i);
171 slice.m_color = m_seriesColor.at(i % m_seriesColor.count());
172 series->update(i, slice);
201 slice.m_color = colors.at(i);
202 slices << slice;
173 203 }
204
205 series->set(slices);
174 206 }
175 207
176 208
177 209 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now