@@ -0,0 +1,46 | |||
|
1 | #include "barchartseries.h" | |
|
2 | QTCOMMERCIALCHART_BEGIN_NAMESPACE | |
|
3 | ||
|
4 | BarChartSeries::BarChartSeries(QList<int> data, QObject *parent) | |
|
5 | : QChartSeries(parent) | |
|
6 | , mData(data) | |
|
7 | { | |
|
8 | } | |
|
9 | ||
|
10 | int BarChartSeries::min() | |
|
11 | { | |
|
12 | // TODO: make min and max members and update them when data changes. | |
|
13 | // This is slower since they are checked every time, even if data is same since previous call. | |
|
14 | int min = mData.at(0); | |
|
15 | ||
|
16 | for (int i=0; i <mData.count(); i++) { | |
|
17 | if (mData.at(i) < min) { | |
|
18 | min = mData.at(i); | |
|
19 | } | |
|
20 | } | |
|
21 | return min; | |
|
22 | } | |
|
23 | ||
|
24 | int BarChartSeries::max() | |
|
25 | { | |
|
26 | int max = mData.at(0); | |
|
27 | ||
|
28 | for (int i=0; i <mData.count(); i++) { | |
|
29 | if (mData.at(i) > max) { | |
|
30 | max = mData.at(i); | |
|
31 | } | |
|
32 | } | |
|
33 | return max; | |
|
34 | } | |
|
35 | ||
|
36 | int BarChartSeries::count() | |
|
37 | { | |
|
38 | return mData.count(); | |
|
39 | } | |
|
40 | ||
|
41 | int BarChartSeries::valueAt(int i) | |
|
42 | { | |
|
43 | return mData.at(i); | |
|
44 | } | |
|
45 | ||
|
46 | QTCOMMERCIALCHART_END_NAMESPACE |
@@ -0,0 +1,34 | |||
|
1 | #ifndef BARCHARTSERIES_H | |
|
2 | #define BARCHARTSERIES_H | |
|
3 | ||
|
4 | #include <QList> | |
|
5 | #include "qchartseries.h" | |
|
6 | #include "qchartglobal.h" | |
|
7 | ||
|
8 | QTCOMMERCIALCHART_BEGIN_NAMESPACE | |
|
9 | ||
|
10 | // Container for series | |
|
11 | class QTCOMMERCIALCHART_EXPORT BarChartSeries : public QChartSeries | |
|
12 | { | |
|
13 | ||
|
14 | public: | |
|
15 | BarChartSeries(QList<int> data, QObject* parent=0); | |
|
16 | ||
|
17 | // from QChartSeries | |
|
18 | static QChartSeries* create(QObject* parent = 0 ); | |
|
19 | virtual QChartSeriesType type() const { return QChartSeries::SeriesTypeBar; } | |
|
20 | ||
|
21 | // Methods to find out minimum and maximum values of data | |
|
22 | int min(); | |
|
23 | int max(); | |
|
24 | int count(); | |
|
25 | int valueAt(int i); | |
|
26 | ||
|
27 | private: | |
|
28 | ||
|
29 | QList<int> mData; | |
|
30 | }; | |
|
31 | ||
|
32 | QTCOMMERCIALCHART_END_NAMESPACE | |
|
33 | ||
|
34 | #endif // BARCHARTSERIES_H |
@@ -0,0 +1,106 | |||
|
1 | #include "bargroup.h" | |
|
2 | #include "bar.h" | |
|
3 | #include <QDebug> | |
|
4 | ||
|
5 | QTCOMMERCIALCHART_BEGIN_NAMESPACE | |
|
6 | ||
|
7 | BarGroup::BarGroup(BarChartSeries& series, QGraphicsItem *parent) : | |
|
8 | QGraphicsItem(parent) | |
|
9 | ,mSeries(series) | |
|
10 | ,mLayoutSet(false) | |
|
11 | ,mLayoutDirty(true) | |
|
12 | { | |
|
13 | dataChanged(); | |
|
14 | } | |
|
15 | ||
|
16 | void BarGroup::resize( int w, int h ) | |
|
17 | { | |
|
18 | qDebug() << "QBarChart::resize"; | |
|
19 | mWidth = w; | |
|
20 | mHeight = h; | |
|
21 | layoutChanged(); | |
|
22 | mLayoutSet = true; | |
|
23 | } | |
|
24 | ||
|
25 | void BarGroup::setBarWidth( int w ) | |
|
26 | { | |
|
27 | mBarDefaultWidth = w; | |
|
28 | } | |
|
29 | ||
|
30 | void BarGroup::setColor( QColor color ) | |
|
31 | { | |
|
32 | mColor = color; | |
|
33 | } | |
|
34 | ||
|
35 | void BarGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) | |
|
36 | { | |
|
37 | if (!mLayoutSet) { | |
|
38 | qDebug() << "QBarChart::paint called without layout set. Aborting."; | |
|
39 | return; | |
|
40 | } | |
|
41 | if (mLayoutDirty) { | |
|
42 | // Layout or data has changed. Need to redraw. | |
|
43 | foreach(QGraphicsItem* i, childItems()) { | |
|
44 | i->paint(painter,option,widget); | |
|
45 | } | |
|
46 | } | |
|
47 | } | |
|
48 | ||
|
49 | QRectF BarGroup::boundingRect() const | |
|
50 | { | |
|
51 | // TODO: correct this (currently ignores position) | |
|
52 | return QRectF(0,0,mWidth,mHeight); | |
|
53 | } | |
|
54 | ||
|
55 | ||
|
56 | void BarGroup::dataChanged() | |
|
57 | { | |
|
58 | qDebug() << "QBarChart::dataChanged mSeries"; | |
|
59 | ||
|
60 | // Find out maximum and minimum of all series | |
|
61 | mMax = mSeries.max(); | |
|
62 | mMin = mSeries.min(); | |
|
63 | ||
|
64 | // Delete old bars | |
|
65 | // Is this correct way to delete childItems? | |
|
66 | foreach (QGraphicsItem* item, childItems()) { | |
|
67 | delete item; | |
|
68 | } | |
|
69 | ||
|
70 | // Create new graphic items for bars | |
|
71 | for (int i=0; i<mSeries.count(); i++) { | |
|
72 | Bar *bar = new Bar(this); | |
|
73 | childItems().append(bar); | |
|
74 | } | |
|
75 | ||
|
76 | mLayoutDirty = true; | |
|
77 | } | |
|
78 | ||
|
79 | void BarGroup::layoutChanged() | |
|
80 | { | |
|
81 | // Scale bars to new layout | |
|
82 | // Layout for bars: | |
|
83 | int count = mSeries.count(); | |
|
84 | if (count <= 0) { | |
|
85 | // Nothing to do. | |
|
86 | return; | |
|
87 | } | |
|
88 | ||
|
89 | // Align center | |
|
90 | int posStep = (mWidth / (count)); | |
|
91 | int startPos = (mWidth / count+1); | |
|
92 | qDebug() << "startpos" << startPos; | |
|
93 | ||
|
94 | // Scaling. TODO: better one. | |
|
95 | for (int i=0; i<count; i++) { | |
|
96 | int barHeight = mSeries.valueAt(i) * mHeight / mMax; | |
|
97 | Bar* bar = reinterpret_cast<Bar*> (childItems().at(i)); | |
|
98 | ||
|
99 | bar->resize(mBarDefaultWidth, barHeight); // TODO: width settable per bar | |
|
100 | bar->setColor(mColor); | |
|
101 | bar->setPos(i*posStep+startPos, 0); | |
|
102 | } | |
|
103 | mLayoutDirty = true; | |
|
104 | } | |
|
105 | ||
|
106 | QTCOMMERCIALCHART_END_NAMESPACE |
@@ -0,0 +1,55 | |||
|
1 | #ifndef QBARCHART_H | |
|
2 | #define QBARCHART_H | |
|
3 | ||
|
4 | #include <QGraphicsItem> | |
|
5 | ||
|
6 | #include "bar.h" | |
|
7 | //#include "qbarchartview.h" | |
|
8 | #include "barchartseries.h" | |
|
9 | ||
|
10 | QTCOMMERCIALCHART_BEGIN_NAMESPACE | |
|
11 | ||
|
12 | // TODO: Better name for this? The function of this class is to know where each bar in series is laid out. | |
|
13 | // Class has knowledge of single series of data (owns vs reference?) | |
|
14 | class BarGroup : public QGraphicsItem | |
|
15 | { | |
|
16 | ||
|
17 | public: | |
|
18 | explicit BarGroup(BarChartSeries& series, QGraphicsItem *parent = 0); | |
|
19 | ||
|
20 | // Layout "api" | |
|
21 | void resize( int w, int h ); // Size for whole series. Single bars are drawn inside this area | |
|
22 | void setPos(qreal x, qreal y); | |
|
23 | void setBarWidth( int w ); // Default width for each bar | |
|
24 | void setColor( QColor color ); // Default color for each bar | |
|
25 | ||
|
26 | // From QGraphicsItem | |
|
27 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); | |
|
28 | QRectF boundingRect() const; | |
|
29 | ||
|
30 | private: | |
|
31 | ||
|
32 | void dataChanged(); // data of series has changed -> need to recalculate bar sizes | |
|
33 | void layoutChanged(); // layout has changed -> need to recalculate bar sizes | |
|
34 | ||
|
35 | private: | |
|
36 | ||
|
37 | // Data | |
|
38 | BarChartSeries& mSeries; | |
|
39 | int mMin; // Min and max values of data. (updated when data is changed, used when drawing) | |
|
40 | int mMax; | |
|
41 | ||
|
42 | int mHeight; // Layout spesific | |
|
43 | int mWidth; | |
|
44 | int mBarDefaultWidth; | |
|
45 | ||
|
46 | QColor mColor; | |
|
47 | ||
|
48 | bool mLayoutSet; // True, if component has been laid out. | |
|
49 | bool mLayoutDirty; | |
|
50 | ||
|
51 | }; | |
|
52 | ||
|
53 | QTCOMMERCIALCHART_END_NAMESPACE | |
|
54 | ||
|
55 | #endif // QBARCHART_H |
@@ -1,26 +1,32 | |||
|
1 |
#include " |
|
|
1 | #include "bar.h" | |
|
2 | 2 | #include <QDebug> |
|
3 | 3 | #include <Qpainter> |
|
4 | 4 | |
|
5 | QBarChartBar::QBarChartBar(QGraphicsItem *parent) | |
|
5 | QTCOMMERCIALCHART_BEGIN_NAMESPACE | |
|
6 | ||
|
7 | Bar::Bar(QGraphicsItem *parent) | |
|
6 | 8 | : QGraphicsItem(parent) |
|
7 | 9 | { |
|
8 | 10 | } |
|
9 | 11 | |
|
10 |
void |
|
|
12 | void Bar::resize( int w, int h ) | |
|
11 | 13 | { |
|
12 | mHeight = h; | |
|
13 | 14 | mWidth = w; |
|
15 | mHeight = h; | |
|
14 | 16 | } |
|
15 | 17 | |
|
16 |
void |
|
|
18 | void Bar::setColor( QColor col ) | |
|
17 | 19 | { |
|
18 | 20 | mColor = col; |
|
19 | 21 | } |
|
22 | void Bar::setPos(qreal x, qreal y) | |
|
23 | { | |
|
24 | mXpos = x; | |
|
25 | mYpos = y; | |
|
26 | } | |
|
20 | 27 | |
|
21 |
void |
|
|
28 | void Bar::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) | |
|
22 | 29 | { |
|
23 | qDebug() << "QBarChartBar::paint" << scenePos(); | |
|
24 | 30 | // Set color for bar. TODO: gradients, textures etc |
|
25 | 31 | QPen pen = painter->pen(); |
|
26 | 32 | pen.setColor( mColor ); |
@@ -28,12 +34,17 void QBarChartBar::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti | |||
|
28 | 34 | painter->setPen(pen); |
|
29 | 35 | |
|
30 | 36 | // Draw bar |
|
31 | painter->drawLine(scenePos().x(), scenePos().y() + parentItem()->boundingRect().height(), | |
|
32 |
|
|
|
37 | // TODO: Pen width affects bar height for now. This should be rect | |
|
38 | painter->drawLine(scenePos().x() + mXpos, scenePos().y() + mYpos + parentItem()->boundingRect().height() - mHeight - mWidth, | |
|
39 | scenePos().x() + mXpos, scenePos().y() + mYpos + parentItem()->boundingRect().height() - mWidth); | |
|
33 | 40 | } |
|
34 | 41 | |
|
35 |
QRectF |
|
|
42 | QRectF Bar::boundingRect() const | |
|
36 | 43 | { |
|
37 | QRectF r(scenePos().x(), scenePos().y(), scenePos().x() + mWidth, scenePos().y() + mHeight ); | |
|
44 | // TODO: check validity of this (I suppose there is easier way, and currently this bit incorrect :) | |
|
45 | // QRectF r(scenePos().x()+mXpos, scenePos().y()+mYpos, scenePos().x() + mWidth, scenePos().y() + mHeight ); | |
|
46 | QRectF r(mXpos, mYpos, mXpos + mWidth, mYpos + mHeight); | |
|
38 | 47 | return r; |
|
39 | 48 | } |
|
49 | ||
|
50 | QTCOMMERCIALCHART_END_NAMESPACE |
@@ -1,18 +1,21 | |||
|
1 |
#ifndef |
|
|
2 |
#define |
|
|
1 | #ifndef BAR_H | |
|
2 | #define BAR_H | |
|
3 | 3 | |
|
4 | 4 | #include <QGraphicsItem> |
|
5 | #include "qchartglobal.h" | |
|
5 | 6 | |
|
6 | // Single bar item of chart | |
|
7 | QTCOMMERCIALCHART_BEGIN_NAMESPACE | |
|
7 | 8 | |
|
8 | class QBarChartBar : public QGraphicsItem | |
|
9 | // Single bar item of chart | |
|
10 | class Bar : public QGraphicsItem | |
|
9 | 11 | { |
|
10 | 12 | public: |
|
11 |
|
|
|
13 | Bar(QGraphicsItem *parent=0); | |
|
12 | 14 | |
|
13 | 15 | // Layout Stuff |
|
14 |
void s |
|
|
16 | void resize( int w, int h ); // Size of bar. in screen coordinates. | |
|
15 | 17 |
void setColor( QColor col ); |
|
18 | void setPos(qreal x, qreal y); | |
|
16 | 19 | |
|
17 | 20 | public: |
|
18 | 21 | // From QGraphicsItem |
@@ -24,8 +27,11 private: | |||
|
24 | 27 | |
|
25 | 28 | int mHeight; |
|
26 | 29 | int mWidth; |
|
27 | QPointF mPos; | |
|
30 | qreal mXpos; | |
|
31 | qreal mYpos; | |
|
28 | 32 | QColor mColor; |
|
29 | 33 | }; |
|
30 | 34 | |
|
31 | #endif // QBARCHARTBAR_H | |
|
35 | QTCOMMERCIALCHART_END_NAMESPACE | |
|
36 | ||
|
37 | #endif // BAR_H |
@@ -4,6 +4,10 | |||
|
4 | 4 | #include "qscatterseries_p.h" |
|
5 | 5 | #include "qpieseries.h" |
|
6 | 6 | #include "qxychartseries.h" |
|
7 | ||
|
8 | #include "barchartseries.h" | |
|
9 | #include "bargroup.h" | |
|
10 | ||
|
7 | 11 | #include "xylinechartitem_p.h" |
|
8 | 12 | #include "xyplotdomain_p.h" |
|
9 | 13 | #include "axis_p.h" |
@@ -74,6 +78,18 void QChart::addSeries(QChartSeries* series) | |||
|
74 | 78 | // } |
|
75 | 79 | // break; |
|
76 | 80 | // } |
|
81 | ||
|
82 | case QChartSeries::SeriesTypeBar: { | |
|
83 | ||
|
84 | qDebug() << "barSeries added"; | |
|
85 | BarChartSeries* barSeries = static_cast<BarChartSeries*>(series); | |
|
86 | ||
|
87 | // Who owns the series? | |
|
88 | BarGroup* group = new BarGroup(*barSeries, this); | |
|
89 | scene()->addItem(group); | |
|
90 | m_BarGroupItems.append(group); // If we need to access group later | |
|
91 | break; | |
|
92 | } | |
|
77 | 93 | } |
|
78 | 94 | } |
|
79 | 95 |
@@ -12,6 +12,7 class XYGrid; | |||
|
12 | 12 | class QChartSeries; |
|
13 | 13 | class XYPlotDomain; |
|
14 | 14 | class XYLineChartItem; |
|
15 | class BarGroup; | |
|
15 | 16 | |
|
16 | 17 | // TODO: We don't need to have QChart tied to QGraphicsItem: |
|
17 | 18 | //class QTCOMMERCIALCHART_EXPORT QChart |
@@ -57,6 +58,8 private: | |||
|
57 | 58 | QList<QGraphicsItem*> m_items; |
|
58 | 59 | int m_plotDataIndex; |
|
59 | 60 | int m_marginSize; |
|
61 | ||
|
62 | QList<BarGroup*> m_BarGroupItems; | |
|
60 | 63 | }; |
|
61 | 64 | |
|
62 | 65 | QTCOMMERCIALCHART_END_NAMESPACE |
@@ -13,7 +13,7 public: | |||
|
13 | 13 | enum QChartSeriesType { |
|
14 | 14 | SeriesTypeLine = 0, |
|
15 | 15 | // SeriesTypeArea, |
|
16 |
|
|
|
16 | SeriesTypeBar, | |
|
17 | 17 | SeriesTypePie, |
|
18 | 18 | SeriesTypeScatter |
|
19 | 19 | // SeriesTypeSpline |
@@ -24,6 +24,7 public: | |||
|
24 | 24 | QSize sizeHint() const; |
|
25 | 25 | |
|
26 | 26 | // TODO: addSeries and createSeries are optional solutions |
|
27 | // TODO: currently createSeries assumes x, y value pairs. This isn't case with all charts. So is there another createSeries for other types (for example one list of ints)? | |
|
27 | 28 | void addSeries(QChartSeries* series); |
|
28 | 29 | QChartSeries* createSeries(QList<qreal> x, QList<qreal> y, QChartSeries::QChartSeriesType type); |
|
29 | 30 |
@@ -12,6 +12,9 CONFIG += debug_and_release | |||
|
12 | 12 | CONFIG(debug, debug|release):TARGET = QtCommercialChartd |
|
13 | 13 | |
|
14 | 14 |
SOURCES += \ |
|
15 | barchart/barchartseries.cpp \ | |
|
16 | barchart/bargroup.cpp \ | |
|
17 | barchart/bar.cpp \ | |
|
15 | 18 | xylinechart/qxychartseries.cpp \ |
|
16 | 19 | xylinechart/xylinechartitem.cpp \ |
|
17 | 20 | xylinechart/xygrid.cpp \ |
@@ -38,12 +41,15 PUBLIC_HEADERS += \ | |||
|
38 | 41 | qchart.h \ |
|
39 | 42 | qchartwidget.h \ |
|
40 | 43 | qchartglobal.h \ |
|
41 | xylinechart/qxychartseries.h | |
|
44 | xylinechart/qxychartseries.h \ | |
|
45 | barchart/barchartseries.h \ | |
|
46 | barchart/bargroup.h | |
|
42 | 47 | |
|
43 | 48 | HEADERS += $$PUBLIC_HEADERS |
|
44 | 49 | HEADERS += $$PRIVATE_HEADERS |
|
45 | 50 | |
|
46 | 51 | INCLUDEPATH += xylinechart \ |
|
52 | barchart \ | |
|
47 | 53 | . |
|
48 | 54 | |
|
49 | 55 | OBJECTS_DIR = $$CHART_BUILD_DIR/lib |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now