##// END OF EJS Templates
Adds layout support for charts....
Michal Klocek -
r115:8cafc623ea10
parent child
Show More
@@ -1,164 +1,164
1 1 #include "axisitem_p.h"
2 2 #include <QPainter>
3 3 #include <QDebug>
4 4
5 5 #define LABEL_PADDING 5
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 9 AxisItem::AxisItem(AxisType type,QGraphicsItem* parent) :
10 10 ChartItem(parent),
11 11 m_ticks(4),
12 12 m_type(type)
13 13 {
14 14 }
15 15
16 16 AxisItem::~AxisItem()
17 17 {
18 18 }
19 19
20 20 void AxisItem::setLength(int length)
21 21 {
22 22 QPainterPath path;
23 23 path.moveTo(QPointF(0,0));
24 24 path.lineTo(length,0);
25 25 // path.lineTo(length-4,0);
26 26 // path.lineTo(length,3);
27 27 // path.lineTo(length-4,6);
28 28 // path.lineTo(length-4,4);
29 29 // path.lineTo(0,4);
30 30 // path.lineTo(0,2);
31 31 m_path=path;
32 32 update();
33 33 }
34 34
35 35 QRectF AxisItem::boundingRect() const
36 36 {
37 37 return m_rect;
38 38 }
39 39
40 40 void AxisItem::setPlotDomain(const PlotDomain& plotDomain)
41 41 {
42 42 m_plotDomain = plotDomain;
43 43 createItems();
44 44 }
45 45
46 void AxisItem::setSize(const QSize &size)
46 void AxisItem::setSize(const QSizeF &size)
47 47 {
48 48 m_rect = QRectF(QPoint(0,0),size);
49 49 createItems();
50 50 }
51 51
52 52 /*
53 53 void AxisItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget)
54 54 {
55 55 if (!m_rect.isValid())
56 56 return;
57 57
58 58 if(m_type==X_AXIS) {
59 59
60 60 const qreal deltaX = m_rect.width() / m_ticks;
61 61
62 62 for (int i = 0; i <= m_ticks; ++i) {
63 63
64 64 int x = i * deltaX + m_rect.left();
65 65
66 66 if(i==0) x--;
67 67 if(i==m_ticks) x++;
68 68
69 69 qreal label = m_plotDomain.m_minX + (i * m_plotDomain.spanX()
70 70 / m_ticks);
71 71 painter->drawLine(x, m_rect.top()-1, x, m_rect.bottom()+1);
72 72 // painter->drawLine(x, m_rect.bottom()-1, x, m_rect.bottom()-1 + 5);
73 73
74 74 painter->drawText(x - 50, m_rect.bottom() + 5, 100, 20,Qt::AlignHCenter | Qt::AlignTop, QString::number(label));
75 75 }
76 76 }
77 77
78 78 if(m_type==Y_AXIS) {
79 79
80 80 const qreal deltaY = (m_rect.height()) / m_ticks;
81 81
82 82 for (int j = 0; j <= m_ticks; ++j) {
83 83
84 84 int y = j * -deltaY + m_rect.bottom();
85 85
86 86 if(j==0) y++;
87 87 if(j==m_ticks) y--;
88 88
89 89 qreal label = m_plotDomain.m_minY + (j * m_plotDomain.spanY()
90 90 / m_ticks);
91 91
92 92 painter->drawLine(m_rect.left()-1, y, m_rect.right()+1, y);
93 93 //painter->drawLine(m_rect.left() - 5, y, m_rect.left(), y);
94 94 //TODO : margin = 50 ;
95 95 painter->drawText(m_rect.left() - 50, y - 10, 50 - 5, 20,
96 96 Qt::AlignRight | Qt::AlignVCenter,
97 97 QString::number(label));
98 98 }
99 99 }
100 100
101 101 //painter->drawRect(m_rect.adjusted(0, 0, -1, -1));
102 102 }
103 103 */
104 104 void AxisItem::createItems()
105 105 {
106 106
107 107 //TODO: this is very inefficient handling
108 108
109 109 qDeleteAll(m_shades);
110 110 m_shades.clear();
111 111 qDeleteAll(m_grid);
112 112 m_grid.clear();
113 113 qDeleteAll(m_labels);
114 114 m_labels.clear();
115 115
116 116
117 117 if(m_type==X_AXIS) {
118 118
119 119 const qreal deltaX = m_rect.width() / m_ticks;
120 120
121 121 for (int i = 0; i <= m_ticks; ++i) {
122 122
123 123 int x = i * deltaX + m_rect.left();
124 124
125 125 qreal label = m_plotDomain.m_minX + (i * m_plotDomain.spanX()/ m_ticks);
126 126
127 127 m_grid<<new QGraphicsLineItem(x, m_rect.top(), x, m_rect.bottom(),this);
128 128
129 129 QGraphicsSimpleTextItem* text = new QGraphicsSimpleTextItem(QString::number(label),this);
130 130 QPointF center = text->boundingRect().center();
131 131 text->setPos(x - center.x(), m_rect.bottom() + LABEL_PADDING);
132 132 //text->rotate(-45);
133 133 m_labels<<text;
134 134 }
135 135 }
136 136
137 137 if(m_type==Y_AXIS) {
138 138
139 139 const qreal deltaY = m_rect.height()/ m_ticks;
140 140
141 141 for (int j = 0; j <= m_ticks; ++j) {
142 142
143 143 int y = j * -deltaY + m_rect.bottom();
144 144
145 145 qreal label = m_plotDomain.m_minY + (j * m_plotDomain.spanY()
146 146 / m_ticks);
147 147
148 148 m_grid<<new QGraphicsLineItem(m_rect.left() , y, m_rect.right(), y,this);
149 149 QGraphicsSimpleTextItem* text = new QGraphicsSimpleTextItem(QString::number(label),this);
150 150 QPointF center = text->boundingRect().center();
151 151
152 152 text->setPos(m_rect.left() - text->boundingRect().width() - LABEL_PADDING , y-center.y());
153 153 //text->rotate(-45);
154 154 m_labels<<text;
155 155
156 156 }
157 157 }
158 158
159 159 //painter->drawRect(m_rect.adjusted(0, 0, -1, -1));
160 160 }
161 161
162 162 //TODO "nice numbers algorithm"
163 163
164 164 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,47 +1,47
1 1 #ifndef AXISITEM_H_
2 2 #define AXISITEM_H_
3 3
4 4 #include "plotdomain_p.h"
5 5 #include "chartitem_p.h"
6 6 #include <QGraphicsItem>
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 10 class AxisItem : public ChartItem
11 11 {
12 12 public:
13 13 enum AxisType{X_AXIS,Y_AXIS};
14 14
15 15 AxisItem(AxisType type = X_AXIS,QGraphicsItem* parent = 0);
16 16 ~AxisItem();
17 17
18 18 //from QGraphicsItem
19 19 QRectF boundingRect() const;
20 20 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){};
21 21
22 22 public: // from ChartItem
23 void setSize(const QSize &size);
23 void setSize(const QSizeF &size);
24 24 void setPlotDomain(const PlotDomain& data);
25 25
26 26 public:
27 27 void setLength(int length);
28 28 void setWidth(int width);
29 29 AxisType axisType() const {return m_type;};
30 30
31 31 private:
32 32 void createItems();
33 33 private:
34 34 QRectF m_rect;
35 35 int m_ticks;
36 36 PlotDomain m_plotDomain;
37 37 QPainterPath m_path;
38 38
39 39 QList<QGraphicsLineItem*> m_grid;
40 40 QList<QGraphicsRectItem*> m_shades;
41 41 QList<QGraphicsSimpleTextItem*> m_labels;
42 42 AxisType m_type;
43 43 };
44 44
45 45 QTCOMMERCIALCHART_END_NAMESPACE
46 46
47 47 #endif /* AXISITEM_H_ */
@@ -1,66 +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(QGraphicsItem *parent)
8 8 : ChartItem(parent)
9 9 {
10 10 }
11 11
12 void Bar::setSize(const QSize& size)
12 void Bar::setSize(const QSizeF& size)
13 13 {
14 14 mWidth = size.width();
15 15 mHeight = size.height();
16 16 }
17 17
18 18 void Bar::setPlotDomain(const PlotDomain& data)
19 19 {
20 20 mPlotDomain = data;
21 21 }
22 22
23 23 void Bar::resize( qreal w, qreal h )
24 24 {
25 25 // qDebug() << "bar::resize" << w << h;
26 26 mWidth = w;
27 27 mHeight = h;
28 28 }
29 29
30 30 void Bar::setColor( QColor col )
31 31 {
32 32 mColor = col;
33 33 }
34 34 void Bar::setPos(qreal x, qreal y)
35 35 {
36 36 // qDebug() << "Bar::setpos" << x << y;
37 37 mXpos = x;
38 38 mYpos = y;
39 39 }
40 40
41 41 void Bar::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
42 42 {
43 43 if (0 == mHeight) {
44 44 return;
45 45 }
46 46 // TODO: accept brush instead of color
47 47 QBrush brush(mColor);
48 48 painter->setBrush(brush);
49 49
50 50 // This compensates for rounding errors. drawRect takes ints and cumulative error of pos + size may be over 1.
51 51 int x0 = mXpos;
52 52 int x1 = (mXpos + mWidth);
53 53 int w = x1-x0;
54 54 int y0 = mYpos;
55 55 int y1 = (mYpos + mHeight);
56 56 int h = y1-y0;
57 57 painter->drawRect(x0, y0 ,w ,h);
58 58 }
59 59
60 60 QRectF Bar::boundingRect() const
61 61 {
62 62 QRectF r(mXpos, mYpos, mXpos + mWidth, mYpos + mHeight);
63 63 return r;
64 64 }
65 65
66 66 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,44 +1,44
1 1 #ifndef BAR_H
2 2 #define BAR_H
3 3
4 4 #include "chartitem_p.h"
5 5 #include "qchartglobal.h"
6 6 #include <QGraphicsItem>
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 10 // Single bar item of chart
11 11 class Bar : public ChartItem
12 12 {
13 13 public:
14 14 Bar(QGraphicsItem *parent=0);
15 15
16 16 public: // from ChartItem
17 void setSize(const QSize &size);
17 void setSize(const QSizeF &size);
18 18 void setPlotDomain(const PlotDomain& data);
19 19
20 20 // Layout Stuff
21 21 void resize( qreal w, qreal h ); // Size of bar.
22 22 void setColor( QColor col ); // Color of bar
23 23 void setPos(qreal x, qreal y);
24 24
25 25 public:
26 26 // From QGraphicsItem
27 27
28 28 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
29 29 QRectF boundingRect() const;
30 30
31 31 private:
32 32
33 33 qreal mHeight;
34 34 qreal mWidth;
35 35 qreal mXpos;
36 36 qreal mYpos;
37 37 QColor mColor;
38 38
39 39 PlotDomain mPlotDomain;
40 40 };
41 41
42 42 QTCOMMERCIALCHART_END_NAMESPACE
43 43
44 44 #endif // BAR_H
@@ -1,157 +1,157
1 1 #include "bargroup.h"
2 2 #include "bar.h"
3 3 #include "barlabel_p.h"
4 4 #include <QDebug>
5 5
6 6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 7
8 8 BarGroup::BarGroup(BarChartSeries& series, QGraphicsItem *parent) :
9 9 ChartItem(parent)
10 10 ,mSeries(series)
11 11 ,mLayoutSet(false)
12 12 ,mLayoutDirty(true)
13 13 ,mBarDefaultWidth(10)
14 14 {
15 15 dataChanged();
16 16 }
17 17
18 void BarGroup::setSize(const QSize& size)
18 void BarGroup::setSize(const QSizeF& size)
19 19 {
20 20 qDebug() << "BarGroup::setSize";
21 21 mWidth = size.width();
22 22 mHeight = size.height();
23 23 layoutChanged();
24 24 mLayoutSet = true;
25 25 }
26 26
27 27 void BarGroup::setPlotDomain(const PlotDomain& data)
28 28 {
29 29 qDebug() << "BarGroup::setPlotDomain";
30 30 // TODO:
31 31 mPlotDomain = data;
32 32 }
33 33
34 34 void BarGroup::setBarWidth( int w )
35 35 {
36 36 mBarDefaultWidth = w;
37 37 }
38 38
39 39 int BarGroup::addColor( QColor color )
40 40 {
41 41 int colorIndex = mColors.count();
42 42 mColors.append(color);
43 43 return colorIndex;
44 44 }
45 45
46 46 void BarGroup::resetColors()
47 47 {
48 48 mColors.clear();
49 49 }
50 50
51 51 void BarGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
52 52 {
53 53 if (!mLayoutSet) {
54 54 qDebug() << "QBarChart::paint called without layout set. Aborting.";
55 55 return;
56 56 }
57 57 if (mLayoutDirty) {
58 58 // Layout or data has changed. Need to redraw.
59 59 foreach(QGraphicsItem* i, childItems()) {
60 60 i->paint(painter,option,widget);
61 61 mLayoutDirty = false;
62 62 }
63 63 }
64 64 }
65 65
66 66 QRectF BarGroup::boundingRect() const
67 67 {
68 68 return QRectF(0,0,mWidth,mHeight);
69 69 }
70 70
71 71
72 72 void BarGroup::dataChanged()
73 73 {
74 74 qDebug() << "QBarChart::dataChanged mSeries";
75 75
76 76 // Find out maximum and minimum of all series
77 77 mMax = mSeries.max();
78 78 mMin = mSeries.min();
79 79
80 80 // Delete old bars
81 81 // Is this correct way to delete childItems?
82 82 foreach (QGraphicsItem* item, childItems()) {
83 83 delete item;
84 84 }
85 85
86 86 // Create new graphic items for bars
87 87 int totalItems = mSeries.countTotalItems();
88 88 for (int i=0; i<totalItems; i++) {
89 89 Bar *bar = new Bar(this);
90 90 childItems().append(bar);
91 91 }
92 92
93 93 // TODO: labels from series. This creates just some example labels
94 94 int count = mSeries.countColumns();
95 95 for (int i=0; i<count; i++) {
96 96 BarLabel* label = new BarLabel(this);
97 97 QString text("Label " + QString::number(i));
98 98 label->set(text);
99 99 childItems().append(label);
100 100 }
101 101
102 102 // TODO: if (autolayout) { layoutChanged() } or something
103 103 mLayoutDirty = true;
104 104 }
105 105
106 106 void BarGroup::layoutChanged()
107 107 {
108 108 // Scale bars to new layout
109 109 // Layout for bars:
110 110 if (mSeries.countRows() <= 0) {
111 111 // Nothing to do.
112 112 return;
113 113 }
114 114
115 115 // TODO: better way to auto-layout?
116 116 // Use reals for accurancy (we might get some compiler warnings... :)
117 117 int columnCount = mSeries.countColumns();
118 118 int rowCount = mSeries.countRows();
119 119
120 120 qreal tW = mWidth;
121 121 qreal tH = mHeight;
122 122 qreal tM = mMax;
123 123 qreal scale = (tH/tM);
124 124
125 125 qreal tC = columnCount+1;
126 126 qreal xStepPerSeries = (tW/tC);
127 127
128 128 // Scaling.
129 129 int itemIndex(0);
130 130 int labelIndex = mSeries.countColumns() * mSeries.countRows();
131 131
132 132 for (int column=0; column < columnCount; column++) {
133 133 qreal xPos = xStepPerSeries * column + ((tW + mBarDefaultWidth*rowCount)/(columnCount*2));
134 134 qreal yPos = mHeight;
135 135 for (int row = 0; row < rowCount; row++) {
136 136 qreal barHeight = mSeries.valueAt(row, column) * scale;
137 137 Bar* bar = reinterpret_cast<Bar*> (childItems().at(itemIndex));
138 138
139 139 // TODO: width settable per bar?
140 140 bar->resize(mBarDefaultWidth, barHeight);
141 141 bar->setColor(mColors.at(row));
142 142 bar->setPos(xPos, yPos-barHeight); // item*posStep+startPos + series * mBarDefaultWidth, mHeight);
143 143 itemIndex++;
144 144 xPos += mBarDefaultWidth;
145 145 }
146 146
147 147 // TODO: Layout for labels, remove magic number
148 148 xPos = xStepPerSeries * column + ((tW + mBarDefaultWidth*rowCount)/(columnCount*2));
149 149 BarLabel* label = reinterpret_cast<BarLabel*> (childItems().at(labelIndex));
150 150 label->setPos(xPos, mHeight + 20);
151 151 labelIndex++;
152 152 }
153 153
154 154 mLayoutDirty = true;
155 155 }
156 156
157 157 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,57 +1,57
1 1 #ifndef QBARGROUP_H
2 2 #define QBARGROUP_H
3 3
4 4 #include "chartitem_p.h"
5 5 #include "bar.h"
6 6 #include "barchartseries.h"
7 7 #include <QGraphicsItem>
8 8
9 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 10
11 11 class BarGroup : public ChartItem
12 12 {
13 13 public:
14 14 explicit BarGroup(BarChartSeries& series, QGraphicsItem *parent = 0);
15 15
16 16 public: // from ChartItem
17 void setSize(const QSize &size);
17 void setSize(const QSizeF &size);
18 18 void setPlotDomain(const PlotDomain& data);
19 19
20 20 // Layout "api"
21 21 void setPos(qreal x, qreal y);
22 22 void setBarWidth( int w ); // Default width for each bar
23 23
24 24 int addColor( QColor color );
25 25 void resetColors();
26 26
27 27 // From QGraphicsItem
28 28 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
29 29 QRectF boundingRect() const;
30 30
31 31 private:
32 32
33 33 void dataChanged(); // data of series has changed -> need to recalculate bar sizes
34 34 void layoutChanged(); // layout has changed -> need to recalculate bar sizes
35 35
36 36 private:
37 37
38 38 // Data
39 39 BarChartSeries& mSeries;
40 40 int mMin; // Min and max values of data. (updated when data is changed, used when drawing)
41 41 int mMax;
42 42
43 43 int mHeight; // Layout spesific
44 44 int mWidth;
45 45 int mBarDefaultWidth;
46 46
47 47 bool mLayoutSet; // True, if component has been laid out.
48 48 bool mLayoutDirty;
49 49
50 50 QList<QColor> mColors; // List of colors for series for now
51 51
52 52 PlotDomain mPlotDomain;
53 53 };
54 54
55 55 QTCOMMERCIALCHART_END_NAMESPACE
56 56
57 57 #endif // QBARGROUP_H
@@ -1,152 +1,152
1 1 #include "percentbargroup.h"
2 2 #include "bar.h"
3 3 #include "barlabel_p.h"
4 4 #include <QDebug>
5 5
6 6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 7
8 8 PercentBarGroup::PercentBarGroup(PercentBarChartSeries& series, QGraphicsItem *parent) :
9 9 ChartItem(parent)
10 10 ,mSeries(series)
11 11 ,mLayoutSet(false)
12 12 ,mLayoutDirty(true)
13 13 ,mBarDefaultWidth(20) // TODO: remove hard coding, when we have layout code ready
14 14 {
15 15 dataChanged();
16 16 }
17 17
18 18
19 void PercentBarGroup::setSize(const QSize& size)
19 void PercentBarGroup::setSize(const QSizeF& size)
20 20 {
21 21 // qDebug() << "PercentBarGroup::setSize";
22 22 mWidth = size.width();
23 23 mHeight = size.height();
24 24 layoutChanged();
25 25 mLayoutSet = true;
26 26 }
27 27
28 28 void PercentBarGroup::setPlotDomain(const PlotDomain& data)
29 29 {
30 30 qDebug() << "PercentBarGroup::setPlotDomain";
31 31 // TODO:
32 32 }
33 33
34 34 void PercentBarGroup::setBarWidth( int w )
35 35 {
36 36 mBarDefaultWidth = w;
37 37 }
38 38
39 39 int PercentBarGroup::addColor( QColor color )
40 40 {
41 41 int colorIndex = mColors.count();
42 42 mColors.append(color);
43 43 return colorIndex;
44 44 }
45 45
46 46 void PercentBarGroup::resetColors()
47 47 {
48 48 mColors.clear();
49 49 }
50 50
51 51 void PercentBarGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
52 52 {
53 53 if (!mLayoutSet) {
54 54 qDebug() << "QBarChart::paint called without layout set. Aborting.";
55 55 return;
56 56 }
57 57 if (mLayoutDirty) {
58 58 // Layout or data has changed. Need to redraw.
59 59 foreach(QGraphicsItem* i, childItems()) {
60 60 i->paint(painter,option,widget);
61 61 }
62 62 mLayoutDirty = false;
63 63 }
64 64 }
65 65
66 66 QRectF PercentBarGroup::boundingRect() const
67 67 {
68 68 return QRectF(0,0,mWidth,mHeight);
69 69 }
70 70
71 71
72 72 void PercentBarGroup::dataChanged()
73 73 {
74 74 qDebug() << "QBarChart::dataChanged mSeries";
75 75
76 76 // Find out maximum and minimum of all series
77 77 mMax = mSeries.max();
78 78 mMin = mSeries.min();
79 79
80 80 // Delete old bars
81 81 // Is this correct way to delete childItems?
82 82 foreach (QGraphicsItem* item, childItems()) {
83 83 delete item;
84 84 }
85 85
86 86 // Create new graphic items for bars
87 87 int totalItems = mSeries.countTotalItems();
88 88 for (int i=0; i<totalItems; i++) {
89 89 Bar *bar = new Bar(this);
90 90 childItems().append(bar);
91 91 }
92 92
93 93 // TODO: labels from series. This creates just some example labels
94 94 int count = mSeries.countColumns();
95 95 for (int i=0; i<count; i++) {
96 96 BarLabel* label = new BarLabel(this);
97 97 QString text("Label " + QString::number(i));
98 98 label->set(text);
99 99 childItems().append(label);
100 100 }
101 101
102 102 // TODO: if (autolayout) { layoutChanged() } or something
103 103 mLayoutDirty = true;
104 104 }
105 105
106 106 void PercentBarGroup::layoutChanged()
107 107 {
108 108 // Scale bars to new layout
109 109 // Layout for bars:
110 110 if (mSeries.countRows() <= 0) {
111 111 // Nothing to do.
112 112 return;
113 113 }
114 114
115 115 // TODO: better way to auto-layout
116 116 // Use reals for accurancy (we might get some compiler warnings... :)
117 117 int count = mSeries.countColumns();
118 118 int itemIndex(0);
119 119 qreal tW = mWidth;
120 120 qreal tC = count+1;
121 121 qreal xStep = (tW/tC);
122 122 // qreal xPos = ((tW/tC) + mBarDefaultWidth / 2);
123 123 qreal xPos = ((tW/tC) - mBarDefaultWidth / 2);
124 124 int labelIndex = mSeries.countColumns() * mSeries.countRows();
125 125
126 126 for (int column = 0; column < mSeries.countColumns(); column++) {
127 127 qreal colSum = mSeries.columnSum(column);
128 128 qreal h = mHeight;
129 129 qreal scale = (h / colSum);
130 130 qreal yPos = h;
131 131 for (int row=0; row < mSeries.countRows(); row++) {
132 132 qreal barHeight = mSeries.valueAt(row, column) * scale;
133 133 Bar* bar = reinterpret_cast<Bar*> (childItems().at(itemIndex));
134 134
135 135 // TODO: width settable per bar?
136 136 bar->resize(mBarDefaultWidth, barHeight);
137 137 bar->setColor(mColors.at(row));
138 138 bar->setPos(xPos, yPos-barHeight);
139 139 itemIndex++;
140 140 yPos -= barHeight;
141 141 }
142 142
143 143 // TODO: Layout for labels, remove magic number
144 144 BarLabel* label = reinterpret_cast<BarLabel*> (childItems().at(labelIndex));
145 145 label->setPos(xPos, mHeight + 20);
146 146 labelIndex++;
147 147 xPos += xStep;
148 148 }
149 149 mLayoutDirty = true;
150 150 }
151 151
152 152 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,57 +1,57
1 1 #ifndef PERCENTBARGROUP_H
2 2 #define PERCENTBARGROUP_H
3 3
4 4 #include "chartitem_p.h"
5 5 #include "bar.h"
6 6 #include "percentbarchartseries.h"
7 7 #include <QGraphicsItem>
8 8
9 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 10
11 11 class PercentBarGroup : public ChartItem
12 12 {
13 13 public:
14 14 PercentBarGroup(PercentBarChartSeries& series, QGraphicsItem *parent = 0);
15 15
16 16 public: // From ChartItem
17 void setSize(const QSize &size);
17 void setSize(const QSizeF &size);
18 18 void setPlotDomain(const PlotDomain& data);
19 19
20 20 public:
21 21 // Layout "api"
22 22 void setPos(qreal x, qreal y);
23 23 void setBarWidth( int w ); // Default width for each bar
24 24
25 25 int addColor( QColor color );
26 26 void resetColors();
27 27
28 28 // From QGraphicsItem
29 29 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
30 30 QRectF boundingRect() const;
31 31
32 32 private:
33 33
34 34 void dataChanged(); // data of series has changed -> need to recalculate bar sizes
35 35 void layoutChanged(); // layout has changed -> need to recalculate bar sizes
36 36
37 37 private:
38 38
39 39 // Data
40 40 PercentBarChartSeries& mSeries;
41 41 int mMin; // Min and max values of data. (updated when data is changed, used when drawing)
42 42 int mMax;
43 43
44 44 int mHeight; // Layout spesific
45 45 int mWidth;
46 46 int mBarDefaultWidth;
47 47
48 48 bool mLayoutSet; // True, if component has been laid out.
49 49 bool mLayoutDirty;
50 50
51 51 QList<QColor> mColors; // List of colors for series for now
52 52
53 53 };
54 54
55 55 QTCOMMERCIALCHART_END_NAMESPACE
56 56
57 57 #endif // PERCENTBARGROUP_H
@@ -1,163 +1,163
1 1 #include "stackedbargroup.h"
2 2 #include "bar.h"
3 3 #include "barlabel_p.h"
4 4 #include <QDebug>
5 5
6 6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 7
8 8 StackedBarGroup::StackedBarGroup(StackedBarChartSeries& series, QGraphicsItem *parent) :
9 9 ChartItem(parent)
10 10 ,mSeries(series)
11 11 ,mLayoutSet(false)
12 12 ,mLayoutDirty(true)
13 13 ,mBarDefaultWidth(20) // TODO: remove hard coding, when we have layout code ready
14 14 ,mTheme(0)
15 15 {
16 16 dataChanged();
17 17 }
18 18
19 19
20 void StackedBarGroup::setSize(const QSize& size)
20 void StackedBarGroup::setSize(const QSizeF& size)
21 21 {
22 22 // qDebug() << "StackedBarGroup::setSize";
23 23 mWidth = size.width();
24 24 mHeight = size.height();
25 25 layoutChanged();
26 26 mLayoutSet = true;
27 27 }
28 28
29 29 void StackedBarGroup::setPlotDomain(const PlotDomain& data)
30 30 {
31 31 qDebug() << "StackedBarGroup::setPlotDomain";
32 32 // TODO:
33 33 }
34 34
35 35 void StackedBarGroup::themeChanged(ChartTheme *theme)
36 36 {
37 37 mTheme = theme;
38 38 }
39 39
40 40 void StackedBarGroup::setBarWidth( int w )
41 41 {
42 42 mBarDefaultWidth = w;
43 43 }
44 44
45 45 int StackedBarGroup::addColor( QColor color )
46 46 {
47 47 int colorIndex = mColors.count();
48 48 mColors.append(color);
49 49 return colorIndex;
50 50 }
51 51
52 52 void StackedBarGroup::resetColors()
53 53 {
54 54 mColors.clear();
55 55 }
56 56
57 57 void StackedBarGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
58 58 {
59 59 if (!mLayoutSet) {
60 60 qDebug() << "QBarChart::paint called without layout set. Aborting.";
61 61 return;
62 62 }
63 63 if (mLayoutDirty) {
64 64 // Layout or data has changed. Need to redraw.
65 65 foreach(QGraphicsItem* i, childItems()) {
66 66 i->paint(painter,option,widget);
67 67 }
68 68 mLayoutDirty = false;
69 69 //TODO: draw labels.
70 70 }
71 71
72 72 }
73 73
74 74 QRectF StackedBarGroup::boundingRect() const
75 75 {
76 76 return QRectF(0,0,mWidth,mHeight);
77 77 }
78 78
79 79
80 80 void StackedBarGroup::dataChanged()
81 81 {
82 82 qDebug() << "QBarChart::dataChanged mSeries";
83 83
84 84 // Find out maximum and minimum of all series
85 85 mMax = mSeries.max();
86 86 mMin = mSeries.min();
87 87
88 88 // Delete old bars
89 89 // Is this correct way to delete childItems?
90 90 foreach (QGraphicsItem* item, childItems()) {
91 91 delete item;
92 92 }
93 93
94 94 // Create new graphic items for bars
95 95 int totalItems = mSeries.countTotalItems();
96 96 for (int i=0; i<totalItems; i++) {
97 97 Bar *bar = new Bar(this);
98 98 childItems().append(bar);
99 99 }
100 100
101 101 // TODO: labels from series. This creates just some example labels
102 102 int count = mSeries.countColumns();
103 103 for (int i=0; i<count; i++) {
104 104 BarLabel* label = new BarLabel(this);
105 105 QString text("Label " + QString::number(i));
106 106 label->set(text);
107 107 childItems().append(label);
108 108 }
109 109
110 110 // TODO: if (autolayout) { layoutChanged() } or something
111 111 mLayoutDirty = true;
112 112 }
113 113
114 114 void StackedBarGroup::layoutChanged()
115 115 {
116 116 // Scale bars to new layout
117 117 // Layout for bars:
118 118 if (mSeries.countRows() <= 0) {
119 119 // Nothing to do.
120 120 return;
121 121 }
122 122
123 123 // TODO: better way to auto-layout
124 124 // Use reals for accurancy (we might get some compiler warnings... :)
125 125 qreal maxSum = mSeries.maxColumnSum();
126 126 qreal h = mHeight;
127 127 qreal scale = (h / maxSum);
128 128
129 129 int count = mSeries.countColumns();
130 130 int itemIndex(0);
131 131 qreal tW = mWidth;
132 132 qreal tC = count+1;
133 133 qreal xStep = (tW/tC);
134 134 qreal xPos = ((tW/tC) - mBarDefaultWidth / 2);
135 135 int labelIndex = mSeries.countColumns() * mSeries.countRows();
136 136
137 137 for (int column = 0; column < mSeries.countColumns(); column++) {
138 138 qreal yPos = h;
139 139 for (int row=0; row < mSeries.countRows(); row++) {
140 140 qreal barHeight = mSeries.valueAt(row, column) * scale;
141 141 Bar* bar = reinterpret_cast<Bar*> (childItems().at(itemIndex));
142 142
143 143 // TODO: width settable per bar?
144 144 // TODO: how to get color for series(x) from theme?
145 145 // mTheme->themeForSeries();
146 146 bar->resize(mBarDefaultWidth, barHeight);
147 147 bar->setColor(mColors.at(row));
148 148 bar->setPos(xPos, yPos-barHeight);
149 149 itemIndex++;
150 150 yPos -= barHeight;
151 151 }
152 152
153 153 // TODO: Layout for labels, remove magic number
154 154 BarLabel* label = reinterpret_cast<BarLabel*> (childItems().at(labelIndex));
155 155 label->setPos(xPos, mHeight + 20);
156 156 labelIndex++;
157 157 xPos += xStep;
158 158 }
159 159
160 160 mLayoutDirty = true;
161 161 }
162 162
163 163 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,65 +1,65
1 1 #ifndef STACKEDBARGROUP_H
2 2 #define STACKEDBARGROUP_H
3 3
4 4 #include "charttheme_p.h"
5 5 #include "chartitem_p.h"
6 6 #include "barlabel_p.h"
7 7 #include "bar.h"
8 8 #include "stackedbarchartseries.h"
9 9 #include <QGraphicsItem>
10 10
11 11 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 12
13 13 // TODO: derive this from ChartObjectInterface, when setSize is back in ChartItem
14 14 class StackedBarGroup : public ChartItem, public ChartThemeObserver
15 15 {
16 16 public:
17 17 StackedBarGroup(StackedBarChartSeries& series, QGraphicsItem *parent = 0);
18 18
19 19 public: // From ChartItem
20 void setSize(const QSize &size);
20 void setSize(const QSizeF &size);
21 21 void setPlotDomain(const PlotDomain& data);
22 22
23 23 // From ChartThemeObserver
24 24 void themeChanged(ChartTheme *theme);
25 25
26 26 public: // Layout "api"
27 27 void setPos(qreal x, qreal y);
28 28 void setBarWidth( int w ); // Default width for each bar
29 29
30 30 int addColor( QColor color );
31 31 void resetColors();
32 32
33 33 // From QGraphicsItem
34 34 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
35 35 QRectF boundingRect() const;
36 36
37 37 private:
38 38
39 39 void dataChanged(); // data of series has changed -> need to recalculate bar sizes
40 40 void layoutChanged(); // layout has changed -> need to recalculate bar sizes
41 41
42 42 private:
43 43
44 44 // Data
45 45 StackedBarChartSeries& mSeries;
46 46 int mMin; // Min and max values of data. (updated when data is changed, used when drawing)
47 47 int mMax;
48 48
49 49 int mHeight; // Layout spesific
50 50 int mWidth;
51 51 int mBarDefaultWidth;
52 52
53 53 bool mLayoutSet; // True, if component has been laid out.
54 54 bool mLayoutDirty;
55 55
56 56 QList<QColor> mColors; // List of colors for series for now
57 57
58 58 ChartTheme* mTheme;
59 59 // QList<BarLabel*> mLabels;
60 60
61 61 };
62 62
63 63 QTCOMMERCIALCHART_END_NAMESPACE
64 64
65 65 #endif // STACKEDBARGROUP_H
@@ -1,21 +1,21
1 1 #ifndef CHARTITEM_H_
2 2 #define CHARTITEM_H_
3 3
4 4 #include "plotdomain_p.h"
5 5 #include <QGraphicsItem>
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 9 class ChartItem : public QGraphicsItem
10 10 {
11 11 enum ChartItemTypes{ AXIS_ITEM = UserType+1, XYLINE_ITEM};
12 12 public:
13 13 ChartItem(QGraphicsItem* parent = 0):QGraphicsItem(parent){};
14 14 virtual ~ChartItem(){};
15 virtual void setSize(const QSize &size) = 0;
15 virtual void setSize(const QSizeF &size) = 0;
16 16 virtual void setPlotDomain(const PlotDomain& data) = 0;
17 17 };
18 18
19 19 QTCOMMERCIALCHART_END_NAMESPACE
20 20
21 21 #endif /* CHARTITEM_H_ */
@@ -1,45 +1,45
1 1 #include "plotdomain_p.h"
2 2
3 3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4 4
5 5 PlotDomain::PlotDomain():
6 6 m_minX(0),
7 7 m_maxX(0),
8 8 m_minY(0),
9 9 m_maxY(0)
10 10 {
11 11
12 12 }
13 13
14 14 PlotDomain::~PlotDomain()
15 15 {
16 16 // TODO Auto-generated destructor stub
17 17 }
18 18
19 19 qreal PlotDomain::spanX() const
20 20 {
21 21 Q_ASSERT(m_maxX >= m_minX);
22 22 return m_maxX - m_minX;
23 23 }
24 24
25 25 qreal PlotDomain::spanY() const
26 26 {
27 27 Q_ASSERT(m_maxY >= m_minY);
28 28 return m_maxY - m_minY;
29 29 }
30 30
31 PlotDomain PlotDomain::subDomain(const QRect& rect, qreal maxWidth,qreal maxHeight) const
31 PlotDomain PlotDomain::subDomain(const QRectF& rect, qreal maxWidth,qreal maxHeight) const
32 32 {
33 33 PlotDomain domain;
34 34
35 35 qreal dx = spanX() / maxWidth;
36 36 qreal dy = spanY() / maxHeight;
37 37
38 38 domain.m_minX = m_minX + dx * rect.left();
39 39 domain.m_maxX = m_minX + dx * rect.right();
40 40 domain.m_minY = m_maxY - dy * rect.bottom();
41 41 domain.m_maxY = m_maxY - dy * rect.top();
42 42
43 43 return domain;
44 44 }
45 45 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,28 +1,28
1 1 #ifndef PLOTDOMAIN_H_
2 2 #define PLOTDOMAIN_H_
3 3 #include "qchartglobal.h"
4 4 #include <QRect>
5 5
6 6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 7
8 8 class PlotDomain {
9 9 public:
10 10 PlotDomain();
11 11 virtual ~PlotDomain();
12 12
13 13 qreal spanX() const;
14 14 qreal spanY() const;
15 15
16 PlotDomain subDomain(const QRect& rect, qreal maxWidth, qreal maxHeight) const;
16 PlotDomain subDomain(const QRectF& rect, qreal maxWidth, qreal maxHeight) const;
17 17
18 18
19 19 public:
20 20 qreal m_minX;
21 21 qreal m_maxX;
22 22 qreal m_minY;
23 23 qreal m_maxY;
24 24 };
25 25
26 26 QTCOMMERCIALCHART_END_NAMESPACE
27 27
28 28 #endif /* PLOTTER_H_ */
@@ -1,402 +1,406
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 "qpieseries_p.h"
7 7 #include "qxychartseries.h"
8 8 #include "qchartaxis.h"
9 9 #include "barchartseries.h"
10 10 #include "bargroup.h"
11 11 #include "stackedbarchartseries.h"
12 12 #include "stackedbargroup.h"
13 13 #include "percentbarchartseries.h"
14 14 #include "percentbargroup.h"
15 15 #include "charttheme_p.h"
16 16 #include "chartitem_p.h"
17 17
18 18 #include "xylinechartitem_p.h"
19 19 #include "plotdomain_p.h"
20 20 #include "axisitem_p.h"
21 21 #include <QGraphicsScene>
22 #include <QGraphicsSceneResizeEvent>
22 23 #include <QDebug>
23 24
24 25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25 26
26 QChart::QChart(QGraphicsObject* parent) : QGraphicsObject(parent),
27 QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags) : QGraphicsWidget(parent,wFlags),
27 28 m_backgroundItem(0),
28 29 m_titleItem(0),
29 30 m_axisXItem(new AxisItem(AxisItem::X_AXIS, this)),
30 31 m_plotDataIndex(0),
31 32 m_marginSize(0),
32 33 m_chartTheme(new ChartTheme(this))
33 34 {
34 35 // TODO: the default theme?
35 36 setTheme(QChart::ChartThemeDefault);
36 37
37 38 PlotDomain domain;
38 39 m_plotDomainList << domain;
39 40 m_axisYItem << new AxisItem(AxisItem::Y_AXIS,this);
40 41 m_chartItems << m_axisXItem;
41 42 m_chartItems << m_axisYItem.at(0);
42 43 }
43 44
44 45 QChart::~QChart(){}
45 46
46 47 QRectF QChart::boundingRect() const
47 48 {
48 49 return m_rect;
49 50 }
50 51
51 52 void QChart::addSeries(QChartSeries* series)
52 53 {
53 54 // TODO: we should check the series not already added
54 55
55 56 m_chartSeries << series;
56 57
57 58 m_plotDataIndex = 0 ;
58 59 m_plotDomainList.resize(1);
59 60 PlotDomain& domain = m_plotDomainList[m_plotDataIndex];
60 61
61 62 switch(series->type())
62 63 {
63 64 case QChartSeries::SeriesTypeLine: {
64 65
65 66 QXYChartSeries* xyseries = static_cast<QXYChartSeries*>(series);
66 67
67 68 for (int i = 0 ; i < xyseries->count() ; i++) {
68 69 qreal x = xyseries->x(i);
69 70 qreal y = xyseries->y(i);
70 71 domain.m_minX = qMin(domain.m_minX,x);
71 72 domain.m_minY = qMin(domain.m_minY,y);
72 73 domain.m_maxX = qMax(domain.m_maxX,x);
73 74 domain.m_maxY = qMax(domain.m_maxY,y);
74 75 }
75 76
76 77 XYLineChartItem* item = new XYLineChartItem(xyseries,this);
77 78
78 79 m_chartItems << item;
79 80 // TODO:
80 81 //m_chartTheme->addObserver(xyseries);
81 82
82 83 break;
83 84 }
84 85 case QChartSeries::SeriesTypeBar: {
85 86
86 87 qDebug() << "barSeries added";
87 88 BarChartSeries* barSeries = static_cast<BarChartSeries*>(series);
88 89 BarGroup* barGroup = new BarGroup(*barSeries,this);
89 90
90 91 // Add some fugly colors for 5 fist series...
91 92 barGroup->addColor(QColor(255,0,0,128));
92 93 barGroup->addColor(QColor(255,255,0,128));
93 94 barGroup->addColor(QColor(0,255,0,128));
94 95 barGroup->addColor(QColor(0,0,255,128));
95 96 barGroup->addColor(QColor(255,128,0,128));
96 97
97 98 m_chartItems << barGroup;
98 99 childItems().append(barGroup);
99 100
100 101 qreal x = barSeries->countColumns();
101 102 qreal y = barSeries->max();
102 103 domain.m_minX = qMin(domain.m_minX,x);
103 104 domain.m_minY = qMin(domain.m_minY,y);
104 105 domain.m_maxX = qMax(domain.m_maxX,x);
105 106 domain.m_maxY = qMax(domain.m_maxY,y);
106 107 break;
107 108 }
108 109 case QChartSeries::SeriesTypeStackedBar: {
109 110
110 111 qDebug() << "barSeries added";
111 112 StackedBarChartSeries* stackedBarSeries = static_cast<StackedBarChartSeries*>(series);
112 113 StackedBarGroup* stackedBarGroup = new StackedBarGroup(*stackedBarSeries,this);
113 114
114 115 // Add some fugly colors for 5 fist series...
115 116 stackedBarGroup->addColor(QColor(255,0,0,128));
116 117 stackedBarGroup->addColor(QColor(255,255,0,128));
117 118 stackedBarGroup->addColor(QColor(0,255,0,128));
118 119 stackedBarGroup->addColor(QColor(0,0,255,128));
119 120 stackedBarGroup->addColor(QColor(255,128,0,128));
120 121
121 122 m_chartItems << stackedBarGroup;
122 123 childItems().append(stackedBarGroup);
123 124
124 125 qreal x = stackedBarSeries->countColumns();
125 126 qreal y = stackedBarSeries->maxColumnSum();
126 127 domain.m_minX = qMin(domain.m_minX,x);
127 128 domain.m_minY = qMin(domain.m_minY,y);
128 129 domain.m_maxX = qMax(domain.m_maxX,x);
129 130 domain.m_maxY = qMax(domain.m_maxY,y);
130 131 break;
131 132 }
132 133 case QChartSeries::SeriesTypePercentBar: {
133 134
134 135 qDebug() << "barSeries added";
135 136 PercentBarChartSeries* percentBarSeries = static_cast<PercentBarChartSeries*>(series);
136 137 PercentBarGroup* percentBarGroup = new PercentBarGroup(*percentBarSeries,this);
137 138
138 139 // Add some fugly colors for 5 fist series...
139 140 percentBarGroup->addColor(QColor(255,0,0,128));
140 141 percentBarGroup->addColor(QColor(255,255,0,128));
141 142 percentBarGroup->addColor(QColor(0,255,0,128));
142 143 percentBarGroup->addColor(QColor(0,0,255,128));
143 144 percentBarGroup->addColor(QColor(255,128,0,128));
144 145
145 146 m_chartItems << percentBarGroup;
146 147 childItems().append(percentBarGroup);
147 148
148 149 qreal x = percentBarSeries->countColumns();
149 150 domain.m_minX = qMin(domain.m_minX,x);
150 151 domain.m_minY = 0;
151 152 domain.m_maxX = qMax(domain.m_maxX,x);
152 153 domain.m_maxY = 100;
153 154 break;
154 155 }
155 156 case QChartSeries::SeriesTypeScatter: {
156 157 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
157 158 scatterSeries->d->m_theme = m_chartTheme->themeForSeries();
158 159 scatterSeries->d->setParentItem(this);
159 160 scatterSeries->d->m_boundingRect = m_rect.adjusted(margin(),margin(), -margin(), -margin());
160 161 m_chartItems << scatterSeries->d;
161 162 m_chartTheme->addObserver(scatterSeries->d);
162 163
163 164 foreach (qreal x, scatterSeries->d->m_x) {
164 165 domain.m_minX = qMin(domain.m_minX, x);
165 166 domain.m_maxX = qMax(domain.m_maxX, x);
166 167 }
167 168 foreach (qreal y, scatterSeries->d->m_y) {
168 169 domain.m_minY = qMin(domain.m_minY, y);
169 170 domain.m_maxY = qMax(domain.m_maxY, y);
170 171 }
171 172
172 173 break;
173 174 }
174 175 case QChartSeries::SeriesTypePie: {
175 176 QPieSeries *pieSeries = qobject_cast<QPieSeries *>(series);
176 177 pieSeries->d->setParentItem(this);
177 178 m_chartItems << pieSeries->d;
178 179 pieSeries->d->m_chartTheme = m_chartTheme;
179 180 m_chartTheme->addObserver(pieSeries->d);
180 181 break;
181 182 }
182 183 }
183 184
184 185 // Update all the items to match the new visible area of the chart
185 186 foreach(ChartItem* i, m_chartItems)
186 187 i->setPlotDomain(m_plotDomainList.at(m_plotDataIndex));
187 188 }
188 189
189 190 QChartSeries* QChart::createSeries(QChartSeries::QChartSeriesType type)
190 191 {
191 192 // TODO: support also other types; not only scatter and pie
192 193
193 194 QChartSeries *series(0);
194 195
195 196 switch (type) {
196 197 case QChartSeries::SeriesTypeLine: {
197 198 series = QXYChartSeries::create();
198 199 break;
199 200 }
200 201 case QChartSeries::SeriesTypeBar: {
201 202 series = new BarChartSeries(this);
202 203 break;
203 204 }
204 205 case QChartSeries::SeriesTypeStackedBar: {
205 206 series = new StackedBarChartSeries(this);
206 207 break;
207 208 }
208 209 case QChartSeries::SeriesTypePercentBar: {
209 210 series = new PercentBarChartSeries(this);
210 211 break;
211 212 }
212 213 case QChartSeries::SeriesTypeScatter: {
213 214 series = new QScatterSeries(this);
214 215 break;
215 216 }
216 217 case QChartSeries::SeriesTypePie: {
217 218 series = new QPieSeries(this);
218 219 break;
219 220 }
220 221 default:
221 222 Q_ASSERT(false);
222 223 break;
223 224 }
224 225
225 226 addSeries(series);
226 227 return series;
227 228 }
228 229
229 void QChart::setSize(const QSize& size)
230 {
231 m_rect = QRect(QPoint(0,0),size);
232 QRect rect = m_rect.adjusted(margin(),margin(), -margin(), -margin());
233
234 // recalculate title position
235 if (m_titleItem) {
236 QPointF center = m_rect.center() -m_titleItem->boundingRect().center();
237 m_titleItem->setPos(center.x(),m_rect.top()/2 + margin()/2);
238 }
239
240 //recalculate background gradient
241 if (m_backgroundItem) {
242 m_backgroundItem->setRect(rect);
243 if (m_bacgroundOrinetation == HorizonatlGradientOrientation)
244 m_backgroundGradient.setFinalStop(m_backgroundItem->rect().width(), 0);
245 else
246 m_backgroundGradient.setFinalStop(0, m_backgroundItem->rect().height());
247 m_backgroundItem->setBrush(m_backgroundGradient);
248 }
249
250 // resize and reposition childs
251 foreach (ChartItem *item, m_chartItems) {
252 item->setPos(rect.topLeft());
253 item->setSize(rect.size());
254 }
255
256 update();
257 }
258
259 230 void QChart::setBackground(const QColor& startColor, const QColor& endColor, GradientOrientation orientation)
260 231 {
261 232
262 233 if(!m_backgroundItem){
263 234 m_backgroundItem = new QGraphicsRectItem(this);
264 235 m_backgroundItem->setZValue(-1);
265 236 }
266 237
267 238 m_bacgroundOrinetation = orientation;
268 239 m_backgroundGradient.setColorAt(0.0, startColor);
269 240 m_backgroundGradient.setColorAt(1.0, endColor);
270 241 m_backgroundGradient.setStart(0,0);
271 242
272 243 if(orientation == VerticalGradientOrientation){
273 244 m_backgroundGradient.setFinalStop(0,m_rect.height());
274 245 }else{
275 246 m_backgroundGradient.setFinalStop(m_rect.width(),0);
276 247 }
277 248
278 249 m_backgroundItem->setBrush(m_backgroundGradient);
279 250 m_backgroundItem->setPen(Qt::NoPen);
280 251 m_backgroundItem->update();
281 252 }
282 253
283 254 void QChart::setTitle(const QString& title,const QFont& font)
284 255 {
285 256 if(!m_titleItem) m_titleItem = new QGraphicsTextItem(this);
286 257 m_titleItem->setPlainText(title);
287 258 m_titleItem->setFont(font);
288 259 }
289 260
290 261 int QChart::margin() const
291 262 {
292 263 return m_marginSize;
293 264 }
294 265
295 266 void QChart::setMargin(int margin)
296 267 {
297 268 m_marginSize = margin;
298 269 }
299 270
300 271 void QChart::setTheme(QChart::ChartThemeId theme)
301 272 {
302 273 m_chartTheme->setTheme(theme);
303 274 setBackground(m_chartTheme->d->m_gradientStartColor,
304 275 m_chartTheme->d->m_gradientEndColor,
305 276 m_bacgroundOrinetation);
306 277
307 278 // TODO: Move the controlling of the series presentations into private implementation of the
308 279 // series instead of QChart controlling themes for each
309 280 // In other words, the following should be used when creating xy series:
310 281 // m_chartTheme->addObserver(xyseries)
311 282 foreach (QChartSeries *series, m_chartSeries) {
312 283 if (series->type() == QChartSeries::SeriesTypeLine) {
313 284 QXYChartSeries *xyseries = static_cast<QXYChartSeries *>(series);
314 285 SeriesTheme seriesTheme = m_chartTheme->themeForSeries();
315 286 xyseries->setPen(seriesTheme.linePen);
316 287 }
317 288 }
318 289
319 290 update();
320 291 }
321 292
322 void QChart::zoomInToRect(const QRect& rectangle)
293 void QChart::zoomInToRect(const QRectF& rectangle)
323 294 {
324 295
325 296 if(!rectangle.isValid()) return;
326 297
327 298 qreal margin = this->margin();
328 299
329 QRect rect = rectangle.normalized();
300 QRectF rect = rectangle.normalized();
330 301 rect.translate(-margin, -margin);
331 302
332 303 PlotDomain& oldDomain = m_plotDomainList[m_plotDataIndex];
333 304
334 305 PlotDomain domain = oldDomain.subDomain(rect,m_rect.width() - 2 * margin,m_rect.height() - 2 * margin);
335 306
336 307 m_plotDomainList.resize(m_plotDataIndex + 1);
337 308 m_plotDomainList<<domain;
338 309 m_plotDataIndex++;
339 310
340 311 foreach (ChartItem* item, m_chartItems)
341 312 item->setPlotDomain(m_plotDomainList[m_plotDataIndex]);
342 313 update();
343 314 }
344 315
345 316 void QChart::zoomIn()
346 317 {
347 318 if (m_plotDataIndex < m_plotDomainList.count() - 1) {
348 319 m_plotDataIndex++;
349 320 foreach (ChartItem* item, m_chartItems)
350 321 item->setPlotDomain(m_plotDomainList[m_plotDataIndex]);
351 322 update();
352 323 } else {
353 QRect rect = m_rect.adjusted(margin(),margin(), -margin(), -margin());
324 QRectF rect = m_rect.adjusted(margin(),margin(), -margin(), -margin());
354 325 rect.setWidth(rect.width()/2);
355 326 rect.setHeight(rect.height()/2);
356 327 rect.moveCenter(m_rect.center());
357 328 zoomInToRect(rect);
358 329 }
359 330 }
360 331
361 332 void QChart::zoomOut()
362 333 {
363 334 if (m_plotDataIndex > 0) {
364 335 m_plotDataIndex--;
365 336 foreach (ChartItem* item, m_chartItems)
366 337 item->setPlotDomain(m_plotDomainList[m_plotDataIndex]);
367 338 update();
368 339 }
369 340 }
370 341
371 342 void QChart::zoomReset()
372 343 {
373 344 if (m_plotDataIndex > 0) {
374 345 m_plotDataIndex = 0;
375 346 foreach (ChartItem* item, m_chartItems)
376 347 item->setPlotDomain(m_plotDomainList[m_plotDataIndex]);
377 348 update();
378 349 }
379 350 }
380 351
381 352 void QChart::setAxisX(const QChartAxis& axis)
382 353 {
383 354 setAxis(m_axisXItem,axis);
384 355 }
385 356 void QChart::setAxisY(const QChartAxis& axis)
386 357 {
387 358 setAxis(m_axisYItem.at(0),axis);
388 359 }
389 360
390 361 void QChart::setAxisY(const QList<QChartAxis>& axis)
391 362 {
392 363 //TODO not implemented
393 364 }
394 365
395 366 void QChart::setAxis(AxisItem *item, const QChartAxis& axis)
396 367 {
397 368 item->setVisible(axis.isAxisVisible());
398 369 }
399 370
371 void QChart::resizeEvent(QGraphicsSceneResizeEvent *event)
372 {
373
374 m_rect = QRectF(QPoint(0,0),event->newSize());
375 QRectF rect = m_rect.adjusted(margin(),margin(), -margin(), -margin());
376
377 // recalculate title position
378 if (m_titleItem) {
379 QPointF center = m_rect.center() -m_titleItem->boundingRect().center();
380 m_titleItem->setPos(center.x(),m_rect.top()/2 + margin()/2);
381 }
382
383 //recalculate background gradient
384 if (m_backgroundItem) {
385 m_backgroundItem->setRect(rect);
386 if (m_bacgroundOrinetation == HorizonatlGradientOrientation)
387 m_backgroundGradient.setFinalStop(m_backgroundItem->rect().width(), 0);
388 else
389 m_backgroundGradient.setFinalStop(0, m_backgroundItem->rect().height());
390 m_backgroundItem->setBrush(m_backgroundGradient);
391 }
392
393 // resize and reposition childs
394 foreach (ChartItem *item, m_chartItems) {
395 item->setPos(rect.topLeft());
396 item->setSize(rect.size());
397 }
398
399 update();
400 }
401
402
403
400 404 #include "moc_qchart.cpp"
401 405
402 406 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,99 +1,103
1 1 #ifndef CHART_H
2 2 #define CHART_H
3 3
4 4 #include <qchartglobal.h>
5 5 #include <qchartseries.h>
6 #include <QGraphicsObject>
6 #include <QGraphicsWidget>
7 7 #include <QLinearGradient>
8 8 #include <QFont>
9 9
10 class QGraphicsSceneResizeEvent;
11
10 12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 13
12 14 class AxisItem;
13 15 class QChartSeries;
14 16 class PlotDomain;
15 17 class BarGroup;
16 18 class QChartAxis;
17 19 class ChartTheme;
18 20 class ChartItem;
19 21
20 22 // TODO: We don't need to have QChart tied to QGraphicsItem:
21 23 //class QTCOMMERCIALCHART_EXPORT QChart
22 24 //class QTCOMMERCIALCHART_EXPORT QChartGraphicsItem : public QGraphicsItem {
23 25 // public: QChartGraphicsItem(QChart &chart);
24 26
25 27 /*!
26 28 * TODO: define the responsibilities
27 29 */
28 class QTCOMMERCIALCHART_EXPORT QChart : public QGraphicsObject
30 class QTCOMMERCIALCHART_EXPORT QChart : public QGraphicsWidget
29 31 {
30 32 Q_OBJECT
31 33 public:
32 34 enum GradientOrientation {
33 35 HorizonatlGradientOrientation,
34 36 VerticalGradientOrientation
35 37 };
36 38 enum ChartThemeId {
37 39 ChartThemeInvalid = -1,
38 40 /*! The default theme follows the GUI style of the Operating System */
39 41 ChartThemeDefault,
40 42 ChartThemeVanilla,
41 43 ChartThemeIcy,
42 44 ChartThemeGrayscale,
43 45 //ChartThemeScientific,
44 46 ChartThemeUnnamed1
45 47 };
46 48
47 49 public:
48 QChart(QGraphicsObject* parent = 0);
50 QChart(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
49 51 ~QChart();
50 52
51 53 //from QGraphicsItem
52 54 QRectF boundingRect() const;
53 55 void paint(QPainter */*painter*/, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/) {}
54 56
55 57 void addSeries(QChartSeries* series);
56 58 //TODO: QChartSeries* createSeries(QSeriesData *data, QChartSeries::QChartSeriesType type);
57 59 // TODO: who owns the series now? maybe owned by chart and returned a reference instead...
58 60 QChartSeries* createSeries(QChartSeries::QChartSeriesType type);
59 61
60 void setSize(const QSize& size);
61 62 void setMargin(int margin);
62 63 int margin() const;
63 64 void setTheme(QChart::ChartThemeId theme);
64 65
65 66 void setTitle(const QString& title,const QFont& font = QFont());
66 67 void setBackground(const QColor& startColor, const QColor& endColor = Qt::white, GradientOrientation orientation = VerticalGradientOrientation);
67 68
68 void zoomInToRect(const QRect& rectangle);
69 void zoomInToRect(const QRectF& rectangle);
69 70 void zoomIn();
70 71 void zoomOut();
71 72 void zoomReset();
72 73
73 74 void setAxisX(const QChartAxis& axis);
74 75 void setAxisY(const QChartAxis& axis);
75 76 void setAxisY(const QList<QChartAxis>& axis);
76 77
78 protected:
79 void resizeEvent(QGraphicsSceneResizeEvent *event);
80
77 81 private:
78 82 void setAxis(AxisItem *item, const QChartAxis& axis);
79 83
80 84 private:
81 85 Q_DISABLE_COPY(QChart)
82 86 QGraphicsRectItem* m_backgroundItem;
83 87 QLinearGradient m_backgroundGradient;
84 88 GradientOrientation m_bacgroundOrinetation;
85 89 QGraphicsTextItem* m_titleItem;
86 90 AxisItem* m_axisXItem;
87 91 QList<AxisItem*> m_axisYItem;
88 QRect m_rect;
92 QRectF m_rect;
89 93 QList<QChartSeries *> m_chartSeries;
90 94 QList<ChartItem *> m_chartItems;
91 95 QVector<PlotDomain> m_plotDomainList;
92 96 int m_plotDataIndex;
93 97 int m_marginSize;
94 98 ChartTheme *m_chartTheme;
95 99 };
96 100
97 101 QTCOMMERCIALCHART_END_NAMESPACE
98 102
99 103 #endif
@@ -1,77 +1,77
1 1 #include "qchartview.h"
2 2 #include "qchart.h"
3 3 #include <QGraphicsView>
4 4 #include <QGraphicsScene>
5 5 #include <QRubberBand>
6 6 #include <QResizeEvent>
7 7 #include <QDebug>
8 8
9 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 10
11 11 QChartView::QChartView(QWidget *parent) :
12 12 QGraphicsView(parent),
13 13 m_scene(new QGraphicsScene()),
14 14 m_chart(new QChart())
15 15 {
16 16 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
17 17 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
18 18 setScene(m_scene);
19 19 m_chart->setMargin(50);
20 20 m_scene->addItem(m_chart);
21 21 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
22 22 }
23 23
24 24 QChartView::~QChartView()
25 25 {
26 26 }
27 27
28 28 void QChartView::resizeEvent(QResizeEvent *event)
29 29 {
30 30 m_scene->setSceneRect(0,0,size().width(),size().height());
31 m_chart->setSize(size());
31 m_chart->resize(size());
32 32 QWidget::resizeEvent(event);
33 33 }
34 34
35 35
36 36 void QChartView::addSeries(QChartSeries* series)
37 37 {
38 38 m_chart->addSeries(series);
39 39 }
40 40
41 41 QChartSeries* QChartView::createSeries(QChartSeries::QChartSeriesType type)
42 42 {
43 43
44 44 return m_chart->createSeries(type);
45 45 }
46 46
47 47 void QChartView::zoomInToRect(const QRect& rectangle)
48 48 {
49 49 m_chart->zoomInToRect(rectangle);
50 50 }
51 51
52 52 void QChartView::zoomIn()
53 53 {
54 54 m_chart->zoomIn();
55 55 }
56 56
57 57 void QChartView::zoomOut()
58 58 {
59 59 m_chart->zoomOut();
60 60 }
61 61
62 62 int QChartView::margin() const
63 63 {
64 64 return m_chart->margin();
65 65 }
66 66
67 67 void QChartView::setTitle(const QString& title)
68 68 {
69 69 m_chart->setTitle(title);
70 70 }
71 71
72 72 void QChartView::setBackground(const QColor& startColor, const QColor& endColor, QChart::GradientOrientation orientation)
73 73 {
74 74 m_chart->setBackground(startColor,endColor,orientation);
75 75 }
76 76
77 77 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,102 +1,102
1 1 #include "qchartwidget.h"
2 2 #include "qchartseries.h"
3 3 #include <QGraphicsView>
4 4 #include <QGraphicsScene>
5 5 #include <QResizeEvent>
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 9 QChartWidget::QChartWidget(QWidget *parent) :
10 10 QGraphicsView(parent),
11 11 m_rubberBand(QRubberBand::Rectangle, this),
12 12 m_originX(0)
13 13 {
14 14 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
15 15 m_scene = new QGraphicsScene();
16 16 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
17 17 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
18 18 setScene(m_scene);
19 19
20 20 m_chart = new QChart();
21 21 // TODO: currently setting the margins explicitly is required, if you wish to have axis labels visible
22 22 m_chart->setMargin(25);
23 23 m_scene->addItem(m_chart);
24 24 m_rubberBand.setEnabled(true); // TODO: should zoom be enabled by default?
25 25 show();
26 26 }
27 27
28 28 QChartWidget::~QChartWidget()
29 29 {
30 30 }
31 31
32 32 void QChartWidget::resizeEvent(QResizeEvent *event)
33 33 {
34 34 m_scene->setSceneRect(0,0,size().width(),size().height());
35 m_chart->setSize(size());
35 m_chart->resize(size());
36 36 QWidget::resizeEvent(event);
37 37 }
38 38
39 39 QSize QChartWidget::sizeHint() const
40 40 {
41 41 // TODO: calculate size hint based on contents?
42 42 return QSize(100, 100);
43 43 }
44 44
45 45 void QChartWidget::mousePressEvent(QMouseEvent *event)
46 46 {
47 47 if(m_rubberBand.isEnabled() && event->button() == Qt::LeftButton) {
48 48 int margin = m_chart->margin();
49 49 QRect rect(margin, margin, width() - 2 * margin, height() - 2 * margin);
50 50
51 51 if (rect.contains(event->pos())) {
52 52 m_originX = event->pos().x();
53 53 m_rubberBand.setGeometry(QRect(m_originX, 0, 0, height()));
54 54 m_rubberBand.show();
55 55 event->accept();
56 56 }
57 57 }
58 58 }
59 59
60 60 void QChartWidget::mouseMoveEvent(QMouseEvent *event)
61 61 {
62 62 if(m_rubberBand.isVisible())
63 63 m_rubberBand.setGeometry(QRect(m_originX, 0,
64 64 event->pos().x() - m_originX, height()).normalized());
65 65 }
66 66
67 67 void QChartWidget::mouseReleaseEvent(QMouseEvent *event)
68 68 {
69 69 if (event->button() == Qt::LeftButton && m_rubberBand.isVisible()) {
70 70 m_rubberBand.hide();
71 71 QRect rect = m_rubberBand.geometry();
72 72 m_chart->zoomInToRect(rect);
73 73 event->accept();
74 74 }
75 75
76 76 if(event->button()==Qt::RightButton)
77 77 m_chart->zoomReset();
78 78 }
79 79
80 80 void QChartWidget::addSeries(QChartSeries* series)
81 81 {
82 82 m_chart->addSeries(series);
83 83 }
84 84
85 85 QChartSeries* QChartWidget::createSeries(QChartSeries::QChartSeriesType type)
86 86 {
87 87 return m_chart->createSeries(type);
88 88 }
89 89
90 90 void QChartWidget::setTheme(QChart::ChartThemeId theme)
91 91 {
92 92 m_chart->setTheme(theme);
93 93 }
94 94
95 95 void QChartWidget::setZoomEnabled(bool enabled)
96 96 {
97 97 m_rubberBand.setEnabled(enabled);
98 98 }
99 99
100 100 #include "moc_qchartwidget.cpp"
101 101
102 102 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,186 +1,186
1 1 #include "qpieseries_p.h"
2 2 #include "qpieseries.h"
3 3 #include <QGraphicsObject>
4 4 #include "pieslice.h"
5 5 #include <QDebug>
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 9 QPieSeriesPrivate::QPieSeriesPrivate(QGraphicsItem *parent) :
10 10 ChartItem(parent),
11 11 m_sizeFactor(1.0),
12 12 m_position(QPieSeries::PiePositionMaximized),
13 13 m_chartTheme(0)
14 14 {
15 15 }
16 16
17 17 QPieSeriesPrivate::~QPieSeriesPrivate()
18 18 {
19 19 while (m_slices.count())
20 20 delete m_slices.takeLast();
21 21 }
22 22
23 23 bool QPieSeriesPrivate::setData(QList<qreal> data)
24 24 {
25 25 m_data = data;
26 26
27 27 if (parentItem()) {
28 28 // Create slices
29 29 qreal fullPie = 360;
30 30 qreal total = 0;
31 31 foreach (qreal value, m_data)
32 32 total += value;
33 33
34 34 m_chartSize = parentItem()->boundingRect();
35 35 qreal angle = 0;
36 36 // TODO: no need to create new slices in case size changed; we should re-use the existing ones
37 37 foreach (qreal value, m_data) {
38 38 qreal span = value / total * fullPie;
39 39 PieSlice *slice = new PieSlice(QColor(), angle, span, parentItem()->boundingRect());
40 40 slice->setParentItem(parentItem());
41 41 m_slices.append(slice);
42 42 angle += span;
43 43 }
44 44
45 45 themeChanged(m_chartTheme);
46 46 resizeSlices(m_chartSize);
47 47 }
48 48
49 49 return true;
50 50 }
51 51
52 void QPieSeriesPrivate::setSize(const QSize &size)
52 void QPieSeriesPrivate::setSize(const QSizeF &size)
53 53 {
54 54 // TODO: allow user setting the size?
55 55 // TODO: allow user defining the margins?
56 56 m_chartSize = QRect(0, 0, size.width(), size.height());
57 57 resizeSlices(m_chartSize);
58 58 }
59 59
60 60 void QPieSeriesPrivate::setPlotDomain(const PlotDomain& plotDomain)
61 61 {
62 62 // TODO
63 63 }
64 64
65 65 void QPieSeriesPrivate::themeChanged(ChartTheme *theme)
66 66 {
67 67 if (theme) {
68 68 m_chartTheme = theme;
69 69 for (int i(0); i < m_slices.count(); i++)
70 70 m_slices.at(i)->m_theme = theme->themeForSeries();
71 71 }
72 72 }
73 73
74 74 void QPieSeriesPrivate::resizeSlices(QRectF rect)
75 75 {
76 76 QRectF tempRect = rect;
77 77 if (tempRect.width() < tempRect.height()) {
78 78 tempRect.setWidth(tempRect.width() * m_sizeFactor);
79 79 tempRect.setHeight(tempRect.width());
80 80 tempRect.moveCenter(rect.center());
81 81 } else {
82 82 tempRect.setHeight(tempRect.height() * m_sizeFactor);
83 83 tempRect.setWidth(tempRect.height());
84 84 tempRect.moveCenter(rect.center());
85 85 }
86 86
87 87 switch (m_position) {
88 88 case QPieSeries::PiePositionTopLeft: {
89 89 tempRect.setHeight(tempRect.height() / 2);
90 90 tempRect.setWidth(tempRect.height());
91 91 tempRect.moveCenter(QPointF(rect.center().x() / 2, rect.center().y() / 2));
92 92 break;
93 93 }
94 94 case QPieSeries::PiePositionTopRight: {
95 95 tempRect.setHeight(tempRect.height() / 2);
96 96 tempRect.setWidth(tempRect.height());
97 97 tempRect.moveCenter(QPointF((rect.center().x() / 2) * 3, rect.center().y() / 2));
98 98 break;
99 99 }
100 100 case QPieSeries::PiePositionBottomLeft: {
101 101 tempRect.setHeight(tempRect.height() / 2);
102 102 tempRect.setWidth(tempRect.height());
103 103 tempRect.moveCenter(QPointF(rect.center().x() / 2, (rect.center().y() / 2) * 3));
104 104 break;
105 105 }
106 106 case QPieSeries::PiePositionBottomRight: {
107 107 tempRect.setHeight(tempRect.height() / 2);
108 108 tempRect.setWidth(tempRect.height());
109 109 tempRect.moveCenter(QPointF((rect.center().x() / 2) * 3, (rect.center().y() / 2) * 3));
110 110 break;
111 111 }
112 112 default:
113 113 break;
114 114 }
115 115
116 116 foreach (PieSlice *slice, m_slices)
117 117 slice->m_rect = tempRect;
118 118 }
119 119
120 120 QPieSeries::QPieSeries(QGraphicsObject *parent) :
121 121 QChartSeries(parent),
122 122 d(new QPieSeriesPrivate(parent))
123 123 {
124 124 }
125 125
126 126 QPieSeries::~QPieSeries()
127 127 {
128 128 delete d;
129 129 }
130 130
131 131 bool QPieSeries::setData(QList<qreal> data)
132 132 {
133 133 return d->setData(data);
134 134 }
135 135
136 136 void QPieSeries::setSliceColor(int index, QColor color)
137 137 {
138 138 if (index >= 0 && index < d->m_slices.count())
139 139 d->m_slices.at(index)->m_color = color;
140 140 }
141 141
142 142 QColor QPieSeries::sliceColor(int index)
143 143 {
144 144 if (index >= 0 && index < d->m_slices.count())
145 145 return d->m_slices.at(index)->m_color;
146 146 else
147 147 return QColor();
148 148 }
149 149
150 150 int QPieSeries::sliceCount()
151 151 {
152 152 return d->m_slices.count();
153 153 }
154 154
155 155 void QPieSeries::setSizeFactor(qreal factor)
156 156 {
157 157 if (factor > 0.0)
158 158 d->m_sizeFactor = factor;
159 159 d->resizeSlices(d->m_chartSize);
160 160
161 161 // Initiate update via the parent graphics item
162 162 // TODO: potential issue: what if this function is called from the parent context?
163 163 if (d->parentItem())
164 164 d->parentItem()->update();
165 165 }
166 166
167 167 qreal QPieSeries::sizeFactor()
168 168 {
169 169 return d->m_sizeFactor;
170 170 }
171 171
172 172 void QPieSeries::setPosition(PiePosition position)
173 173 {
174 174 d->m_position = position;
175 175 d->resizeSlices(d->m_chartSize);
176 176
177 177 // Initiate update via the parent graphics item
178 178 // TODO: potential issue: what if this function is called from the parent context?
179 179 QGraphicsItem *parentItem = qobject_cast<QGraphicsItem *>(parent());
180 180 Q_ASSERT(parentItem);
181 181 parentItem->update();
182 182 }
183 183
184 184 #include "moc_qpieseries.cpp"
185 185
186 186 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,45 +1,45
1 1 #ifndef PIESERIESPRIVATE_H
2 2 #define PIESERIESPRIVATE_H
3 3
4 4 #include "chartitem_p.h"
5 5 #include "charttheme_p.h"
6 6 #include "qpieseries.h"
7 7 #include <QRectF>
8 8 #include <QColor>
9 9
10 10 class QGraphicsItem;
11 11 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 12 class PieSlice;
13 13
14 14 class QPieSeriesPrivate : public ChartItem, public ChartThemeObserver
15 15 {
16 16 public:
17 17 // TODO: use a generic data class instead of x and y
18 18 QPieSeriesPrivate(QGraphicsItem *parent);
19 19 ~QPieSeriesPrivate();
20 20
21 21 public: // from ChartItem
22 void setSize(const QSize &size);
22 void setSize(const QSizeF &size);
23 23 void setPlotDomain(const PlotDomain& data);
24 24 // This is a dummy QGraphicsItem; dummy implementation
25 25 QRectF boundingRect() const { return parentItem()->boundingRect(); }
26 26 // This is a dummy QGraphicsItem; no implementation
27 27 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) {}
28 28
29 29 public: // from ChartThemeObserver
30 30 void themeChanged(ChartTheme *theme);
31 31
32 32 public:
33 33 bool setData(QList<qreal> data);
34 34 void resizeSlices(QRectF rect);
35 35 QList<qreal> m_data;
36 36 QList<PieSlice*> m_slices;
37 37 QRectF m_chartSize;
38 38 qreal m_sizeFactor;
39 39 QPieSeries::PiePosition m_position;
40 40 ChartTheme *m_chartTheme;
41 41 };
42 42
43 43 QTCOMMERCIALCHART_END_NAMESPACE
44 44
45 45 #endif // PIESERIESPRIVATE_H
@@ -1,140 +1,140
1 1 #include "qscatterseries.h"
2 2 #include "qscatterseries_p.h"
3 3 #include "qchart.h"
4 4 #include <QPainter>
5 5 #include <QGraphicsScene>
6 6 #include <QDebug>
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 10 //#define QSeriesData QList<qreal>
11 11
12 12 QScatterSeriesPrivate::QScatterSeriesPrivate(QGraphicsItem *parent) :
13 13 ChartItem(parent),
14 14 m_markerColor(QColor()),
15 15 m_visibleChartArea(),
16 16 m_boundingRect()
17 17 {
18 18 if (parent)
19 19 m_boundingRect = parent->boundingRect();
20 20 }
21 21
22 22 void QScatterSeriesPrivate::changeGeometry()
23 23 {
24 24 if (m_boundingRect.isValid()) {
25 25 prepareGeometryChange();
26 26 qreal scalex = m_boundingRect.width() / m_visibleChartArea.spanX();
27 27 qreal scaley = m_boundingRect.height() / m_visibleChartArea.spanY();
28 28 m_scenex.clear();
29 29 m_sceney.clear();
30 30
31 31 // Convert relative coordinates to absolute pixel coordinates that can be used for drawing
32 32 foreach(qreal x, m_x)
33 33 m_scenex.append(m_boundingRect.left() + x * scalex - m_visibleChartArea.m_minX * scalex);
34 34
35 35 foreach(qreal y, m_y)
36 36 m_sceney.append(m_boundingRect.bottom() - y * scaley + m_visibleChartArea.m_minY * scaley);
37 37 }
38 38 }
39 39
40 void QScatterSeriesPrivate::setSize(const QSize &size)
40 void QScatterSeriesPrivate::setSize(const QSizeF &size)
41 41 {
42 42 // m_boundingRect = QRectF(pos().x(), pos().y(), size.width(), size.height());
43 43 m_boundingRect = QRectF(0, 0, size.width(), size.height());
44 44 changeGeometry();
45 45 }
46 46
47 47 void QScatterSeriesPrivate::themeChanged(ChartTheme *theme)
48 48 {
49 49 m_theme = theme->themeForSeries();
50 50 }
51 51
52 52 void QScatterSeriesPrivate::setPlotDomain(const PlotDomain& plotDomain)
53 53 {
54 54 m_visibleChartArea = plotDomain;
55 55 changeGeometry();
56 56 }
57 57
58 58 QRectF QScatterSeriesPrivate::boundingRect() const
59 59 {
60 60 return m_boundingRect;
61 61 }
62 62
63 63 void QScatterSeriesPrivate::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
64 64 {
65 65 // TODO: The opacity should be user definable?
66 66 //brush.setColor(QColor(255, 82, 0, 100));
67 67 if (m_markerColor.isValid()) {
68 68 QPen pen = painter->pen();
69 69 QBrush brush = pen.brush();
70 70 brush.setColor(m_markerColor);
71 71 pen.setBrush(brush);
72 72 pen.setWidth(4);
73 73 painter->setPen(pen);
74 74 }
75 75 else
76 76 painter->setPen(m_theme.markerPen);
77 77 // brush.setColor(m_theme..lineColor);
78 78
79 79 // TODO: m_scenex and m_sceny are left empty during construction -> we would need a resize
80 80 // event right after construction or maybe given a size during initialization
81 81 for (int i(0); i < m_scenex.count() && i < m_sceney.count(); i++) {
82 82 if (scene()->width() > m_scenex.at(i) && scene()->height() > m_sceney.at(i))
83 83 //painter->drawArc(m_scenex.at(i), m_sceney.at(i), 2, 2, 0, 5760);
84 84 painter->drawPoint(m_scenex.at(i), m_sceney.at(i));
85 85 }
86 86 }
87 87
88 88 QScatterSeries::QScatterSeries(QObject *parent) :
89 89 QChartSeries(parent),
90 90 d(new QScatterSeriesPrivate(qobject_cast<QGraphicsItem *> (parent)))
91 91 {
92 92 }
93 93
94 94 bool QScatterSeries::setData(QList<qreal> xlist, QList<qreal> ylist)
95 95 {
96 96 // TODO: validate data
97 97 d->m_x = xlist;
98 98 d->m_y = ylist;
99 99
100 100 // TODO: the following updates the visible chart area setting of the series, we would instead
101 101 // need to update the _chart's_ visible area... this would require a callback or
102 102 // similar to the parenting QChart object...
103 103 foreach (qreal x, d->m_x) {
104 104 d->m_visibleChartArea.m_minX = qMin(d->m_visibleChartArea.m_minX, x);
105 105 d->m_visibleChartArea.m_maxX = qMax(d->m_visibleChartArea.m_maxX, x);
106 106 }
107 107 foreach (qreal y, d->m_y) {
108 108 d->m_visibleChartArea.m_minY = qMin(d->m_visibleChartArea.m_minY, y);
109 109 d->m_visibleChartArea.m_maxY = qMax(d->m_visibleChartArea.m_maxY, y);
110 110 }
111 111
112 112 d->changeGeometry();
113 113
114 114 return true;
115 115 }
116 116
117 117 void QScatterSeries::setMarkerColor(QColor color)
118 118 {
119 119 d->m_markerColor = color;
120 120 }
121 121
122 122 QColor QScatterSeries::markerColor()
123 123 {
124 124 return d->m_markerColor;
125 125 }
126 126
127 127 // TODO:
128 128 //void QScatterSeries::chartScaleChanged(qreal xscale, qreal yscale)
129 129 //{
130 130 // d->rescale(xscale, yscale);
131 131 //}
132 132
133 133 QScatterSeries::~QScatterSeries()
134 134 {
135 135 delete d;
136 136 }
137 137
138 138 #include "moc_qscatterseries.cpp"
139 139
140 140 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,47 +1,47
1 1 #ifndef QSCATTERSERIESPRIVATE_H
2 2 #define QSCATTERSERIESPRIVATE_H
3 3
4 4 #include "qchartseries.h"
5 5 #include "charttheme_p.h"
6 6 #include "chartitem_p.h"
7 7 #include "plotdomain_p.h"
8 8 #include <QGraphicsItem>
9 9
10 10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 11
12 12 /*!
13 13 * The PIMPL class of QScatterSeries.
14 14 */
15 15 class QScatterSeriesPrivate : public ChartItem, public ChartThemeObserver
16 16 {
17 17 public:
18 18 QScatterSeriesPrivate(QGraphicsItem *parent);
19 19
20 20 public: // from ChartObjectInterface
21 void setSize(const QSize &size);
21 void setSize(const QSizeF &size);
22 22 void setPlotDomain(const PlotDomain& data);
23 23
24 24 public: // from ChartThemeObserver
25 25 void themeChanged(ChartTheme *theme);
26 26
27 27 public: // from QGraphicsItem
28 28 QRectF boundingRect() const;
29 29 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
30 30
31 31 public:
32 32 void changeGeometry();
33 33
34 34 QRectF m_boundingRect;
35 35 // TODO: use the chart data class instead of list of x and y values?
36 36 QList<qreal> m_x;
37 37 QList<qreal> m_y;
38 38 QList<qreal> m_scenex;
39 39 QList<qreal> m_sceney;
40 40 QColor m_markerColor;
41 41 SeriesTheme m_theme;
42 42 PlotDomain m_visibleChartArea;
43 43 };
44 44
45 45 QTCOMMERCIALCHART_END_NAMESPACE
46 46
47 47 #endif // QSCATTERSERIESPRIVATE_H
@@ -1,72 +1,72
1 1 #include "xylinechartitem_p.h"
2 2 #include "axisitem_p.h"
3 3 #include "qxychartseries.h"
4 4 #include <QPainter>
5 5 #include <QStyleOptionGraphicsItem>
6 6 #include <QDebug>
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 10 XYLineChartItem::XYLineChartItem(QXYChartSeries* series,QGraphicsItem *parent) :
11 11 ChartItem(parent),
12 12 m_series(series),
13 13 m_pathItem(new QGraphicsPathItem(this))
14 14 {
15 15 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
16 16 }
17 17
18 void XYLineChartItem::setSize(const QSize &size)
18 void XYLineChartItem::setSize(const QSizeF &size)
19 19 {
20 20 m_rect = QRect(0, 0, size.width(), size.height());
21 21 prepareGeometryChange();
22 22 updateGeometry();
23 23 }
24 24
25 25 void XYLineChartItem::setPlotDomain(const PlotDomain& data)
26 26 {
27 27 m_plotDomain=data;
28 28 prepareGeometryChange();
29 29 updateGeometry();
30 30
31 31 }
32 32
33 33 QRectF XYLineChartItem::boundingRect() const
34 34 {
35 35 return m_rect;
36 36 }
37 37
38 38 void XYLineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
39 39 {
40 40 m_pathItem->setPen(m_series->pen());
41 41 }
42 42
43 43 /*
44 44 QPainterPath XYLineChartItem::shape() const
45 45 {
46 46 return m_pathItem->shape();
47 47 }
48 48 */
49 49 void XYLineChartItem::updateGeometry()
50 50 {
51 51 if (!m_rect.isValid()) return;
52 52
53 53 const qreal deltaX = m_rect.width()/m_plotDomain.spanX();
54 54 const qreal deltaY = m_rect.height()/m_plotDomain.spanY();
55 55
56 56 QPainterPath path;
57 57
58 58 for (int j = 0; j < m_series->count(); ++j) {
59 59 qreal dx = m_series->x(j) - m_plotDomain.m_minX;
60 60 qreal dy = m_series->y(j) - m_plotDomain.m_minY;
61 61 qreal x = (dx * deltaX) + m_rect.left();
62 62 qreal y = - (dy * deltaY) + m_rect.bottom();
63 63 if(j==0) path.moveTo(x,y);
64 64 else path.lineTo(x,y);
65 65 }
66 66
67 67 m_pathItem->setPath(path);
68 68 m_pathItem->setPen(m_series->pen());
69 69 m_pathItem->setBrush(Qt::NoBrush);
70 70 }
71 71
72 72 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,41 +1,41
1 1 #ifndef XYLINECHARTITEM_H
2 2 #define XYLINECHARTITEM_H
3 3
4 4 #include "qchartglobal.h"
5 5 #include "chartitem_p.h"
6 6 #include <QGraphicsItem>
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 10 class QXYChartSeries;
11 11
12 12 class XYLineChartItem : public ChartItem
13 13 {
14 14
15 15 public:
16 16 XYLineChartItem(QXYChartSeries* m_series,QGraphicsItem *parent = 0);
17 17 ~ XYLineChartItem(){};
18 18
19 19 //from QGraphicsItem
20 20 QRectF boundingRect() const;
21 21 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
22 22 // virtual QPainterPath shape() const;
23 23
24 24 public: // from ChartItem
25 void setSize(const QSize &size);
25 void setSize(const QSizeF &size);
26 26 void setPlotDomain(const PlotDomain& data);
27 27
28 28 private:
29 29 void updateGeometry();
30 30
31 31 private:
32 32 QRect m_rect;
33 33 QPolygonF m_polyline;
34 34 QXYChartSeries* m_series;
35 35 PlotDomain m_plotDomain;
36 36 QGraphicsPathItem *m_pathItem;
37 37 };
38 38
39 39 QTCOMMERCIALCHART_END_NAMESPACE
40 40
41 41 #endif
General Comments 0
You need to be logged in to leave comments. Login now