charttheme.cpp
300 lines
| 8.8 KiB
| text/x-c
|
CppLexer
/ src / charttheme.cpp
Tero Ahola
|
r103 | #include "charttheme_p.h" | ||
#include "qchart.h" | ||||
Michal Klocek
|
r176 | #include "qchartaxis.h" | ||
Jani Honkonen
|
r324 | #include <QTime> | ||
Tero Ahola
|
r103 | |||
Michal Klocek
|
r143 | //series | ||
sauimone
|
r214 | #include "qbarset.h" | ||
sauimone
|
r338 | #include "qbarseries.h" | ||
#include "qstackedbarseries.h" | ||||
#include "qpercentbarseries.h" | ||||
Michal Klocek
|
r349 | #include "qlineseries.h" | ||
Michal Klocek
|
r421 | #include "qareaseries.h" | ||
Tero Ahola
|
r182 | #include "qscatterseries.h" | ||
Jani Honkonen
|
r163 | #include "qpieseries.h" | ||
Jani Honkonen
|
r203 | #include "qpieslice.h" | ||
Jani Honkonen
|
r163 | |||
Michal Klocek
|
r143 | //items | ||
#include "axisitem_p.h" | ||||
sauimone
|
r381 | #include "barpresenter_p.h" | ||
#include "stackedbarpresenter_p.h" | ||||
#include "percentbarpresenter_p.h" | ||||
Michal Klocek
|
r145 | #include "linechartitem_p.h" | ||
Michal Klocek
|
r421 | #include "areachartitem_p.h" | ||
Tero Ahola
|
r194 | #include "scatterpresenter_p.h" | ||
Jani Honkonen
|
r353 | #include "piepresenter_p.h" | ||
Tero Ahola
|
r103 | |||
Michal Klocek
|
r143 | //themes | ||
#include "chartthemevanilla_p.h" | ||||
#include "chartthemeicy_p.h" | ||||
#include "chartthemegrayscale_p.h" | ||||
#include "chartthemescientific_p.h" | ||||
Tero Ahola
|
r103 | |||
Tero Ahola
|
r125 | |||
Michal Klocek
|
r143 | QTCOMMERCIALCHART_BEGIN_NAMESPACE | ||
/* TODO | ||||
Tero Ahola
|
r103 | case QChart::ChartThemeUnnamed1: | ||
Tero Ahola
|
r108 | m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xff3fa9f5)), 2)); | ||
m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xff7AC943)), 2)); | ||||
m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF931E)), 2)); | ||||
m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF1D25)), 2)); | ||||
m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF7BAC)), 2)); | ||||
Tero Ahola
|
r103 | |||
m_gradientStartColor = QColor(QRgb(0xfff3dc9e)); | ||||
m_gradientEndColor = QColor(QRgb(0xffafafaf)); | ||||
Michal Klocek
|
r143 | */ | ||
Michal Klocek
|
r153 | ChartTheme::ChartTheme(QChart::ChartTheme id) | ||
Michal Klocek
|
r143 | { | ||
Michal Klocek
|
r153 | m_id = id; | ||
Michal Klocek
|
r143 | m_seriesColor.append(QRgb(0xff000000)); | ||
m_seriesColor.append(QRgb(0xff707070)); | ||||
m_gradientStartColor = QColor(QRgb(0xffffffff)); | ||||
m_gradientEndColor = QColor(QRgb(0xffafafaf)); | ||||
Jani Honkonen
|
r324 | |||
qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); | ||||
Michal Klocek
|
r143 | } | ||
Michal Klocek
|
r153 | ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme) | ||
Michal Klocek
|
r143 | { | ||
switch(theme) { | ||||
case QChart::ChartThemeDefault: | ||||
Michal Klocek
|
r421 | return new ChartTheme(); | ||
Michal Klocek
|
r143 | case QChart::ChartThemeVanilla: | ||
return new ChartThemeVanilla(); | ||||
case QChart::ChartThemeIcy: | ||||
return new ChartThemeIcy(); | ||||
case QChart::ChartThemeGrayscale: | ||||
return new ChartThemeGrayscale(); | ||||
case QChart::ChartThemeScientific: | ||||
return new ChartThemeScientific(); | ||||
} | ||||
} | ||||
void ChartTheme::decorate(QChart* chart) | ||||
{ | ||||
QLinearGradient backgroundGradient; | ||||
backgroundGradient.setColorAt(0.0, m_gradientStartColor); | ||||
backgroundGradient.setColorAt(1.0, m_gradientEndColor); | ||||
backgroundGradient.setCoordinateMode(QGradient::ObjectBoundingMode); | ||||
chart->setChartBackgroundBrush(backgroundGradient); | ||||
} | ||||
//TODO helper to by removed later | ||||
Michal Klocek
|
r360 | void ChartTheme::decorate(ChartItem* item, QSeries* series,int count) | ||
Michal Klocek
|
r143 | { | ||
switch(series->type()) | ||||
{ | ||||
Michal Klocek
|
r360 | case QSeries::SeriesTypeLine: { | ||
Michal Klocek
|
r349 | QLineSeries* s = static_cast<QLineSeries*>(series); | ||
Michal Klocek
|
r145 | LineChartItem* i = static_cast<LineChartItem*>(item); | ||
Michal Klocek
|
r143 | decorate(i,s,count); | ||
break; | ||||
} | ||||
Michal Klocek
|
r421 | case QSeries::SeriesTypeArea: { | ||
QAreaSeries* s = static_cast<QAreaSeries*>(series); | ||||
AreaChartItem* i = static_cast<AreaChartItem*>(item); | ||||
decorate(i,s,count); | ||||
break; | ||||
} | ||||
Michal Klocek
|
r360 | case QSeries::SeriesTypeBar: { | ||
sauimone
|
r338 | QBarSeries* b = static_cast<QBarSeries*>(series); | ||
sauimone
|
r216 | BarPresenter* i = static_cast<BarPresenter*>(item); | ||
Michal Klocek
|
r143 | decorate(i,b,count); | ||
break; | ||||
} | ||||
Michal Klocek
|
r360 | case QSeries::SeriesTypeStackedBar: { | ||
sauimone
|
r338 | QStackedBarSeries* s = static_cast<QStackedBarSeries*>(series); | ||
sauimone
|
r216 | StackedBarPresenter* i = static_cast<StackedBarPresenter*>(item); | ||
Michal Klocek
|
r143 | decorate(i,s,count); | ||
break; | ||||
} | ||||
Michal Klocek
|
r360 | case QSeries::SeriesTypePercentBar: { | ||
sauimone
|
r338 | QPercentBarSeries* s = static_cast<QPercentBarSeries*>(series); | ||
sauimone
|
r216 | PercentBarPresenter* i = static_cast<PercentBarPresenter*>(item); | ||
Michal Klocek
|
r143 | decorate(i,s,count); | ||
break; | ||||
} | ||||
Michal Klocek
|
r360 | case QSeries::SeriesTypeScatter: { | ||
Tero Ahola
|
r195 | QScatterSeries* s = qobject_cast<QScatterSeries*>(series); | ||
Q_ASSERT(s); | ||||
ScatterPresenter* i = static_cast<ScatterPresenter*>(item); | ||||
Q_ASSERT(i); | ||||
decorate(i, s, count); | ||||
break; | ||||
} | ||||
Michal Klocek
|
r360 | case QSeries::SeriesTypePie: { | ||
Jani Honkonen
|
r163 | QPieSeries* s = static_cast<QPieSeries*>(series); | ||
PiePresenter* i = static_cast<PiePresenter*>(item); | ||||
decorate(i,s,count); | ||||
break; | ||||
} | ||||
Michal Klocek
|
r143 | default: | ||
qDebug()<<"Wrong item to be decorated by theme"; | ||||
Tero Ahola
|
r103 | break; | ||
} | ||||
Michal Klocek
|
r143 | |||
Tero Ahola
|
r103 | } | ||
Michal Klocek
|
r421 | void ChartTheme::decorate(AreaChartItem* item, QAreaSeries* series,int count) | ||
{ | ||||
QPen pen; | ||||
QBrush brush; | ||||
if(pen != series->pen()){ | ||||
item->setPen(series->pen()); | ||||
}else{ | ||||
pen.setColor(m_seriesColor.at(count%m_seriesColor.size())); | ||||
pen.setWidthF(2); | ||||
item->setPen(pen); | ||||
} | ||||
if(brush != series->brush()){ | ||||
item->setBrush(series->brush()); | ||||
}else{ | ||||
QBrush brush(m_seriesColor.at(count%m_seriesColor.size())); | ||||
item->setBrush(brush); | ||||
} | ||||
} | ||||
Michal Klocek
|
r349 | void ChartTheme::decorate(LineChartItem* item, QLineSeries* series,int count) | ||
Tero Ahola
|
r103 | { | ||
Michal Klocek
|
r152 | QPen pen; | ||
if(pen != series->pen()){ | ||||
item->setPen(series->pen()); | ||||
return; | ||||
} | ||||
pen.setColor(m_seriesColor.at(count%m_seriesColor.size())); | ||||
pen.setWidthF(2); | ||||
item->setPen(pen); | ||||
Tero Ahola
|
r103 | } | ||
sauimone
|
r338 | void ChartTheme::decorate(BarPresenter* item, QBarSeries* series,int count) | ||
Tero Ahola
|
r108 | { | ||
sauimone
|
r357 | QList<QBarSet*> sets = series->barSets(); | ||
sauimone
|
r366 | for (int i=0; i<series->barsetCount(); i++) { | ||
sauimone
|
r357 | sets.at(i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count()))); | ||
sauimone
|
r164 | } | ||
Tero Ahola
|
r108 | } | ||
sauimone
|
r338 | void ChartTheme::decorate(StackedBarPresenter* item, QStackedBarSeries* series,int count) | ||
Tero Ahola
|
r103 | { | ||
sauimone
|
r357 | QList<QBarSet*> sets = series->barSets(); | ||
sauimone
|
r366 | for (int i=0; i<series->barsetCount(); i++) { | ||
sauimone
|
r357 | sets.at(i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count()))); | ||
sauimone
|
r164 | } | ||
Tero Ahola
|
r103 | } | ||
sauimone
|
r338 | void ChartTheme::decorate(PercentBarPresenter* item, QPercentBarSeries* series,int count) | ||
Michal Klocek
|
r143 | { | ||
sauimone
|
r357 | QList<QBarSet*> sets = series->barSets(); | ||
sauimone
|
r366 | for (int i=0; i<series->barsetCount(); i++) { | ||
sauimone
|
r357 | sets.at(i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count()))); | ||
sauimone
|
r164 | } | ||
Michal Klocek
|
r143 | } | ||
Tero Ahola
|
r103 | |||
Tero Ahola
|
r182 | void ChartTheme::decorate(ScatterPresenter* presenter, QScatterSeries* series, int count) | ||
{ | ||||
Q_ASSERT(presenter); | ||||
Q_ASSERT(series); | ||||
Tero Ahola
|
r195 | QColor color = m_seriesColor.at(count % m_seriesColor.size()); | ||
// TODO: define alpha in the theme? or in the series? | ||||
Tero Ahola
|
r278 | //color.setAlpha(120); | ||
Tero Ahola
|
r195 | |||
QBrush brush(color, Qt::SolidPattern); | ||||
presenter->m_markerBrush = brush; | ||||
Tero Ahola
|
r182 | |||
Tero Ahola
|
r278 | QPen pen(brush, 3); | ||
Tero Ahola
|
r195 | pen.setColor(color); | ||
presenter->m_markerPen = pen; | ||||
Tero Ahola
|
r182 | } | ||
Jani Honkonen
|
r163 | void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int /*count*/) | ||
{ | ||||
Jani Honkonen
|
r166 | // create a list of slice colors based on current theme | ||
int i = 0; | ||||
QList<QColor> colors; | ||||
while (colors.count() < series->count()) { | ||||
// get base color | ||||
QColor c = m_seriesColor[i++]; | ||||
i = i % m_seriesColor.count(); | ||||
Jani Honkonen
|
r340 | // dont use black colors... looks bad | ||
if (c == Qt::black) | ||||
continue; | ||||
Jani Honkonen
|
r324 | // by default use the "raw" theme color | ||
if (!colors.contains(c)) { | ||||
colors << c; | ||||
continue; | ||||
} | ||||
// ...ok we need to generate something that looks like the same color | ||||
// but different lightness | ||||
int tryCount = 0; | ||||
while (tryCount++ < 100) { | ||||
Jani Honkonen
|
r166 | |||
Jani Honkonen
|
r324 | // find maximum value we can raise the lightness | ||
int lMax = 255; | ||||
if (lMax > 255 - c.red()) | ||||
lMax = 255 - c.red(); | ||||
if (lMax > 255 - c.green()) | ||||
lMax = 255 - c.green(); | ||||
if (lMax > 255 - c.blue()) | ||||
lMax = 255 - c.blue(); | ||||
Jani Honkonen
|
r166 | |||
Jani Honkonen
|
r324 | // find maximum value we can make it darker | ||
int dMax = 255; | ||||
if (dMax > c.red()) | ||||
dMax = c.red(); | ||||
if (dMax > c.green()) | ||||
dMax = c.green(); | ||||
if (dMax > c.blue()) | ||||
dMax = c.blue(); | ||||
int max = dMax + lMax; | ||||
if (max == 0) { | ||||
// no room to make color lighter or darker... | ||||
qDebug() << "cannot generate a color for pie!"; | ||||
break; | ||||
} | ||||
// generate random color | ||||
int r = c.red() - dMax; | ||||
int g = c.green() - dMax; | ||||
int b = c.blue() - dMax; | ||||
int d = qrand() % max; | ||||
c.setRgb(r+d, g+d, b+d); | ||||
// found a unique color? | ||||
if (!colors.contains(c)) | ||||
break; | ||||
Jani Honkonen
|
r166 | } | ||
Jani Honkonen
|
r324 | qDebug() << "generated a color for pie" << c; | ||
colors << c; | ||||
Jani Honkonen
|
r166 | } | ||
// finally update colors | ||||
Jani Honkonen
|
r203 | foreach (QPieSlice* s, series->slices()) { | ||
Jani Honkonen
|
r324 | QColor c = colors.takeFirst(); | ||
s->setPen(c); | ||||
s->setBrush(c); | ||||
Jani Honkonen
|
r163 | } | ||
} | ||||
Tero Ahola
|
r103 | |||
Michal Klocek
|
r223 | void ChartTheme::decorate(QChartAxis* axis,AxisItem* item) | ||
Michal Klocek
|
r176 | { | ||
//TODO: dummy defults for now | ||||
Michal Klocek
|
r223 | axis->setLabelsBrush(Qt::black); | ||
axis->setLabelsPen(Qt::NoPen); | ||||
axis->setShadesPen(Qt::NoPen); | ||||
axis->setShadesOpacity(0.5); | ||||
Michal Klocek
|
r176 | } | ||
Tero Ahola
|
r103 | QTCOMMERCIALCHART_END_NAMESPACE | ||