##// END OF EJS Templates
correct drawing for barchart
sauimone -
r82:144fd3c1acc4
parent child
Show More
@@ -1,47 +1,88
1 1 #include <QApplication>
2 2 #include <QMainWindow>
3 3 #include <QStandardItemModel>
4 4 #include <barchartseries.h>
5 5 #include "chartwidget.h"
6 6
7 7 QTCOMMERCIALCHART_USE_NAMESPACE
8 8
9 9 int main(int argc, char *argv[])
10 10 {
11 11 QApplication a(argc, argv);
12 12 QMainWindow window;
13 13
14 14 BarChartSeries* series0 = new BarChartSeries();
15 15
16 16 // Create some test data to chart
17 QStandardItemModel dataModel(2,10);
17 QStandardItemModel dataModel(5,10);
18 18 QModelIndex index;
19 19 index = dataModel.index(0,0);
20 // Series 1, items 6 to 9 missing.
20
21 // Series 0
21 22 dataModel.setData(dataModel.index(0,0),1);
22 dataModel.setData(dataModel.index(0,1),12);
23 dataModel.setData(dataModel.index(0,2),5);
24 dataModel.setData(dataModel.index(0,3),8);
25 dataModel.setData(dataModel.index(0,4),17);
26 dataModel.setData(dataModel.index(0,5),9);
23 dataModel.setData(dataModel.index(0,1),2);
24 dataModel.setData(dataModel.index(0,2),3);
25 dataModel.setData(dataModel.index(0,3),4);
26 dataModel.setData(dataModel.index(0,4),5);
27 dataModel.setData(dataModel.index(0,5),6);
28 dataModel.setData(dataModel.index(0,6),7);
29 dataModel.setData(dataModel.index(0,7),8);
30 dataModel.setData(dataModel.index(0,8),9);
31 dataModel.setData(dataModel.index(0,9),10);
27 32
28 // Series 2, some other items missing
33 // Series 1, some other items missing
29 34 dataModel.setData(dataModel.index(1,0),5);
30 35 dataModel.setData(dataModel.index(1,3),4);
31 36 dataModel.setData(dataModel.index(1,5),7);
32 37 dataModel.setData(dataModel.index(1,6),8);
33 38 dataModel.setData(dataModel.index(1,8),9);
34 39 dataModel.setData(dataModel.index(1,9),9);
35 40
41 // Series 2
42 dataModel.setData(dataModel.index(2,0),3);
43 dataModel.setData(dataModel.index(2,1),5);
44 dataModel.setData(dataModel.index(2,2),8);
45 dataModel.setData(dataModel.index(2,3),13);
46 dataModel.setData(dataModel.index(2,4),8);
47 dataModel.setData(dataModel.index(2,5),5);
48 dataModel.setData(dataModel.index(2,6),3);
49 dataModel.setData(dataModel.index(2,7),2);
50 dataModel.setData(dataModel.index(2,8),1);
51 dataModel.setData(dataModel.index(2,9),1);
52
53 // Series 3
54 dataModel.setData(dataModel.index(3,0),5);
55 dataModel.setData(dataModel.index(3,1),6);
56 dataModel.setData(dataModel.index(3,2),7);
57 dataModel.setData(dataModel.index(3,3),3);
58 dataModel.setData(dataModel.index(3,4),4);
59 dataModel.setData(dataModel.index(3,5),5);
60 dataModel.setData(dataModel.index(3,6),8);
61 dataModel.setData(dataModel.index(3,7),9);
62 dataModel.setData(dataModel.index(3,8),10);
63 dataModel.setData(dataModel.index(3,9),5);
64
65 // Series 4
66 dataModel.setData(dataModel.index(4,0),9);
67 dataModel.setData(dataModel.index(4,1),7);
68 dataModel.setData(dataModel.index(4,2),5);
69 dataModel.setData(dataModel.index(4,3),3);
70 dataModel.setData(dataModel.index(4,4),1);
71 dataModel.setData(dataModel.index(4,5),2);
72 dataModel.setData(dataModel.index(4,6),4);
73 dataModel.setData(dataModel.index(4,7),6);
74 dataModel.setData(dataModel.index(4,8),8);
75 dataModel.setData(dataModel.index(4,9),10);
76
36 77 series0->setData(&dataModel);
37 78
38 79 ChartWidget* chartWidget = new ChartWidget(&window);
39 80 chartWidget->addSeries(series0);
40 81
41 82 window.setCentralWidget(chartWidget);
42 83 window.resize(400, 300);
43 84 window.show();
44 85
45 86 return a.exec();
46 87 }
47 88
@@ -1,64 +1,66
1 1 #include "bar.h"
2 2 #include <QDebug>
3 3 #include <QPainter>
4 4
5 5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 6
7 7 Bar::Bar(ChartItem *parent)
8 8 : ChartItem(parent)
9 9 {
10 10 }
11 11
12 12 void Bar::setSize(const QSize& size)
13 13 {
14 14 //mSize = size;
15 15 mWidth = size.width();
16 16 mHeight = size.height();
17 17 }
18 18
19 19 void Bar::setPlotDomain(const PlotDomain& data)
20 20 {
21 21 mPlotDomain = data;
22 22 }
23 23
24 24 void Bar::resize( int w, int h )
25 25 {
26 26 qDebug() << "bar::resize" << w << h;
27 27 mWidth = w;
28 28 mHeight = h;
29 29 }
30 30
31 31 void Bar::setColor( QColor col )
32 32 {
33 33 mColor = col;
34 34 }
35 35 void Bar::setPos(qreal x, qreal y)
36 36 {
37 37 qDebug() << "Bar::setpos" << x << y;
38 38 mXpos = x;
39 39 mYpos = y;
40 40 }
41 41
42 42 void Bar::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
43 43 {
44 if (0 == mHeight) {
45 return;
46 }
44 47 // Set color for bar. TODO: gradients, textures etc
45 48 QPen pen = painter->pen();
46 49 pen.setColor( mColor );
47 50 pen.setWidth( mWidth );
48 51 painter->setPen(pen);
49 52
50 53 // Draw bar
51 54 // TODO: Pen width affects bar height for now. This should be rect
52 painter->drawLine(scenePos().x() + mXpos, scenePos().y() + mYpos + parentItem()->boundingRect().height() - mHeight - mWidth,
53 scenePos().x() + mXpos, scenePos().y() + mYpos + parentItem()->boundingRect().height() - mWidth);
55 // painter->drawRect(mXpos,mYpos,mWidth,mHeight);
56 painter->drawLine(mXpos, mYpos + mHeight - mWidth,
57 mXpos, mYpos + mWidth);
54 58 }
55 59
56 60 QRectF Bar::boundingRect() const
57 61 {
58 // TODO: check validity of this (I suppose there is easier way, and currently this bit incorrect :)
59 // QRectF r(scenePos().x()+mXpos, scenePos().y()+mYpos, scenePos().x() + mWidth, scenePos().y() + mHeight );
60 62 QRectF r(mXpos, mYpos, mXpos + mWidth, mYpos + mHeight);
61 63 return r;
62 64 }
63 65
64 66 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,90 +1,91
1 1 #include <QDebug>
2 2 #include "barchartseries.h"
3 3 #include "bargroup.h"
4 4 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5 5
6 6 BarChartSeries::BarChartSeries(QObject *parent)
7 7 : QChartSeries(parent)
8 8 {
9 9 }
10 10
11 11 bool BarChartSeries::setData(QAbstractItemModel* model)
12 12 {
13 13 mModel = model;
14 14 }
15 15
16 16 int BarChartSeries::min()
17 17 {
18 18 Q_ASSERT(mModel->rowCount() > 0);
19 19 Q_ASSERT(mModel->columnCount() > 0);
20 20
21 21 // TODO: make min and max members and update them when data changes.
22 22 // This is slower since they are checked every time, even if data is same since previous call.
23 23 QModelIndex modelIndex = mModel->index(0,0);
24 24 int min = mModel->data(modelIndex).toInt();
25 25
26 26 for (int i=0; i <mModel->rowCount(); i++) {
27 27 for(int j=0; j<mModel->columnCount(); j++) {
28 28 modelIndex = mModel->index(i,j);
29 29 int temp = mModel->data(modelIndex).toInt();
30 30 if (temp < min) {
31 31 min = temp;
32 32 }
33 33 }
34 34 }
35 35 return min;
36 36 }
37 37
38 38 int BarChartSeries::max()
39 39 {
40 40 Q_ASSERT(mModel->rowCount() > 0);
41 41 Q_ASSERT(mModel->columnCount() > 0);
42 42
43 43 // TODO: make min and max members and update them when data changes.
44 44 // This is slower since they are checked every time, even if data is same since previous call.
45 45 QModelIndex modelIndex = mModel->index(0,0);
46 46 int max = mModel->data(modelIndex).toInt();
47 47
48 48 for (int i=0; i <mModel->rowCount(); i++) {
49 49 for(int j=0; j<mModel->columnCount(); j++) {
50 50 modelIndex = mModel->index(i,j);
51 51 int temp = mModel->data(modelIndex).toInt();
52 52 if (temp > max) {
53 53 max = temp;
54 54 }
55 55 }
56 56 }
57 57 return max;
58 58 }
59 59
60 60
61 61 int BarChartSeries::countSeries()
62 62 {
63 63 return mModel->rowCount();
64 64 }
65 65
66 66 int BarChartSeries::countItemsInSeries()
67 67 {
68 68 return mModel->columnCount();
69 69 }
70 70
71 71 int BarChartSeries::countTotalItems()
72 72 {
73 73 return mModel->rowCount() * mModel->columnCount();
74 74 }
75 75
76 76 int BarChartSeries::valueAt(int series, int item)
77 77 {
78 78 QModelIndex index = mModel->index(series,item);
79 79 return mModel->data(index).toInt();
80 80 }
81 81
82 /*
82 83 void BarChartSeries::chartSizeChanged(QRectF rect)
83 84 {
84 85 qDebug() << "barchart size changed:" << rect;
85 86 // mBarGroup->resize(rect.toRect().width(), rect.toRect().height());
86 87 }
87
88 */
88 89 #include "moc_barchartseries.cpp"
89 90
90 91 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,48 +1,49
1 1 #ifndef BARCHARTSERIES_H
2 2 #define BARCHARTSERIES_H
3 3
4 4 #include <QList>
5 5 #include <QRectF>
6 6 #include <QAbstractItemModel>
7 7 #include "qchartseries.h"
8 8 #include "qchartglobal.h"
9 9
10 10 // TODO: Can this class be combined with series?
11 11 class BarGroup;
12 12
13 13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
14 14
15 15 // Container for series
16 16 class QTCOMMERCIALCHART_EXPORT BarChartSeries : public QChartSeries
17 17 {
18 18 Q_OBJECT
19 19 public:
20 20 BarChartSeries(QObject* parent=0);
21 21
22 22 // from QChartSeries
23 23 virtual QChartSeriesType type() const { return QChartSeries::SeriesTypeBar; }
24 24
25 // TODO: This as dataModel instead of n different setters. (data model itself can accept lists and whatnot)
25 // TODO: Better data model?
26 26 virtual bool setData(QAbstractItemModel* model);
27 27
28 28 // Methods to find out minimum and maximum values of data
29 29 int min();
30 30 int max();
31 31 int countSeries();
32 32 int countItemsInSeries(); // Count items in one series.
33 33 int countTotalItems();
34 34 int valueAt(int series, int item);
35 35
36 36 public Q_SLOTS:
37 37
38 void chartSizeChanged(QRectF rect);
38 // TODO: wrong place for this... series don't know anything about layout
39 // void chartSizeChanged(QRectF rect);
39 40
40 41 private:
41 42
42 43 QAbstractItemModel* mModel;
43 44 BarGroup* mBarGroup;
44 45 };
45 46
46 47 QTCOMMERCIALCHART_END_NAMESPACE
47 48
48 49 #endif // BARCHARTSERIES_H
@@ -1,138 +1,138
1 1 #include "bargroup.h"
2 2 #include "bar.h"
3 3 #include <QDebug>
4 4
5 5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 6
7 7 // TODO: singleton?
8 8 //BarGroup* BarGroup::mBarGroupInstance = NULL;
9 9
10 10 //BarGroup::BarGroup(QGraphicsItem *parent) :
11 11 // QGraphicsItem(parent)
12 12 // ,mSeries(series)
13 13 BarGroup::BarGroup(BarChartSeries& series, QGraphicsItem *parent) :
14 14 ChartItem(parent)
15 15 ,mSeries(series)
16 16 ,mLayoutSet(false)
17 17 ,mLayoutDirty(true)
18 18 ,mBarDefaultWidth(10)
19 19 {
20 20 dataChanged();
21 21 }
22 22
23 23
24 24 void BarGroup::setSize(const QSize& size)
25 25 {
26 26 // TODO: refactor this
27 27 qDebug() << "BarGroup::setSize";
28 28 resize(size.width(),size.height());
29 29 }
30 30
31 31 void BarGroup::setPlotDomain(const PlotDomain& data)
32 32 {
33 33 qDebug() << "BarGroup::setPlotDomain";
34 // TODO:
34 35 }
35 36
36 37
37 38 void BarGroup::resize( int w, int h )
38 39 {
39 40 qDebug() << "QBarChart::resize";
40 41 mWidth = w;
41 42 mHeight = h;
42 43 layoutChanged();
43 44 mLayoutSet = true;
44 45 }
45 46
46 47 void BarGroup::setBarWidth( int w )
47 48 {
48 49 mBarDefaultWidth = w;
49 50 }
50 51
51 void BarGroup::setColor( QColor color )
52 int BarGroup::addColor( QColor color )
52 53 {
53 mColor = color;
54 int colorIndex = mColors.count();
55 mColors.append(color);
56 return colorIndex;
54 57 }
55 58
56 59 void BarGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
57 60 {
58 61 if (!mLayoutSet) {
59 62 qDebug() << "QBarChart::paint called without layout set. Aborting.";
60 63 return;
61 64 }
62 65 if (mLayoutDirty) {
63 66 // Layout or data has changed. Need to redraw.
64 67 foreach(QGraphicsItem* i, childItems()) {
65 68 i->paint(painter,option,widget);
66 69 }
67 70 }
68 71 }
69 72
70 73 QRectF BarGroup::boundingRect() const
71 74 {
72 // TODO: correct this (currently ignores position)
73 75 return QRectF(0,0,mWidth,mHeight);
74 76 }
75 77
76 78
77 79 void BarGroup::dataChanged()
78 80 {
79 81 qDebug() << "QBarChart::dataChanged mSeries";
80 82
81 83 // Find out maximum and minimum of all series
82 84 mMax = mSeries.max();
83 85 mMin = mSeries.min();
84 86
85 87 // Delete old bars
86 88 // Is this correct way to delete childItems?
87 89 foreach (QGraphicsItem* item, childItems()) {
88 90 delete item;
89 91 }
90 92
91 93 // Create new graphic items for bars
92 94 int totalItems = mSeries.countTotalItems();
93 95 for (int i=0; i<totalItems; i++) {
94 96 Bar *bar = new Bar(this);
95 97 childItems().append(bar);
96 98 }
97 99
98 100 mLayoutDirty = true;
99 101 }
100 102
101 103 void BarGroup::layoutChanged()
102 104 {
103 105 // Scale bars to new layout
104 106 // Layout for bars:
105 107 if (mSeries.countSeries() <= 0) {
106 108 // Nothing to do.
107 109 return;
108 110 }
109 111
110 // Align center
112 // TODO: better way to auto-layout
111 113 int count = mSeries.countItemsInSeries();
112 int posStep = (mWidth / (count));
113 int startPos = (mWidth / count+1);
114 int posStep = (mWidth / (count+1));
115 int startPos = (mWidth / (count+1)) - mSeries.countSeries() * mBarDefaultWidth /2;
114 116 qDebug() << "startpos" << startPos;
115 117
116 // Scaling. TODO: better one.
118 // Scaling.
117 119 int itemIndex(0);
118 120 for (int series = 0; series < mSeries.countSeries(); series++) {
119 121 for (int item=0; item < mSeries.countItemsInSeries(); item++) {
120 122 qDebug() << itemIndex;
121 123 int barHeight = mSeries.valueAt(series, item) * mHeight / mMax;
122 124 Bar* bar = reinterpret_cast<Bar*> (childItems().at(itemIndex));
123 125
124 bar->resize(mBarDefaultWidth, barHeight); // TODO: width settable per bar
125 //TODO: test hack
126 if (0 == series) {
127 bar->setColor(QColor(255,0,0,128));
128 } else {
129 bar->setColor(QColor(255,255,0,128));
130 }
131 bar->setPos(item*posStep+startPos + series * mBarDefaultWidth, 0);
126 // TODO: width settable per bar?
127 bar->resize(mBarDefaultWidth, barHeight);
128 bar->setColor(mColors.at(series));
129
130 // TODO: bar width shouldn't affect height. Currently it does because pen width also affects height. (QPainter thingy...)
131 bar->setPos(item*posStep+startPos + series * mBarDefaultWidth, mHeight - barHeight + mBarDefaultWidth);
132 132 itemIndex++;
133 133 }
134 134 }
135 135 mLayoutDirty = true;
136 136 }
137 137
138 138 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,71 +1,72
1 1 #ifndef QBARCHART_H
2 2 #define QBARCHART_H
3 3
4 4 #include "chartitem_p.h"
5 5 #include "bar.h"
6 6 #include "barchartseries.h"
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 10 // TODO: Better name for this? The function of this class is to know where each bar in series is laid out.
11 11 //class BarGroup : public QGraphicsItemGroup
12 12
13 13 class BarGroup : public ChartItem
14 14 {
15 15 /* // TODO: implement as singleton?
16 16 private:
17 17 static BarGroup* mBarGroupInstance;
18 18
19 19 public:
20 20 static BarGroup* instance()
21 21 {
22 22 if (mBarGroupInstance == NULL) {
23 23 mBarGroupInstance = new BarGroup();
24 24 }
25 25 return mBarGroupInstance;
26 26 }
27 27 private:
28 28 */
29 29 public:
30 30 explicit BarGroup(BarChartSeries& series, QGraphicsItem *parent = 0);
31 31
32 32 // From ChartItem
33 33 virtual void setSize(const QSize& size);
34 34 virtual void setPlotDomain(const PlotDomain& data);
35 35
36 36 // Layout "api"
37 37 void resize( int w, int h ); // Size for whole series. Single bars are drawn inside this area
38 38 void setPos(qreal x, qreal y);
39 39 void setBarWidth( int w ); // Default width for each bar
40 void setColor( QColor color ); // Default color for each bar
40
41 // TODO: set color theme instead? or use some external color theme call this
42 int addColor( QColor color );
41 43
42 44 // From QGraphicsItem
43 45 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
44 46 QRectF boundingRect() const;
45 47
46 48 private:
47 49
48 50 void dataChanged(); // data of series has changed -> need to recalculate bar sizes
49 51 void layoutChanged(); // layout has changed -> need to recalculate bar sizes
50 52
51 53 private:
52 54
53 55 // Data
54 56 BarChartSeries& mSeries;
55 57 int mMin; // Min and max values of data. (updated when data is changed, used when drawing)
56 58 int mMax;
57 59
58 60 int mHeight; // Layout spesific
59 61 int mWidth;
60 62 int mBarDefaultWidth;
61 63
62 QColor mColor;
63
64 64 bool mLayoutSet; // True, if component has been laid out.
65 65 bool mLayoutDirty;
66 66
67 QList<QColor> mColors; // List of colors for series for now
67 68 };
68 69
69 70 QTCOMMERCIALCHART_END_NAMESPACE
70 71
71 72 #endif // QBARCHART_H
@@ -1,337 +1,345
1 1 #include "qchart.h"
2 2 #include "qchartseries.h"
3 3 #include "qscatterseries.h"
4 4 #include "qscatterseries_p.h"
5 5 #include "qpieseries.h"
6 6 #include "qxychartseries.h"
7 7
8 8 #include "barchartseries.h"
9 9 #include "bargroup.h"
10 10
11 11 #include "xylinechartitem_p.h"
12 12 #include "plotdomain_p.h"
13 13 #include "axisitem_p.h"
14 14 #include <QGraphicsScene>
15 15 #include <QDebug>
16 16
17 17 QTCOMMERCIALCHART_BEGIN_NAMESPACE
18 18
19 19 QChart::QChart(QGraphicsObject* parent) : QGraphicsObject(parent),
20 20 m_background(new QGraphicsRectItem(this)),
21 21 m_title(new QGraphicsTextItem(this)),
22 22 m_axisX(new AxisItem(AxisItem::X_AXIS,this)),
23 23 m_axisY(new AxisItem(AxisItem::Y_AXIS,this)),
24 24 m_plotDataIndex(0),
25 25 m_marginSize(0)
26 26 {
27 27 // TODO: the default theme?
28 28 setTheme(QChart::ChartThemeVanilla);
29 29 // setFlags(QGraphicsItem::ItemClipsChildrenToShape);
30 30 PlotDomain domain;
31 31 m_plotDomainList<<domain;
32 32
33 33 m_chartItems<<m_axisX;
34 34 m_chartItems<<m_axisY;
35 35 }
36 36
37 37 QChart::~QChart(){}
38 38
39 39 QRectF QChart::boundingRect() const
40 40 {
41 41 return m_rect;
42 42 }
43 43
44 44 void QChart::addSeries(QChartSeries* series)
45 45 {
46 46 // TODO: we should check the series not already added
47 47
48 48 m_chartSeries << series;
49 49
50 50 switch(series->type())
51 51 {
52 52 case QChartSeries::SeriesTypeLine: {
53 53
54 54 QXYChartSeries* xyseries = static_cast<QXYChartSeries*>(series);
55 55 // Use color defined by theme in case the series does not define a custom color
56 56 if (!xyseries->color().isValid() && m_themeColors.count())
57 57 xyseries->setColor(nextColor());
58 58
59 59 m_plotDataIndex = 0 ;
60 60 m_plotDomainList.resize(1);
61 61
62 62 PlotDomain& domain = m_plotDomainList[m_plotDataIndex];
63 63
64 64 for (int i = 0 ; i < xyseries->count() ; i++)
65 65 {
66 66 qreal x = xyseries->x(i);
67 67 qreal y = xyseries->y(i);
68 68 domain.m_minX = qMin(domain.m_minX,x);
69 69 domain.m_minY = qMin(domain.m_minY,y);
70 70 domain.m_maxX = qMax(domain.m_maxX,x);
71 71 domain.m_maxY = qMax(domain.m_maxY,y);
72 72 }
73 73
74 74 XYLineChartItem* item = new XYLineChartItem(xyseries,this);
75 75 m_chartItems<<item;
76 76
77 77 foreach(ChartItem* i ,m_chartItems)
78 78 i->setPlotDomain(m_plotDomainList.at(m_plotDataIndex));
79 79
80 80 break;
81 81 }
82 82 case QChartSeries::SeriesTypeBar: {
83 83
84 84 qDebug() << "barSeries added";
85 85 BarChartSeries* barSeries = static_cast<BarChartSeries*>(series);
86 86 BarGroup* barGroup = new BarGroup(*barSeries,this);
87
88 // Add some fugly colors for 5 fist series...
89 barGroup->addColor(QColor(255,0,0,128));
90 barGroup->addColor(QColor(255,255,0,128));
91 barGroup->addColor(QColor(0,255,0,128));
92 barGroup->addColor(QColor(0,0,255,128));
93 barGroup->addColor(QColor(255,128,0,128));
94
87 95 m_chartItems<<barGroup;
88 96 childItems().append(barGroup);
89 97 break;
90 98 }
91 99 case QChartSeries::SeriesTypeScatter: {
92 100 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
93 101 scatterSeries->d->setParentItem(this);
94 102 // Set pre-defined colors in case the series has no colors defined
95 103 if (!scatterSeries->markerColor().isValid())
96 104 scatterSeries->setMarkerColor(nextColor());
97 105 connect(this, SIGNAL(sizeChanged(QRectF)),
98 106 scatterSeries, SLOT(chartSizeChanged(QRectF)));
99 107 // QColor nextColor = m_themeColors.takeFirst();
100 108 // nextColor.setAlpha(150); // TODO: default opacity?
101 109 // scatterSeries->setMarkerColor(nextColor);
102 110 break;
103 111 }
104 112 case QChartSeries::SeriesTypePie: {
105 113 QPieSeries *pieSeries = qobject_cast<QPieSeries *>(series);
106 114 for (int i(0); i < pieSeries->sliceCount(); i++) {
107 115 if (!pieSeries->sliceColor(i).isValid())
108 116 pieSeries->setSliceColor(i, nextColor());
109 117 }
110 118 connect(this, SIGNAL(sizeChanged(QRectF)),
111 119 pieSeries, SLOT(chartSizeChanged(QRectF)));
112 120
113 121 // Set pre-defined colors in case the series has no colors defined
114 122 // TODO: how to define the color for all the slices of a pie?
115 123 // for (int (i); i < pieSeries.sliceCount(); i++)
116 124 break;
117 125 }
118 126 }
119 127 }
120 128
121 129 QChartSeries* QChart::createSeries(QChartSeries::QChartSeriesType type)
122 130 {
123 131 // TODO: support also other types; not only scatter and pie
124 132
125 133 QChartSeries *series(0);
126 134
127 135 switch (type) {
128 136 case QChartSeries::SeriesTypeLine: {
129 137 series = QXYChartSeries::create();
130 138 break;
131 139 }
132 140 case QChartSeries::SeriesTypeBar: {
133 141 series = new BarChartSeries(this);
134 142 break;
135 143 }
136 144 case QChartSeries::SeriesTypeScatter: {
137 145 series = new QScatterSeries(this);
138 146 break;
139 147 }
140 148 case QChartSeries::SeriesTypePie: {
141 149 series = new QPieSeries(this);
142 150 break;
143 151 }
144 152 default:
145 153 Q_ASSERT(false);
146 154 break;
147 155 }
148 156
149 157 addSeries(series);
150 158 return series;
151 159 }
152 160
153 161 void QChart::setSize(const QSize& size)
154 162 {
155 163 m_rect = QRect(QPoint(0,0),size);
156 164 QRect rect = m_rect.adjusted(margin(),margin(), -margin(), -margin());
157 165
158 166
159 167 //recalculate background gradient
160 168 m_background->setRect(rect);
161 169 m_backgroundGradient.setFinalStop(0,m_background->rect().height());
162 170 m_background->setBrush(m_backgroundGradient);
163 171
164 172 //resize elements
165 173 foreach (ChartItem* item ,m_chartItems) {
166 174 item->setPos(rect.topLeft());
167 175 item->setSize(rect.size());
168 176
169 177 }
170 178 // TODO: TTD for setting scale
171 179 //emit scaleChanged(100, 100);
172 180 // TODO: calculate the origo
173 181 // TODO: not sure if emitting a signal here is the best from performance point of view
174 182 emit sizeChanged(QRectF(0, 0, size.width(), size.height()));
175 183
176 184 update();
177 185 }
178 186
179 187 void QChart::setBackgroundColor(const QColor& color)
180 188 {
181 189 m_backgroundGradient.setColorAt( 0.0, Qt::white);
182 190 m_backgroundGradient.setColorAt( 1.0, color);
183 191 m_background->setBrush(m_backgroundGradient);
184 192 m_background->setPen(Qt::NoPen);
185 193 m_background->update();
186 194 }
187 195
188 196 void QChart::setTitle(const QString& title)
189 197 {
190 198 m_title->setPlainText(title);
191 199 }
192 200
193 201 int QChart::margin() const
194 202 {
195 203 return m_marginSize;
196 204 }
197 205
198 206 void QChart::setMargin(int margin)
199 207 {
200 208 m_marginSize = margin;
201 209 }
202 210
203 211 void QChart::setTheme(QChart::ChartThemeId theme)
204 212 {
205 213 // if (theme != m_currentTheme) {
206 214 m_themeColors.clear();
207 215
208 216 // TODO: define color themes
209 217 switch (theme) {
210 218 case QChart::ChartThemeDefault:
211 219 // TODO: define the default theme based on the OS
212 220 // For now we just fallthrough to "vanilla"
213 221 case QChart::ChartThemeVanilla:
214 222 m_themeColors.append(QColor(217, 197, 116));
215 223 m_themeColors.append(QColor(214, 168, 150));
216 224 m_themeColors.append(QColor(160, 160, 113));
217 225 m_themeColors.append(QColor(210, 210, 52));
218 226 m_themeColors.append(QColor(136, 114, 58));
219 227
220 228 m_backgroundGradient.setColorAt(0.0, QColor(QRgb(0xff9d844d)));
221 229 m_backgroundGradient.setColorAt(1.0, QColor(QRgb(0xffafafaf)));
222 230 break;
223 231 case QChart::ChartThemeIcy:
224 232 m_themeColors.append(QColor(0, 3, 165));
225 233 m_themeColors.append(QColor(49, 52, 123));
226 234 m_themeColors.append(QColor(71, 114, 187));
227 235 m_themeColors.append(QColor(48, 97, 87));
228 236 m_themeColors.append(QColor(19, 71, 90));
229 237 m_themeColors.append(QColor(110, 70, 228));
230 238
231 239 m_backgroundGradient.setColorAt(0.0, QColor(QRgb(0xffe4ffff)));
232 240 m_backgroundGradient.setColorAt(1.0, QColor(QRgb(0xffe4ffff)));
233 241 break;
234 242 case QChart::ChartThemeGrayscale:
235 243 m_themeColors.append(QColor(0, 0, 0));
236 244 m_themeColors.append(QColor(50, 50, 50));
237 245 m_themeColors.append(QColor(100, 100, 100));
238 246 m_themeColors.append(QColor(140, 140, 140));
239 247 m_themeColors.append(QColor(180, 180, 180));
240 248
241 249 m_backgroundGradient.setColorAt(0.0, QColor(QRgb(0xffffffff)));
242 250 m_backgroundGradient.setColorAt(1.0, QColor(QRgb(0xffafafaf)));
243 251 break;
244 252 case QChart::ChartThemeUnnamed1:
245 253 m_themeColors.append(QColor(QRgb(0xff3fa9f5)));
246 254 m_themeColors.append(QColor(QRgb(0xff7AC943)));
247 255 m_themeColors.append(QColor(QRgb(0xffFF931E)));
248 256 m_themeColors.append(QColor(QRgb(0xffFF1D25)));
249 257 m_themeColors.append(QColor(QRgb(0xffFF7BAC)));
250 258
251 259 m_backgroundGradient.setColorAt(0.0, QColor(QRgb(0xfff3dc9e)));
252 260 m_backgroundGradient.setColorAt(1.0, QColor(QRgb(0xffafafaf)));
253 261 break;
254 262 default:
255 263 Q_ASSERT(false);
256 264 break;
257 265 }
258 266
259 267 m_background->setBrush(m_backgroundGradient);
260 268 m_background->setPen(Qt::NoPen);
261 269
262 270 foreach(QChartSeries* series, m_chartSeries) {
263 271 // TODO: other series interested on themes?
264 272 if (series->type() == QChartSeries::SeriesTypeLine) {
265 273 QXYChartSeries *lineseries = reinterpret_cast<QXYChartSeries *>(series);
266 274 lineseries->setColor(nextColor());
267 275 } else if (series->type() == QChartSeries::SeriesTypeScatter) {
268 276 QScatterSeries *scatter = qobject_cast<QScatterSeries *>(series);
269 277 scatter->setMarkerColor(nextColor());
270 278 } else if (series->type() == QChartSeries::SeriesTypePie) {
271 279 QPieSeries *pieSeries = qobject_cast<QPieSeries *>(series);
272 280 for (int i(0); i < pieSeries->sliceCount(); i++)
273 281 pieSeries->setSliceColor(i, nextColor());
274 282 }
275 283 }
276 284 update();
277 285 }
278 286
279 287 QColor QChart::nextColor()
280 288 {
281 289 QColor nextColor = m_themeColors.first();
282 290 m_themeColors.move(0, m_themeColors.size() - 1);
283 291 return nextColor;
284 292 }
285 293
286 294 void QChart::zoomInToRect(const QRect& rectangle)
287 295 {
288 296
289 297 if(!rectangle.isValid()) return;
290 298
291 299 qreal margin = this->margin();
292 300
293 301 QRect rect = rectangle.normalized();
294 302 rect.translate(-margin, -margin);
295 303
296 304 PlotDomain& oldDomain = m_plotDomainList[m_plotDataIndex];
297 305
298 306 PlotDomain domain = oldDomain.subDomain(rect,m_rect.width() - 2 * margin,m_rect.height() - 2 * margin);
299 307
300 308 m_plotDomainList.resize(m_plotDataIndex + 1);
301 309 m_plotDomainList<<domain;
302 310 m_plotDataIndex++;
303 311
304 312 foreach (ChartItem* item ,m_chartItems)
305 313 item->setPlotDomain(m_plotDomainList[m_plotDataIndex]);
306 314 update();
307 315 }
308 316
309 317 void QChart::zoomIn()
310 318 {
311 319 if (m_plotDataIndex < m_plotDomainList.count() - 1) {
312 320 m_plotDataIndex++;
313 321 foreach (ChartItem* item ,m_chartItems)
314 322 item->setPlotDomain(m_plotDomainList[m_plotDataIndex]);
315 323 update();
316 324 }else{
317 325 QRect rect = m_rect.adjusted(margin(),margin(), -margin(), -margin());
318 326 rect.setWidth(rect.width()/2);
319 327 rect.setHeight(rect.height()/2);
320 328 rect.moveCenter(m_rect.center());
321 329 zoomInToRect(rect);
322 330 }
323 331 }
324 332
325 333 void QChart::zoomOut()
326 334 {
327 335 if (m_plotDataIndex > 0) {
328 336 m_plotDataIndex--;
329 337 foreach (ChartItem* item ,m_chartItems)
330 338 item->setPlotDomain(m_plotDomainList[m_plotDataIndex]);
331 339 update();
332 340 }
333 341 }
334 342
335 343 #include "moc_qchart.cpp"
336 344
337 345 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now