##// END OF EJS Templates
Added hovered signal to QLineSeries. Updated callout example
Marek Rosa -
r2255:31c21c535136
parent child
Show More
@@ -1,56 +1,71
1 #include "widget.h"
1 #include "widget.h"
2 #include <QGraphicsScene>
2 #include <QGraphicsScene>
3 #include <QGraphicsView>
3 #include <QGraphicsView>
4 #include <QVBoxLayout>
4 #include <QVBoxLayout>
5 #include <QChart>
5 #include <QChart>
6 #include <QLineSeries>
6 #include <QLineSeries>
7 #include <QGraphicsTextItem>
7 #include <QGraphicsTextItem>
8 #include <QGraphicsLineItem>
8 #include <QGraphicsLineItem>
9 #include "callout.h"
9 #include "callout.h"
10
10
11 QTCOMMERCIALCHART_USE_NAMESPACE
11 QTCOMMERCIALCHART_USE_NAMESPACE
12
12
13 Widget::Widget(QWidget *parent)
13 Widget::Widget(QWidget *parent)
14 : QWidget(parent),
14 : QWidget(parent),
15 m_scene(0),
15 m_scene(0),
16 m_chart(0),
16 m_chart(0),
17 m_view(0)
17 m_view(0),
18 m_tooltip(0)
18 {
19 {
19 // chart
20 // chart
20 m_chart = new QChart;
21 m_chart = new QChart;
21 m_chart->setMinimumSize(640, 480);
22 m_chart->setMinimumSize(640, 480);
23 m_chart->setTitle("Hover the line to show callout. Click the line to make it stay");
24 m_chart->legend()->hide();
22 QLineSeries *series = new QLineSeries;
25 QLineSeries *series = new QLineSeries;
23 series->setName("Click the line to create a movable callout");
24 series->append(1, 3);
26 series->append(1, 3);
25 series->append(4, 5);
27 series->append(4, 5);
26 series->append(5, 4.5);
28 series->append(5, 4.5);
27 series->append(7, 1);
29 series->append(7, 1);
28 series->append(11, 2);
30 series->append(11, 2);
29 m_chart->addSeries(series);
31 m_chart->addSeries(series);
30 m_chart->createDefaultAxes();
32 m_chart->createDefaultAxes();
31
33
32 m_scene = new QGraphicsScene;
34 m_scene = new QGraphicsScene;
33 m_view = new QGraphicsView(m_scene);
35 m_view = new QGraphicsView(m_scene);
34 m_view->setRenderHint(QPainter::Antialiasing);
36 m_view->setRenderHint(QPainter::Antialiasing);
35 m_scene->addItem(m_chart);
37 m_scene->addItem(m_chart);
36
38
37 QVBoxLayout *mainLayout = new QVBoxLayout;
39 QVBoxLayout *mainLayout = new QVBoxLayout;
38 mainLayout->addWidget(m_view);
40 mainLayout->addWidget(m_view);
39 setLayout(mainLayout);
41 setLayout(mainLayout);
40
42
41 connect(series, SIGNAL(clicked(QPointF)), this, SLOT(addCallout(QPointF)));
43 connect(series, SIGNAL(clicked(QPointF)), this, SLOT(keepCallout()));
44 connect(series, SIGNAL(hovered(QPointF, bool)), this, SLOT(tooltip(QPointF,bool)));
42 }
45 }
43
46
44 Widget::~Widget()
47 Widget::~Widget()
45 {
48 {
46
49
47 }
50 }
48
51
49 void Widget::addCallout(QPointF point)
52 void Widget::keepCallout()
50 {
53 {
51 Callout *label = new Callout(m_chart);
54 m_tooltip = new Callout(m_chart);
52 label->setText(QString("X: %1\nY: %2").arg(point.x()).arg(point.y()));
55 }
53 label->setAnchor(m_chart->mapFromParent(m_view->mapToScene(m_view->mapFromGlobal(QCursor::pos()))));
56
54 label->setPos(m_chart->mapFromParent(m_view->mapToScene(m_view->mapFromGlobal(QCursor::pos() + QPoint(10, -50)))));
57 void Widget::tooltip(QPointF point, bool state)
55 label->setZValue(11);
58 {
59 if (m_tooltip == 0)
60 m_tooltip = new Callout(m_chart);
61
62 if (state) {
63 m_tooltip->setText(QString("X: %1\nY: %2").arg(point.x()).arg(point.y()));
64 m_tooltip->setAnchor(m_chart->mapFromParent(m_view->mapToScene(m_view->mapFromGlobal(QCursor::pos()))));
65 m_tooltip->setPos(m_chart->mapFromParent(m_view->mapToScene(m_view->mapFromGlobal(QCursor::pos() + QPoint(10, -50)))));
66 m_tooltip->setZValue(11);
67 m_tooltip->show();
68 } else {
69 m_tooltip->hide();
70 }
56 }
71 }
@@ -1,29 +1,32
1 #ifndef WIDGET_H
1 #ifndef WIDGET_H
2 #define WIDGET_H
2 #define WIDGET_H
3
3
4 #include <QWidget>
4 #include <QWidget>
5 #include <QChart>
5 #include <QChart>
6
6
7 class QGraphicsScene;
7 class QGraphicsScene;
8 class QGraphicsView;
8 class QGraphicsView;
9 class Callout;
9
10
10 QTCOMMERCIALCHART_USE_NAMESPACE
11 QTCOMMERCIALCHART_USE_NAMESPACE
11
12
12 class Widget : public QWidget
13 class Widget : public QWidget
13 {
14 {
14 Q_OBJECT
15 Q_OBJECT
15
16
16 public:
17 public:
17 Widget(QWidget *parent = 0);
18 Widget(QWidget *parent = 0);
18 ~Widget();
19 ~Widget();
19
20
20 public slots:
21 public slots:
21 void addCallout(QPointF point);
22 void keepCallout();
23 void tooltip(QPointF point, bool state);
22
24
23 private:
25 private:
24 QGraphicsScene *m_scene;
26 QGraphicsScene *m_scene;
25 QChart *m_chart;
27 QChart *m_chart;
26 QGraphicsView *m_view;
28 QGraphicsView *m_view;
29 Callout *m_tooltip;
27 };
30 };
28
31
29 #endif // WIDGET_H
32 #endif // WIDGET_H
@@ -1,137 +1,150
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "linechartitem_p.h"
21 #include "linechartitem_p.h"
22 #include "qlineseries.h"
22 #include "qlineseries.h"
23 #include "qlineseries_p.h"
23 #include "qlineseries_p.h"
24 #include "chartpresenter_p.h"
24 #include "chartpresenter_p.h"
25 #include <QPainter>
25 #include <QPainter>
26 #include <QGraphicsSceneMouseEvent>
26 #include <QGraphicsSceneMouseEvent>
27
27
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29
29
30 const qreal mouseEventMinWidth(12);
30 const qreal mouseEventMinWidth(12);
31
31
32 LineChartItem::LineChartItem(QLineSeries *series, ChartPresenter *presenter)
32 LineChartItem::LineChartItem(QLineSeries *series, ChartPresenter *presenter)
33 : XYChart(series, presenter),
33 : XYChart(series, presenter),
34 QGraphicsItem(presenter ? presenter->rootItem() : 0),
34 QGraphicsItem(presenter ? presenter->rootItem() : 0),
35 m_series(series),
35 m_series(series),
36 m_pointsVisible(false)
36 m_pointsVisible(false)
37 {
37 {
38 setAcceptHoverEvents(true);
38 setZValue(ChartPresenter::LineChartZValue);
39 setZValue(ChartPresenter::LineChartZValue);
39 QObject::connect(series->d_func(), SIGNAL(updated()), this, SLOT(handleUpdated()));
40 QObject::connect(series->d_func(), SIGNAL(updated()), this, SLOT(handleUpdated()));
40 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
41 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
41 QObject::connect(series, SIGNAL(opacityChanged()), this, SLOT(handleUpdated()));
42 QObject::connect(series, SIGNAL(opacityChanged()), this, SLOT(handleUpdated()));
42 handleUpdated();
43 handleUpdated();
43 }
44 }
44
45
45 QRectF LineChartItem::boundingRect() const
46 QRectF LineChartItem::boundingRect() const
46 {
47 {
47 return m_rect;
48 return m_rect;
48 }
49 }
49
50
50 QPainterPath LineChartItem::shape() const
51 QPainterPath LineChartItem::shape() const
51 {
52 {
52 return m_path;
53 return m_path;
53 }
54 }
54
55
55 void LineChartItem::updateGeometry()
56 void LineChartItem::updateGeometry()
56 {
57 {
57 m_points = geometryPoints();
58 m_points = geometryPoints();
58
59
59 if (m_points.size() == 0) {
60 if (m_points.size() == 0) {
60 prepareGeometryChange();
61 prepareGeometryChange();
61 m_path = QPainterPath();
62 m_path = QPainterPath();
62 m_rect = QRect();
63 m_rect = QRect();
63 return;
64 return;
64 }
65 }
65
66
66 QPainterPath linePath(m_points.at(0));
67 QPainterPath linePath(m_points.at(0));
67
68
68 if (m_pointsVisible) {
69 if (m_pointsVisible) {
69
70
70 int size = m_linePen.width();
71 int size = m_linePen.width();
71 linePath.addEllipse(m_points.at(0), size, size);
72 linePath.addEllipse(m_points.at(0), size, size);
72 for (int i = 1; i < m_points.size(); i++) {
73 for (int i = 1; i < m_points.size(); i++) {
73 linePath.lineTo(m_points.at(i));
74 linePath.lineTo(m_points.at(i));
74 linePath.addEllipse(m_points.at(i), size, size);
75 linePath.addEllipse(m_points.at(i), size, size);
75 }
76 }
76
77
77 } else {
78 } else {
78 for (int i = 1; i < m_points.size(); i++)
79 for (int i = 1; i < m_points.size(); i++)
79 linePath.lineTo(m_points.at(i));
80 linePath.lineTo(m_points.at(i));
80 }
81 }
81
82
82 m_linePath = linePath;
83 m_linePath = linePath;
83
84
84 QPainterPathStroker stroker;
85 QPainterPathStroker stroker;
85 // QPainter::drawLine does not respect join styles, for example BevelJoin becomes MiterJoin.
86 // QPainter::drawLine does not respect join styles, for example BevelJoin becomes MiterJoin.
86 // This is why we are prepared for the "worst case" scenario, i.e. use always MiterJoin and
87 // This is why we are prepared for the "worst case" scenario, i.e. use always MiterJoin and
87 // multiply line width with square root of two when defining shape and bounding rectangle.
88 // multiply line width with square root of two when defining shape and bounding rectangle.
88 stroker.setWidth(m_linePen.width() * 1.42);
89 stroker.setWidth(m_linePen.width() * 1.42);
89 stroker.setJoinStyle(Qt::MiterJoin);
90 stroker.setJoinStyle(Qt::MiterJoin);
90 stroker.setCapStyle(Qt::SquareCap);
91 stroker.setCapStyle(Qt::SquareCap);
91 stroker.setMiterLimit(m_linePen.miterLimit());
92 stroker.setMiterLimit(m_linePen.miterLimit());
92
93
93 prepareGeometryChange();
94 prepareGeometryChange();
94
95
95 m_path = stroker.createStroke(linePath);
96 m_path = stroker.createStroke(linePath);
96 m_rect = m_path.boundingRect();
97 m_rect = m_path.boundingRect();
97
98
98 setPos(origin());
99 setPos(origin());
99 }
100 }
100
101
101 void LineChartItem::handleUpdated()
102 void LineChartItem::handleUpdated()
102 {
103 {
103 setVisible(m_series->isVisible());
104 setVisible(m_series->isVisible());
104 setOpacity(m_series->opacity());
105 setOpacity(m_series->opacity());
105 m_pointsVisible = m_series->pointsVisible();
106 m_pointsVisible = m_series->pointsVisible();
106 m_linePen = m_series->pen();
107 m_linePen = m_series->pen();
107 update();
108 update();
108 }
109 }
109
110
110 void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
111 void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
111 {
112 {
112 Q_UNUSED(widget)
113 Q_UNUSED(widget)
113 Q_UNUSED(option)
114 Q_UNUSED(option)
114
115
115 painter->save();
116 painter->save();
116 painter->setPen(m_linePen);
117 painter->setPen(m_linePen);
117 painter->setBrush(m_linePen.color());
118 painter->setBrush(m_linePen.color());
118 painter->setClipRect(clipRect());
119 painter->setClipRect(clipRect());
119
120
120 if (m_pointsVisible) {
121 if (m_pointsVisible) {
121 painter->drawPath(m_linePath);
122 painter->drawPath(m_linePath);
122 } else {
123 } else {
123 for (int i(1); i < m_points.size(); i++)
124 for (int i(1); i < m_points.size(); i++)
124 painter->drawLine(m_points.at(i - 1), m_points.at(i));
125 painter->drawLine(m_points.at(i - 1), m_points.at(i));
125 }
126 }
126 painter->restore();
127 painter->restore();
127 }
128 }
128
129
129 void LineChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
130 void LineChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
130 {
131 {
131 emit XYChart::clicked(calculateDomainPoint(event->pos()));
132 emit XYChart::clicked(calculateDomainPoint(event->pos()));
132 QGraphicsItem::mousePressEvent(event);
133 QGraphicsItem::mousePressEvent(event);
133 }
134 }
134
135
136 void LineChartItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
137 {
138 emit XYChart::hovered(calculateDomainPoint(event->pos()), true);
139 QGraphicsItem::hoverEnterEvent(event);
140 }
141
142 void LineChartItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
143 {
144 emit XYChart::hovered(calculateDomainPoint(event->pos()), false);
145 QGraphicsItem::hoverEnterEvent(event);
146 }
147
135 #include "moc_linechartitem_p.cpp"
148 #include "moc_linechartitem_p.cpp"
136
149
137 QTCOMMERCIALCHART_END_NAMESPACE
150 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,76 +1,78
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef LINECHARTITEM_H
30 #ifndef LINECHARTITEM_H
31 #define LINECHARTITEM_H
31 #define LINECHARTITEM_H
32
32
33 #include "qchartglobal.h"
33 #include "qchartglobal.h"
34 #include "xychart_p.h"
34 #include "xychart_p.h"
35 #include <QPen>
35 #include <QPen>
36
36
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38
38
39 class QLineSeries;
39 class QLineSeries;
40 class ChartPresenter;
40 class ChartPresenter;
41
41
42 class LineChartItem : public XYChart , public QGraphicsItem
42 class LineChartItem : public XYChart , public QGraphicsItem
43 {
43 {
44 Q_OBJECT
44 Q_OBJECT
45 Q_INTERFACES(QGraphicsItem)
45 Q_INTERFACES(QGraphicsItem)
46 public:
46 public:
47 explicit LineChartItem(QLineSeries *series, ChartPresenter *presenter);
47 explicit LineChartItem(QLineSeries *series, ChartPresenter *presenter);
48 ~LineChartItem() {}
48 ~LineChartItem() {}
49
49
50 //from QGraphicsItem
50 //from QGraphicsItem
51 QRectF boundingRect() const;
51 QRectF boundingRect() const;
52 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
52 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
53 QPainterPath shape() const;
53 QPainterPath shape() const;
54
54
55 QPainterPath path() const { return m_linePath; }
55 QPainterPath path() const { return m_linePath; }
56
56
57 public Q_SLOTS:
57 public Q_SLOTS:
58 void handleUpdated();
58 void handleUpdated();
59
59
60 protected:
60 protected:
61 void updateGeometry();
61 void updateGeometry();
62 void mousePressEvent(QGraphicsSceneMouseEvent *event);
62 void mousePressEvent(QGraphicsSceneMouseEvent *event);
63 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
64 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
63
65
64 private:
66 private:
65 QLineSeries *m_series;
67 QLineSeries *m_series;
66 QPainterPath m_path;
68 QPainterPath m_path;
67 QPainterPath m_linePath;
69 QPainterPath m_linePath;
68 QVector<QPointF> m_points;
70 QVector<QPointF> m_points;
69 QRectF m_rect;
71 QRectF m_rect;
70 QPen m_linePen;
72 QPen m_linePen;
71 bool m_pointsVisible;
73 bool m_pointsVisible;
72 };
74 };
73
75
74 QTCOMMERCIALCHART_END_NAMESPACE
76 QTCOMMERCIALCHART_END_NAMESPACE
75
77
76 #endif
78 #endif
@@ -1,95 +1,96
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #ifndef QXYSERIES_H
21 #ifndef QXYSERIES_H
22 #define QXYSERIES_H
22 #define QXYSERIES_H
23
23
24 #include <qchartglobal.h>
24 #include <qchartglobal.h>
25 #include <qabstractseries.h>
25 #include <qabstractseries.h>
26 #include <QPen>
26 #include <QPen>
27 #include <QBrush>
27 #include <QBrush>
28
28
29 class QModelIndex;
29 class QModelIndex;
30
30
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32
32
33 class QXYSeriesPrivate;
33 class QXYSeriesPrivate;
34 class QXYModelMapper;
34 class QXYModelMapper;
35
35
36 class QTCOMMERCIALCHART_EXPORT QXYSeries : public QAbstractSeries
36 class QTCOMMERCIALCHART_EXPORT QXYSeries : public QAbstractSeries
37 {
37 {
38 Q_OBJECT
38 Q_OBJECT
39 Q_PROPERTY(bool pointsVisible READ pointsVisible WRITE setPointsVisible)
39 Q_PROPERTY(bool pointsVisible READ pointsVisible WRITE setPointsVisible)
40 Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
40 Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
41
41
42 protected:
42 protected:
43 explicit QXYSeries(QXYSeriesPrivate &d, QObject *parent = 0);
43 explicit QXYSeries(QXYSeriesPrivate &d, QObject *parent = 0);
44
44
45 public:
45 public:
46 ~QXYSeries();
46 ~QXYSeries();
47 void append(qreal x, qreal y);
47 void append(qreal x, qreal y);
48 void append(const QPointF &point);
48 void append(const QPointF &point);
49 void append(const QList<QPointF> &points);
49 void append(const QList<QPointF> &points);
50 void replace(qreal oldX, qreal oldY, qreal newX, qreal newY);
50 void replace(qreal oldX, qreal oldY, qreal newX, qreal newY);
51 void replace(const QPointF &oldPoint, const QPointF &newPoint);
51 void replace(const QPointF &oldPoint, const QPointF &newPoint);
52 void remove(qreal x, qreal y);
52 void remove(qreal x, qreal y);
53 void remove(const QPointF &point);
53 void remove(const QPointF &point);
54 void insert(int index, const QPointF &point);
54 void insert(int index, const QPointF &point);
55 void clear();
55 void clear();
56
56
57 int count() const;
57 int count() const;
58 QList<QPointF> points() const;
58 QList<QPointF> points() const;
59
59
60 QXYSeries &operator << (const QPointF &point);
60 QXYSeries &operator << (const QPointF &point);
61 QXYSeries &operator << (const QList<QPointF> &points);
61 QXYSeries &operator << (const QList<QPointF> &points);
62
62
63 virtual void setPen(const QPen &pen);
63 virtual void setPen(const QPen &pen);
64 QPen pen() const;
64 QPen pen() const;
65
65
66 virtual void setBrush(const QBrush &brush);
66 virtual void setBrush(const QBrush &brush);
67 QBrush brush() const;
67 QBrush brush() const;
68
68
69 virtual void setColor(const QColor &color);
69 virtual void setColor(const QColor &color);
70 virtual QColor color() const;
70 virtual QColor color() const;
71
71
72 void setPointsVisible(bool visible = true);
72 void setPointsVisible(bool visible = true);
73 bool pointsVisible() const;
73 bool pointsVisible() const;
74
74
75 void replace(QList<QPointF> points);
75 void replace(QList<QPointF> points);
76
76
77 Q_SIGNALS:
77 Q_SIGNALS:
78 void clicked(const QPointF &point);
78 void clicked(const QPointF &point);
79 void hovered(const QPointF &point, bool state);
79 void pointReplaced(int index);
80 void pointReplaced(int index);
80 void pointRemoved(int index);
81 void pointRemoved(int index);
81 void pointAdded(int index);
82 void pointAdded(int index);
82 void colorChanged(QColor color);
83 void colorChanged(QColor color);
83 void pointsReplaced();
84 void pointsReplaced();
84
85
85 private:
86 private:
86 Q_DECLARE_PRIVATE(QXYSeries)
87 Q_DECLARE_PRIVATE(QXYSeries)
87 Q_DISABLE_COPY(QXYSeries)
88 Q_DISABLE_COPY(QXYSeries)
88 friend class QXYLegendMarkerPrivate;
89 friend class QXYLegendMarkerPrivate;
89 friend class XYLegendMarker;
90 friend class XYLegendMarker;
90 friend class XYChart;
91 friend class XYChart;
91 };
92 };
92
93
93 QTCOMMERCIALCHART_END_NAMESPACE
94 QTCOMMERCIALCHART_END_NAMESPACE
94
95
95 #endif // QXYSERIES_H
96 #endif // QXYSERIES_H
@@ -1,227 +1,228
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "xychart_p.h"
21 #include "xychart_p.h"
22 #include "qxyseries.h"
22 #include "qxyseries.h"
23 #include "qxyseries_p.h"
23 #include "qxyseries_p.h"
24 #include "chartpresenter_p.h"
24 #include "chartpresenter_p.h"
25 #include "domain_p.h"
25 #include "domain_p.h"
26 #include "qxymodelmapper.h"
26 #include "qxymodelmapper.h"
27 #include <QPainter>
27 #include <QPainter>
28 #include <QAbstractItemModel>
28 #include <QAbstractItemModel>
29
29
30
30
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32
32
33 //TODO: optimize : remove points which are not visible
33 //TODO: optimize : remove points which are not visible
34
34
35 XYChart::XYChart(QXYSeries *series, ChartPresenter *presenter)
35 XYChart::XYChart(QXYSeries *series, ChartPresenter *presenter)
36 : ChartElement(presenter),
36 : ChartElement(presenter),
37 m_minX(0),
37 m_minX(0),
38 m_maxX(0),
38 m_maxX(0),
39 m_minY(0),
39 m_minY(0),
40 m_maxY(0),
40 m_maxY(0),
41 m_series(series),
41 m_series(series),
42 m_animation(0),
42 m_animation(0),
43 m_dirty(true)
43 m_dirty(true)
44 {
44 {
45 QObject::connect(series, SIGNAL(pointReplaced(int)), this, SLOT(handlePointReplaced(int)));
45 QObject::connect(series, SIGNAL(pointReplaced(int)), this, SLOT(handlePointReplaced(int)));
46 QObject::connect(series, SIGNAL(pointsReplaced()), this, SLOT(handlePointsReplaced()));
46 QObject::connect(series, SIGNAL(pointsReplaced()), this, SLOT(handlePointsReplaced()));
47 QObject::connect(series, SIGNAL(pointAdded(int)), this, SLOT(handlePointAdded(int)));
47 QObject::connect(series, SIGNAL(pointAdded(int)), this, SLOT(handlePointAdded(int)));
48 QObject::connect(series, SIGNAL(pointRemoved(int)), this, SLOT(handlePointRemoved(int)));
48 QObject::connect(series, SIGNAL(pointRemoved(int)), this, SLOT(handlePointRemoved(int)));
49 QObject::connect(this, SIGNAL(clicked(QPointF)), series, SIGNAL(clicked(QPointF)));
49 QObject::connect(this, SIGNAL(clicked(QPointF)), series, SIGNAL(clicked(QPointF)));
50 QObject::connect(this, SIGNAL(hovered(QPointF,bool)), series, SIGNAL(hovered(QPointF,bool)));
50 }
51 }
51
52
52 void XYChart::setGeometryPoints(const QVector<QPointF>& points)
53 void XYChart::setGeometryPoints(const QVector<QPointF>& points)
53 {
54 {
54 m_points = points;
55 m_points = points;
55 }
56 }
56
57
57 void XYChart::setClipRect(const QRectF &rect)
58 void XYChart::setClipRect(const QRectF &rect)
58 {
59 {
59 m_clipRect = rect;
60 m_clipRect = rect;
60 }
61 }
61
62
62 void XYChart::setAnimation(XYAnimation *animation)
63 void XYChart::setAnimation(XYAnimation *animation)
63 {
64 {
64 m_animation = animation;
65 m_animation = animation;
65 }
66 }
66
67
67 void XYChart::setDirty(bool dirty)
68 void XYChart::setDirty(bool dirty)
68 {
69 {
69 m_dirty = dirty;
70 m_dirty = dirty;
70 }
71 }
71
72
72 QPointF XYChart::calculateGeometryPoint(const QPointF &point) const
73 QPointF XYChart::calculateGeometryPoint(const QPointF &point) const
73 {
74 {
74 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
75 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
75 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
76 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
76 qreal x = (point.x() - m_minX) * deltaX;
77 qreal x = (point.x() - m_minX) * deltaX;
77 qreal y = (point.y() - m_minY) * -deltaY + m_size.height();
78 qreal y = (point.y() - m_minY) * -deltaY + m_size.height();
78 return QPointF(x, y);
79 return QPointF(x, y);
79 }
80 }
80
81
81 QPointF XYChart::calculateGeometryPoint(int index) const
82 QPointF XYChart::calculateGeometryPoint(int index) const
82 {
83 {
83 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
84 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
84 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
85 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
85 const QList<QPointF>& vector = m_series->points();
86 const QList<QPointF>& vector = m_series->points();
86 qreal x = (vector[index].x() - m_minX) * deltaX;
87 qreal x = (vector[index].x() - m_minX) * deltaX;
87 qreal y = (vector[index].y() - m_minY) * -deltaY + m_size.height();
88 qreal y = (vector[index].y() - m_minY) * -deltaY + m_size.height();
88 return QPointF(x, y);
89 return QPointF(x, y);
89 }
90 }
90
91
91 QVector<QPointF> XYChart::calculateGeometryPoints() const
92 QVector<QPointF> XYChart::calculateGeometryPoints() const
92 {
93 {
93 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
94 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
94 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
95 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
95
96
96 QVector<QPointF> result;
97 QVector<QPointF> result;
97 result.resize(m_series->count());
98 result.resize(m_series->count());
98 const QList<QPointF>& vector = m_series->points();
99 const QList<QPointF>& vector = m_series->points();
99 for (int i = 0; i < m_series->count(); ++i) {
100 for (int i = 0; i < m_series->count(); ++i) {
100 qreal x = (vector[i].x() - m_minX) * deltaX;
101 qreal x = (vector[i].x() - m_minX) * deltaX;
101 qreal y = (vector[i].y() - m_minY) * -deltaY + m_size.height();
102 qreal y = (vector[i].y() - m_minY) * -deltaY + m_size.height();
102 result[i].setX(x);
103 result[i].setX(x);
103 result[i].setY(y);
104 result[i].setY(y);
104 }
105 }
105 return result;
106 return result;
106 }
107 }
107
108
108 QPointF XYChart::calculateDomainPoint(const QPointF &point) const
109 QPointF XYChart::calculateDomainPoint(const QPointF &point) const
109 {
110 {
110 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
111 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
111 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
112 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
112 qreal x = point.x() / deltaX + m_minX;
113 qreal x = point.x() / deltaX + m_minX;
113 qreal y = (point.y() - m_size.height()) / (-deltaY) + m_minY;
114 qreal y = (point.y() - m_size.height()) / (-deltaY) + m_minY;
114 return QPointF(x, y);
115 return QPointF(x, y);
115 }
116 }
116
117
117 void XYChart::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, int index)
118 void XYChart::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, int index)
118 {
119 {
119
120
120 if (m_animation) {
121 if (m_animation) {
121 m_animation->setup(oldPoints, newPoints, index);
122 m_animation->setup(oldPoints, newPoints, index);
122 m_points = newPoints;
123 m_points = newPoints;
123 setDirty(false);
124 setDirty(false);
124 presenter()->startAnimation(m_animation);
125 presenter()->startAnimation(m_animation);
125 } else {
126 } else {
126 m_points = newPoints;
127 m_points = newPoints;
127 updateGeometry();
128 updateGeometry();
128 }
129 }
129 }
130 }
130
131
131 //handlers
132 //handlers
132
133
133 void XYChart::handlePointAdded(int index)
134 void XYChart::handlePointAdded(int index)
134 {
135 {
135 Q_ASSERT(index < m_series->count());
136 Q_ASSERT(index < m_series->count());
136 Q_ASSERT(index >= 0);
137 Q_ASSERT(index >= 0);
137
138
138 QVector<QPointF> points;
139 QVector<QPointF> points;
139
140
140 if (m_dirty) {
141 if (m_dirty) {
141 points = calculateGeometryPoints();
142 points = calculateGeometryPoints();
142 } else {
143 } else {
143 points = m_points;
144 points = m_points;
144 QPointF point = calculateGeometryPoint(index);
145 QPointF point = calculateGeometryPoint(index);
145 points.insert(index, point);
146 points.insert(index, point);
146 }
147 }
147
148
148 updateChart(m_points, points, index);
149 updateChart(m_points, points, index);
149 }
150 }
150
151
151 void XYChart::handlePointRemoved(int index)
152 void XYChart::handlePointRemoved(int index)
152 {
153 {
153 Q_ASSERT(index <= m_series->count());
154 Q_ASSERT(index <= m_series->count());
154 Q_ASSERT(index >= 0);
155 Q_ASSERT(index >= 0);
155
156
156 QVector<QPointF> points;
157 QVector<QPointF> points;
157
158
158 if (m_dirty) {
159 if (m_dirty) {
159 points = calculateGeometryPoints();
160 points = calculateGeometryPoints();
160 } else {
161 } else {
161 points = m_points;
162 points = m_points;
162 points.remove(index);
163 points.remove(index);
163 }
164 }
164
165
165 updateChart(m_points, points, index);
166 updateChart(m_points, points, index);
166 }
167 }
167
168
168 void XYChart::handlePointReplaced(int index)
169 void XYChart::handlePointReplaced(int index)
169 {
170 {
170 Q_ASSERT(index < m_series->count());
171 Q_ASSERT(index < m_series->count());
171 Q_ASSERT(index >= 0);
172 Q_ASSERT(index >= 0);
172
173
173 QVector<QPointF> points;
174 QVector<QPointF> points;
174
175
175 if (m_dirty) {
176 if (m_dirty) {
176 points = calculateGeometryPoints();
177 points = calculateGeometryPoints();
177 } else {
178 } else {
178 QPointF point = calculateGeometryPoint(index);
179 QPointF point = calculateGeometryPoint(index);
179 points = m_points;
180 points = m_points;
180 points.replace(index, point);
181 points.replace(index, point);
181 }
182 }
182
183
183 updateChart(m_points, points, index);
184 updateChart(m_points, points, index);
184 }
185 }
185
186
186 void XYChart::handlePointsReplaced()
187 void XYChart::handlePointsReplaced()
187 {
188 {
188 // All the points were replaced -> recalculate
189 // All the points were replaced -> recalculate
189 QVector<QPointF> points = calculateGeometryPoints();
190 QVector<QPointF> points = calculateGeometryPoints();
190 updateChart(m_points, points, -1);
191 updateChart(m_points, points, -1);
191 }
192 }
192
193
193 void XYChart::handleDomainUpdated()
194 void XYChart::handleDomainUpdated()
194 {
195 {
195 m_minX = domain()->minX();
196 m_minX = domain()->minX();
196 m_maxX = domain()->maxX();
197 m_maxX = domain()->maxX();
197 m_minY = domain()->minY();
198 m_minY = domain()->minY();
198 m_maxY = domain()->maxY();
199 m_maxY = domain()->maxY();
199 if (isEmpty()) return;
200 if (isEmpty()) return;
200
201
201 QVector<QPointF> points = calculateGeometryPoints();
202 QVector<QPointF> points = calculateGeometryPoints();
202
203
203 updateChart(m_points, points);
204 updateChart(m_points, points);
204 }
205 }
205
206
206 void XYChart::handleGeometryChanged(const QRectF &rect)
207 void XYChart::handleGeometryChanged(const QRectF &rect)
207 {
208 {
208 Q_ASSERT(rect.isValid());
209 Q_ASSERT(rect.isValid());
209 m_size = rect.size();
210 m_size = rect.size();
210 m_clipRect = rect.translated(-rect.topLeft());
211 m_clipRect = rect.translated(-rect.topLeft());
211 m_origin = rect.topLeft();
212 m_origin = rect.topLeft();
212
213
213 if (isEmpty()) return;
214 if (isEmpty()) return;
214
215
215 QVector<QPointF> points = calculateGeometryPoints();
216 QVector<QPointF> points = calculateGeometryPoints();
216
217
217 updateChart(m_points, points);
218 updateChart(m_points, points);
218 }
219 }
219
220
220 bool XYChart::isEmpty()
221 bool XYChart::isEmpty()
221 {
222 {
222 return !m_clipRect.isValid() || qFuzzyCompare(m_maxX, m_minX) || qFuzzyCompare(m_maxY, m_minY) || m_series->points().isEmpty();
223 return !m_clipRect.isValid() || qFuzzyCompare(m_maxX, m_minX) || qFuzzyCompare(m_maxY, m_minY) || m_series->points().isEmpty();
223 }
224 }
224
225
225 #include "moc_xychart_p.cpp"
226 #include "moc_xychart_p.cpp"
226
227
227 QTCOMMERCIALCHART_END_NAMESPACE
228 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,106 +1,107
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef XYCHART_H
30 #ifndef XYCHART_H
31 #define XYCHART_H
31 #define XYCHART_H
32
32
33 #include "qchartglobal.h"
33 #include "qchartglobal.h"
34 #include "chartitem_p.h"
34 #include "chartitem_p.h"
35 #include "xyanimation_p.h"
35 #include "xyanimation_p.h"
36 #include "qvalueaxis.h"
36 #include "qvalueaxis.h"
37 #include <QPen>
37 #include <QPen>
38
38
39 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39 QTCOMMERCIALCHART_BEGIN_NAMESPACE
40
40
41 class ChartPresenter;
41 class ChartPresenter;
42 class QXYSeries;
42 class QXYSeries;
43
43
44 class XYChart : public ChartElement
44 class XYChart : public ChartElement
45 {
45 {
46 Q_OBJECT
46 Q_OBJECT
47 public:
47 public:
48 explicit XYChart(QXYSeries *series, ChartPresenter *presenter);
48 explicit XYChart(QXYSeries *series, ChartPresenter *presenter);
49 ~XYChart() {}
49 ~XYChart() {}
50
50
51 void setGeometryPoints(const QVector<QPointF>& points);
51 void setGeometryPoints(const QVector<QPointF>& points);
52 QVector<QPointF> geometryPoints() const { return m_points; }
52 QVector<QPointF> geometryPoints() const { return m_points; }
53
53
54 void setClipRect(const QRectF &rect);
54 void setClipRect(const QRectF &rect);
55 QRectF clipRect() const { return m_clipRect; }
55 QRectF clipRect() const { return m_clipRect; }
56
56
57 QSizeF size() const { return m_size; }
57 QSizeF size() const { return m_size; }
58 QPointF origin() const { return m_origin; }
58 QPointF origin() const { return m_origin; }
59
59
60 void setAnimation(XYAnimation *animation);
60 void setAnimation(XYAnimation *animation);
61 ChartAnimation *animation() const { return m_animation; }
61 ChartAnimation *animation() const { return m_animation; }
62 virtual void updateGeometry() = 0;
62 virtual void updateGeometry() = 0;
63
63
64 bool isDirty() const { return m_dirty; }
64 bool isDirty() const { return m_dirty; }
65 void setDirty(bool dirty);
65 void setDirty(bool dirty);
66
66
67 public Q_SLOTS:
67 public Q_SLOTS:
68 void handlePointAdded(int index);
68 void handlePointAdded(int index);
69 void handlePointRemoved(int index);
69 void handlePointRemoved(int index);
70 void handlePointReplaced(int index);
70 void handlePointReplaced(int index);
71 void handlePointsReplaced();
71 void handlePointsReplaced();
72 void handleDomainUpdated();
72 void handleDomainUpdated();
73 void handleGeometryChanged(const QRectF &size);
73 void handleGeometryChanged(const QRectF &size);
74
74
75 Q_SIGNALS:
75 Q_SIGNALS:
76 void clicked(const QPointF &point);
76 void clicked(const QPointF &point);
77 void hovered(const QPointF &point, bool state);
77
78
78 protected:
79 protected:
79 virtual void updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, int index = -1);
80 virtual void updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, int index = -1);
80 QPointF calculateGeometryPoint(const QPointF &point) const;
81 QPointF calculateGeometryPoint(const QPointF &point) const;
81 QPointF calculateGeometryPoint(int index) const;
82 QPointF calculateGeometryPoint(int index) const;
82 QPointF calculateDomainPoint(const QPointF &point) const;
83 QPointF calculateDomainPoint(const QPointF &point) const;
83 QVector<QPointF> calculateGeometryPoints() const;
84 QVector<QPointF> calculateGeometryPoints() const;
84
85
85 private:
86 private:
86 inline bool isEmpty();
87 inline bool isEmpty();
87
88
88 protected:
89 protected:
89 qreal m_minX;
90 qreal m_minX;
90 qreal m_maxX;
91 qreal m_maxX;
91 qreal m_minY;
92 qreal m_minY;
92 qreal m_maxY;
93 qreal m_maxY;
93 QXYSeries *m_series;
94 QXYSeries *m_series;
94 QSizeF m_size;
95 QSizeF m_size;
95 QPointF m_origin;
96 QPointF m_origin;
96 QRectF m_clipRect;
97 QRectF m_clipRect;
97 QVector<QPointF> m_points;
98 QVector<QPointF> m_points;
98 XYAnimation *m_animation;
99 XYAnimation *m_animation;
99 bool m_dirty;
100 bool m_dirty;
100
101
101 friend class AreaChartItem;
102 friend class AreaChartItem;
102 };
103 };
103
104
104 QTCOMMERCIALCHART_END_NAMESPACE
105 QTCOMMERCIALCHART_END_NAMESPACE
105
106
106 #endif
107 #endif
General Comments 0
You need to be logged in to leave comments. Login now