KD Chart 2  [rev.2.8]
PaintingHelpers_p.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 ** Copyright (C) 2001-2021 Klaralvdalens Datakonsult AB. All rights reserved.
3 **
4 ** This file is part of the KD Chart library.
5 **
6 ** Licensees holding valid commercial KD Chart licenses may use this file in
7 ** accordance with the KD Chart Commercial License Agreement provided with
8 ** the Software.
9 **
10 **
11 ** This file may be distributed and/or modified under the terms of the
12 ** GNU General Public License version 2 and version 3 as published by the
13 ** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
14 **
15 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17 **
18 ** Contact info@kdab.com if any conditions of this licensing are not
19 ** clear to you.
20 **
21 **********************************************************************/
22 
23 #include "PaintingHelpers_p.h"
24 
25 #include "KDChartGlobal.h"
26 
27 #include "KDChartAbstractDiagram.h"
28 #include "KDChartAbstractDiagram_p.h"
30 #include "KDChartLineDiagram.h"
31 #include "KDChartLineDiagram_p.h"
33 #include "KDChartPaintContext.h"
34 #include "KDChartPainterSaver_p.h"
35 #include "KDChartPlotter.h"
38 #include "ReverseMapper.h"
39 
40 namespace KDChart {
41 namespace PaintingHelpers {
42 
48 const QPointF project( const QPointF& point, const ThreeDLineAttributes& tdAttributes )
49 {
50  //Pending Michel FIXME - the rotation does not work as expected atm
51  qreal xrad = DEGTORAD( tdAttributes.lineXRotation() );
52  qreal yrad = DEGTORAD( tdAttributes.lineYRotation() );
53  return QPointF( point.x() * cos( yrad ) + tdAttributes.depth() * sin( yrad ),
54  point.y() * cos( xrad ) - tdAttributes.depth() * sin( xrad ) );
55 }
56 
57 QPainterPath fitPoints( const QPolygonF &points, qreal tension, SplineDirection splineDirection )
58 {
59  QPainterPath path;
60  path.moveTo( points.at( 0 ) );
61  const int count = points.size();
62 
63  // TODO: convert to lambda when we stop caring about pre-C++11
64  // auto dataAt = [&] (int i) {
65  // return i < 0 || i >= count ? QPointF(NAN, NAN) : points.at( i );
66  // };
67  struct dataAtLambda {
68  dataAtLambda(const QPolygonF &points, int count)
69  : points(points)
70  , count(count)
71  {}
72 
73  const QPolygonF &points;
74  int count;
75 
76  QPointF operator() (int i) const
77  {
78  return i < 0 || i >= count ? QPointF(NAN, NAN) : points.at( i );
79  }
80  };
81 
82  dataAtLambda dataAt(points, count);
83 
84  for (int i = 1; i < count; ++i) {
85  addSplineChunkTo( path, tension, dataAt( i - 2 ), points.at( i - 1 ), points.at( i ), dataAt( i + 1 ), splineDirection );
86  }
87 
88  return path;
89 }
90 
91 void paintPolyline( PaintContext* ctx, const QBrush& brush, const QPen& pen, const QPolygonF& points )
92 {
93  ctx->painter()->setBrush( brush );
94  ctx->painter()->setPen( PrintingParameters::scalePen(
95  QPen( pen.color(), pen.width(), pen.style(), Qt::FlatCap, Qt::MiterJoin ) ) );
96  ctx->painter()->drawPolyline( points );
97 }
98 
99 void paintSpline( PaintContext* ctx, const QBrush& brush, const QPen& pen, const QPolygonF& points, qreal tension, SplineDirection splineDirection )
100 {
101  if (points.size() < 3) {
102  paintPolyline( ctx, brush, pen, points );
103  return;
104  }
105 
106  ctx->painter()->setBrush( brush );
107  ctx->painter()->setBrush( QBrush() );
108  ctx->painter()->setPen( PrintingParameters::scalePen(
109  QPen( pen.color(), pen.width(), pen.style(), Qt::FlatCap, Qt::MiterJoin ) ) );
110 
111  ctx->painter()->drawPath( fitPoints(points, tension, splineDirection) );
112 }
113 
114 void paintThreeDLines( PaintContext* ctx, AbstractDiagram *diagram, const QModelIndex& index,
115  const QPointF& from, const QPointF& to, const ThreeDLineAttributes& tdAttributes,
116  ReverseMapper* reverseMapper )
117 {
118  const QPointF topLeft = project( from, tdAttributes );
119  const QPointF topRight = project ( to, tdAttributes );
120  const QPolygonF segment = QPolygonF() << from << topLeft << topRight << to;
121 
122  QBrush indexBrush( diagram->brush( index ) );
123  indexBrush = tdAttributes.threeDBrush( indexBrush, QRectF(topLeft, topRight) );
124 
125  const PainterSaver painterSaver( ctx->painter() );
126 
127  ctx->painter()->setRenderHint( QPainter::Antialiasing, diagram->antiAliasing() );
128  ctx->painter()->setBrush( indexBrush );
129  ctx->painter()->setPen( PrintingParameters::scalePen( diagram->pen( index ) ) );
130 
131  reverseMapper->addPolygon( index.row(), index.column(), segment );
132  ctx->painter()->drawPolygon( segment );
133 }
134 
135 void paintValueTracker( PaintContext* ctx, const ValueTrackerAttributes& vt, const QPointF& at )
136 {
137  CartesianCoordinatePlane* plane = qobject_cast<CartesianCoordinatePlane*>( ctx->coordinatePlane() );
138  if ( !plane )
139  return;
140 
141  DataDimensionsList gridDimensions = ctx->coordinatePlane()->gridDimensionsList();
142  const QPointF bottomLeft( ctx->coordinatePlane()->translate(
143  QPointF( plane->isHorizontalRangeReversed() ?
144  gridDimensions.at( 0 ).end :
145  gridDimensions.at( 0 ).start,
146  plane->isVerticalRangeReversed() ?
147  gridDimensions.at( 1 ).end :
148  gridDimensions.at( 1 ).start ) ) );
149  const QPointF topRight( ctx->coordinatePlane()->translate(
150  QPointF( plane->isHorizontalRangeReversed() ?
151  gridDimensions.at( 0 ).start :
152  gridDimensions.at( 0 ).end,
153  plane->isVerticalRangeReversed() ?
154  gridDimensions.at( 1 ).start :
155  gridDimensions.at( 1 ).end ) ) );
156  const QPointF markerPoint = at;
157 
158  QPointF startPoint;
159  if ( vt.orientations() & Qt::Horizontal ) {
160  startPoint = QPointF( bottomLeft.x(), at.y() );
161  } else {
162  startPoint = QPointF( at.x(), topRight.y() );
163  }
164 
165  QPointF endPoint;
166  if ( vt.orientations() & Qt::Vertical ) {
167  endPoint = QPointF( at.x(), bottomLeft.y() );
168  } else {
169  endPoint = QPointF( topRight.x(), at.y() );
170  }
171 
172  const QSizeF markerSize = vt.markerSize();
173  const QRectF ellipseMarker = QRectF( at.x() - markerSize.width() / 2,
174  at.y() - markerSize.height() / 2,
175  markerSize.width(), markerSize.height() );
176 
177  QPointF startMarker[3];
178  if ( vt.orientations() & Qt::Horizontal ) {
179  startMarker[0] = startPoint + QPointF( 0, markerSize.height() / 2 );
180  startMarker[1] = startPoint + QPointF( markerSize.width() / 2, 0 );
181  startMarker[2] = startPoint - QPointF( 0, markerSize.height() / 2 );
182  } else {
183  startMarker[0] = startPoint + QPointF( 0, markerSize.height() / 2 );
184  startMarker[1] = startPoint + QPointF( markerSize.width() / 2, 0 );
185  startMarker[2] = startPoint - QPointF( markerSize.width() / 2, 0 );
186  }
187 
188  QPointF endMarker[3];
189 
190  if ( vt.orientations() & Qt::Vertical ) {
191  endMarker[0] = endPoint + QPointF( markerSize.width() / 2, 0 );
192  endMarker[1] = endPoint - QPointF( 0, markerSize.height() / 2 );
193  endMarker[2] = endPoint - QPointF( markerSize.width() / 2, 0 );
194  } else {
195  endMarker[0] = endPoint + QPointF( 0, markerSize.width() / 2 );
196  endMarker[1] = endPoint - QPointF( 0, markerSize.height() / 2 );
197  endMarker[2] = endPoint - QPointF( markerSize.width() / 2, 0 );
198  }
199 
200  QPointF topLeft = startPoint;
201  QPointF bottomRightOffset = endPoint - topLeft;
202  QSizeF size( bottomRightOffset.x(), bottomRightOffset.y() );
203  QRectF area( topLeft, size );
204 
205  PainterSaver painterSaver( ctx->painter() );
206  ctx->painter()->setPen( PrintingParameters::scalePen( vt.linePen() ) );
207  ctx->painter()->setBrush( QBrush() );
208  ctx->painter()->drawLine( markerPoint, startPoint );
209  ctx->painter()->drawLine( markerPoint, endPoint );
210 
211  ctx->painter()->fillRect( area, vt.areaBrush() );
212 
213  ctx->painter()->setPen( PrintingParameters::scalePen( vt.markerPen() ) );
214  ctx->painter()->setBrush( vt.markerBrush() );
215  ctx->painter()->drawEllipse( ellipseMarker );
216 
217  ctx->painter()->setPen( PrintingParameters::scalePen( vt.arrowBrush().color() ) );
218  ctx->painter()->setBrush( vt.arrowBrush() );
219  ctx->painter()->drawPolygon( startMarker, 3 );
220  ctx->painter()->drawPolygon( endMarker, 3 );
221 }
222 
223 // ### for BC reasons we cannot insert a common interface for LineDiagram and Plotter into the class
224 // hierarchy, so we have to use hacks to use their common methods
225 static ThreeDLineAttributes threeDLineAttributes( AbstractDiagram* diagram, const QModelIndex& index )
226 {
227  if ( Plotter *plotter = qobject_cast< Plotter* >( diagram ) ) {
228  return plotter->threeDLineAttributes( index );
229  } else if ( LineDiagram *lineDiagram = qobject_cast< LineDiagram* >( diagram ) ) {
230  return lineDiagram->threeDLineAttributes( index );
231  }
232  Q_ASSERT( false );
233  return ThreeDLineAttributes();
234 }
235 
236 static ValueTrackerAttributes valueTrackerAttributes( AbstractDiagram* diagram, const QModelIndex& index )
237 {
238  if ( Plotter *plotter = qobject_cast< Plotter* >( diagram ) ) {
239  return plotter->valueTrackerAttributes( index );
240  } else if ( LineDiagram *lineDiagram = qobject_cast< LineDiagram* >( diagram ) ) {
241  return lineDiagram->valueTrackerAttributes( index );
242  }
243  Q_ASSERT( false );
244  return ValueTrackerAttributes();
245 }
246 
247 void paintObject ( AbstractDiagram::Private *diagramPrivate, PaintContext* ctx, const QBrush& brush, const QPen& pen, const QPolygonF& points )
248 {
249  qreal tension = 0;
250  SplineDirection splineDirection = NormalSplineDirection;
251 
252  if ( LineDiagram::Private* lineDiagram = dynamic_cast<LineDiagram::Private*>( diagramPrivate ) ) {
253  tension = lineDiagram->tension;
254  Q_ASSERT(dynamic_cast<CartesianCoordinatePlane*>(ctx->coordinatePlane()));
255  const auto plane = static_cast<CartesianCoordinatePlane*>(ctx->coordinatePlane());
256  splineDirection = plane->isHorizontalRangeReversed() ? ReverseSplineDirection : NormalSplineDirection;
257  }
258 
259  if ( qFuzzyIsNull(tension) ) {
260  paintPolyline( ctx, brush, pen, points );
261  } else {
262  paintSpline( ctx, brush, pen, points, tension, splineDirection );
263  }
264 }
265 
266 void paintElements( AbstractDiagram::Private *diagramPrivate, PaintContext* ctx,
267  const LabelPaintCache& lpc, const LineAttributesInfoList& lineList )
268 {
269  AbstractDiagram* diagram = diagramPrivate->diagram;
270  // paint all lines and their attributes
271  const PainterSaver painterSaver( ctx->painter() );
272  ctx->painter()->setRenderHint( QPainter::Antialiasing, diagram->antiAliasing() );
273 
274  QBrush curBrush;
275  QPen curPen;
276  QPolygonF points;
277  KDAB_FOREACH ( const LineAttributesInfo& lineInfo, lineList ) {
278  const QModelIndex& index = lineInfo.index;
279  const ThreeDLineAttributes td = threeDLineAttributes( diagram, index );
280 
281  if ( td.isEnabled() ) {
282  PaintingHelpers::paintThreeDLines( ctx, diagram, index, lineInfo.value,
283  lineInfo.nextValue, td, &diagramPrivate->reverseMapper );
284  } else {
285  const QBrush brush( diagram->brush( index ) );
286  const QPen pen( diagram->pen( index ) );
287 
288  // line goes from lineInfo.value to lineInfo.nextValue
289  // We don't want it added if we're not drawing it, since the reverse mapper is used
290  // for lookup when trying to find e.g. tooltips. Having the line added when invisible gives
291  // us tooltips in empty areas.
292  if (pen.style() != Qt::NoPen)
293  diagramPrivate->reverseMapper.addLine( lineInfo.index.row(), lineInfo.index.column(),
294  lineInfo.value, lineInfo.nextValue );
295 
296  if ( points.count() && points.last() == lineInfo.value && curBrush == brush && curPen == pen ) {
297  // continue the current run of lines
298  } else {
299  // different painter settings or discontinuous line: start a new run of lines
300  if ( points.count() ) {
301  paintObject( diagramPrivate, ctx, curBrush, curPen, points );
302  }
303  curBrush = brush;
304  curPen = pen;
305  points.clear();
306  points << lineInfo.value;
307  }
308  points << lineInfo.nextValue;
309  }
310  }
311  if ( points.count() ) {
312  // the last run of lines is yet to be painted - do it now
313  paintObject( diagramPrivate, ctx, curBrush, curPen, points );
314  }
315 
316  KDAB_FOREACH ( const LineAttributesInfo& lineInfo, lineList ) {
317  const ValueTrackerAttributes vt = valueTrackerAttributes( diagram, lineInfo.index );
318  if ( vt.isEnabled() ) {
319  PaintingHelpers::paintValueTracker( ctx, vt, lineInfo.nextValue );
320  }
321  }
322 
323  // paint all data value texts and the point markers
324  diagramPrivate->paintDataValueTextsAndMarkers( ctx, lpc, true );
325 }
326 
327 void paintAreas( AbstractDiagram::Private* diagramPrivate, PaintContext* ctx, const QModelIndex& index,
328  const QList< QPolygonF >& areas, uint opacity )
329 {
330  AbstractDiagram* diagram = diagramPrivate->diagram;
331  QPainterPath path;
332  for ( int i = 0; i < areas.count(); ++i )
333  {
334  const QPolygonF& p = areas[ i ];
335  path.addPolygon( p );
336  diagramPrivate->reverseMapper.addPolygon( index.row(), index.column(), p );
337  path.closeSubpath();
338  }
339 
340  ThreeDLineAttributes threeDAttrs = threeDLineAttributes( diagram, index );
341  QBrush trans = diagram->brush( index );
342  if ( threeDAttrs.isEnabled() ) {
343  trans = threeDAttrs.threeDBrush( trans, path.boundingRect() );
344  }
345  QColor transColor = trans.color();
346  transColor.setAlpha( opacity );
347  trans.setColor(transColor);
348  QPen indexPen = diagram->pen(index);
349  indexPen.setBrush( trans );
350  const PainterSaver painterSaver( ctx->painter() );
351 
352  ctx->painter()->setRenderHint( QPainter::Antialiasing, diagram->antiAliasing() );
353  ctx->painter()->setPen( PrintingParameters::scalePen( indexPen ) );
354  ctx->painter()->setBrush( trans );
355 
356  ctx->painter()->drawPath( path );
357 }
358 
359 void paintAreas( AbstractDiagram::Private* diagramPrivate, PaintContext* ctx, const QModelIndex& index,
360  const QList< QPainterPath >& areas, uint opacity )
361 {
362  AbstractDiagram* diagram = diagramPrivate->diagram;
363  QPainterPath path;
364  for ( int i = 0; i < areas.count(); ++i )
365  {
366  path += areas[ i ];
367  // diagramPrivate->reverseMapper.addPolygon( index.row(), index.column(), p );
368  }
369 
370  QBrush trans = diagram->brush( index );
371  QColor transColor = trans.color();
372  transColor.setAlpha( opacity );
373  trans.setColor( transColor );
374  QPen indexPen = diagram->pen( index );
375  indexPen.setBrush( trans );
376  const PainterSaver painterSaver( ctx->painter() );
377 
378  ctx->painter()->setRenderHint( QPainter::Antialiasing, diagram->antiAliasing() );
379  ctx->painter()->setPen( PrintingParameters::scalePen( indexPen ) );
380  ctx->painter()->setBrush( trans );
381 
382  ctx->painter()->drawPath( path );
383 }
384 
385 } // namespace PaintingHelpers
386 } // namespace KDChart
KDChart::Plotter
Plotter defines a diagram type plotting two-dimensional data.
Definition: KDChartPlotter.h:39
KDChart::CartesianCoordinatePlane::isVerticalRangeReversed
bool isVerticalRangeReversed() const
Definition: KDChartCartesianCoordinatePlane.cpp:855
KDChart::ValueTrackerAttributes::markerPen
QPen markerPen() const
Definition: KDChartValueTrackerAttributes.cpp:127
QList
Definition: KDChartPosition.h:36
KDChart::ValueTrackerAttributes::isEnabled
bool isEnabled() const
Definition: KDChartValueTrackerAttributes.cpp:187
KDChart::PaintingHelpers::paintValueTracker
void paintValueTracker(PaintContext *ctx, const ValueTrackerAttributes &vt, const QPointF &at)
Definition: PaintingHelpers_p.cpp:135
KDChart::PaintingHelpers::paintElements
void paintElements(AbstractDiagram::Private *diagramPrivate, PaintContext *ctx, const LabelPaintCache &lpc, const LineAttributesInfoList &lineList)
Definition: PaintingHelpers_p.cpp:266
KDChart::ValueTrackerAttributes::orientations
Qt::Orientations orientations() const
Definition: KDChartValueTrackerAttributes.cpp:172
ReverseMapper.h
KDChart::ValueTrackerAttributes::arrowBrush
QBrush arrowBrush() const
Definition: KDChartValueTrackerAttributes.cpp:147
KDChart::PrintingParameters::scalePen
static QPen scalePen(const QPen &pen)
Definition: KDChartPrintingParameters.cpp:48
KDChart::ValueTrackerAttributes::markerBrush
QBrush markerBrush() const
Definition: KDChartValueTrackerAttributes.cpp:137
KDChart::PaintingHelpers::paintAreas
void paintAreas(AbstractDiagram::Private *diagramPrivate, PaintContext *ctx, const QModelIndex &index, const QList< QPolygonF > &areas, uint opacity)
Definition: PaintingHelpers_p.cpp:327
KDChart::AbstractDiagram::pen
QPen pen() const
Retrieve the pen to be used for painting datapoints globally.
Definition: KDChartAbstractDiagram.cpp:661
KDChart::CartesianCoordinatePlane::isHorizontalRangeReversed
bool isHorizontalRangeReversed() const
Definition: KDChartCartesianCoordinatePlane.cpp:840
KDChart
Definition: KDChartAbstractCartesianDiagram.h:30
KDChart::PaintContext::coordinatePlane
AbstractCoordinatePlane * coordinatePlane() const
Definition: KDChartPaintContext.cpp:78
KDChartCartesianCoordinatePlane.h
KDChart::AbstractCoordinatePlane::translate
virtual const QPointF translate(const QPointF &diagramPoint) const =0
Translate the given point in value space coordinates to a position in pixel space.
KDChartPaintContext.h
KDChartPrintingParameters.h
KDChart::PaintContext
Stores information about painting diagrams.
Definition: KDChartPaintContext.h:42
KDChart::ValueTrackerAttributes::areaBrush
QBrush areaBrush() const
Definition: KDChartValueTrackerAttributes.cpp:157
KDChart::LineDiagram
LineDiagram defines a common line diagram.
Definition: KDChartLineDiagram.h:45
KDChartGlobal.h
KDChart::AbstractThreeDAttributes::isEnabled
bool isEnabled() const
Definition: KDChartAbstractThreeDAttributes.cpp:88
KDChart::ThreeDLineAttributes::lineYRotation
uint lineYRotation() const
Definition: KDChartThreeDLineAttributes.cpp:95
KDChart::AbstractDiagram::antiAliasing
bool antiAliasing() const
Definition: KDChartAbstractDiagram.cpp:376
KDChart::PaintContext::painter
QPainter * painter() const
Definition: KDChartPaintContext.cpp:68
KDChart::ThreeDLineAttributes
A set of 3D line attributes.
Definition: KDChartThreeDLineAttributes.h:36
KDChart::ValueTrackerAttributes
Cell-specific attributes regarding value tracking.
Definition: KDChartValueTrackerAttributes.h:43
KDChart::PaintingHelpers::paintSpline
void paintSpline(PaintContext *ctx, const QBrush &brush, const QPen &pen, const QPolygonF &points, qreal tension, SplineDirection splineDirection)
Definition: PaintingHelpers_p.cpp:99
KDChartAbstractDiagram.h
KDChart::ThreeDLineAttributes::lineXRotation
uint lineXRotation() const
Definition: KDChartThreeDLineAttributes.cpp:85
KDChart::AbstractThreeDAttributes::depth
qreal depth() const
Definition: KDChartAbstractThreeDAttributes.cpp:99
KDChartValueTrackerAttributes.h
KDChartThreeDLineAttributes.h
KDChart::PaintingHelpers::paintPolyline
void paintPolyline(PaintContext *ctx, const QBrush &brush, const QPen &pen, const QPolygonF &points)
Definition: PaintingHelpers_p.cpp:91
KDChart::PaintingHelpers::paintObject
void paintObject(AbstractDiagram::Private *diagramPrivate, PaintContext *ctx, const QBrush &brush, const QPen &pen, const QPolygonF &points)
Definition: PaintingHelpers_p.cpp:247
KDChart::AbstractDiagram
AbstractDiagram defines the interface for diagram classes.
Definition: KDChartAbstractDiagram.h:51
KDChart::PaintingHelpers::paintThreeDLines
void paintThreeDLines(PaintContext *ctx, AbstractDiagram *diagram, const QModelIndex &index, const QPointF &from, const QPointF &to, const ThreeDLineAttributes &tdAttributes, ReverseMapper *reverseMapper)
Definition: PaintingHelpers_p.cpp:114
KDChart::PaintingHelpers::project
const QPointF project(const QPointF &point, const ThreeDLineAttributes &tdAttributes)
Definition: PaintingHelpers_p.cpp:48
KDChart::PaintingHelpers::fitPoints
QPainterPath fitPoints(const QPolygonF &points, qreal tension, SplineDirection splineDirection)
Definition: PaintingHelpers_p.cpp:57
KDChart::AbstractThreeDAttributes::threeDBrush
virtual QBrush threeDBrush(const QBrush &brush, const QRectF &rect) const
Definition: KDChartAbstractThreeDAttributes.cpp:120
KDChart::ReverseMapper
The ReverseMapper stores information about objects on a chart and their respective model indexes.
Definition: ReverseMapper.h:45
KDChart::AbstractCoordinatePlane::gridDimensionsList
DataDimensionsList gridDimensionsList()
Returns the dimensions used for drawing the grid lines.
Definition: KDChartAbstractCoordinatePlane.cpp:168
KDChartPlotter.h
KDChart::ReverseMapper::addPolygon
void addPolygon(int row, int column, const QPolygonF &polygon)
Definition: ReverseMapper.cpp:135
KDChart::PaintingHelpers::threeDLineAttributes
static ThreeDLineAttributes threeDLineAttributes(AbstractDiagram *diagram, const QModelIndex &index)
Definition: PaintingHelpers_p.cpp:225
KDChart::CartesianCoordinatePlane
Cartesian coordinate plane.
Definition: KDChartCartesianCoordinatePlane.h:40
KDChart::PaintingHelpers::valueTrackerAttributes
static ValueTrackerAttributes valueTrackerAttributes(AbstractDiagram *diagram, const QModelIndex &index)
Definition: PaintingHelpers_p.cpp:236
KDChart::ValueTrackerAttributes::markerSize
QSizeF markerSize() const
Definition: KDChartValueTrackerAttributes.cpp:167
KDChartLineDiagram.h
KDChart::AbstractDiagram::brush
QBrush brush() const
Retrieve the brush to be used for painting datapoints globally.
Definition: KDChartAbstractDiagram.cpp:702
KDChart::ValueTrackerAttributes::linePen
QPen linePen() const
Definition: KDChartValueTrackerAttributes.cpp:117

Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/

https://www.kdab.com/development-resources/qt-tools/kd-chart/