void MainWindow::on_paintValuesCB_toggled( bool checked ) { const int colCount = m_lines->model()->columnCount(); for ( int iColumn = 0; iColumn<colCount; ++iColumn ) { DataValueAttributes a = m_lines->dataValueAttributes( iColumn ); a.setVisible( true ); TextAttributes ta = a.textAttributes(); ta.setRotation( 0 ); ta.setFont( QFont( "Comic", 10 ) ); ta.setPen( m_lines->brush( iColumn ).color() ); ta.setVisible( checked ); a.setTextAttributes( ta ); m_lines->setDataValueAttributes( iColumn, a); } }
void markPeak(Plotter* p, const QModelIndex& peak, quint64 cost, const KColorScheme& scheme) { QBrush brush = p->model()->data(peak, DatasetBrushRole).value<QBrush>(); QColor outline = brush.color(); QColor foreground = scheme.foreground().color(); QBrush background = scheme.background(); DataValueAttributes dataAttributes = p->dataValueAttributes(peak); dataAttributes.setDataLabel(prettyCost(cost)); dataAttributes.setVisible(true); dataAttributes.setShowRepetitiveDataLabels(true); dataAttributes.setShowOverlappingDataLabels(false); FrameAttributes frameAttrs = dataAttributes.frameAttributes(); QPen framePen(outline); framePen.setWidth(2); frameAttrs.setPen(framePen); frameAttrs.setVisible(true); dataAttributes.setFrameAttributes(frameAttrs); MarkerAttributes a = dataAttributes.markerAttributes(); a.setMarkerSize(QSizeF(7, 7)); a.setPen(outline); a.setMarkerStyle(KChart::MarkerAttributes::MarkerDiamond); a.setVisible(true); dataAttributes.setMarkerAttributes(a); TextAttributes txtAttrs = dataAttributes.textAttributes(); txtAttrs.setPen(foreground); txtAttrs.setFontSize(Measure(12)); dataAttributes.setTextAttributes(txtAttrs); BackgroundAttributes bkgAtt = dataAttributes.backgroundAttributes(); bkgAtt.setBrush(background); bkgAtt.setVisible(true); dataAttributes.setBackgroundAttributes(bkgAtt); p->setDataValueAttributes(peak, dataAttributes); }
bool DataValueAttributes::operator==( const DataValueAttributes& r ) const { /* qDebug() << "DataValueAttributes::operator== finds" << "b" << (isVisible() == r.isVisible()) << "c" << (textAttributes() == r.textAttributes()) << "d" << (frameAttributes() == r.frameAttributes()) << "e" << (backgroundAttributes() == r.backgroundAttributes()) << "f" << (markerAttributes() == r.markerAttributes()) << "g" << (decimalDigits() == r.decimalDigits()) << "h" << (prefix() == r.prefix()) << "i" << (suffix() == r.suffix()) << "j" << (dataLabel() == r.dataLabel()) << "k" << (powerOfTenDivisor() == r.powerOfTenDivisor()) << "l" << (showInfinite() == r.showInfinite()) << "m" << (negativePosition() == r.negativePosition()) << "n" << (positivePosition() == r.positivePosition()) << "o" << (showRepetitiveDataLabels() == r.showRepetitiveDataLabels()) << "p" << (showOverlappingDataLabels() == r.showOverlappingDataLabels()); */ return ( isVisible() == r.isVisible() && textAttributes() == r.textAttributes() && frameAttributes() == r.frameAttributes() && backgroundAttributes() == r.backgroundAttributes() && markerAttributes() == r.markerAttributes() && decimalDigits() == r.decimalDigits() && prefix() == r.prefix() && suffix() == r.suffix() && dataLabel() == r.dataLabel() && powerOfTenDivisor() == r.powerOfTenDivisor() && showInfinite() == r.showInfinite() && negativePosition() == r.negativePosition() && positivePosition() == r.positivePosition() && showRepetitiveDataLabels() == r.showRepetitiveDataLabels() && showOverlappingDataLabels() == r.showOverlappingDataLabels() && usePercentage() == r.usePercentage() ); }
void AbstractDiagram::Private::addLabel( LabelPaintCache* cache, const QModelIndex& index, const CartesianDiagramDataCompressor::CachePosition* position, const PositionPoints& points, const Position& autoPositionPositive, const Position& autoPositionNegative, const qreal value, qreal favoriteAngle /* = 0.0 */ ) { CartesianDiagramDataCompressor::AggregatedDataValueAttributes allAttrs( aggregatedAttrs( index, position ) ); QMap<QModelIndex, DataValueAttributes>::const_iterator it; for ( it = allAttrs.constBegin(); it != allAttrs.constEnd(); ++it ) { DataValueAttributes dva = it.value(); if ( !dva.isVisible() ) { continue; } const bool isPositive = ( value >= 0.0 ); RelativePosition relPos( dva.position( isPositive ) ); relPos.setReferencePoints( points ); if ( relPos.referencePosition().isUnknown() ) { relPos.setReferencePosition( isPositive ? autoPositionPositive : autoPositionNegative ); } // Rotate the label position (not the label itself) if the diagram is rotated so that the defaults still work if ( isTransposed() ) { KChartEnums::PositionValue posValue = relPos.referencePosition().value(); if ( posValue >= KChartEnums::PositionNorthWest && posValue <= KChartEnums::PositionWest ) { // rotate 90 degrees clockwise posValue = static_cast< KChartEnums::PositionValue >( posValue + 2 ); if ( posValue > KChartEnums::PositionWest ) { // wraparound posValue = static_cast< KChartEnums::PositionValue >( posValue - ( KChartEnums::PositionWest - KChartEnums::PositionNorthWest ) ); } relPos.setReferencePosition( Position( posValue ) ); } } const QPointF referencePoint = relPos.referencePoint(); if ( !diagram->coordinatePlane()->isVisiblePoint( referencePoint ) ) { continue; } const qreal fontHeight = cachedFontMetrics( dva.textAttributes(). calculatedFont( plane, KChartEnums::MeasureOrientationMinimum ), diagram )->height(); // Note: When printing data value texts and padding's Measure is using automatic reference area // detection, the font height is used as reference size for both horizontal and vertical // padding. QSizeF relativeMeasureSize( fontHeight, fontHeight ); if ( !dva.textAttributes().hasRotation() ) { TextAttributes ta = dva.textAttributes(); ta.setRotation( favoriteAngle ); dva.setTextAttributes( ta ); } // get the size of the label text using a subset of the information going into the final layout const QString text = formatDataValueText( dva, index, value ); QTextDocument doc; doc.setDocumentMargin( 0 ); if ( Qt::mightBeRichText( text ) ) { doc.setHtml( text ); } else { doc.setPlainText( text ); } const QFont calculatedFont( dva.textAttributes() .calculatedFont( plane, KChartEnums::MeasureOrientationMinimum ) ); doc.setDefaultFont( calculatedFont ); const QRectF plainRect = doc.documentLayout()->frameBoundingRect( doc.rootFrame() ); /** * A few hints on how the positioning of the text frame is done: * * Let's assume we have a bar chart, a text for a positive value * to be drawn, and "North" as attrs.positivePosition(). * * The reference point (pos) is then set to the top center point * of a bar. The offset now depends on the alignment: * * Top: text is centered horizontally to the bar, bottom of * text frame starts at top of bar * * Bottom: text is centered horizontally to the bar, top of * text frame starts at top of bar * * Center: text is centered horizontally to the bar, center * line of text frame is same as top of bar * * TopLeft: right edge of text frame is horizontal center of * bar, bottom of text frame is top of bar. * * ... * * Positive and negative value labels are treated equally, "North" * also refers to the top of a negative bar, and *not* to the bottom. * * * "NorthEast" likewise refers to the top right edge of the bar, * "NorthWest" to the top left edge of the bar, and so on. * * In other words, attrs.positivePosition() always refers to a * position of the *bar*, and relPos.alignment() always refers * to an alignment of the text frame relative to this position. */ QTransform transform; { // move to the general area where the label should be QPointF calcPoint = relPos.calculatedPoint( relativeMeasureSize ); transform.translate( calcPoint.x(), calcPoint.y() ); // align the text rect; find out by how many half-widths / half-heights to move. int dx = -1; if ( relPos.alignment() & Qt::AlignLeft ) { dx -= 1; } else if ( relPos.alignment() & Qt::AlignRight ) { dx += 1; } int dy = -1; if ( relPos.alignment() & Qt::AlignTop ) { dy -= 1; } else if ( relPos.alignment() & Qt::AlignBottom ) { dy += 1; } transform.translate( qreal( dx ) * plainRect.width() * 0.5, qreal( dy ) * plainRect.height() * 0.5 ); // rotate the text rect around its center transform.translate( plainRect.center().x(), plainRect.center().y() ); int rotation = dva.textAttributes().rotation(); if ( !isPositive && dva.mirrorNegativeValueTextRotation() ) { rotation *= -1; } transform.rotate( rotation ); transform.translate( -plainRect.center().x(), -plainRect.center().y() ); } QPainterPath labelArea; //labelArea.addPolygon( transform.mapToPolygon( plainRect.toRect() ) ); //labelArea.closeSubpath(); // Not doing that because QTransform has a special case for 180° that gives a different than // usual ordering of the points in the polygon returned by mapToPolygon( const QRect & ). // We expect a particular ordering in paintDataValueTextsAndMarkers() by using elementAt( 0 ), // and similar things might happen elsewhere. labelArea.addPolygon( transform.map( QPolygon( plainRect.toRect(), true ) ) ); // store the label geometry and auxiliary data cache->paintReplay.append( LabelPaintInfo( it.key(), dva, labelArea, referencePoint, value >= 0.0, text ) ); } }