##// END OF EJS Templates
Removed the visible frame around chart view
Tero Ahola -
r700:4707806c8913
parent child
Show More
@@ -1,402 +1,403
1 #include "qchartview.h"
1 #include "qchartview.h"
2 #include "qchart.h"
2 #include "qchart.h"
3 #include "qchartaxis.h"
3 #include "qchartaxis.h"
4 #include <QGraphicsView>
4 #include <QGraphicsView>
5 #include <QGraphicsScene>
5 #include <QGraphicsScene>
6 #include <QRubberBand>
6 #include <QRubberBand>
7 #include <QResizeEvent>
7 #include <QResizeEvent>
8 #include <QDebug>
8 #include <QDebug>
9
9
10 /*!
10 /*!
11 \enum QChartView::RubberBandPolicy
11 \enum QChartView::RubberBandPolicy
12
12
13 This enum describes the different types of rubber bands that can be used for zoom rect selection
13 This enum describes the different types of rubber bands that can be used for zoom rect selection
14
14
15 \value NoRubberBand
15 \value NoRubberBand
16 \value VerticalRubberBand
16 \value VerticalRubberBand
17 \value HorizonalRubberBand
17 \value HorizonalRubberBand
18 \value RectangleRubberBand
18 \value RectangleRubberBand
19 */
19 */
20
20
21 /*!
21 /*!
22 \class QChartView
22 \class QChartView
23 \brief Standalone charting widget.
23 \brief Standalone charting widget.
24
24
25 QChartView is a standalone widget that can display charts. It does not require separate
25 QChartView is a standalone widget that can display charts. It does not require separate
26 QGraphicsScene to work. It manages the graphical representation of different types of
26 QGraphicsScene to work. It manages the graphical representation of different types of
27 QChartSeries and other chart related objects like QChartAxis and QChartLegend. If you want to
27 QChartSeries and other chart related objects like QChartAxis and QChartLegend. If you want to
28 display a chart in your existing QGraphicsScene, you can use the QChart class instead.
28 display a chart in your existing QGraphicsScene, you can use the QChart class instead.
29
29
30 \sa QChart
30 \sa QChart
31 */
31 */
32
32
33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34
34
35 /*!
35 /*!
36 Constructs a chartView object which is a child of a\a parent.
36 Constructs a chartView object which is a child of a\a parent.
37 */
37 */
38 QChartView::QChartView(QWidget *parent) :
38 QChartView::QChartView(QWidget *parent) :
39 QGraphicsView(parent),
39 QGraphicsView(parent),
40 m_scene(new QGraphicsScene(this)),
40 m_scene(new QGraphicsScene(this)),
41 m_chart(new QChart()),
41 m_chart(new QChart()),
42 m_rubberBand(0),
42 m_rubberBand(0),
43 m_verticalRubberBand(false),
43 m_verticalRubberBand(false),
44 m_horizonalRubberBand(false)
44 m_horizonalRubberBand(false)
45 {
45 {
46 setFrameShape(QFrame::NoFrame);
46 setBackgroundRole(QPalette::Window);
47 setBackgroundRole(QPalette::Window);
47 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
48 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
48 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
49 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
49 setScene(m_scene);
50 setScene(m_scene);
50 m_scene->addItem(m_chart);
51 m_scene->addItem(m_chart);
51 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
52 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
52 }
53 }
53
54
54
55
55 /*!
56 /*!
56 Destroys the object and it's children, like QChartSeries and QChartAxis object added to it.
57 Destroys the object and it's children, like QChartSeries and QChartAxis object added to it.
57 */
58 */
58 QChartView::~QChartView()
59 QChartView::~QChartView()
59 {
60 {
60 }
61 }
61
62
62 /*!
63 /*!
63 Resizes and updates the chart area using the \a event data
64 Resizes and updates the chart area using the \a event data
64 */
65 */
65 void QChartView::resizeEvent(QResizeEvent *event)
66 void QChartView::resizeEvent(QResizeEvent *event)
66 {
67 {
67 // If the scene rect is the size of the view, you will get scrolling effect at least on OSX;
68 // If the scene rect is the size of the view, you will get scrolling effect at least on OSX;
68 // i.e. you are able to move the chart inside the view a couple of pixels by mouse flicking
69 // i.e. you are able to move the chart inside the view a couple of pixels by mouse flicking
69 m_scene->setSceneRect(0, 0, size().width() - 2, size().height() - 2);
70 m_scene->setSceneRect(0, 0, size().width() - 2, size().height() - 2);
70 m_chart->resize(size());
71 m_chart->resize(size());
71 QWidget::resizeEvent(event);
72 QWidget::resizeEvent(event);
72 }
73 }
73
74
74 /*!
75 /*!
75 Adds the \a series and optional \a axisY onto the chart and takes the ownership of the objects.
76 Adds the \a series and optional \a axisY onto the chart and takes the ownership of the objects.
76 If auto scaling is enabled, re-scales the axes the series is bound to (both the x axis and
77 If auto scaling is enabled, re-scales the axes the series is bound to (both the x axis and
77 the y axis).
78 the y axis).
78 \sa removeSeries(), removeAllSeries()
79 \sa removeSeries(), removeAllSeries()
79 */
80 */
80 void QChartView::addSeries(QSeries* series,QChartAxis *axisY)
81 void QChartView::addSeries(QSeries* series,QChartAxis *axisY)
81 {
82 {
82 m_chart->addSeries(series,axisY);
83 m_chart->addSeries(series,axisY);
83 }
84 }
84
85
85 /*!
86 /*!
86 Removes the \a series specified in a perameter from the QChartView.
87 Removes the \a series specified in a perameter from the QChartView.
87 It releses its ownership of the specified QChartSeries object.
88 It releses its ownership of the specified QChartSeries object.
88 It does not delete the pointed QChartSeries data object
89 It does not delete the pointed QChartSeries data object
89 \sa addSeries(), removeAllSeries()
90 \sa addSeries(), removeAllSeries()
90 */
91 */
91 void QChartView::removeSeries(QSeries* series)
92 void QChartView::removeSeries(QSeries* series)
92 {
93 {
93 m_chart->removeSeries(series);
94 m_chart->removeSeries(series);
94 }
95 }
95
96
96 /*!
97 /*!
97 Removes all the QChartSeries that have been added to the QChartView
98 Removes all the QChartSeries that have been added to the QChartView
98 It also deletes the pointed QChartSeries data objects
99 It also deletes the pointed QChartSeries data objects
99 \sa addSeries(), removeSeries()
100 \sa addSeries(), removeSeries()
100 */
101 */
101 void QChartView::removeAllSeries()
102 void QChartView::removeAllSeries()
102 {
103 {
103 m_chart->removeAllSeries();
104 m_chart->removeAllSeries();
104 }
105 }
105
106
106 /*!
107 /*!
107 Zooms in the view by a factor of 2
108 Zooms in the view by a factor of 2
108 */
109 */
109 void QChartView::zoomIn()
110 void QChartView::zoomIn()
110 {
111 {
111 m_chart->zoomIn();
112 m_chart->zoomIn();
112 }
113 }
113
114
114 /*!
115 /*!
115 Zooms in the view to a maximum level at which \a rect is still fully visible.
116 Zooms in the view to a maximum level at which \a rect is still fully visible.
116 */
117 */
117 void QChartView::zoomIn(const QRect& rect)
118 void QChartView::zoomIn(const QRect& rect)
118 {
119 {
119 m_chart->zoomIn(rect);
120 m_chart->zoomIn(rect);
120 }
121 }
121
122
122 /*!
123 /*!
123 Restores the view zoom level to the previous one.
124 Restores the view zoom level to the previous one.
124 */
125 */
125 void QChartView::zoomOut()
126 void QChartView::zoomOut()
126 {
127 {
127 m_chart->zoomOut();
128 m_chart->zoomOut();
128 }
129 }
129
130
130 /*!
131 /*!
131 Sets the chart \a title. A description text that is drawn above the chart.
132 Sets the chart \a title. A description text that is drawn above the chart.
132 */
133 */
133 void QChartView::setChartTitle(const QString& title)
134 void QChartView::setChartTitle(const QString& title)
134 {
135 {
135 m_chart->setTitle(title);
136 m_chart->setTitle(title);
136 }
137 }
137
138
138 /*!
139 /*!
139 Returns the chart's title. A description text that is drawn above the chart.
140 Returns the chart's title. A description text that is drawn above the chart.
140 */
141 */
141 QString QChartView::chartTitle() const
142 QString QChartView::chartTitle() const
142 {
143 {
143 return m_chart->title();
144 return m_chart->title();
144 }
145 }
145
146
146 /*!
147 /*!
147 Sets the \a font that is used for rendering the description text that is rendered above the chart.
148 Sets the \a font that is used for rendering the description text that is rendered above the chart.
148 */
149 */
149 void QChartView::setChartTitleFont(const QFont& font)
150 void QChartView::setChartTitleFont(const QFont& font)
150 {
151 {
151 m_chart->setTitleFont(font);
152 m_chart->setTitleFont(font);
152 }
153 }
153
154
154 /*!
155 /*!
155 Sets the \a brush used for rendering the title text.
156 Sets the \a brush used for rendering the title text.
156 */
157 */
157 void QChartView::setChartTitleBrush(const QBrush &brush)
158 void QChartView::setChartTitleBrush(const QBrush &brush)
158 {
159 {
159 m_chart->setTitleBrush(brush);
160 m_chart->setTitleBrush(brush);
160 }
161 }
161
162
162 /*!
163 /*!
163 Returns the brush used for rendering the title text.
164 Returns the brush used for rendering the title text.
164 */
165 */
165 QBrush QChartView::chartTitleBrush()
166 QBrush QChartView::chartTitleBrush()
166 {
167 {
167 return m_chart->titleBrush();
168 return m_chart->titleBrush();
168 }
169 }
169
170
170 /*!
171 /*!
171 Sets the \a brush that is used for painting the background of the chart area of the QChartView widget.
172 Sets the \a brush that is used for painting the background of the chart area of the QChartView widget.
172 */
173 */
173 void QChartView::setChartBackgroundBrush(const QBrush& brush)
174 void QChartView::setChartBackgroundBrush(const QBrush& brush)
174 {
175 {
175 m_chart->setBackgroundBrush(brush);
176 m_chart->setBackgroundBrush(brush);
176 }
177 }
177
178
178 /*!
179 /*!
179 Sets the \a pen that is used for painting the background of the chart area of the QChartView widget.
180 Sets the \a pen that is used for painting the background of the chart area of the QChartView widget.
180 */
181 */
181 void QChartView::setChartBackgroundPen(const QPen& pen)
182 void QChartView::setChartBackgroundPen(const QPen& pen)
182 {
183 {
183 m_chart->setBackgroundPen(pen);
184 m_chart->setBackgroundPen(pen);
184 }
185 }
185
186
186 /*!
187 /*!
187 Sets the RubberBandPlicy to \a policy. Selected policy determines the way zooming is performed.
188 Sets the RubberBandPlicy to \a policy. Selected policy determines the way zooming is performed.
188 */
189 */
189 void QChartView::setRubberBandPolicy(const RubberBandPolicy policy)
190 void QChartView::setRubberBandPolicy(const RubberBandPolicy policy)
190 {
191 {
191 switch(policy) {
192 switch(policy) {
192 case VerticalRubberBand:
193 case VerticalRubberBand:
193 m_verticalRubberBand = true;
194 m_verticalRubberBand = true;
194 m_horizonalRubberBand = false;
195 m_horizonalRubberBand = false;
195 break;
196 break;
196 case HorizonalRubberBand:
197 case HorizonalRubberBand:
197 m_verticalRubberBand = false;
198 m_verticalRubberBand = false;
198 m_horizonalRubberBand = true;
199 m_horizonalRubberBand = true;
199 break;
200 break;
200 case RectangleRubberBand:
201 case RectangleRubberBand:
201 m_verticalRubberBand = true;
202 m_verticalRubberBand = true;
202 m_horizonalRubberBand = true;
203 m_horizonalRubberBand = true;
203 break;
204 break;
204 case NoRubberBand:
205 case NoRubberBand:
205 default:
206 default:
206 delete m_rubberBand;
207 delete m_rubberBand;
207 m_rubberBand=0;
208 m_rubberBand=0;
208 m_horizonalRubberBand = false;
209 m_horizonalRubberBand = false;
209 m_verticalRubberBand = false;
210 m_verticalRubberBand = false;
210 return;
211 return;
211 }
212 }
212 if(!m_rubberBand) {
213 if(!m_rubberBand) {
213 m_rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
214 m_rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
214 m_rubberBand->setEnabled(true);
215 m_rubberBand->setEnabled(true);
215 }
216 }
216 }
217 }
217
218
218 /*!
219 /*!
219 Returns the RubberBandPolicy that is currently being used by the widget.
220 Returns the RubberBandPolicy that is currently being used by the widget.
220 */
221 */
221 QChartView::RubberBandPolicy QChartView::rubberBandPolicy() const
222 QChartView::RubberBandPolicy QChartView::rubberBandPolicy() const
222 {
223 {
223 if(m_horizonalRubberBand && m_verticalRubberBand) return RectangleRubberBand;
224 if(m_horizonalRubberBand && m_verticalRubberBand) return RectangleRubberBand;
224 if(m_horizonalRubberBand) return HorizonalRubberBand;
225 if(m_horizonalRubberBand) return HorizonalRubberBand;
225 if(m_verticalRubberBand) return VerticalRubberBand;
226 if(m_verticalRubberBand) return VerticalRubberBand;
226 return NoRubberBand;
227 return NoRubberBand;
227 }
228 }
228
229
229 /*!
230 /*!
230 If Left mouse button is pressed and the RubberBandPolicy is enabled the \a event is accepted and the rubber band is displayed on the screen allowing the user to select the zoom area.
231 If Left mouse button is pressed and the RubberBandPolicy is enabled the \a event is accepted and the rubber band is displayed on the screen allowing the user to select the zoom area.
231 If different mouse button is pressed and/or the RubberBandPolicy is disabled then the \a event is passed to QGraphicsView::mousePressEvent() implementation.
232 If different mouse button is pressed and/or the RubberBandPolicy is disabled then the \a event is passed to QGraphicsView::mousePressEvent() implementation.
232 */
233 */
233 void QChartView::mousePressEvent(QMouseEvent *event)
234 void QChartView::mousePressEvent(QMouseEvent *event)
234 {
235 {
235 if(m_rubberBand && m_rubberBand->isEnabled() && event->button() == Qt::LeftButton) {
236 if(m_rubberBand && m_rubberBand->isEnabled() && event->button() == Qt::LeftButton) {
236
237
237 int padding = m_chart->padding();
238 int padding = m_chart->padding();
238 QRect rect(padding, padding, width() - 2 * padding, height() - 2 * padding);
239 QRect rect(padding, padding, width() - 2 * padding, height() - 2 * padding);
239
240
240 if (rect.contains(event->pos())) {
241 if (rect.contains(event->pos())) {
241 m_rubberBandOrigin = event->pos();
242 m_rubberBandOrigin = event->pos();
242 m_rubberBand->setGeometry(QRect(m_rubberBandOrigin, QSize()));
243 m_rubberBand->setGeometry(QRect(m_rubberBandOrigin, QSize()));
243 m_rubberBand->show();
244 m_rubberBand->show();
244 event->accept();
245 event->accept();
245 }
246 }
246 }
247 }
247 else {
248 else {
248 QGraphicsView::mousePressEvent(event);
249 QGraphicsView::mousePressEvent(event);
249 }
250 }
250 }
251 }
251
252
252 /*!
253 /*!
253 If RubberBand rectange specification has been initiated in pressEvent then \a event data is used to update RubberBand geometry.
254 If RubberBand rectange specification has been initiated in pressEvent then \a event data is used to update RubberBand geometry.
254 In other case the defualt QGraphicsView::mouseMoveEvent implementation is called.
255 In other case the defualt QGraphicsView::mouseMoveEvent implementation is called.
255 */
256 */
256 void QChartView::mouseMoveEvent(QMouseEvent *event)
257 void QChartView::mouseMoveEvent(QMouseEvent *event)
257 {
258 {
258 if(m_rubberBand && m_rubberBand->isVisible()) {
259 if(m_rubberBand && m_rubberBand->isVisible()) {
259 int padding = m_chart->padding();
260 int padding = m_chart->padding();
260 QRect rect(padding, padding, width() - 2 * padding, height() - 2 * padding);
261 QRect rect(padding, padding, width() - 2 * padding, height() - 2 * padding);
261 int width = event->pos().x() - m_rubberBandOrigin.x();
262 int width = event->pos().x() - m_rubberBandOrigin.x();
262 int height = event->pos().y() - m_rubberBandOrigin.y();
263 int height = event->pos().y() - m_rubberBandOrigin.y();
263 if(!m_verticalRubberBand) {
264 if(!m_verticalRubberBand) {
264 m_rubberBandOrigin.setY(rect.top());
265 m_rubberBandOrigin.setY(rect.top());
265 height = rect.height();
266 height = rect.height();
266 }
267 }
267 if(!m_horizonalRubberBand) {
268 if(!m_horizonalRubberBand) {
268 m_rubberBandOrigin.setX(rect.left());
269 m_rubberBandOrigin.setX(rect.left());
269 width= rect.width();
270 width= rect.width();
270 }
271 }
271 m_rubberBand->setGeometry(QRect(m_rubberBandOrigin.x(),m_rubberBandOrigin.y(), width,height).normalized());
272 m_rubberBand->setGeometry(QRect(m_rubberBandOrigin.x(),m_rubberBandOrigin.y(), width,height).normalized());
272 }
273 }
273 else {
274 else {
274 QGraphicsView::mouseMoveEvent(event);
275 QGraphicsView::mouseMoveEvent(event);
275 }
276 }
276 }
277 }
277
278
278 /*!
279 /*!
279 If left mouse button is release and RubberBand is enabled then \a event is accepted and the view is zoomed in to rect specified by RubberBand
280 If left mouse button is release and RubberBand is enabled then \a event is accepted and the view is zoomed in to rect specified by RubberBand
280 If it is the right mouse button \a event then RubberBand is dissmissed and zoom is canceled.
281 If it is the right mouse button \a event then RubberBand is dissmissed and zoom is canceled.
281 */
282 */
282 void QChartView::mouseReleaseEvent(QMouseEvent *event)
283 void QChartView::mouseReleaseEvent(QMouseEvent *event)
283 {
284 {
284 if(m_rubberBand) {
285 if(m_rubberBand) {
285 if (event->button() == Qt::LeftButton && m_rubberBand->isVisible()) {
286 if (event->button() == Qt::LeftButton && m_rubberBand->isVisible()) {
286 m_rubberBand->hide();
287 m_rubberBand->hide();
287 QRect rect = m_rubberBand->geometry();
288 QRect rect = m_rubberBand->geometry();
288 m_chart->zoomIn(rect);
289 m_chart->zoomIn(rect);
289 event->accept();
290 event->accept();
290 }
291 }
291
292
292 if(event->button()==Qt::RightButton){
293 if(event->button()==Qt::RightButton){
293 m_chart->zoomOut();
294 m_chart->zoomOut();
294 event->accept();
295 event->accept();
295 }
296 }
296 }
297 }
297 else {
298 else {
298 QGraphicsView::mouseReleaseEvent(event);
299 QGraphicsView::mouseReleaseEvent(event);
299 }
300 }
300 }
301 }
301
302
302 /*!
303 /*!
303 Pressing + and - keys performs zoomIn() and zoomOut() respectivly.
304 Pressing + and - keys performs zoomIn() and zoomOut() respectivly.
304 In other \a event is passed to the QGraphicsView::keyPressEvent() implementation
305 In other \a event is passed to the QGraphicsView::keyPressEvent() implementation
305 */
306 */
306 void QChartView::keyPressEvent(QKeyEvent *event)
307 void QChartView::keyPressEvent(QKeyEvent *event)
307 {
308 {
308 switch (event->key()) {
309 switch (event->key()) {
309 case Qt::Key_Plus:
310 case Qt::Key_Plus:
310 zoomIn();
311 zoomIn();
311 break;
312 break;
312 case Qt::Key_Minus:
313 case Qt::Key_Minus:
313 zoomOut();
314 zoomOut();
314 break;
315 break;
315 default:
316 default:
316 QGraphicsView::keyPressEvent(event);
317 QGraphicsView::keyPressEvent(event);
317 break;
318 break;
318 }
319 }
319 }
320 }
320
321
321 /*!
322 /*!
322 Sets the \a theme used by the chart for rendering the graphical representation of the data
323 Sets the \a theme used by the chart for rendering the graphical representation of the data
323 \sa QChart::ChartTheme, chartTheme()
324 \sa QChart::ChartTheme, chartTheme()
324 */
325 */
325 void QChartView::setChartTheme(QChart::ChartTheme theme)
326 void QChartView::setChartTheme(QChart::ChartTheme theme)
326 {
327 {
327 m_chart->setChartTheme(theme);
328 m_chart->setChartTheme(theme);
328 }
329 }
329
330
330 /*!
331 /*!
331 Returns the theme enum used by the chart.
332 Returns the theme enum used by the chart.
332 \sa setChartTheme()
333 \sa setChartTheme()
333 */
334 */
334 QChart::ChartTheme QChartView::chartTheme() const
335 QChart::ChartTheme QChartView::chartTheme() const
335 {
336 {
336 return m_chart->chartTheme();
337 return m_chart->chartTheme();
337 }
338 }
338
339
339 /*!
340 /*!
340 Returns the pointer to the x axis object of the chart
341 Returns the pointer to the x axis object of the chart
341 */
342 */
342 QChartAxis* QChartView::axisX() const
343 QChartAxis* QChartView::axisX() const
343 {
344 {
344 return m_chart->axisX();
345 return m_chart->axisX();
345 }
346 }
346
347
347 /*!
348 /*!
348 Returns the pointer to the y axis object of the chart
349 Returns the pointer to the y axis object of the chart
349 */
350 */
350 QChartAxis* QChartView::axisY() const
351 QChartAxis* QChartView::axisY() const
351 {
352 {
352 return m_chart->axisY();
353 return m_chart->axisY();
353 }
354 }
354
355
355 /*!
356 /*!
356 Returns the pointer to legend object of the chart
357 Returns the pointer to legend object of the chart
357 */
358 */
358 QLegend* QChartView::legend() const
359 QLegend* QChartView::legend() const
359 {
360 {
360 return m_chart->legend();
361 return m_chart->legend();
361 }
362 }
362
363
363 /*!
364 /*!
364 Sets animation \a options for the chart
365 Sets animation \a options for the chart
365 */
366 */
366 void QChartView::setAnimationOptions(QChart::AnimationOptions options)
367 void QChartView::setAnimationOptions(QChart::AnimationOptions options)
367 {
368 {
368 m_chart->setAnimationOptions(options);
369 m_chart->setAnimationOptions(options);
369 }
370 }
370
371
371 /*!
372 /*!
372 Returns animation options for the chart
373 Returns animation options for the chart
373 */
374 */
374 QChart::AnimationOptions QChartView::animationOptions() const
375 QChart::AnimationOptions QChartView::animationOptions() const
375 {
376 {
376 return m_chart->animationOptions();
377 return m_chart->animationOptions();
377 }
378 }
378
379
379 void QChartView::scrollLeft()
380 void QChartView::scrollLeft()
380 {
381 {
381 m_chart->scrollLeft();
382 m_chart->scrollLeft();
382 }
383 }
383
384
384 void QChartView::scrollRight()
385 void QChartView::scrollRight()
385 {
386 {
386 m_chart->scrollRight();
387 m_chart->scrollRight();
387 }
388 }
388
389
389 void QChartView::scrollUp()
390 void QChartView::scrollUp()
390 {
391 {
391 m_chart->scrollUp();
392 m_chart->scrollUp();
392 }
393 }
393
394
394 void QChartView::scrollDown()
395 void QChartView::scrollDown()
395 {
396 {
396 m_chart->scrollDown();
397 m_chart->scrollDown();
397 }
398 }
398
399
399
400
400 #include "moc_qchartview.cpp"
401 #include "moc_qchartview.cpp"
401
402
402 QTCOMMERCIALCHART_END_NAMESPACE
403 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now