##// END OF EJS Templates
Revert previous change to LineChartItem...
Titta Heikkala -
r2818:d27e6a35ae04
parent child
Show More
@@ -1,438 +1,441
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2015 The Qt Company Ltd
4 4 ** All rights reserved.
5 5 ** For any questions to The Qt Company, please use contact form at http://qt.io
6 6 **
7 7 ** This file is part of the Qt Charts module.
8 8 **
9 9 ** Licensees holding valid commercial license for Qt may use this file in
10 10 ** accordance with the Qt License Agreement provided with the Software
11 11 ** or, alternatively, in accordance with the terms contained in a written
12 12 ** agreement between you and The Qt Company.
13 13 **
14 14 ** If you have questions regarding the use of this file, please use
15 15 ** contact form at http://qt.io
16 16 **
17 17 ****************************************************************************/
18 18
19 19 #include <private/linechartitem_p.h>
20 20 #include <QtCharts/QLineSeries>
21 21 #include <private/qlineseries_p.h>
22 22 #include <private/chartpresenter_p.h>
23 23 #include <private/polardomain_p.h>
24 24 #include <private/chartthememanager_p.h>
25 25 #include <private/charttheme_p.h>
26 26 #include <QtGui/QPainter>
27 27 #include <QtWidgets/QGraphicsSceneMouseEvent>
28 28
29 29 QT_CHARTS_BEGIN_NAMESPACE
30 30
31 31 const qreal mouseEventMinWidth(12);
32 32
33 33 LineChartItem::LineChartItem(QLineSeries *series, QGraphicsItem *item)
34 34 : XYChart(series,item),
35 35 m_series(series),
36 36 m_pointsVisible(false),
37 37 m_chartType(QChart::ChartTypeUndefined),
38 38 m_pointLabelsVisible(false),
39 39 m_pointLabelsFormat(series->pointLabelsFormat()),
40 40 m_pointLabelsFont(series->pointLabelsFont()),
41 41 m_pointLabelsColor(series->pointLabelsColor()),
42 42 m_pointLabelsClipping(true),
43 43 m_mousePressed(false)
44 44 {
45 45 setAcceptHoverEvents(true);
46 46 setFlag(QGraphicsItem::ItemIsSelectable);
47 47 setZValue(ChartPresenter::LineChartZValue);
48 48 QObject::connect(series->d_func(), SIGNAL(updated()), this, SLOT(handleUpdated()));
49 49 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
50 50 QObject::connect(series, SIGNAL(opacityChanged()), this, SLOT(handleUpdated()));
51 51 QObject::connect(series, SIGNAL(pointLabelsFormatChanged(QString)),
52 52 this, SLOT(handleUpdated()));
53 53 QObject::connect(series, SIGNAL(pointLabelsVisibilityChanged(bool)),
54 54 this, SLOT(handleUpdated()));
55 55 QObject::connect(series, SIGNAL(pointLabelsFontChanged(QFont)), this, SLOT(handleUpdated()));
56 56 QObject::connect(series, SIGNAL(pointLabelsColorChanged(QColor)), this, SLOT(handleUpdated()));
57 57 QObject::connect(series, SIGNAL(pointLabelsClippingChanged(bool)), this, SLOT(handleUpdated()));
58 58 handleUpdated();
59 59 }
60 60
61 61 QRectF LineChartItem::boundingRect() const
62 62 {
63 63 return m_rect;
64 64 }
65 65
66 66 QPainterPath LineChartItem::shape() const
67 67 {
68 68 return m_shapePath;
69 69 }
70 70
71 71 void LineChartItem::updateGeometry()
72 72 {
73 const QVector<QPointF> &points = geometryPoints();
73 // Store the points to a local variable so that the old line gets properly cleared
74 // when animation starts.
75 m_linePoints = geometryPoints();
76 const QVector<QPointF> &points = m_linePoints;
74 77
75 78 if (points.size() == 0) {
76 79 prepareGeometryChange();
77 80 m_fullPath = QPainterPath();
78 81 m_linePath = QPainterPath();
79 82 m_rect = QRect();
80 83 return;
81 84 }
82 85
83 86 QPainterPath linePath;
84 87 QPainterPath fullPath;
85 88 // Use worst case scenario to determine required margin.
86 89 qreal margin = m_linePen.width() * 1.42;
87 90
88 91 // Area series use component line series that aren't necessarily added to the chart themselves,
89 92 // so check if chart type is forced before trying to obtain it from the chart.
90 93 QChart::ChartType chartType = m_chartType;
91 94 if (chartType == QChart::ChartTypeUndefined)
92 95 chartType = m_series->chart()->chartType();
93 96
94 97 // For polar charts, we need special handling for angular (horizontal)
95 98 // points that are off-grid.
96 99 if (chartType == QChart::ChartTypePolar) {
97 100 QPainterPath linePathLeft;
98 101 QPainterPath linePathRight;
99 102 QPainterPath *currentSegmentPath = 0;
100 103 QPainterPath *previousSegmentPath = 0;
101 104 qreal minX = domain()->minX();
102 105 qreal maxX = domain()->maxX();
103 106 qreal minY = domain()->minY();
104 107 QPointF currentSeriesPoint = m_series->at(0);
105 108 QPointF currentGeometryPoint = points.at(0);
106 109 QPointF previousGeometryPoint = points.at(0);
107 110 int size = m_linePen.width();
108 111 bool pointOffGrid = false;
109 112 bool previousPointWasOffGrid = (currentSeriesPoint.x() < minX || currentSeriesPoint.x() > maxX);
110 113
111 114 qreal domainRadius = domain()->size().height() / 2.0;
112 115 const QPointF centerPoint(domainRadius, domainRadius);
113 116
114 117 if (!previousPointWasOffGrid) {
115 118 fullPath.moveTo(points.at(0));
116 119 if (m_pointsVisible && currentSeriesPoint.y() >= minY) {
117 120 // Do not draw ellipses for points below minimum Y.
118 121 linePath.addEllipse(points.at(0), size, size);
119 122 fullPath.addEllipse(points.at(0), size, size);
120 123 linePath.moveTo(points.at(0));
121 124 fullPath.moveTo(points.at(0));
122 125 }
123 126 }
124 127
125 128 qreal leftMarginLine = centerPoint.x() - margin;
126 129 qreal rightMarginLine = centerPoint.x() + margin;
127 130 qreal horizontal = centerPoint.y();
128 131
129 132 // See ScatterChartItem::updateGeometry() for explanation why seriesLastIndex is needed
130 133 const int seriesLastIndex = m_series->count() - 1;
131 134
132 135 for (int i = 1; i < points.size(); i++) {
133 136 // Interpolating line fragments would be ugly when thick pen is used,
134 137 // so we work around it by utilizing three separate
135 138 // paths for line segments and clip those with custom regions at paint time.
136 139 // "Right" path contains segments that cross the axis line with visible point on the
137 140 // right side of the axis line, as well as segments that have one point within the margin
138 141 // on the right side of the axis line and another point on the right side of the chart.
139 142 // "Left" path contains points with similarly on the left side.
140 143 // "Full" path contains rest of the points.
141 144 // This doesn't yield perfect results always. E.g. when segment covers more than 90
142 145 // degrees and both of the points are within the margin, one in the top half and one in the
143 146 // bottom half of the chart, the bottom one gets clipped incorrectly.
144 147 // However, this should be rare occurrence in any sensible chart.
145 148 currentSeriesPoint = m_series->at(qMin(seriesLastIndex, i));
146 149 currentGeometryPoint = points.at(i);
147 150 pointOffGrid = (currentSeriesPoint.x() < minX || currentSeriesPoint.x() > maxX);
148 151
149 152 // Draw something unless both off-grid
150 153 if (!pointOffGrid || !previousPointWasOffGrid) {
151 154 QPointF intersectionPoint;
152 155 qreal y;
153 156 if (pointOffGrid != previousPointWasOffGrid) {
154 157 if (currentGeometryPoint.x() == previousGeometryPoint.x()) {
155 158 y = currentGeometryPoint.y() + (currentGeometryPoint.y() - previousGeometryPoint.y()) / 2.0;
156 159 } else {
157 160 qreal ratio = (centerPoint.x() - currentGeometryPoint.x()) / (currentGeometryPoint.x() - previousGeometryPoint.x());
158 161 y = currentGeometryPoint.y() + (currentGeometryPoint.y() - previousGeometryPoint.y()) * ratio;
159 162 }
160 163 intersectionPoint = QPointF(centerPoint.x(), y);
161 164 }
162 165
163 166 bool dummyOk; // We know points are ok, but this is needed
164 167 qreal currentAngle = 0;
165 168 qreal previousAngle = 0;
166 169 if (const PolarDomain *pd = qobject_cast<const PolarDomain *>(domain())) {
167 170 currentAngle = pd->toAngularCoordinate(currentSeriesPoint.x(), dummyOk);
168 171 previousAngle = pd->toAngularCoordinate(m_series->at(i - 1).x(), dummyOk);
169 172 } else {
170 173 qWarning() << Q_FUNC_INFO << "Unexpected domain: " << domain();
171 174 }
172 175 if ((qAbs(currentAngle - previousAngle) > 180.0)) {
173 176 // If the angle between two points is over 180 degrees (half X range),
174 177 // any direct segment between them becomes meaningless.
175 178 // In this case two line segments are drawn instead, from previous
176 179 // point to the center and from center to current point.
177 180 if ((previousAngle < 0.0 || (previousAngle <= 180.0 && previousGeometryPoint.x() < rightMarginLine))
178 181 && previousGeometryPoint.y() < horizontal) {
179 182 currentSegmentPath = &linePathRight;
180 183 } else if ((previousAngle > 360.0 || (previousAngle > 180.0 && previousGeometryPoint.x() > leftMarginLine))
181 184 && previousGeometryPoint.y() < horizontal) {
182 185 currentSegmentPath = &linePathLeft;
183 186 } else if (previousAngle > 0.0 && previousAngle < 360.0) {
184 187 currentSegmentPath = &linePath;
185 188 } else {
186 189 currentSegmentPath = 0;
187 190 }
188 191
189 192 if (currentSegmentPath) {
190 193 if (previousSegmentPath != currentSegmentPath)
191 194 currentSegmentPath->moveTo(previousGeometryPoint);
192 195 if (previousPointWasOffGrid)
193 196 fullPath.moveTo(intersectionPoint);
194 197
195 198 currentSegmentPath->lineTo(centerPoint);
196 199 fullPath.lineTo(centerPoint);
197 200 }
198 201
199 202 previousSegmentPath = currentSegmentPath;
200 203
201 204 if ((currentAngle < 0.0 || (currentAngle <= 180.0 && currentGeometryPoint.x() < rightMarginLine))
202 205 && currentGeometryPoint.y() < horizontal) {
203 206 currentSegmentPath = &linePathRight;
204 207 } else if ((currentAngle > 360.0 || (currentAngle > 180.0 &&currentGeometryPoint.x() > leftMarginLine))
205 208 && currentGeometryPoint.y() < horizontal) {
206 209 currentSegmentPath = &linePathLeft;
207 210 } else if (currentAngle > 0.0 && currentAngle < 360.0) {
208 211 currentSegmentPath = &linePath;
209 212 } else {
210 213 currentSegmentPath = 0;
211 214 }
212 215
213 216 if (currentSegmentPath) {
214 217 if (previousSegmentPath != currentSegmentPath)
215 218 currentSegmentPath->moveTo(centerPoint);
216 219 if (!previousSegmentPath)
217 220 fullPath.moveTo(centerPoint);
218 221
219 222 currentSegmentPath->lineTo(currentGeometryPoint);
220 223 if (pointOffGrid)
221 224 fullPath.lineTo(intersectionPoint);
222 225 else
223 226 fullPath.lineTo(currentGeometryPoint);
224 227 }
225 228 } else {
226 229 if (previousAngle < 0.0 || currentAngle < 0.0
227 230 || ((previousAngle <= 180.0 && currentAngle <= 180.0)
228 231 && ((previousGeometryPoint.x() < rightMarginLine && previousGeometryPoint.y() < horizontal)
229 232 || (currentGeometryPoint.x() < rightMarginLine && currentGeometryPoint.y() < horizontal)))) {
230 233 currentSegmentPath = &linePathRight;
231 234 } else if (previousAngle > 360.0 || currentAngle > 360.0
232 235 || ((previousAngle > 180.0 && currentAngle > 180.0)
233 236 && ((previousGeometryPoint.x() > leftMarginLine && previousGeometryPoint.y() < horizontal)
234 237 || (currentGeometryPoint.x() > leftMarginLine && currentGeometryPoint.y() < horizontal)))) {
235 238 currentSegmentPath = &linePathLeft;
236 239 } else {
237 240 currentSegmentPath = &linePath;
238 241 }
239 242
240 243 if (currentSegmentPath != previousSegmentPath)
241 244 currentSegmentPath->moveTo(previousGeometryPoint);
242 245 if (previousPointWasOffGrid)
243 246 fullPath.moveTo(intersectionPoint);
244 247
245 248 if (pointOffGrid)
246 249 fullPath.lineTo(intersectionPoint);
247 250 else
248 251 fullPath.lineTo(currentGeometryPoint);
249 252 currentSegmentPath->lineTo(currentGeometryPoint);
250 253 }
251 254 } else {
252 255 currentSegmentPath = 0;
253 256 }
254 257
255 258 previousPointWasOffGrid = pointOffGrid;
256 259 if (m_pointsVisible && !pointOffGrid && currentSeriesPoint.y() >= minY) {
257 260 linePath.addEllipse(points.at(i), size, size);
258 261 fullPath.addEllipse(points.at(i), size, size);
259 262 linePath.moveTo(points.at(i));
260 263 fullPath.moveTo(points.at(i));
261 264 }
262 265 previousSegmentPath = currentSegmentPath;
263 266 previousGeometryPoint = currentGeometryPoint;
264 267 }
265 268 m_linePathPolarRight = linePathRight;
266 269 m_linePathPolarLeft = linePathLeft;
267 270 // Note: This construction of m_fullpath is not perfect. The partial segments that are
268 271 // outside left/right clip regions at axis boundary still generate hover/click events,
269 272 // because shape doesn't get clipped. It doesn't seem possible to do sensibly.
270 273 } else { // not polar
271 274 linePath.moveTo(points.at(0));
272 275 if (m_pointsVisible) {
273 276 int size = m_linePen.width();
274 277 linePath.addEllipse(points.at(0), size, size);
275 278 linePath.moveTo(points.at(0));
276 279 for (int i = 1; i < points.size(); i++) {
277 280 linePath.lineTo(points.at(i));
278 281 linePath.addEllipse(points.at(i), size, size);
279 282 linePath.moveTo(points.at(i));
280 283 }
281 284 } else {
282 285 for (int i = 1; i < points.size(); i++)
283 286 linePath.lineTo(points.at(i));
284 287 }
285 288 fullPath = linePath;
286 289 }
287 290
288 291 QPainterPathStroker stroker;
289 292 // QPainter::drawLine does not respect join styles, for example BevelJoin becomes MiterJoin.
290 293 // This is why we are prepared for the "worst case" scenario, i.e. use always MiterJoin and
291 294 // multiply line width with square root of two when defining shape and bounding rectangle.
292 295 stroker.setWidth(margin);
293 296 stroker.setJoinStyle(Qt::MiterJoin);
294 297 stroker.setCapStyle(Qt::SquareCap);
295 298 stroker.setMiterLimit(m_linePen.miterLimit());
296 299
297 300 QPainterPath checkShapePath = stroker.createStroke(fullPath);
298 301
299 302 // Only zoom in if the bounding rects of the paths fit inside int limits. QWidget::update() uses
300 303 // a region that has to be compatible with QRect.
301 304 if (checkShapePath.boundingRect().height() <= INT_MAX
302 305 && checkShapePath.boundingRect().width() <= INT_MAX
303 306 && linePath.boundingRect().height() <= INT_MAX
304 307 && linePath.boundingRect().width() <= INT_MAX
305 308 && fullPath.boundingRect().height() <= INT_MAX
306 309 && fullPath.boundingRect().width() <= INT_MAX) {
307 310 prepareGeometryChange();
308 311
309 312 m_linePath = linePath;
310 313 m_fullPath = fullPath;
311 314 m_shapePath = checkShapePath;
312 315
313 316 m_rect = m_shapePath.boundingRect();
314 317 } else {
315 318 update();
316 319 }
317 320 }
318 321
319 322 void LineChartItem::handleUpdated()
320 323 {
321 324 // If points visibility has changed, a geometry update is needed.
322 325 // Also, if pen changes when points are visible, geometry update is needed.
323 326 bool doGeometryUpdate =
324 327 (m_pointsVisible != m_series->pointsVisible())
325 328 || (m_series->pointsVisible() && (m_linePen != m_series->pen()));
326 329 setVisible(m_series->isVisible());
327 330 setOpacity(m_series->opacity());
328 331 m_pointsVisible = m_series->pointsVisible();
329 332 m_linePen = m_series->pen();
330 333 m_pointLabelsFormat = m_series->pointLabelsFormat();
331 334 m_pointLabelsVisible = m_series->pointLabelsVisible();
332 335 m_pointLabelsFont = m_series->pointLabelsFont();
333 336 m_pointLabelsColor = m_series->pointLabelsColor();
334 337 m_pointLabelsClipping = m_series->pointLabelsClipping();
335 338 if (doGeometryUpdate)
336 339 updateGeometry();
337 340 update();
338 341 }
339 342
340 343 void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
341 344 {
342 345 Q_UNUSED(widget)
343 346 Q_UNUSED(option)
344 347
345 348 QRectF clipRect = QRectF(QPointF(0, 0), domain()->size());
346 349
347 350 painter->save();
348 351 painter->setPen(m_linePen);
349 352 bool alwaysUsePath = false;
350 353
351 354 if (m_series->chart()->chartType() == QChart::ChartTypePolar) {
352 355 qreal halfWidth = domain()->size().width() / 2.0;
353 356 QRectF clipRectLeft = QRectF(0, 0, halfWidth, domain()->size().height());
354 357 QRectF clipRectRight = QRectF(halfWidth, 0, halfWidth, domain()->size().height());
355 358 QRegion fullPolarClipRegion(clipRect.toRect(), QRegion::Ellipse);
356 359 QRegion clipRegionLeft(fullPolarClipRegion.intersected(clipRectLeft.toRect()));
357 360 QRegion clipRegionRight(fullPolarClipRegion.intersected(clipRectRight.toRect()));
358 361 painter->setClipRegion(clipRegionLeft);
359 362 painter->drawPath(m_linePathPolarLeft);
360 363 painter->setClipRegion(clipRegionRight);
361 364 painter->drawPath(m_linePathPolarRight);
362 365 painter->setClipRegion(fullPolarClipRegion);
363 366 alwaysUsePath = true; // required for proper clipping
364 367 } else {
365 368 painter->setClipRect(clipRect);
366 369 }
367 370
368 371 reversePainter(painter, clipRect);
369 372
370 373 if (m_pointsVisible) {
371 374 painter->setBrush(m_linePen.color());
372 375 painter->drawPath(m_linePath);
373 376 } else {
374 377 painter->setBrush(QBrush(Qt::NoBrush));
375 378 if (m_linePen.style() != Qt::SolidLine || alwaysUsePath) {
376 379 // If pen style is not solid line, always fall back to path painting
377 380 // to ensure proper continuity of the pattern
378 381 painter->drawPath(m_linePath);
379 382 } else {
380 for (int i(1); i < m_points.size(); i++)
381 painter->drawLine(m_points.at(i - 1), m_points.at(i));
383 for (int i(1); i < m_linePoints.size(); i++)
384 painter->drawLine(m_linePoints.at(i - 1), m_linePoints.at(i));
382 385 }
383 386 }
384 387
385 388 reversePainter(painter, clipRect);
386 389
387 390 if (m_pointLabelsVisible) {
388 391 if (m_pointLabelsClipping)
389 392 painter->setClipping(true);
390 393 else
391 394 painter->setClipping(false);
392 m_series->d_func()->drawSeriesPointLabels(painter, m_points, m_linePen.width() / 2);
395 m_series->d_func()->drawSeriesPointLabels(painter, m_linePoints, m_linePen.width() / 2);
393 396 }
394 397
395 398 painter->restore();
396 399
397 400 }
398 401
399 402 void LineChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
400 403 {
401 404 emit XYChart::pressed(domain()->calculateDomainPoint(event->pos()));
402 405 m_lastMousePos = event->pos();
403 406 m_mousePressed = true;
404 407 QGraphicsItem::mousePressEvent(event);
405 408 }
406 409
407 410 void LineChartItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
408 411 {
409 412 emit XYChart::hovered(domain()->calculateDomainPoint(event->pos()), true);
410 413 // event->accept();
411 414 QGraphicsItem::hoverEnterEvent(event);
412 415 }
413 416
414 417 void LineChartItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
415 418 {
416 419 emit XYChart::hovered(domain()->calculateDomainPoint(event->pos()), false);
417 420 // event->accept();
418 421 QGraphicsItem::hoverEnterEvent(event);
419 422 }
420 423
421 424 void LineChartItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
422 425 {
423 426 emit XYChart::released(domain()->calculateDomainPoint(m_lastMousePos));
424 427 if (m_mousePressed)
425 428 emit XYChart::clicked(domain()->calculateDomainPoint(m_lastMousePos));
426 429 m_mousePressed = false;
427 430 QGraphicsItem::mouseReleaseEvent(event);
428 431 }
429 432
430 433 void LineChartItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
431 434 {
432 435 emit XYChart::doubleClicked(domain()->calculateDomainPoint(m_lastMousePos));
433 436 QGraphicsItem::mouseDoubleClickEvent(event);
434 437 }
435 438
436 439 #include "moc_linechartitem_p.cpp"
437 440
438 441 QT_CHARTS_END_NAMESPACE
@@ -1,94 +1,95
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2015 The Qt Company Ltd
4 4 ** All rights reserved.
5 5 ** For any questions to The Qt Company, please use contact form at http://qt.io
6 6 **
7 7 ** This file is part of the Qt Charts module.
8 8 **
9 9 ** Licensees holding valid commercial license for Qt may use this file in
10 10 ** accordance with the Qt License Agreement provided with the Software
11 11 ** or, alternatively, in accordance with the terms contained in a written
12 12 ** agreement between you and The Qt Company.
13 13 **
14 14 ** If you have questions regarding the use of this file, please use
15 15 ** contact form at http://qt.io
16 16 **
17 17 ****************************************************************************/
18 18
19 19 // W A R N I N G
20 20 // -------------
21 21 //
22 22 // This file is not part of the Qt Chart API. It exists purely as an
23 23 // implementation detail. This header file may change from version to
24 24 // version without notice, or even be removed.
25 25 //
26 26 // We mean it.
27 27
28 28 #ifndef LINECHARTITEM_H
29 29 #define LINECHARTITEM_H
30 30
31 31 #include <QtCharts/QChartGlobal>
32 32 #include <private/xychart_p.h>
33 33 #include <QtCharts/QChart>
34 34 #include <QtGui/QPen>
35 35
36 36 QT_CHARTS_BEGIN_NAMESPACE
37 37
38 38 class QLineSeries;
39 39 class ChartPresenter;
40 40
41 41 class LineChartItem : public XYChart
42 42 {
43 43 Q_OBJECT
44 44 Q_INTERFACES(QGraphicsItem)
45 45 public:
46 46 explicit LineChartItem(QLineSeries *series, QGraphicsItem *item = 0);
47 47 ~LineChartItem() {}
48 48
49 49 //from QGraphicsItem
50 50 QRectF boundingRect() const;
51 51 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
52 52 QPainterPath shape() const;
53 53
54 54 QPainterPath path() const { return m_fullPath; }
55 55
56 56 public Q_SLOTS:
57 57 void handleUpdated();
58 58
59 59 protected:
60 60 void updateGeometry();
61 61 void mousePressEvent(QGraphicsSceneMouseEvent *event);
62 62 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
63 63 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
64 64 void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
65 65 void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
66 66 void suppressPoints() { m_pointsVisible = false; }
67 67 void forceChartType(QChart::ChartType chartType) { m_chartType = chartType; }
68 68
69 69 private:
70 70 QLineSeries *m_series;
71 71 QPainterPath m_linePath;
72 72 QPainterPath m_linePathPolarRight;
73 73 QPainterPath m_linePathPolarLeft;
74 74 QPainterPath m_fullPath;
75 75 QPainterPath m_shapePath;
76 76
77 QVector<QPointF> m_linePoints;
77 78 QRectF m_rect;
78 79 QPen m_linePen;
79 80 bool m_pointsVisible;
80 81 QChart::ChartType m_chartType;
81 82
82 83 bool m_pointLabelsVisible;
83 84 QString m_pointLabelsFormat;
84 85 QFont m_pointLabelsFont;
85 86 QColor m_pointLabelsColor;
86 87 bool m_pointLabelsClipping;
87 88
88 89 QPointF m_lastMousePos;
89 90 bool m_mousePressed;
90 91 };
91 92
92 93 QT_CHARTS_END_NAMESPACE
93 94
94 95 #endif
General Comments 0
You need to be logged in to leave comments. Login now