##// END OF EJS Templates
Refactors barchart axis hadnling...
Michal Klocek -
r679:2f2494d0880e
parent child
Show More
@@ -1,83 +1,83
1 #include <QApplication>
1 #include <QApplication>
2 #include <QMainWindow>
2 #include <QMainWindow>
3 #include <QStandardItemModel>
3 #include <QStandardItemModel>
4 #include <qpercentbarseries.h>
4 #include <qpercentbarseries.h>
5 #include <qchartview.h>
5 #include <qchartview.h>
6 #include <qbarset.h>
6 #include <qbarset.h>
7 #include <qchartaxis.h>
7 #include <qchartaxis.h>
8 #include <QStringList>
8 #include <QStringList>
9
9
10 QTCOMMERCIALCHART_USE_NAMESPACE
10 QTCOMMERCIALCHART_USE_NAMESPACE
11
11
12 int main(int argc, char *argv[])
12 int main(int argc, char *argv[])
13 {
13 {
14 QApplication a(argc, argv);
14 QApplication a(argc, argv);
15 QMainWindow window;
15 QMainWindow window;
16
16
17 //! [1]
17 //! [1]
18 // Define categories
18 // Define categories
19 QStringList categories;
19 QStringList categories;
20 categories << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "Jun";
20 categories << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "Jun";
21 //! [1]
21 //! [1]
22
22
23 //! [2]
23 //! [2]
24 // Create some test sets for chat
24 // Create some test sets for chat
25 QBarSet *set0 = new QBarSet("Bub");
25 QBarSet *set0 = new QBarSet("Bub");
26 QBarSet *set1 = new QBarSet("Bob");
26 QBarSet *set1 = new QBarSet("Bob");
27 QBarSet *set2 = new QBarSet("Guybrush");
27 QBarSet *set2 = new QBarSet("Guybrush");
28 QBarSet *set3 = new QBarSet("Larry");
28 QBarSet *set3 = new QBarSet("Larry");
29 QBarSet *set4 = new QBarSet("Zak");
29 QBarSet *set4 = new QBarSet("Zak");
30
30
31 *set0 << 1 << 2 << 3 << 4 << 5 << 6;
31 *set0 << 1 << 2 << 3 << 4 << 5 << 6;
32 *set1 << 5 << 0 << 0 << 4 << 0 << 7;
32 *set1 << 5 << 0 << 0 << 4 << 0 << 7;
33 *set2 << 3 << 5 << 8 << 13 << 8 << 5;
33 *set2 << 3 << 5 << 8 << 13 << 8 << 5;
34 *set3 << 5 << 6 << 7 << 3 << 4 << 5;
34 *set3 << 5 << 6 << 7 << 3 << 4 << 5;
35 *set4 << 9 << 7 << 5 << 3 << 1 << 2;
35 *set4 << 9 << 7 << 5 << 3 << 1 << 2;
36 //! [2]
36 //! [2]
37
37
38 //! [3]
38 //! [3]
39 // Create series and add sets to it
39 // Create series and add sets to it
40 QPercentBarSeries* series = new QPercentBarSeries(categories);
40 QPercentBarSeries* series = new QPercentBarSeries(categories);
41
41
42 series->addBarSet(set0);
42 series->addBarSet(set0);
43 series->addBarSet(set1);
43 series->addBarSet(set1);
44 series->addBarSet(set2);
44 series->addBarSet(set2);
45 series->addBarSet(set3);
45 series->addBarSet(set3);
46 series->addBarSet(set4);
46 series->addBarSet(set4);
47 //! [3]
47 //! [3]
48
48
49 //! [4]
49 //! [4]
50 // Enable tooltip
50 // Enable tooltip
51 series->setToolTipEnabled();
51 series->setToolTipEnabled();
52
52
53 // Connect clicked signal of set to toggle floating values of set.
53 // Connect clicked signal of set to toggle floating values of set.
54 // Note that we leave QBarset "Zak" unconnected here, so clicking on it doesn't toggle values.
54 // Note that we leave QBarset "Zak" unconnected here, so clicking on it doesn't toggle values.
55 QObject::connect(set0,SIGNAL(clicked(QString)),set0,SIGNAL(toggleFloatingValues()));
55 QObject::connect(set0,SIGNAL(clicked(QString)),set0,SIGNAL(toggleFloatingValues()));
56 QObject::connect(set1,SIGNAL(clicked(QString)),set1,SIGNAL(toggleFloatingValues()));
56 QObject::connect(set1,SIGNAL(clicked(QString)),set1,SIGNAL(toggleFloatingValues()));
57 QObject::connect(set2,SIGNAL(clicked(QString)),set2,SIGNAL(toggleFloatingValues()));
57 QObject::connect(set2,SIGNAL(clicked(QString)),set2,SIGNAL(toggleFloatingValues()));
58 QObject::connect(set3,SIGNAL(clicked(QString)),set3,SIGNAL(toggleFloatingValues()));
58 QObject::connect(set3,SIGNAL(clicked(QString)),set3,SIGNAL(toggleFloatingValues()));
59 QObject::connect(set4,SIGNAL(clicked(QString)),set4,SIGNAL(toggleFloatingValues()));
59 QObject::connect(set4,SIGNAL(clicked(QString)),set4,SIGNAL(toggleFloatingValues()));
60 //! [4]
60 //! [4]
61
61
62 //! [5]
62 //! [5]
63 // Create view for chart and add series to it. Apply theme.
63 // Create view for chart and add series to it. Apply theme.
64
64
65 QChartView* chartView = new QChartView(&window);
65 QChartView* chartView = new QChartView(&window);
66 chartView->addSeries(series);
66 chartView->addSeries(series);
67 chartView->setChartTitle("simple percent barchart");
67 chartView->setChartTitle("simple percent barchart");
68 chartView->setChartTheme(QChart::ChartThemeIcy);
68 chartView->setChartTheme(QChart::ChartThemeIcy);
69 //! [5]
69 //! [5]
70
70
71 //! [6]
71 //! [6]
72 chartView->axisX()->setAxisVisible(false);
72 //chartView->axisX()->setAxisVisible(false);
73 chartView->axisX()->setGridLineVisible(false);
73 chartView->axisX()->setGridLineVisible(false);
74 chartView->axisX()->setLabelsVisible(false);
74 chartView->axisX()->setLabelsVisible(false);
75 //! [6]
75 //! [6]
76
76
77 window.setCentralWidget(chartView);
77 window.setCentralWidget(chartView);
78 window.resize(400, 300);
78 window.resize(400, 300);
79 window.show();
79 window.show();
80
80
81 return a.exec();
81 return a.exec();
82 }
82 }
83
83
@@ -1,122 +1,124
1 #ifndef AXISITEM_H_
1 #ifndef AXISITEM_H_
2 #define AXISITEM_H_
2 #define AXISITEM_H_
3
3
4 #include "domain_p.h"
4 #include "domain_p.h"
5 #include "chart_p.h"
5 #include "chart_p.h"
6 #include <QGraphicsItem>
6 #include <QGraphicsItem>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 class QChartAxis;
10 class QChartAxis;
11 class ChartPresenter;
11 class ChartPresenter;
12
12
13 class Axis : public Chart
13 class Axis : public Chart
14 {
14 {
15 Q_OBJECT
15 Q_OBJECT
16 public:
16 public:
17 enum AxisType{X_AXIS,Y_AXIS};
17 enum AxisType{X_AXIS,Y_AXIS};
18
18
19 Axis(QChartAxis* axis,ChartPresenter* presenter,AxisType type = X_AXIS);
19 Axis(QChartAxis* axis,ChartPresenter* presenter,AxisType type = X_AXIS);
20 ~Axis();
20 ~Axis();
21
21
22 AxisType axisType() const {return m_type;};
22 AxisType axisType() const {return m_type;};
23
23
24 void setAxisOpacity(qreal opacity);
24 void setAxisOpacity(qreal opacity);
25 qreal axisOpacity() const;
25 qreal axisOpacity() const;
26
26
27 void setGridOpacity(qreal opacity);
27 void setGridOpacity(qreal opacity);
28 qreal gridOpacity() const;
28 qreal gridOpacity() const;
29
29
30 void setLabelsOpacity(qreal opacity);
30 void setLabelsOpacity(qreal opacity);
31 qreal labelsOpacity() const;
31 qreal labelsOpacity() const;
32
32
33 void setShadesOpacity(qreal opacity);
33 void setShadesOpacity(qreal opacity);
34 qreal shadesOpacity() const;
34 qreal shadesOpacity() const;
35
35
36 void setLabelsAngle(int angle);
36 void setLabelsAngle(int angle);
37 int labelsAngle()const { return m_labelsAngle; }
37 int labelsAngle()const { return m_labelsAngle; }
38
38
39 void setShadesBrush(const QBrush& brush);
39 void setShadesBrush(const QBrush& brush);
40 void setShadesPen(const QPen& pen);
40 void setShadesPen(const QPen& pen);
41
41
42 void setAxisPen(const QPen& pen);
42 void setAxisPen(const QPen& pen);
43 void setGridPen(const QPen& pen);
43 void setGridPen(const QPen& pen);
44
44
45 void setLabelsPen(const QPen& pen);
45 void setLabelsPen(const QPen& pen);
46 void setLabelsBrush(const QBrush& brush);
46 void setLabelsBrush(const QBrush& brush);
47 void setLabelsFont(const QFont& font);
47 void setLabelsFont(const QFont& font);
48
48
49 inline QRectF geometry() const { return m_rect; }
49 inline QRectF geometry() const { return m_rect; }
50 inline QVector<qreal> layout() { return m_layoutVector;};
50 inline QVector<qreal> layout() { return m_layoutVector;};
51
51
52 public slots:
52 public slots:
53 void handleAxisUpdated();
53 void handleAxisUpdated();
54 void handleAxisCategoriesUpdated();
54 void handleAxisCategoriesUpdated();
55 void handleRangeChanged(qreal min , qreal max,int tickCount);
55 void handleRangeChanged(qreal min , qreal max,int tickCount);
56 void handleGeometryChanged(const QRectF& size);
56 void handleGeometryChanged(const QRectF& size);
57
57
58
58
59 private:
59 private:
60 inline bool isEmpty();
60 inline bool isEmpty();
61 void createItems(int count);
61 void createItems(int count);
62 void deleteItems(int count);
62 void deleteItems(int count);
63
63
64 QVector<qreal> calculateLayout() const;
64 QVector<qreal> calculateLayout() const;
65 void updateLayout(QVector<qreal>& layout);
65 void updateLayout(QVector<qreal>& layout);
66 void setLayout(QVector<qreal>& layout);
66 void setLayout(QVector<qreal>& layout);
67
67
68 QStringList createLabels(int ticks, qreal min, qreal max) const;
68 QStringList createLabels(int ticks, qreal min, qreal max) const;
69 void axisSelected();
69 void axisSelected();
70
70
71 private:
71 private:
72 QChartAxis* m_chartAxis;
72 QChartAxis* m_chartAxis;
73 AxisType m_type;
73 AxisType m_type;
74 QRectF m_rect;
74 QRectF m_rect;
75 int m_labelsAngle;
75 int m_labelsAngle;
76 QGraphicsItemGroup m_grid;
76 QGraphicsItemGroup m_grid;
77 QGraphicsItemGroup m_shades;
77 QGraphicsItemGroup m_shades;
78 QGraphicsItemGroup m_labels;
78 QGraphicsItemGroup m_labels;
79 QGraphicsItemGroup m_axis;
79 QGraphicsItemGroup m_axis;
80 QVector<qreal> m_layoutVector;
80 QVector<qreal> m_layoutVector;
81 qreal m_min;
81 qreal m_min;
82 qreal m_max;
82 qreal m_max;
83 int m_ticksCount;
83 int m_ticksCount;
84 qreal m_zoomFactor;
84 qreal m_zoomFactor;
85
85
86 friend class AxisAnimation;
86 friend class AxisAnimation;
87 friend class AxisItem;
87 friend class AxisItem;
88
88
89 };
89 };
90
90
91 class AxisItem: public QGraphicsLineItem
91 class AxisItem: public QGraphicsLineItem
92 {
92 {
93 public:
93 public:
94
94
95 AxisItem(Axis* axis,QGraphicsItem* parent=0):QGraphicsLineItem(parent),m_axis(axis){};
95 AxisItem(Axis* axis,QGraphicsItem* parent=0):QGraphicsLineItem(parent),m_axis(axis){};
96
96
97 protected:
97 protected:
98 void mousePressEvent(QGraphicsSceneMouseEvent *event)
98 void mousePressEvent(QGraphicsSceneMouseEvent *event)
99 {
99 {
100 Q_UNUSED(event)
100 Q_UNUSED(event)
101 m_axis->axisSelected();
101 m_axis->axisSelected();
102 }
102 }
103
103
104 QRectF boundingRect() const
104 QRectF boundingRect() const
105 {
105 {
106 return QGraphicsLineItem::boundingRect().adjusted(0,0,m_axis->axisType()!=Axis::X_AXIS?10:0,m_axis->axisType()!=Axis::Y_AXIS?10:0);
106 return shape().boundingRect();
107 }
107 }
108
108
109 QPainterPath shape() const
109 QPainterPath shape() const
110 {
110 {
111 QPainterPath path;
111 QPainterPath path = QGraphicsLineItem::shape();
112 path.addRect(boundingRect());
112 QRectF rect = path.boundingRect();
113 path.addRect(rect.adjusted(0,0,m_axis->axisType()!=Axis::X_AXIS?8:0,m_axis->axisType()!=Axis::Y_AXIS?8:0));
113 return path;
114 return path;
114 }
115 }
116
115 private:
117 private:
116 Axis* m_axis;
118 Axis* m_axis;
117
119
118 };
120 };
119
121
120 QTCOMMERCIALCHART_END_NAMESPACE
122 QTCOMMERCIALCHART_END_NAMESPACE
121
123
122 #endif /* AXISITEM_H_ */
124 #endif /* AXISITEM_H_ */
@@ -1,99 +1,37
1 #include "bar_p.h"
1 #include "bar_p.h"
2 #include <QDebug>
2 #include <QDebug>
3 #include <QPainter>
3 #include <QPainter>
4 #include <QGraphicsSceneEvent>
4 #include <QGraphicsSceneEvent>
5
5
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
7
8 Bar::Bar(QString category, QGraphicsItem *parent)
8 Bar::Bar(QString category, QGraphicsItem *parent)
9 : QGraphicsObject(parent),
9 : QGraphicsRectItem(parent),
10 mXpos(0),
11 mYpos(0),
12 mWidth(0),
13 mHeight(0),
14 mBrush(QBrush()),
15 mPen(QPen()),
16 mCategory(category)
10 mCategory(category)
17 {
11 {
18 setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
12 setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
19 setAcceptHoverEvents(true);
13 setAcceptHoverEvents(true);
20 }
14 }
21
15
22 void Bar::setSize(const QSizeF& size)
23 {
24 mWidth = size.width();
25 mHeight = size.height();
26 }
27
28
29 void Bar::resize( qreal w, qreal h )
30 {
31 mWidth = w;
32 mHeight = h;
33 }
34
35 void Bar::setPos(qreal x, qreal y)
36 {
37 mXpos = x;
38 mYpos = y;
39 }
40
41 void Bar::setPen(QPen pen)
42 {
43 mPen = pen;
44 }
45
46 void Bar::setBrush(QBrush brush)
47 {
48 mBrush = brush;
49 }
50
51 void Bar::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
52 {
53 Q_UNUSED(option)
54 Q_UNUSED(widget)
55
56 if (0 == mHeight) {
57 return;
58 }
59 painter->setPen(mPen);
60 painter->setBrush(mBrush);
61
62 // This compensates for rounding errors. drawRect takes ints and cumulative error of pos + size may be over 1.
63 int x0 = mXpos;
64 int x1 = (mXpos + mWidth);
65 int w = x1-x0;
66 int y0 = mYpos;
67 int y1 = (mYpos + mHeight);
68 int h = y1-y0;
69 painter->drawRect(x0, y0 ,w ,h);
70 }
71
72 QRectF Bar::boundingRect() const
73 {
74 QRectF r(mXpos, mYpos, mWidth, mHeight);
75 return r;
76 }
77
78 void Bar::mousePressEvent(QGraphicsSceneMouseEvent* event)
16 void Bar::mousePressEvent(QGraphicsSceneMouseEvent* event)
79 {
17 {
80 if (event->button() == Qt::LeftButton) {
18 if (event->button() == Qt::LeftButton) {
81 emit clicked(mCategory);
19 emit clicked(mCategory);
82 } else if (event->button() == Qt::RightButton) {
20 } else if (event->button() == Qt::RightButton) {
83 emit rightClicked(mCategory);
21 emit rightClicked(mCategory);
84 }
22 }
85 }
23 }
86
24
87 void Bar::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
25 void Bar::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
88 {
26 {
89 emit hoverEntered(event->lastScreenPos());
27 emit hoverEntered(event->lastScreenPos());
90 }
28 }
91
29
92 void Bar::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
30 void Bar::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
93 {
31 {
94 emit hoverLeaved();
32 emit hoverLeaved();
95 }
33 }
96
34
97 #include "moc_bar_p.cpp"
35 #include "moc_bar_p.cpp"
98
36
99 QTCOMMERCIALCHART_END_NAMESPACE
37 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,56 +1,33
1 #ifndef BAR_H
1 #ifndef BAR_H
2 #define BAR_H
2 #define BAR_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include <QGraphicsObject>
5 #include <QGraphicsRectItem>
6 #include <QPen>
7 #include <QBrush>
8
6
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10
8
11 // Single visual bar item of chart
9 // Single visual bar item of chart
12 class Bar : public QGraphicsObject
10 class Bar : public QObject, public QGraphicsRectItem
13 {
11 {
14 Q_OBJECT
12 Q_OBJECT
15 public:
13 public:
16 Bar(QString category, QGraphicsItem *parent=0);
14 Bar(QString category, QGraphicsItem *parent=0);
17
15
18 public: // from ChartItem
19 void setSize(const QSizeF &size);
20
21 // Layout Stuff
22 void resize(qreal w, qreal h);
23 void setPos(qreal x, qreal y);
24 void setPen(QPen pen);
25 void setBrush(QBrush brush);
26
27 public:
16 public:
28 // From QGraphicsItem
29 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
30 QRectF boundingRect() const;
31 void mousePressEvent(QGraphicsSceneMouseEvent *event);
17 void mousePressEvent(QGraphicsSceneMouseEvent *event);
32 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
18 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
33 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
19 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
34
20
35 Q_SIGNALS:
21 Q_SIGNALS:
36 void clicked(QString category);
22 void clicked(QString category);
37 void rightClicked(QString category);
23 void rightClicked(QString category);
38 void hoverEntered(QPoint pos);
24 void hoverEntered(QPoint pos);
39 void hoverLeaved();
25 void hoverLeaved();
40
26
41 private:
27 private:
42
43 qreal mXpos;
44 qreal mYpos;
45 qreal mWidth;
46 qreal mHeight;
47
48 QBrush mBrush;
49 QPen mPen;
50
51 QString mCategory;
28 QString mCategory;
52 };
29 };
53
30
54 QTCOMMERCIALCHART_END_NAMESPACE
31 QTCOMMERCIALCHART_END_NAMESPACE
55
32
56 #endif // BAR_H
33 #endif // BAR_H
@@ -1,280 +1,266
1 #include "barchartitem_p.h"
1 #include "barchartitem_p.h"
2 #include "bar_p.h"
2 #include "bar_p.h"
3 #include "barvalue_p.h"
3 #include "barvalue_p.h"
4 #include "qbarset.h"
4 #include "qbarset.h"
5 #include "qbarseries.h"
5 #include "qbarseries.h"
6 #include "qchart.h"
6 #include "qchart.h"
7 #include "qchartaxis.h"
7 #include "qchartaxis.h"
8 #include "qchartaxiscategories.h"
8 #include "qchartaxiscategories.h"
9 #include "chartpresenter_p.h"
9 #include "chartpresenter_p.h"
10 #include "chartanimator_p.h"
10 #include "chartanimator_p.h"
11 #include "chartdataset_p.h"
11 #include <QDebug>
12 #include <QDebug>
12 #include <QToolTip>
13 #include <QToolTip>
13
14
14 QTCOMMERCIALCHART_BEGIN_NAMESPACE
15 QTCOMMERCIALCHART_BEGIN_NAMESPACE
15
16
16 BarChartItem::BarChartItem(QBarSeries *series, ChartPresenter *presenter) :
17 BarChartItem::BarChartItem(QBarSeries *series, ChartPresenter *presenter) :
17 ChartItem(presenter),
18 ChartItem(presenter),
18 mHeight(0),
19 mWidth(0),
20 mLayoutSet(false),
19 mLayoutSet(false),
21 mSeries(series)
20 mSeries(series)
22 {
21 {
23 connect(series,SIGNAL(showToolTip(QPoint,QString)),this,SLOT(showToolTip(QPoint,QString)));
22 connect(series,SIGNAL(showToolTip(QPoint,QString)),this,SLOT(showToolTip(QPoint,QString)));
24 connect(series, SIGNAL(updatedBars()), this, SLOT(layoutChanged()));
23 connect(series, SIGNAL(updatedBars()), this, SLOT(layoutChanged()));
25 //TODO: connect(series,SIGNAL("position or size has changed"), this, SLOT(handleLayoutChanged()));
24 //TODO: connect(series,SIGNAL("position or size has changed"), this, SLOT(handleLayoutChanged()));
26 connect(series, SIGNAL(restructuredBar(int)), this, SLOT(handleModelChanged(int)));
25 connect(series, SIGNAL(restructuredBar(int)), this, SLOT(handleModelChanged(int)));
27 setZValue(ChartPresenter::BarSeriesZValue);
26 setZValue(ChartPresenter::BarSeriesZValue);
28 initAxisLabels();
27 initAxisLabels();
29 dataChanged();
28 dataChanged();
30 }
29 }
31
30
32 BarChartItem::~BarChartItem()
31 BarChartItem::~BarChartItem()
33 {
32 {
34 disconnect(this,SLOT(showToolTip(QPoint,QString)));
33 disconnect(this,SLOT(showToolTip(QPoint,QString)));
35 }
34 }
36
35
37 void BarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
36 void BarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
38 {
37 {
39 if (!mLayoutSet) {
38 if (!mLayoutSet) {
40 qDebug() << "BarChartItem::paint called without layout set. Aborting.";
39 qDebug() << "BarChartItem::paint called without layout set. Aborting.";
41 return;
40 return;
42 }
41 }
43 foreach(QGraphicsItem* i, childItems()) {
42 foreach(QGraphicsItem* i, childItems()) {
44 i->paint(painter,option,widget);
43 i->paint(painter,option,widget);
45 }
44 }
46 }
45 }
47
46
48 QRectF BarChartItem::boundingRect() const
47 QRectF BarChartItem::boundingRect() const
49 {
48 {
50 return QRectF(0, 0, mWidth, mHeight);
49 return m_rect;
51 }
50 }
52
51
53 void BarChartItem::dataChanged()
52 void BarChartItem::dataChanged()
54 {
53 {
55 // TODO: performance optimizations. Do we really need to delete and create items every time data is changed or can we reuse them?
54 // TODO: performance optimizations. Do we really need to delete and create items every time data is changed or can we reuse them?
56 // Delete old bars
55 // Delete old bars
57 foreach (QGraphicsItem* item, childItems()) {
56 foreach (QGraphicsItem* item, childItems()) {
58 delete item;
57 delete item;
59 }
58 }
60
59
61 mBars.clear();
60 mBars.clear();
62 mFloatingValues.clear();
61 mFloatingValues.clear();
63
62
64 // Create new graphic items for bars
63 // Create new graphic items for bars
65 for (int c=0; c<mSeries->categoryCount(); c++) {
64 for (int c=0; c<mSeries->categoryCount(); c++) {
66 QString category = mSeries->categoryName(c);
65 QString category = mSeries->categoryName(c);
67 for (int s=0; s<mSeries->barsetCount(); s++) {
66 for (int s=0; s<mSeries->barsetCount(); s++) {
68 QBarSet *set = mSeries->barsetAt(s);
67 QBarSet *set = mSeries->barsetAt(s);
69 Bar *bar = new Bar(category,this);
68 Bar *bar = new Bar(category,this);
70 childItems().append(bar);
69 childItems().append(bar);
71 mBars.append(bar);
70 mBars.append(bar);
72 connect(bar,SIGNAL(clicked(QString)),set,SIGNAL(clicked(QString)));
71 connect(bar,SIGNAL(clicked(QString)),set,SIGNAL(clicked(QString)));
73 connect(bar,SIGNAL(rightClicked(QString)),set,SIGNAL(rightClicked(QString)));
72 connect(bar,SIGNAL(rightClicked(QString)),set,SIGNAL(rightClicked(QString)));
74 connect(bar,SIGNAL(hoverEntered(QPoint)),set,SLOT(barHoverEnterEvent(QPoint)));
73 connect(bar,SIGNAL(hoverEntered(QPoint)),set,SLOT(barHoverEnterEvent(QPoint)));
75 connect(bar,SIGNAL(hoverLeaved()),set,SLOT(barHoverLeaveEvent()));
74 connect(bar,SIGNAL(hoverLeaved()),set,SLOT(barHoverLeaveEvent()));
76 }
75 }
77 }
76 }
78
77
79 // Create floating values
78 // Create floating values
80 for (int category=0; category<mSeries->categoryCount(); category++) {
79 for (int category=0; category<mSeries->categoryCount(); category++) {
81 for (int s=0; s<mSeries->barsetCount(); s++) {
80 for (int s=0; s<mSeries->barsetCount(); s++) {
82 QBarSet *set = mSeries->barsetAt(s);
81 QBarSet *set = mSeries->barsetAt(s);
83 BarValue *value = new BarValue(*set, this);
82 BarValue *value = new BarValue(*set, this);
84 childItems().append(value);
83 childItems().append(value);
85 mFloatingValues.append(value);
84 mFloatingValues.append(value);
86 connect(set,SIGNAL(toggleFloatingValues()),value,SLOT(toggleVisible()));
85 connect(set,SIGNAL(toggleFloatingValues()),value,SLOT(toggleVisible()));
87 }
86 }
88 }
87 }
89 }
88 }
90
89
91 void BarChartItem::layoutChanged()
90 void BarChartItem::layoutChanged()
92 {
91 {
93 // Scale bars to new layout
92 // Scale bars to new layout
94 // Layout for bars:
93 // Layout for bars:
95 if (mSeries->barsetCount() <= 0) {
94 if (mSeries->barsetCount() <= 0) {
96 qDebug() << "No sets in model!";
95 qDebug() << "No sets in model!";
97 return;
96 return;
98 }
97 }
99
98
100 if (childItems().count() == 0) {
99 if (childItems().count() == 0) {
101 qDebug() << "WARNING: BarChartitem::layoutChanged called before graphics items are created!";
100 qDebug() << "WARNING: BarChartitem::layoutChanged called before graphics items are created!";
102 return;
101 return;
103 }
102 }
104
103
105 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
106 int categoryCount = mSeries->categoryCount();
107 int setCount = mSeries->barsetCount();
108
104
109 qreal tW = mWidth;
105 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
110 qreal tH = mHeight;
106 qreal categoryCount = mSeries->categoryCount();
111 qreal tM = mSeries->max();
107 qreal setCount = mSeries->barsetCount();
108 qreal max = mSeries->max();
112
109
113 // Domain:
110 // Domain:
114 if (mDomainMaxY > tM) {
111 if (mDomainMaxY > max) {
115 tM = mDomainMaxY;
112 max = mDomainMaxY;
116 }
113 }
117
114
118 qreal scale = (tH/tM);
115 qreal width = geometry().width();
119 qreal tC = categoryCount + 1;
116 qreal height = geometry().height();
120 qreal categoryWidth = tW/tC;
117 qreal scale = (height/max);
121 mBarWidth = categoryWidth / (setCount+1);
118 qreal categoryWidth = width/categoryCount;
119 qreal barWidth = categoryWidth / (setCount+1);
122
120
123 int itemIndex(0);
121 int itemIndex(0);
124 for (int category=0; category < categoryCount; category++) {
122 for (int category=0; category < categoryCount; category++) {
125 qreal xPos = categoryWidth * category + categoryWidth /2 + mBarWidth/2;
123 qreal xPos = categoryWidth * category + barWidth/2;
126 qreal yPos = mHeight;
124 qreal yPos = height;
127 for (int set = 0; set < setCount; set++) {
125 for (int set = 0; set < setCount; set++) {
128 qreal barHeight = mSeries->valueAt(set,category) * scale;
126 qreal barHeight = mSeries->valueAt(set,category) * scale;
129 Bar* bar = mBars.at(itemIndex);
127 Bar* bar = mBars.at(itemIndex);
130
128
131 // TODO: width settable per bar?
129 // TODO: width settable per bar?
132 bar->resize(mBarWidth, barHeight);
130 bar->setRect(xPos, yPos-barHeight,barWidth, barHeight);
133 bar->setPen(mSeries->barsetAt(set)->pen());
131 bar->setPen(mSeries->barsetAt(set)->pen());
134 bar->setBrush(mSeries->barsetAt(set)->brush());
132 bar->setBrush(mSeries->barsetAt(set)->brush());
135 bar->setPos(xPos, yPos-barHeight);
133
136 itemIndex++;
134 itemIndex++;
137 xPos += mBarWidth;
135 xPos += barWidth;
138 }
136 }
139 }
137 }
140
138
141 // Position floating values
139 // Position floating values
142 itemIndex = 0;
140 itemIndex = 0;
143 for (int category=0; category < mSeries->categoryCount(); category++) {
141 for (int category=0; category < mSeries->categoryCount(); category++) {
144 qreal xPos = categoryWidth * category + categoryWidth/2 + mBarWidth;
142 qreal xPos = categoryWidth * category + categoryWidth/2 + barWidth;
145 qreal yPos = mHeight;
143 qreal yPos = height;
146 for (int set=0; set < mSeries->barsetCount(); set++) {
144 for (int set=0; set < mSeries->barsetCount(); set++) {
147 qreal barHeight = mSeries->valueAt(set,category) * scale;
145 qreal barHeight = mSeries->valueAt(set,category) * scale;
148 BarValue* value = mFloatingValues.at(itemIndex);
146 BarValue* value = mFloatingValues.at(itemIndex);
149
147
150 QBarSet* barSet = mSeries->barsetAt(set);
148 QBarSet* barSet = mSeries->barsetAt(set);
151 value->resize(100,50); // TODO: proper layout for this.
149 value->resize(100,50); // TODO: proper layout for this.
152 value->setPos(xPos, yPos-barHeight/2);
150 value->setPos(xPos, yPos-barHeight/2);
153 value->setPen(barSet->floatingValuePen());
151 value->setPen(barSet->floatingValuePen());
154
152
155 if (mSeries->valueAt(set,category) != 0) {
153 if (mSeries->valueAt(set,category) != 0) {
156 value->setValueString(QString::number(mSeries->valueAt(set,category)));
154 value->setValueString(QString::number(mSeries->valueAt(set,category)));
157 } else {
155 } else {
158 value->setValueString(QString(""));
156 value->setValueString(QString(""));
159 }
157 }
160
158
161 itemIndex++;
159 itemIndex++;
162 xPos += mBarWidth;
160 xPos += barWidth;
163 }
161 }
164 }
162 }
165 update();
163 update();
166 }
164 }
167
165
168 BarLayout BarChartItem::calculateLayout()
166 BarLayout BarChartItem::calculateLayout()
169 {
167 {
170 BarLayout layout;
168 BarLayout layout;
171 foreach(Bar* bar, mBars) {
169 foreach(Bar* bar, mBars) {
172 layout.insert(bar,bar->boundingRect().size());
170 layout.insert(bar,bar->boundingRect());
173 }
171 }
174
172
175 return layout;
173 return layout;
176 }
174 }
177
175
178 void BarChartItem::applyLayout(const BarLayout &layout)
176 void BarChartItem::applyLayout(const BarLayout &layout)
179 {
177 {
180 if (m_animator)
178 if (animator())
181 m_animator->updateLayout(this, layout);
179 animator()->updateLayout(this, layout);
182 else
180 else
183 setLayout(layout);
181 setLayout(layout);
184 }
182 }
185
183
186 void BarChartItem::setLayout(const BarLayout &layout)
184 void BarChartItem::setLayout(const BarLayout &layout)
187 {
185 {
188 foreach (Bar *bar, layout.keys()) {
186 foreach (Bar *bar, layout.keys()) {
189 bar->setSize(layout.value(bar));
187 bar->setRect(layout.value(bar));
190 }
188 }
191 update();
189 update();
192 }
190 }
193
191
194 void BarChartItem::initAxisLabels()
192 void BarChartItem::initAxisLabels()
195 {
193 {
196 int count = mSeries->categoryCount();
194 int count = mSeries->categoryCount();
197 if (0 == count) {
195 if (0 == count) {
198 return;
196 return;
199 }
197 }
200
198
201 mChart->axisX()->setTicksCount(count+2);
199 Domain* domain = presenter()->dataSet()->domain(mSeries);
202
200
203 qreal min = 0;
201 qreal min = 0;
204 qreal max = count+1;
202 qreal max = count+1;
205
203
206 mChart->axisX()->setMin(min);
204 domain->setRangeX(min,max,count+1);
207 mChart->axisX()->setMax(max);
208
209 QChartAxisCategories* categories = mChart->axisX()->categories();
210 categories->clear();
211 for (int i=0; i<count; i++) {
212 categories->insert(i+1,mSeries->categoryName(i));
213 }
214
215
216
217 mChart->axisX()->setLabelsVisible(true);
218 }
205 }
219
206
220 //handlers
207 //handlers
221
208
222 void BarChartItem::handleModelChanged(int index)
209 void BarChartItem::handleModelChanged(int index)
223 {
210 {
224 Q_UNUSED(index)
211 Q_UNUSED(index)
225 dataChanged();
212 dataChanged();
226 }
213 }
227
214
228 void BarChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
215 void BarChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
229 {
216 {
230 mDomainMinX = minX;
217 mDomainMinX = minX;
231 mDomainMaxX = maxX;
218 mDomainMaxX = maxX;
232 mDomainMinY = minY;
219 mDomainMinY = minY;
233 mDomainMaxY = maxY;
220 mDomainMaxY = maxY;
234 layoutChanged();
221 layoutChanged();
235
222
236 /*
223 /*
237 int count = mSeries->categoryCount();
224 int count = mSeries->categoryCount();
238 if (0 == count) {
225 if (0 == count) {
239 return;
226 return;
240 }
227 }
241
228
242 // Position labels to domain
229 // Position labels to domain
243 qreal min = domain.minX();
230 qreal min = domain.minX();
244 qreal max = domain.maxX();
231 qreal max = domain.maxX();
245 qreal step = (max-min)/count;
232 qreal step = (max-min)/count;
246 QChartAxisCategories& categories = mChart->axisX()->categories();
233 QChartAxisCategories& categories = mChart->axisX()->categories();
247 categories.clear();
234 categories.clear();
248 for (int i=0; i<count; i++) {
235 for (int i=0; i<count; i++) {
249 categories.insert(min,mSeries->categoryName(i));
236 categories.insert(min,mSeries->categoryName(i));
250 min += step;
237 min += step;
251 }
238 }
252 */
239 */
253 }
240 }
254
241
255 void BarChartItem::handleGeometryChanged(const QRectF& rect)
242 void BarChartItem::handleGeometryChanged(const QRectF& rect)
256 {
243 {
257 mWidth = rect.width();
244 m_rect=rect;
258 mHeight = rect.height();
259 layoutChanged();
245 layoutChanged();
260 mLayoutSet = true;
246 mLayoutSet = true;
261 setPos(rect.topLeft());
247 setPos(rect.topLeft());
262 }
248 }
263
249
264 void BarChartItem::handleLayoutChanged()
250 void BarChartItem::handleLayoutChanged()
265 {
251 {
266 BarLayout layout = calculateLayout();
252 BarLayout layout = calculateLayout();
267 applyLayout(layout);
253 applyLayout(layout);
268 update();
254 update();
269 }
255 }
270
256
271
257
272 void BarChartItem::showToolTip(QPoint pos, QString tip)
258 void BarChartItem::showToolTip(QPoint pos, QString tip)
273 {
259 {
274 // TODO: cool tooltip instead of default
260 // TODO: cool tooltip instead of default
275 QToolTip::showText(pos,tip);
261 QToolTip::showText(pos,tip);
276 }
262 }
277
263
278 #include "moc_barchartitem_p.cpp"
264 #include "moc_barchartitem_p.cpp"
279
265
280 QTCOMMERCIALCHART_END_NAMESPACE
266 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,78 +1,77
1 #ifndef BARCHARTITEM_H
1 #ifndef BARCHARTITEM_H
2 #define BARCHARTITEM_H
2 #define BARCHARTITEM_H
3
3
4 #include "chartitem_p.h"
4 #include "chartitem_p.h"
5 #include "qbarseries.h"
5 #include "qbarseries.h"
6 #include <QPen>
6 #include <QPen>
7 #include <QBrush>
7 #include <QBrush>
8 #include <QGraphicsItem>
8 #include <QGraphicsItem>
9
9
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11
11
12 class Bar;
12 class Bar;
13 class BarValue;
13 class BarValue;
14 class QChartAxisCategories;
14 class QChartAxisCategories;
15 class QChart;
15 class QChart;
16
16
17 typedef QHash<Bar*, QSizeF> BarLayout;
17 typedef QHash<Bar*, QRectF> BarLayout;
18
18
19 class BarChartItem : public QObject, public ChartItem
19 class BarChartItem : public ChartItem
20 {
20 {
21 Q_OBJECT
21 Q_OBJECT
22 public:
22 public:
23 BarChartItem(QBarSeries *series, ChartPresenter *presenter);
23 BarChartItem(QBarSeries *series, ChartPresenter *presenter);
24 virtual ~BarChartItem();
24 virtual ~BarChartItem();
25
25
26 // Common implemantation of different presenters. Not to be instantiated.
26 // Common implemantation of different presenters. Not to be instantiated.
27 // TODO: combine this with BarPresenter and derive other presenters from it?
27 // TODO: combine this with BarPresenter and derive other presenters from it?
28
28
29 public:
29 public:
30 // From QGraphicsItem
30 // From QGraphicsItem
31 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
31 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
32 QRectF boundingRect() const;
32 QRectF boundingRect() const;
33
33
34 // TODO: Consider the domain for layoutChanged. May be use case, may not be. If it is, then the derived classes need to implement it
34 // TODO: Consider the domain for layoutChanged. May be use case, may not be. If it is, then the derived classes need to implement it
35 virtual void dataChanged(); // data of series has changed -> need to recalculate bar sizes
35 virtual void dataChanged(); // data of series has changed -> need to recalculate bar sizes
36 private slots:
36 private slots:
37 virtual void layoutChanged(); // layout has changed -> need to recalculate bar sizes
37 virtual void layoutChanged(); // layout has changed -> need to recalculate bar sizes
38
38
39 public:
39 public:
40 BarLayout calculateLayout();
40 BarLayout calculateLayout();
41 void applyLayout(const BarLayout &layout);
41 void applyLayout(const BarLayout &layout);
42 void setLayout(const BarLayout &layout);
42 void setLayout(const BarLayout &layout);
43
43
44 QRectF geometry() const { return m_rect;}
45
44 protected:
46 protected:
45 void initAxisLabels();
47 void initAxisLabels();
46
48
47 public slots:
49 public slots:
48 void handleModelChanged(int index);
50 void handleModelChanged(int index);
49 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
51 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
50 void handleGeometryChanged(const QRectF& size);
52 void handleGeometryChanged(const QRectF& size);
51 void handleLayoutChanged();
53 void handleLayoutChanged();
52
54
53 // Internal slots
55 // Internal slots
54 void showToolTip(QPoint pos, QString tip); // shows tooltip (if enabled)
56 void showToolTip(QPoint pos, QString tip); // shows tooltip (if enabled)
55
57
56 protected:
58 protected:
57
59
58 // TODO: consider these.
60 // TODO: consider these.
59 int mHeight; // Layout spesific
60 int mWidth;
61 qreal mBarWidth;
62
63 qreal mDomainMinX;
61 qreal mDomainMinX;
64 qreal mDomainMaxX;
62 qreal mDomainMaxX;
65 qreal mDomainMinY;
63 qreal mDomainMinY;
66 qreal mDomainMaxY;
64 qreal mDomainMaxY;
67
65
66 QRectF m_rect;
68 bool mLayoutSet; // True, if component has been laid out.
67 bool mLayoutSet; // True, if component has been laid out.
69
68
70 // Not owned.
69 // Not owned.
71 QBarSeries* mSeries;
70 QBarSeries* mSeries;
72 QList<Bar*> mBars;
71 QList<Bar*> mBars;
73 QList<BarValue*> mFloatingValues;
72 QList<BarValue*> mFloatingValues;
74 };
73 };
75
74
76 QTCOMMERCIALCHART_END_NAMESPACE
75 QTCOMMERCIALCHART_END_NAMESPACE
77
76
78 #endif // BARCHARTITEM_H
77 #endif // BARCHARTITEM_H
@@ -1,93 +1,94
1 #include "percentbarchartitem_p.h"
1 #include "percentbarchartitem_p.h"
2 #include "bar_p.h"
2 #include "bar_p.h"
3 #include "barvalue_p.h"
3 #include "barvalue_p.h"
4 #include "qbarset.h"
4 #include "qbarset.h"
5 #include <QDebug>
5 #include <QDebug>
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 PercentBarChartItem::PercentBarChartItem(QBarSeries *series, ChartPresenter* presenter) :
9 PercentBarChartItem::PercentBarChartItem(QBarSeries *series, ChartPresenter* presenter) :
10 BarChartItem(series, presenter)
10 BarChartItem(series, presenter)
11 {
11 {
12 }
12 }
13
13
14 void PercentBarChartItem::layoutChanged()
14 void PercentBarChartItem::layoutChanged()
15 {
15 {
16 // Scale bars to new layout
16 // Scale bars to new layout
17 // Layout for bars:
17 // Layout for bars:
18 if (mSeries->barsetCount() <= 0) {
18 if (mSeries->barsetCount() <= 0) {
19 qDebug() << "No sets in model!";
19 qDebug() << "No sets in model!";
20 // Nothing to do.
20 // Nothing to do.
21 return;
21 return;
22 }
22 }
23
23
24 if (childItems().count() == 0) {
24 if (childItems().count() == 0) {
25 qDebug() << "WARNING: PercentBarChartItem::layoutChanged called before graphics items are created!";
25 qDebug() << "WARNING: PercentBarChartItem::layoutChanged called before graphics items are created!";
26 return;
26 return;
27 }
27 }
28
28
29 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
29 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
30 qreal tW = mWidth;
30 qreal width = geometry().width();
31 qreal tC = mSeries->categoryCount() + 1;
31 qreal height = geometry().height();
32 qreal cC = mSeries->categoryCount() * 2 + 1;
32
33 mBarWidth = tW / cC;
33 qreal categoryCount = mSeries->categoryCount();
34 qreal xStep = (tW/tC);
34 qreal barWidth = width / (mSeries->categoryCount() * 2);
35 qreal xPos = ((tW/tC) - mBarWidth / 2);
35 qreal xStep = width/categoryCount;
36 qreal h = mHeight;
36 qreal xPos = xStep/2 - barWidth / 2;
37
37
38 int itemIndex(0);
38 int itemIndex(0);
39 for (int category = 0; category < mSeries->categoryCount(); category++) {
39 for (int category = 0; category < categoryCount ; category++) {
40 qreal colSum = mSeries->categorySum(category);
40 qreal colSum = mSeries->categorySum(category);
41 qreal scale = (h / colSum);
41 qreal scale = (height / colSum);
42 qreal yPos = h;
42 qreal yPos = height;
43 for (int set=0; set < mSeries->barsetCount(); set++) {
43 for (int set=0; set < mSeries->barsetCount(); set++) {
44 qreal barHeight = mSeries->valueAt(set, category) * scale;
44 qreal barHeight = mSeries->valueAt(set, category) * scale;
45 Bar* bar = mBars.at(itemIndex);
45 Bar* bar = mBars.at(itemIndex);
46
46
47 // TODO: width settable per bar?
47 // TODO: width settable per bar?
48 bar->resize(mBarWidth, barHeight);
48
49 bar->setPen(mSeries->barsetAt(set)->pen());
49 bar->setPen(mSeries->barsetAt(set)->pen());
50 bar->setRect(xPos, yPos-barHeight,barWidth, barHeight);
50 bar->setBrush(mSeries->barsetAt(set)->brush());
51 bar->setBrush(mSeries->barsetAt(set)->brush());
51 bar->setPos(xPos, yPos-barHeight);
52
52 itemIndex++;
53 itemIndex++;
53 yPos -= barHeight;
54 yPos -= barHeight;
54 }
55 }
55 xPos += xStep;
56 xPos += xStep;
56 }
57 }
57
58
58 // Position floating values
59 // Position floating values
59 itemIndex = 0;
60 itemIndex = 0;
60 xPos = (tW/tC);
61 xPos = (width/categoryCount);
61 for (int category=0; category < mSeries->categoryCount(); category++) {
62 for (int category=0; category < mSeries->categoryCount(); category++) {
62 qreal yPos = h;
63 qreal yPos = height;
63 qreal colSum = mSeries->categorySum(category);
64 qreal colSum = mSeries->categorySum(category);
64 qreal scale = (h / colSum);
65 qreal scale = (height / colSum);
65 for (int set=0; set < mSeries->barsetCount(); set++) {
66 for (int set=0; set < mSeries->barsetCount(); set++) {
66 qreal barHeight = mSeries->valueAt(set,category) * scale;
67 qreal barHeight = mSeries->valueAt(set,category) * scale;
67 BarValue* value = mFloatingValues.at(itemIndex);
68 BarValue* value = mFloatingValues.at(itemIndex);
68
69
69 QBarSet* barSet = mSeries->barsetAt(set);
70 QBarSet* barSet = mSeries->barsetAt(set);
70 value->resize(100,50); // TODO: proper layout for this.
71 value->resize(100,50); // TODO: proper layout for this.
71 value->setPos(xPos, yPos-barHeight/2);
72 value->setPos(xPos, yPos-barHeight/2);
72 value->setPen(barSet->floatingValuePen());
73 value->setPen(barSet->floatingValuePen());
73
74
74 if (mSeries->valueAt(set,category) != 0) {
75 if (mSeries->valueAt(set,category) != 0) {
75 int p = mSeries->percentageAt(set,category) * 100;
76 int p = mSeries->percentageAt(set,category) * 100;
76 QString vString(QString::number(p));
77 QString vString(QString::number(p));
77 vString.truncate(3);
78 vString.truncate(3);
78 vString.append("%");
79 vString.append("%");
79 value->setValueString(vString);
80 value->setValueString(vString);
80 } else {
81 } else {
81 value->setValueString(QString(""));
82 value->setValueString(QString(""));
82 }
83 }
83
84
84 itemIndex++;
85 itemIndex++;
85 yPos -= barHeight;
86 yPos -= barHeight;
86 }
87 }
87 xPos += xStep;
88 xPos += xStep;
88 }
89 }
89 }
90 }
90
91
91 #include "moc_percentbarchartitem_p.cpp"
92 #include "moc_percentbarchartitem_p.cpp"
92
93
93 QTCOMMERCIALCHART_END_NAMESPACE
94 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,28 +1,28
1 #ifndef PERCENTBARCHARTITEM_H
1 #ifndef PERCENTBARCHARTITEM_H
2 #define PERCENTBARCHARTITEM_H
2 #define PERCENTBARCHARTITEM_H
3
3
4 #include "barchartitem_p.h"
4 #include "barchartitem_p.h"
5 #include <QGraphicsItem>
5 #include <QGraphicsItem>
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 class QBarSeries;
9 class QBarSeries;
10
10
11 class PercentBarChartItem : public BarChartItem
11 class PercentBarChartItem : public BarChartItem
12 {
12 {
13 Q_OBJECT
13 Q_OBJECT
14 public:
14 public:
15 PercentBarChartItem(QBarSeries *series, QChart *parent = 0);
15 PercentBarChartItem(QBarSeries *series, ChartPresenter *presenter);
16
16
17 private:
17 private:
18
18
19 void layoutChanged(); // layout has changed -> need to recalculate bar sizes
19 void layoutChanged(); // layout has changed -> need to recalculate bar sizes
20
20
21 private:
21 private:
22
22
23 // Data
23 // Data
24 };
24 };
25
25
26 QTCOMMERCIALCHART_END_NAMESPACE
26 QTCOMMERCIALCHART_END_NAMESPACE
27
27
28 #endif // PERCENTBARCHARTITEM_H
28 #endif // PERCENTBARCHARTITEM_H
@@ -1,102 +1,101
1 #include "stackedbarchartitem_p.h"
1 #include "stackedbarchartitem_p.h"
2 #include "bar_p.h"
2 #include "bar_p.h"
3 #include "barvalue_p.h"
3 #include "barvalue_p.h"
4 #include "qbarset.h"
4 #include "qbarset.h"
5 #include <QDebug>
5 #include <QDebug>
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 StackedBarChartItem::StackedBarChartItem(QBarSeries *series, ChartPresenter *presenter) :
9 StackedBarChartItem::StackedBarChartItem(QBarSeries *series, ChartPresenter *presenter) :
10 BarChartItem(series,presenter)
10 BarChartItem(series,presenter)
11 {
11 {
12 }
12 }
13
13
14 StackedBarChartItem::~StackedBarChartItem()
14 StackedBarChartItem::~StackedBarChartItem()
15 {
15 {
16 }
16 }
17
17
18
18
19 void StackedBarChartItem::layoutChanged()
19 void StackedBarChartItem::layoutChanged()
20 {
20 {
21 // Scale bars to new layout
21 // Scale bars to new layout
22 // Layout for bars:
22 // Layout for bars:
23 if (mSeries->barsetCount() <= 0) {
23 if (mSeries->barsetCount() <= 0) {
24 qDebug() << "No sets in model!";
24 qDebug() << "No sets in model!";
25 // Nothing to do.
25 // Nothing to do.
26 return;
26 return;
27 }
27 }
28
28
29 if (mSeries->categoryCount() == 0) {
29 if (mSeries->categoryCount() == 0) {
30 qDebug() << "No categories in model!";
30 qDebug() << "No categories in model!";
31 // Nothing to do
31 // Nothing to do
32 return;
32 return;
33 }
33 }
34
34
35 if (childItems().count() == 0) {
35 if (childItems().count() == 0) {
36 qDebug() << "WARNING: StackedBarChartItem::layoutChanged called before graphics items are created!";
36 qDebug() << "WARNING: StackedBarChartItem::layoutChanged called before graphics items are created!";
37 return;
37 return;
38 }
38 }
39
39
40 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
40 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
41
41 qreal maxSum = mSeries->maxCategorySum();
42 qreal maxSum = mSeries->maxCategorySum();
42 // Domain:
43 // Domain:
43 if (mDomainMaxY > maxSum) {
44 if (mDomainMaxY > maxSum) {
44 maxSum = mDomainMaxY;
45 maxSum = mDomainMaxY;
45 }
46 }
46
47
47 qreal h = mHeight;
48 qreal height = geometry().height();
48 qreal scale = (h / maxSum);
49 qreal width = geometry().width();
49 qreal tW = mWidth;
50 qreal scale = (height / mSeries->maxCategorySum());
50 qreal tC = mSeries->categoryCount() + 1;
51 qreal categotyCount = mSeries->categoryCount();
51 qreal cC = mSeries->categoryCount() * 2 + 1;
52 qreal barWidth = width / (categotyCount *2);
52 mBarWidth = tW / cC;
53 qreal xStep = width/categotyCount;
53 qreal xStep = (tW/tC);
54 qreal xPos = xStep/2 - barWidth/2;
54 qreal xPos = ((tW/tC) - mBarWidth / 2);
55
55
56
56 int itemIndex(0);
57 int itemIndex(0);
57 for (int category = 0; category < mSeries->categoryCount(); category++) {
58 for (int category = 0; category < categotyCount; category++) {
58 qreal yPos = h;
59 qreal yPos = height;
59 for (int set=0; set < mSeries->barsetCount(); set++) {
60 for (int set=0; set < mSeries->barsetCount(); set++) {
60 qreal barHeight = mSeries->valueAt(set, category) * scale;
61 qreal barHeight = mSeries->valueAt(set, category) * scale;
61 Bar* bar = mBars.at(itemIndex);
62 Bar* bar = mBars.at(itemIndex);
62
63 bar->resize(mBarWidth, barHeight);
64 bar->setPen(mSeries->barsetAt(set)->pen());
63 bar->setPen(mSeries->barsetAt(set)->pen());
65 bar->setBrush(mSeries->barsetAt(set)->brush());
64 bar->setBrush(mSeries->barsetAt(set)->brush());
66 bar->setPos(xPos, yPos-barHeight);
65 bar->setRect(xPos, yPos-barHeight,barWidth, barHeight);
67 itemIndex++;
66 itemIndex++;
68 yPos -= barHeight;
67 yPos -= barHeight;
69 }
68 }
70 xPos += xStep;
69 xPos += xStep;
71 }
70 }
72
71
73 // Position floating values
72 // Position floating values
74 itemIndex = 0;
73 itemIndex = 0;
75 xPos = (tW/tC);
74 xPos = (width/categotyCount);
76 for (int category=0; category < mSeries->categoryCount(); category++) {
75 for (int category=0; category < mSeries->categoryCount(); category++) {
77 qreal yPos = h;
76 qreal yPos = height;
78 for (int set=0; set < mSeries->barsetCount(); set++) {
77 for (int set=0; set < mSeries->barsetCount(); set++) {
79 qreal barHeight = mSeries->valueAt(set,category) * scale;
78 qreal barHeight = mSeries->valueAt(set,category) * scale;
80 BarValue* value = mFloatingValues.at(itemIndex);
79 BarValue* value = mFloatingValues.at(itemIndex);
81
80
82 QBarSet* barSet = mSeries->barsetAt(set);
81 QBarSet* barSet = mSeries->barsetAt(set);
83 value->resize(100,50); // TODO: proper layout for this.
82 value->resize(100,50); // TODO: proper layout for this.
84 value->setPos(xPos, yPos-barHeight/2);
83 value->setPos(xPos, yPos-barHeight/2);
85 value->setPen(barSet->floatingValuePen());
84 value->setPen(barSet->floatingValuePen());
86
85
87 if (mSeries->valueAt(set,category) != 0) {
86 if (mSeries->valueAt(set,category) != 0) {
88 value->setValueString(QString::number(mSeries->valueAt(set,category)));
87 value->setValueString(QString::number(mSeries->valueAt(set,category)));
89 } else {
88 } else {
90 value->setValueString(QString(""));
89 value->setValueString(QString(""));
91 }
90 }
92
91
93 itemIndex++;
92 itemIndex++;
94 yPos -= barHeight;
93 yPos -= barHeight;
95 }
94 }
96 xPos += xStep;
95 xPos += xStep;
97 }
96 }
98 }
97 }
99
98
100 #include "moc_stackedbarchartitem_p.cpp"
99 #include "moc_stackedbarchartitem_p.cpp"
101
100
102 QTCOMMERCIALCHART_END_NAMESPACE
101 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,28 +1,28
1 #ifndef STACKEDBARCHARTITEM_H
1 #ifndef STACKEDBARCHARTITEM_H
2 #define STACKEDBARCHARTITEM_H
2 #define STACKEDBARCHARTITEM_H
3
3
4 #include "barchartitem_p.h"
4 #include "barchartitem_p.h"
5 #include "qstackedbarseries.h"
5 #include "qstackedbarseries.h"
6 #include <QGraphicsItem>
6 #include <QGraphicsItem>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 class StackedBarChartItem : public BarChartItem
10 class StackedBarChartItem : public BarChartItem
11 {
11 {
12 Q_OBJECT
12 Q_OBJECT
13 public:
13 public:
14 StackedBarChartItem(QBarSeries *series, QChart *parent = 0);
14 StackedBarChartItem(QBarSeries *series, ChartPresenter *presenter);
15 ~StackedBarChartItem();
15 ~StackedBarChartItem();
16
16
17 private:
17 private:
18 // From BarChartItem
18 // From BarChartItem
19 void layoutChanged(); // layout has changed -> need to recalculate bar sizes
19 void layoutChanged(); // layout has changed -> need to recalculate bar sizes
20
20
21 private:
21 private:
22
22
23 // Data
23 // Data
24 };
24 };
25
25
26 QTCOMMERCIALCHART_END_NAMESPACE
26 QTCOMMERCIALCHART_END_NAMESPACE
27
27
28 #endif // STACKEDBARCHARTITEM_H
28 #endif // STACKEDBARCHARTITEM_H
@@ -1,248 +1,259
1 #include "domain_p.h"
1 #include "domain_p.h"
2 #include <cmath>
2 #include <cmath>
3
3
4 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5
5
6 Domain::Domain(QObject* parent):QObject(parent),
6 Domain::Domain(QObject* parent):QObject(parent),
7 m_minX(0),
7 m_minX(0),
8 m_maxX(0),
8 m_maxX(0),
9 m_minY(0),
9 m_minY(0),
10 m_maxY(0),
10 m_maxY(0),
11 m_tickXCount(5),
11 m_tickXCount(5),
12 m_tickYCount(5),
12 m_tickYCount(5),
13 m_selection(QChartAxis::NativeLabelsSelection)
13 m_selection(QChartAxis::NativeLabelsSelection)
14 {
14 {
15 }
15 }
16
16
17 Domain::~Domain()
17 Domain::~Domain()
18 {
18 {
19 }
19 }
20
20
21 void Domain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
21 void Domain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
22 {
22 {
23 setRange(minX, maxX, minY, maxY,m_tickXCount,m_tickYCount);
23 setRange(minX, maxX, minY, maxY,m_tickXCount,m_tickYCount);
24 }
24 }
25
25
26 void Domain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY,int tickXCount,int tickYCount)
26 void Domain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY,int tickXCount,int tickYCount)
27 {
27 {
28 bool domainChanged = false;
28 bool domainChanged = false;
29 bool tickXChanged = false;
29 bool tickXChanged = false;
30 bool tickYChanged = false;
30 bool tickYChanged = false;
31
31
32 if(m_tickXCount!=tickXCount) {
32 if(m_tickXCount!=tickXCount) {
33 m_tickXCount=tickXCount;
33 m_tickXCount=tickXCount;
34 tickXChanged=true;
34 tickXChanged=true;
35 }
35 }
36
36
37 if(m_tickXCount!=tickYCount) {
37 if(m_tickXCount!=tickYCount) {
38 m_tickXCount=tickYCount;
38 m_tickYCount=tickYCount;
39 tickYChanged=true;
39 tickYChanged=true;
40 }
40 }
41
41
42 if(m_minX!=minX || m_maxX!=maxX) {
42 if(m_minX!=minX || m_maxX!=maxX) {
43 niceNumbers(minX, maxX, m_tickXCount);
43 niceNumbers(minX, maxX, m_tickXCount);
44 m_minX=minX;
44 m_minX=minX;
45 m_maxX=maxX;
45 m_maxX=maxX;
46 domainChanged=true;
46 domainChanged=true;
47 tickXChanged=false;
47 tickXChanged=false;
48 emit rangeXChanged(minX,maxX, m_tickXCount);
48 emit rangeXChanged(minX,maxX, m_tickXCount);
49 }
49 }
50
50
51 if(m_minY!=minY || m_maxY!=maxY) {
51 if(m_minY!=minY || m_maxY!=maxY) {
52 niceNumbers(minY, maxY, m_tickYCount);
52 niceNumbers(minY, maxY, m_tickYCount);
53 m_minY=minY;
53 m_minY=minY;
54 m_maxY=maxY;
54 m_maxY=maxY;
55 domainChanged=true;
55 domainChanged=true;
56 tickYChanged=false;
56 tickYChanged=false;
57 emit rangeYChanged(minY,maxY, m_tickYCount);
57 emit rangeYChanged(minY,maxY, m_tickYCount);
58 }
58 }
59
59
60 if(domainChanged) {
60 if(domainChanged) {
61 emit this->domainChanged(m_minX, m_maxX, m_minY, m_maxY);
61 emit this->domainChanged(m_minX, m_maxX, m_minY, m_maxY);
62 }
62 }
63
63
64 if(tickXChanged) {
64 if(tickXChanged) {
65 emit rangeXChanged(minX,maxX, m_tickXCount);
65 emit rangeXChanged(minX,maxX, m_tickXCount);
66 }
66 }
67
67
68 if(tickYChanged) {
68 if(tickYChanged) {
69 emit rangeYChanged(minY,maxY, m_tickYCount);
69 emit rangeYChanged(minY,maxY, m_tickYCount);
70 }
70 }
71 }
71 }
72
72
73 void Domain::setRangeX(qreal min, qreal max)
73 void Domain::setRangeX(qreal min, qreal max)
74 {
74 {
75 setRange(min,max,m_minY, m_maxY);
75 setRange(min,max,m_minY, m_maxY);
76 }
76 }
77
78 void Domain::setRangeX(qreal min, qreal max, int tickCount)
79 {
80 setRange(min,max,m_minY, m_maxY,tickCount,m_tickYCount);
81 }
82
77 void Domain::setRangeY(qreal min, qreal max)
83 void Domain::setRangeY(qreal min, qreal max)
78 {
84 {
79 setRange(m_minX, m_maxX, min, max);
85 setRange(m_minX, m_maxX, min, max);
80 }
86 }
81
87
88 void Domain::setRangeY(qreal min, qreal max,int tickCount)
89 {
90 setRange(m_minX, m_maxX, min, max,m_tickXCount,tickCount);
91 }
92
82 void Domain::setMinX(qreal min)
93 void Domain::setMinX(qreal min)
83 {
94 {
84 setRange(min, m_maxX, m_minY, m_maxY);
95 setRange(min, m_maxX, m_minY, m_maxY);
85 }
96 }
86
97
87 void Domain::setMaxX(qreal max)
98 void Domain::setMaxX(qreal max)
88 {
99 {
89 setRange(m_minX, max, m_minY, m_maxY);
100 setRange(m_minX, max, m_minY, m_maxY);
90 }
101 }
91
102
92 void Domain::setMinY(qreal min)
103 void Domain::setMinY(qreal min)
93 {
104 {
94 setRange(m_minX, m_maxX, min, m_maxY);
105 setRange(m_minX, m_maxX, min, m_maxY);
95 }
106 }
96
107
97 void Domain::setMaxY(qreal max)
108 void Domain::setMaxY(qreal max)
98 {
109 {
99 setRange(m_minX, m_maxX, m_minY, max);
110 setRange(m_minX, m_maxX, m_minY, max);
100 }
111 }
101
112
102 qreal Domain::spanX() const
113 qreal Domain::spanX() const
103 {
114 {
104 Q_ASSERT(m_maxX >= m_minX);
115 Q_ASSERT(m_maxX >= m_minX);
105 return m_maxX - m_minX;
116 return m_maxX - m_minX;
106 }
117 }
107
118
108 qreal Domain::spanY() const
119 qreal Domain::spanY() const
109 {
120 {
110 Q_ASSERT(m_maxY >= m_minY);
121 Q_ASSERT(m_maxY >= m_minY);
111 return m_maxY - m_minY;
122 return m_maxY - m_minY;
112 }
123 }
113
124
114 bool Domain::isEmpty() const
125 bool Domain::isEmpty() const
115 {
126 {
116 return spanX()==0 || spanY()==0;
127 return spanX()==0 || spanY()==0;
117 }
128 }
118
129
119 void Domain::zoomIn(const QRectF& rect, const QSizeF& size)
130 void Domain::zoomIn(const QRectF& rect, const QSizeF& size)
120 {
131 {
121 qreal dx = spanX() / size.width();
132 qreal dx = spanX() / size.width();
122 qreal dy = spanY() / size.height();
133 qreal dy = spanY() / size.height();
123
134
124 m_maxX = m_minX + dx * rect.right();
135 m_maxX = m_minX + dx * rect.right();
125 m_minX = m_minX + dx * rect.left();
136 m_minX = m_minX + dx * rect.left();
126 m_minY = m_maxY - dy * rect.bottom();
137 m_minY = m_maxY - dy * rect.bottom();
127 m_maxY = m_maxY - dy * rect.top();
138 m_maxY = m_maxY - dy * rect.top();
128
139
129 niceNumbers(m_minX, m_maxX, m_tickXCount);
140 niceNumbers(m_minX, m_maxX, m_tickXCount);
130 niceNumbers(m_minY, m_maxY, m_tickYCount);
141 niceNumbers(m_minY, m_maxY, m_tickYCount);
131
142
132 emit domainChanged(m_minX, m_maxX, m_minY, m_maxY);
143 emit domainChanged(m_minX, m_maxX, m_minY, m_maxY);
133 emit rangeXChanged(m_minX, m_maxX, m_tickXCount);
144 emit rangeXChanged(m_minX, m_maxX, m_tickXCount);
134 emit rangeYChanged(m_minY, m_maxY, m_tickYCount);
145 emit rangeYChanged(m_minY, m_maxY, m_tickYCount);
135 }
146 }
136
147
137 void Domain::zoomOut(const QRectF& rect, const QSizeF& size)
148 void Domain::zoomOut(const QRectF& rect, const QSizeF& size)
138 {
149 {
139 qreal dx = spanX() / rect.width();
150 qreal dx = spanX() / rect.width();
140 qreal dy = spanY() / rect.height();
151 qreal dy = spanY() / rect.height();
141
152
142 m_minX = m_maxX - dx * rect.right();
153 m_minX = m_maxX - dx * rect.right();
143 m_maxX = m_minX + dx * size.width();
154 m_maxX = m_minX + dx * size.width();
144 m_maxY = m_minY + dy * rect.bottom();
155 m_maxY = m_minY + dy * rect.bottom();
145 m_minY = m_maxY - dy * size.height();
156 m_minY = m_maxY - dy * size.height();
146
157
147 niceNumbers(m_minX, m_maxX, m_tickXCount);
158 niceNumbers(m_minX, m_maxX, m_tickXCount);
148 niceNumbers(m_minY, m_maxY, m_tickYCount);
159 niceNumbers(m_minY, m_maxY, m_tickYCount);
149
160
150 emit domainChanged(m_minX, m_maxX, m_minY, m_maxY);
161 emit domainChanged(m_minX, m_maxX, m_minY, m_maxY);
151 emit rangeXChanged(m_minX, m_maxX, m_tickXCount);
162 emit rangeXChanged(m_minX, m_maxX, m_tickXCount);
152 emit rangeYChanged(m_minY, m_maxY, m_tickYCount);
163 emit rangeYChanged(m_minY, m_maxY, m_tickYCount);
153 }
164 }
154
165
155 void Domain::move(int dx,int dy,const QSizeF& size)
166 void Domain::move(int dx,int dy,const QSizeF& size)
156 {
167 {
157 qreal x = spanX() / size.width();
168 qreal x = spanX() / size.width();
158 qreal y = spanY() / size.height();
169 qreal y = spanY() / size.height();
159
170
160 if(dx!=0) {
171 if(dx!=0) {
161 m_minX = m_minX + x * dx;
172 m_minX = m_minX + x * dx;
162 m_maxX = m_maxX + x * dx;
173 m_maxX = m_maxX + x * dx;
163 emit rangeXChanged(m_minX, m_maxX, m_tickXCount);
174 emit rangeXChanged(m_minX, m_maxX, m_tickXCount);
164 }
175 }
165 if(dy!=0) {
176 if(dy!=0) {
166 m_minY = m_minY + y * dy;
177 m_minY = m_minY + y * dy;
167 m_maxY = m_maxY + y * dy;
178 m_maxY = m_maxY + y * dy;
168 emit rangeYChanged(m_minY, m_maxY, m_tickYCount);
179 emit rangeYChanged(m_minY, m_maxY, m_tickYCount);
169 }
180 }
170
181
171 emit domainChanged(m_minX, m_maxX, m_minY, m_maxY);
182 emit domainChanged(m_minX, m_maxX, m_minY, m_maxY);
172 }
183 }
173
184
174 void Domain::handleAxisXChanged(qreal min,qreal max,int tickXCount,QChartAxis::LabelsSelection mode)
185 void Domain::handleAxisXChanged(qreal min,qreal max,int tickXCount,QChartAxis::LabelsSelection mode)
175 {
186 {
176 m_selection=mode;
187 m_selection=mode;
177 setRange(min,max,m_minY, m_maxY,tickXCount,m_tickYCount);
188 setRange(min,max,m_minY, m_maxY,tickXCount,m_tickYCount);
178 }
189 }
179
190
180 void Domain::handleAxisYChanged(qreal min,qreal max,int tickYCount,QChartAxis::LabelsSelection mode)
191 void Domain::handleAxisYChanged(qreal min,qreal max,int tickYCount,QChartAxis::LabelsSelection mode)
181 {
192 {
182 m_selection=mode;
193 m_selection=mode;
183 setRange(m_minX, m_maxX, min, max,m_tickXCount,tickYCount);
194 setRange(m_minX, m_maxX, min, max,m_tickXCount,tickYCount);
184 }
195 }
185
196
186 //algorithm defined by Paul S.Heckbert GraphicalGems I
197 //algorithm defined by Paul S.Heckbert GraphicalGems I
187
198
188 void Domain::niceNumbers(qreal &min, qreal &max, int &ticksCount)
199 void Domain::niceNumbers(qreal &min, qreal &max, int &ticksCount)
189 {
200 {
190 if(m_selection!=QChartAxis::NativeLabelsSelection)
201 if(m_selection!=QChartAxis::NativeLabelsSelection)
191 looseNiceNumbers(min,max,ticksCount);
202 looseNiceNumbers(min,max,ticksCount);
192 }
203 }
193
204
194 void Domain::looseNiceNumbers(qreal &min, qreal &max, int &ticksCount)
205 void Domain::looseNiceNumbers(qreal &min, qreal &max, int &ticksCount)
195 {
206 {
196 qreal range = niceNumber(max-min,true); //range with ceiling
207 qreal range = niceNumber(max-min,true); //range with ceiling
197 qreal step = niceNumber(range/(ticksCount-1),false);
208 qreal step = niceNumber(range/(ticksCount-1),false);
198 min = floor(min/step);
209 min = floor(min/step);
199 max = ceil(max/step);
210 max = ceil(max/step);
200 ticksCount = int(max-min) +1;
211 ticksCount = int(max-min) +1;
201 min*=step;
212 min*=step;
202 max*=step;
213 max*=step;
203 }
214 }
204
215
205 //nice numbers can be expressed as form of 1*10^n, 2* 10^n or 5*10^n
216 //nice numbers can be expressed as form of 1*10^n, 2* 10^n or 5*10^n
206
217
207 qreal Domain::niceNumber(qreal x,bool ceiling)
218 qreal Domain::niceNumber(qreal x,bool ceiling)
208 {
219 {
209 qreal z = pow(10,floor(log10(x))); //find corresponding number of the form of 10^n than is smaller than x
220 qreal z = pow(10,floor(log10(x))); //find corresponding number of the form of 10^n than is smaller than x
210 qreal q = x/z;//q<10 && q>=1;
221 qreal q = x/z;//q<10 && q>=1;
211
222
212 if(ceiling) {
223 if(ceiling) {
213 if(q <= 1.0) q=1;
224 if(q <= 1.0) q=1;
214 else if(q <= 2.0) q=2;
225 else if(q <= 2.0) q=2;
215 else if(q <= 5.0) q=5;
226 else if(q <= 5.0) q=5;
216 else q=10;
227 else q=10;
217 }
228 }
218 else {
229 else {
219 if(q < 1.5) q=1;
230 if(q < 1.5) q=1;
220 else if(q < 3.0) q=2;
231 else if(q < 3.0) q=2;
221 else if(q < 7.0) q=5;
232 else if(q < 7.0) q=5;
222 else q=10;
233 else q=10;
223 }
234 }
224 return q*z;
235 return q*z;
225 }
236 }
226
237
227 bool operator== (const Domain &domain1, const Domain &domain2)
238 bool operator== (const Domain &domain1, const Domain &domain2)
228 {
239 {
229 return (domain1.m_maxX == domain2.m_maxX &&
240 return (domain1.m_maxX == domain2.m_maxX &&
230 domain1.m_maxY == domain2.m_maxY &&
241 domain1.m_maxY == domain2.m_maxY &&
231 domain1.m_minX == domain2.m_minX &&
242 domain1.m_minX == domain2.m_minX &&
232 domain1.m_minY == domain2.m_minY);
243 domain1.m_minY == domain2.m_minY);
233 }
244 }
234
245
235 bool operator!= (const Domain &domain1, const Domain &domain2)
246 bool operator!= (const Domain &domain1, const Domain &domain2)
236 {
247 {
237 return !(domain1 == domain2);
248 return !(domain1 == domain2);
238 }
249 }
239
250
240 QDebug operator<<(QDebug dbg, const Domain &domain)
251 QDebug operator<<(QDebug dbg, const Domain &domain)
241 {
252 {
242 dbg.nospace() << "Domain("<<domain.m_minX<<','<<domain.m_maxX<<','<<domain.m_minY<<','<<domain.m_maxY<<')';
253 dbg.nospace() << "Domain("<<domain.m_minX<<','<<domain.m_maxX<<','<<domain.m_minY<<','<<domain.m_maxY<<')' << domain.m_tickXCount << "," << domain.m_tickYCount ;
243 return dbg.maybeSpace();
254 return dbg.maybeSpace();
244 }
255 }
245
256
246 #include "moc_domain_p.cpp"
257 #include "moc_domain_p.cpp"
247
258
248 QTCOMMERCIALCHART_END_NAMESPACE
259 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,71 +1,73
1 #ifndef DOMAIN_H_
1 #ifndef DOMAIN_H_
2 #define DOMAIN_H_
2 #define DOMAIN_H_
3 #include "qchartglobal.h"
3 #include "qchartglobal.h"
4 #include "qchartaxis.h"
4 #include "qchartaxis.h"
5 #include <QRectF>
5 #include <QRectF>
6 #include <QSizeF>
6 #include <QSizeF>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 class Domain: public QObject {
10 class Domain: public QObject {
11 Q_OBJECT
11 Q_OBJECT
12 public:
12 public:
13 explicit Domain(QObject* object=0);
13 explicit Domain(QObject* object=0);
14 virtual ~Domain();
14 virtual ~Domain();
15
15
16 void setRange(qreal minX, qreal maxX, qreal minY, qreal maxY);
16 void setRange(qreal minX, qreal maxX, qreal minY, qreal maxY);
17 void setRange(qreal minX, qreal maxX, qreal minY, qreal maxY, int tickXCount, int tickYCount);
17 void setRange(qreal minX, qreal maxX, qreal minY, qreal maxY, int tickXCount, int tickYCount);
18 void setRangeX(qreal min, qreal max);
18 void setRangeX(qreal min, qreal max);
19 void setRangeX(qreal min, qreal max, int tickCount);
19 void setRangeY(qreal min, qreal max);
20 void setRangeY(qreal min, qreal max);
21 void setRangeY(qreal min, qreal max, int tickCount);
20 void setMinX(qreal min);
22 void setMinX(qreal min);
21 void setMaxX(qreal max);
23 void setMaxX(qreal max);
22 void setMinY(qreal min);
24 void setMinY(qreal min);
23 void setMaxY(qreal max);
25 void setMaxY(qreal max);
24
26
25 qreal minX() const {return m_minX;};
27 qreal minX() const {return m_minX;};
26 qreal maxX() const {return m_maxX;};
28 qreal maxX() const {return m_maxX;};
27 qreal minY() const {return m_minY;};
29 qreal minY() const {return m_minY;};
28 qreal maxY() const {return m_maxY;};
30 qreal maxY() const {return m_maxY;};
29
31
30 qreal spanX() const;
32 qreal spanX() const;
31 qreal spanY() const;
33 qreal spanY() const;
32 bool isEmpty() const;
34 bool isEmpty() const;
33
35
34 int tickXCount() const {return m_tickXCount;}
36 int tickXCount() const {return m_tickXCount;}
35 int tickYCount() const {return m_tickYCount;}
37 int tickYCount() const {return m_tickYCount;}
36
38
37 friend bool operator== (const Domain &domain1, const Domain &domain2);
39 friend bool operator== (const Domain &domain1, const Domain &domain2);
38 friend bool operator!= (const Domain &domain1, const Domain &domain2);
40 friend bool operator!= (const Domain &domain1, const Domain &domain2);
39 friend QDebug operator<<(QDebug dbg, const Domain &domain);
41 friend QDebug operator<<(QDebug dbg, const Domain &domain);
40
42
41 void zoomIn(const QRectF& rect, const QSizeF& size);
43 void zoomIn(const QRectF& rect, const QSizeF& size);
42 void zoomOut(const QRectF& rect, const QSizeF& size);
44 void zoomOut(const QRectF& rect, const QSizeF& size);
43 void move(int dx,int dy,const QSizeF& size);
45 void move(int dx,int dy,const QSizeF& size);
44
46
45 signals:
47 signals:
46 void domainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
48 void domainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
47 void rangeXChanged(qreal min, qreal max, int tickXCount);
49 void rangeXChanged(qreal min, qreal max, int tickXCount);
48 void rangeYChanged(qreal min, qreal max, int tickYCount);
50 void rangeYChanged(qreal min, qreal max, int tickYCount);
49
51
50 public slots:
52 public slots:
51 void handleAxisXChanged(qreal min,qreal max,int tickXCount,QChartAxis::LabelsSelection mode);
53 void handleAxisXChanged(qreal min,qreal max,int tickXCount,QChartAxis::LabelsSelection mode);
52 void handleAxisYChanged(qreal min,qreal max,int tickYCount,QChartAxis::LabelsSelection mode);
54 void handleAxisYChanged(qreal min,qreal max,int tickYCount,QChartAxis::LabelsSelection mode);
53
55
54 private:
56 private:
55 void niceNumbers(qreal &min, qreal &max, int &ticksCount);
57 void niceNumbers(qreal &min, qreal &max, int &ticksCount);
56 void looseNiceNumbers(qreal &min, qreal &max, int &ticksCount);
58 void looseNiceNumbers(qreal &min, qreal &max, int &ticksCount);
57 qreal niceNumber(qreal x,bool celing);
59 qreal niceNumber(qreal x,bool celing);
58
60
59 private:
61 private:
60 qreal m_minX;
62 qreal m_minX;
61 qreal m_maxX;
63 qreal m_maxX;
62 qreal m_minY;
64 qreal m_minY;
63 qreal m_maxY;
65 qreal m_maxY;
64 int m_tickXCount;
66 int m_tickXCount;
65 int m_tickYCount;
67 int m_tickYCount;
66 QChartAxis::LabelsSelection m_selection;
68 QChartAxis::LabelsSelection m_selection;
67 };
69 };
68
70
69 QTCOMMERCIALCHART_END_NAMESPACE
71 QTCOMMERCIALCHART_END_NAMESPACE
70
72
71 #endif
73 #endif
@@ -1,192 +1,192
1 #include "piechartitem_p.h"
1 #include "piechartitem_p.h"
2 #include "piesliceitem_p.h"
2 #include "piesliceitem_p.h"
3 #include "qpieslice.h"
3 #include "qpieslice.h"
4 #include "qpiesliceprivate_p.h"
4 #include "qpiesliceprivate_p.h"
5 #include "qpieseries.h"
5 #include "qpieseries.h"
6 #include "chartpresenter_p.h"
6 #include "chartpresenter_p.h"
7 #include "chartdataset_p.h"
7 #include "chartdataset_p.h"
8 #include "chartanimator_p.h"
8 #include "chartanimator_p.h"
9 #include <QDebug>
9 #include <QDebug>
10 #include <QPainter>
10 #include <QPainter>
11 #include <QTimer>
11 #include <QTimer>
12
12
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
14
14
15 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter* presenter)
15 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter* presenter)
16 :ChartItem(presenter),
16 :ChartItem(presenter),
17 m_series(series)
17 m_series(series)
18 {
18 {
19 Q_ASSERT(series);
19 Q_ASSERT(series);
20 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
20 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
21 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
21 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
22 connect(series, SIGNAL(piePositionChanged()), this, SLOT(handlePieLayoutChanged()));
22 connect(series, SIGNAL(piePositionChanged()), this, SLOT(handlePieLayoutChanged()));
23 connect(series, SIGNAL(pieSizeChanged()), this, SLOT(handlePieLayoutChanged()));
23 connect(series, SIGNAL(pieSizeChanged()), this, SLOT(handlePieLayoutChanged()));
24
24
25 QTimer::singleShot(0, this, SLOT(initialize()));
25 QTimer::singleShot(0, this, SLOT(initialize()));
26
26
27 // Note: the following does not affect as long as the item does not have anything to paint
27 // Note: the following does not affect as long as the item does not have anything to paint
28 setZValue(ChartPresenter::PieSeriesZValue);
28 setZValue(ChartPresenter::PieSeriesZValue);
29 }
29 }
30
30
31 PieChartItem::~PieChartItem()
31 PieChartItem::~PieChartItem()
32 {
32 {
33 // slices deleted automatically through QGraphicsItem
33 // slices deleted automatically through QGraphicsItem
34 }
34 }
35
35
36 void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
36 void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
37 {
37 {
38 Q_UNUSED(painter)
38 Q_UNUSED(painter)
39 // TODO: paint shadows for all components
39 // TODO: paint shadows for all components
40 // - get paths from items & merge & offset and draw with shadow color?
40 // - get paths from items & merge & offset and draw with shadow color?
41 //painter->setBrush(QBrush(Qt::red));
41 //painter->setBrush(QBrush(Qt::red));
42 //painter->drawRect(m_debugRect);
42 //painter->drawRect(m_debugRect);
43 }
43 }
44
44
45 void PieChartItem::initialize()
45 void PieChartItem::initialize()
46 {
46 {
47 handleSlicesAdded(m_series->slices());
47 handleSlicesAdded(m_series->slices());
48 }
48 }
49
49
50 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
50 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
51 {
51 {
52 bool isEmpty = m_slices.isEmpty();
52 bool isEmpty = m_slices.isEmpty();
53
53
54 presenter()->theme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
54 presenter()->theme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
55
55
56 foreach (QPieSlice *s, slices) {
56 foreach (QPieSlice *s, slices) {
57 PieSliceItem* item = new PieSliceItem(this);
57 PieSliceItem* item = new PieSliceItem(this);
58 m_slices.insert(s, item);
58 m_slices.insert(s, item);
59 connect(s, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
59 connect(s, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
60 connect(item, SIGNAL(clicked()), s, SIGNAL(clicked()));
60 connect(item, SIGNAL(clicked()), s, SIGNAL(clicked()));
61 connect(item, SIGNAL(hoverEnter()), s, SIGNAL(hoverEnter()));
61 connect(item, SIGNAL(hoverEnter()), s, SIGNAL(hoverEnter()));
62 connect(item, SIGNAL(hoverLeave()), s, SIGNAL(hoverLeave()));
62 connect(item, SIGNAL(hoverLeave()), s, SIGNAL(hoverLeave()));
63
63
64 PieSliceData data = sliceData(s);
64 PieSliceData data = sliceData(s);
65
65
66 if (m_animator)
66 if (animator())
67 m_animator->addAnimation(this, s, data, isEmpty);
67 animator()->addAnimation(this, s, data, isEmpty);
68 else
68 else
69 setLayout(s, data);
69 setLayout(s, data);
70 }
70 }
71 }
71 }
72
72
73 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
73 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
74 {
74 {
75 presenter()->theme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
75 presenter()->theme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
76
76
77 foreach (QPieSlice *s, slices) {
77 foreach (QPieSlice *s, slices) {
78 if (animator())
78 if (animator())
79 animator()->removeAnimation(this, s);
79 animator()->removeAnimation(this, s);
80 else
80 else
81 destroySlice(s);
81 destroySlice(s);
82 }
82 }
83 }
83 }
84
84
85 void PieChartItem::handlePieLayoutChanged()
85 void PieChartItem::handlePieLayoutChanged()
86 {
86 {
87 PieLayout layout = calculateLayout();
87 PieLayout layout = calculateLayout();
88 applyLayout(layout);
88 applyLayout(layout);
89 update();
89 update();
90 }
90 }
91
91
92 void PieChartItem::handleSliceChanged()
92 void PieChartItem::handleSliceChanged()
93 {
93 {
94 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
94 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
95 Q_ASSERT(m_slices.contains(slice));
95 Q_ASSERT(m_slices.contains(slice));
96 PieSliceData data = sliceData(slice);
96 PieSliceData data = sliceData(slice);
97 updateLayout(slice, data);
97 updateLayout(slice, data);
98 update();
98 update();
99 }
99 }
100
100
101 void PieChartItem::handleDomainChanged(qreal, qreal, qreal, qreal)
101 void PieChartItem::handleDomainChanged(qreal, qreal, qreal, qreal)
102 {
102 {
103 // TODO
103 // TODO
104 }
104 }
105
105
106 void PieChartItem::handleGeometryChanged(const QRectF& rect)
106 void PieChartItem::handleGeometryChanged(const QRectF& rect)
107 {
107 {
108 prepareGeometryChange();
108 prepareGeometryChange();
109 m_rect = rect;
109 m_rect = rect;
110 handlePieLayoutChanged();
110 handlePieLayoutChanged();
111 }
111 }
112
112
113 void PieChartItem::calculatePieLayout()
113 void PieChartItem::calculatePieLayout()
114 {
114 {
115 // find pie center coordinates
115 // find pie center coordinates
116 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->pieHorizontalPosition()));
116 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->pieHorizontalPosition()));
117 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->pieVerticalPosition()));
117 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->pieVerticalPosition()));
118
118
119 // find maximum radius for pie
119 // find maximum radius for pie
120 m_pieRadius = m_rect.height() / 2;
120 m_pieRadius = m_rect.height() / 2;
121 if (m_rect.width() < m_rect.height())
121 if (m_rect.width() < m_rect.height())
122 m_pieRadius = m_rect.width() / 2;
122 m_pieRadius = m_rect.width() / 2;
123
123
124 // apply size factor
124 // apply size factor
125 m_pieRadius *= m_series->pieSize();
125 m_pieRadius *= m_series->pieSize();
126 }
126 }
127
127
128 PieSliceData PieChartItem::sliceData(QPieSlice *slice)
128 PieSliceData PieChartItem::sliceData(QPieSlice *slice)
129 {
129 {
130 PieSliceData sliceData = slice->data_ptr()->m_data;
130 PieSliceData sliceData = slice->data_ptr()->m_data;
131 sliceData.m_center = PieSliceItem::sliceCenter(m_pieCenter, m_pieRadius, slice);
131 sliceData.m_center = PieSliceItem::sliceCenter(m_pieCenter, m_pieRadius, slice);
132 sliceData.m_radius = m_pieRadius;
132 sliceData.m_radius = m_pieRadius;
133 sliceData.m_angleSpan = slice->endAngle() - slice->startAngle();
133 sliceData.m_angleSpan = slice->endAngle() - slice->startAngle();
134 return sliceData;
134 return sliceData;
135 }
135 }
136
136
137 PieLayout PieChartItem::calculateLayout()
137 PieLayout PieChartItem::calculateLayout()
138 {
138 {
139 calculatePieLayout();
139 calculatePieLayout();
140 PieLayout layout;
140 PieLayout layout;
141 foreach (QPieSlice* s, m_series->slices()) {
141 foreach (QPieSlice* s, m_series->slices()) {
142 if (m_slices.contains(s)) // calculate layout only for those slices that are already visible
142 if (m_slices.contains(s)) // calculate layout only for those slices that are already visible
143 layout.insert(s, sliceData(s));
143 layout.insert(s, sliceData(s));
144 }
144 }
145 return layout;
145 return layout;
146 }
146 }
147
147
148 void PieChartItem::applyLayout(const PieLayout &layout)
148 void PieChartItem::applyLayout(const PieLayout &layout)
149 {
149 {
150 if (animator())
150 if (animator())
151 animator()->updateLayout(this, layout);
151 animator()->updateLayout(this, layout);
152 else
152 else
153 setLayout(layout);
153 setLayout(layout);
154 }
154 }
155
155
156 void PieChartItem::updateLayout(QPieSlice *slice, const PieSliceData &sliceData)
156 void PieChartItem::updateLayout(QPieSlice *slice, const PieSliceData &sliceData)
157 {
157 {
158 if (m_animator)
158 if (animator())
159 m_animator->updateLayout(this, slice, sliceData);
159 animator()->updateLayout(this, slice, sliceData);
160 else
160 else
161 setLayout(slice, sliceData);
161 setLayout(slice, sliceData);
162 }
162 }
163
163
164 void PieChartItem::setLayout(const PieLayout &layout)
164 void PieChartItem::setLayout(const PieLayout &layout)
165 {
165 {
166 foreach (QPieSlice *slice, layout.keys()) {
166 foreach (QPieSlice *slice, layout.keys()) {
167 PieSliceItem *item = m_slices.value(slice);
167 PieSliceItem *item = m_slices.value(slice);
168 Q_ASSERT(item);
168 Q_ASSERT(item);
169 item->setSliceData(layout.value(slice));
169 item->setSliceData(layout.value(slice));
170 item->updateGeometry();
170 item->updateGeometry();
171 item->update();
171 item->update();
172 }
172 }
173 }
173 }
174
174
175 void PieChartItem::setLayout(QPieSlice *slice, const PieSliceData &sliceData)
175 void PieChartItem::setLayout(QPieSlice *slice, const PieSliceData &sliceData)
176 {
176 {
177 // find slice
177 // find slice
178 PieSliceItem *item = m_slices.value(slice);
178 PieSliceItem *item = m_slices.value(slice);
179 Q_ASSERT(item);
179 Q_ASSERT(item);
180 item->setSliceData(sliceData);
180 item->setSliceData(sliceData);
181 item->updateGeometry();
181 item->updateGeometry();
182 item->update();
182 item->update();
183 }
183 }
184
184
185 void PieChartItem::destroySlice(QPieSlice *slice)
185 void PieChartItem::destroySlice(QPieSlice *slice)
186 {
186 {
187 delete m_slices.take(slice);
187 delete m_slices.take(slice);
188 }
188 }
189
189
190 #include "moc_piechartitem_p.cpp"
190 #include "moc_piechartitem_p.cpp"
191
191
192 QTCOMMERCIALCHART_END_NAMESPACE
192 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now