bool ValueTrackerAttributes::operator==( const ValueTrackerAttributes& r ) const { return ( pen() == r.pen() && areaBrush() == r.areaBrush() && markerSize() == r.markerSize() && isEnabled() == r.isEnabled() ); }
void paintElements( AbstractDiagram::Private *diagramPrivate, PaintContext* ctx, const LabelPaintCache& lpc, const LineAttributesInfoList& lineList ) { AbstractDiagram* diagram = diagramPrivate->diagram; // paint all lines and their attributes const PainterSaver painterSaver( ctx->painter() ); ctx->painter()->setRenderHint( QPainter::Antialiasing, diagram->antiAliasing() ); QBrush curBrush; QPen curPen; QPolygonF points; KDAB_FOREACH ( const LineAttributesInfo& lineInfo, lineList ) { const QModelIndex& index = lineInfo.index; const ThreeDLineAttributes td = threeDLineAttributes( diagram, index ); if ( td.isEnabled() ) { PaintingHelpers::paintThreeDLines( ctx, diagram, index, lineInfo.value, lineInfo.nextValue, td, &diagramPrivate->reverseMapper ); } else { const QBrush brush( diagram->brush( index ) ); const QPen pen( diagram->pen( index ) ); // line goes from lineInfo.value to lineInfo.nextValue diagramPrivate->reverseMapper.addLine( lineInfo.index.row(), lineInfo.index.column(), lineInfo.value, lineInfo.nextValue ); if ( points.count() && points.last() == lineInfo.value && curBrush == brush && curPen == pen ) { // continue the current run of lines } else { // different painter settings or discontinuous line: start a new run of lines if ( points.count() ) { PaintingHelpers::paintPolyline( ctx, curBrush, curPen, points ); } curBrush = brush; curPen = pen; points.clear(); points << lineInfo.value; } points << lineInfo.nextValue; } } if ( points.count() ) { // the last run of lines is yet to be painted - do it now PaintingHelpers::paintPolyline( ctx, curBrush, curPen, points ); } KDAB_FOREACH ( const LineAttributesInfo& lineInfo, lineList ) { const ValueTrackerAttributes vt = valueTrackerAttributes( diagram, lineInfo.index ); if ( vt.isEnabled() ) { PaintingHelpers::paintValueTracker( ctx, vt, lineInfo.nextValue ); } } // paint all data value texts and the point markers diagramPrivate->paintDataValueTextsAndMarkers( ctx, lpc, true ); }
void LineDiagram::LineDiagramType::paintValueTracker( PaintContext* ctx, const ValueTrackerAttributes& vt, const QPointF& at ) { CartesianCoordinatePlane* plane = qobject_cast<CartesianCoordinatePlane*>( ctx->coordinatePlane() ); if( !plane ) return; DataDimensionsList gridDimensions = ctx->coordinatePlane()->gridDimensionsList(); const QPointF bottomLeft( ctx->coordinatePlane()->translate( QPointF( plane->isHorizontalRangeReversed() ? gridDimensions.at( 0 ).end : gridDimensions.at( 0 ).start, plane->isVerticalRangeReversed() ? gridDimensions.at( 1 ).end : gridDimensions.at( 1 ).start ) ) ); const QPointF markerPoint = at; const QPointF ordinatePoint( bottomLeft.x(), at.y() ); const QPointF abscissaPoint( at.x(), bottomLeft.y() ); const QSizeF markerSize = vt.markerSize(); const QRectF ellipseMarker = QRectF( at.x() - markerSize.width() / 2, at.y() - markerSize.height() / 2, markerSize.width(), markerSize.height() ); const QPointF ordinateMarker[3] = { QPointF( ordinatePoint.x(), at.y() + markerSize.height() / 2 ), QPointF( ordinatePoint.x() + markerSize.width() / 2, at.y() ), QPointF( ordinatePoint.x(), at.y() - markerSize.height() / 2 ) }; const QPointF abscissaMarker[3] = { QPointF( at.x() + markerSize.width() / 2, abscissaPoint.y() ), QPointF( at.x(), abscissaPoint.y() - markerSize.height() / 2 ), QPointF( at.x() - markerSize.width() / 2, abscissaPoint.y() ) }; QPointF topLeft = ordinatePoint; QPointF bottomRightOffset = abscissaPoint - topLeft; QSizeF size( bottomRightOffset.x(), bottomRightOffset.y() ); QRectF area( topLeft, size ); PainterSaver painterSaver( ctx->painter() ); ctx->painter()->setPen( PrintingParameters::scalePen( vt.pen() ) ); ctx->painter()->setBrush( QBrush() ); ctx->painter()->drawLine( markerPoint, ordinatePoint ); ctx->painter()->drawLine( markerPoint, abscissaPoint ); ctx->painter()->fillRect( area, vt.areaBrush() ); ctx->painter()->drawEllipse( ellipseMarker ); ctx->painter()->setBrush( vt.pen().color() ); ctx->painter()->drawPolygon( ordinateMarker, 3 ); ctx->painter()->drawPolygon( abscissaMarker, 3 ); }
// this method is factored out from LineDiagram::paint, and contains // the common parts of the method that previously implemented all // chart types in one void LineDiagram::LineDiagramType::paintElements( PaintContext* ctx, DataValueTextInfoList& list, LineAttributesInfoList& lineList, LineAttributes::MissingValuesPolicy policy ) { Q_UNUSED( policy ); // paint all lines and their attributes const PainterSaver painterSaver( ctx->painter() ); if ( diagram()->antiAliasing() ) ctx->painter()->setRenderHint ( QPainter::Antialiasing ); LineAttributesInfoListIterator itline ( lineList ); QBrush curBrush; QPen curPen; QPolygonF points; while ( itline.hasNext() ) { const LineAttributesInfo& lineInfo = itline.next(); const QModelIndex& index = lineInfo.index; const ThreeDLineAttributes td = diagram()->threeDLineAttributes( index ); const ValueTrackerAttributes vt = diagram()->valueTrackerAttributes( index ); if( td.isEnabled() ){ paintThreeDLines( ctx, index, lineInfo.value, lineInfo.nextValue, td.depth() ); } else { const QBrush br( diagram()->brush( index ) ); const QPen pn( diagram()->pen( index ) ); if( points.count() && points.last() == lineInfo.value && curBrush == br && curPen == pn ) { // line goes from last value in points to lineInfo.nextValue reverseMapper().addLine( lineInfo.index.row(), lineInfo.index.column(), points.last(), lineInfo.nextValue ); points << lineInfo.nextValue; } else { if( points.count() ) paintPolyline( ctx, curBrush, curPen, points ); curBrush = br; curPen = pn; points.clear(); // line goes from lineInfo.value to lineInfo,nextValue reverseMapper().addLine( lineInfo.index.row(), lineInfo.index.column(), lineInfo.value, lineInfo.nextValue ); points << lineInfo.value << lineInfo.nextValue; } } if( vt.isEnabled() ) paintValueTracker( ctx, vt, lineInfo.value ); } if( points.count() ) paintPolyline( ctx, curBrush, curPen, points ); // paint all data value texts and the point markers paintDataValueTextsAndMarkers( diagram(), ctx, list, true ); }
void paintValueTracker( PaintContext* ctx, const ValueTrackerAttributes& vt, const QPointF& at ) { CartesianCoordinatePlane* plane = qobject_cast<CartesianCoordinatePlane*>( ctx->coordinatePlane() ); if ( !plane ) return; DataDimensionsList gridDimensions = ctx->coordinatePlane()->gridDimensionsList(); const QPointF bottomLeft( ctx->coordinatePlane()->translate( QPointF( plane->isHorizontalRangeReversed() ? gridDimensions.at( 0 ).end : gridDimensions.at( 0 ).start, plane->isVerticalRangeReversed() ? gridDimensions.at( 1 ).end : gridDimensions.at( 1 ).start ) ) ); const QPointF topRight( ctx->coordinatePlane()->translate( QPointF( plane->isHorizontalRangeReversed() ? gridDimensions.at( 0 ).start : gridDimensions.at( 0 ).end, plane->isVerticalRangeReversed() ? gridDimensions.at( 1 ).start : gridDimensions.at( 1 ).end ) ) ); const QPointF markerPoint = at; QPointF startPoint; if ( vt.orientations() & Qt::Horizontal ) { startPoint = QPointF( bottomLeft.x(), at.y() ); } else { startPoint = QPointF( at.x(), topRight.y() ); } QPointF endPoint; if ( vt.orientations() & Qt::Vertical ) { endPoint = QPointF( at.x(), bottomLeft.y() ); } else { endPoint = QPointF( topRight.x(), at.y() ); } const QSizeF markerSize = vt.markerSize(); const QRectF ellipseMarker = QRectF( at.x() - markerSize.width() / 2, at.y() - markerSize.height() / 2, markerSize.width(), markerSize.height() ); QPointF startMarker[3]; if ( vt.orientations() & Qt::Horizontal ) { startMarker[0] = startPoint + QPointF( 0, markerSize.height() / 2 ); startMarker[1] = startPoint + QPointF( markerSize.width() / 2, 0 ); startMarker[2] = startPoint - QPointF( 0, markerSize.height() / 2 ); } else { startMarker[0] = startPoint + QPointF( 0, markerSize.height() / 2 ); startMarker[1] = startPoint + QPointF( markerSize.width() / 2, 0 ); startMarker[2] = startPoint - QPointF( markerSize.width() / 2, 0 ); } QPointF endMarker[3]; if ( vt.orientations() & Qt::Vertical ) { endMarker[0] = endPoint + QPointF( markerSize.width() / 2, 0 ); endMarker[1] = endPoint - QPointF( 0, markerSize.height() / 2 ); endMarker[2] = endPoint - QPointF( markerSize.width() / 2, 0 ); } else { endMarker[0] = endPoint + QPointF( 0, markerSize.width() / 2 ); endMarker[1] = endPoint - QPointF( 0, markerSize.height() / 2 ); endMarker[2] = endPoint - QPointF( markerSize.width() / 2, 0 ); } QPointF topLeft = startPoint; QPointF bottomRightOffset = endPoint - topLeft; QSizeF size( bottomRightOffset.x(), bottomRightOffset.y() ); QRectF area( topLeft, size ); PainterSaver painterSaver( ctx->painter() ); ctx->painter()->setPen( PrintingParameters::scalePen( vt.linePen() ) ); ctx->painter()->setBrush( QBrush() ); ctx->painter()->drawLine( markerPoint, startPoint ); ctx->painter()->drawLine( markerPoint, endPoint ); ctx->painter()->fillRect( area, vt.areaBrush() ); ctx->painter()->setPen( PrintingParameters::scalePen( vt.markerPen() ) ); ctx->painter()->setBrush( vt.markerBrush() ); ctx->painter()->drawEllipse( ellipseMarker ); ctx->painter()->setPen( PrintingParameters::scalePen( vt.arrowBrush().color() ) ); ctx->painter()->setBrush( vt.arrowBrush() ); ctx->painter()->drawPolygon( startMarker, 3 ); ctx->painter()->drawPolygon( endMarker, 3 ); }