From 3fdf1960a0ba975a93b0aeac59eb5ec1dbecc62a Mon Sep 17 00:00:00 2001 From: Jason Harris Date: Sun, 29 Oct 2006 21:31:43 +0000 Subject: [PATCH] Draw a line from a data point to its label if the label is not very near the point. When a line is drawn, it also draws a rounded rectangle around the label text. CCMAIL: kde-edu@kde.org svn path=/trunk/KDE/kdeedu/libkdeedu/; revision=600211 --- kdeeduplot/kplotwidget.cpp | 46 +++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/kdeeduplot/kplotwidget.cpp b/kdeeduplot/kplotwidget.cpp index db63d00..77474af 100644 --- a/kdeeduplot/kplotwidget.cpp +++ b/kdeeduplot/kplotwidget.cpp @@ -36,12 +36,7 @@ #define YPADDING 20 #define BIGTICKSIZE 10 #define SMALLTICKSIZE 4 - -//Different architectures seem to draw the tickmarks differently. -#define TICKOFFSET 2 -#if defined DARWIN #define TICKOFFSET 0 -#endif KPlotWidget::KPlotWidget( QWidget *parent, double x1, double x2, double y1, double y2 ) : QFrame( parent ), ShowGrid( false ), ShowObjectToolTips( true ), UseAntialias( false ) @@ -307,8 +302,9 @@ void KPlotWidget::maskAlongLine( const QPointF &p1, const QPointF &p2, float val } void KPlotWidget::placeLabel( QPainter *painter, KPlotPoint *pp ) { - int textFlags = Qt::TextSingleLine | Qt::AlignLeft | Qt::AlignTop; + int textFlags = Qt::TextSingleLine | Qt::AlignCenter; + float rbest = 100; float bestCost = 1.0e7; QPointF pos = toScreen( pp->position() ); QRectF bestRect; @@ -319,13 +315,16 @@ void KPlotWidget::placeLabel( QPainter *painter, KPlotPoint *pp ) { for ( int iy=iy0-20; iy= 0 && ix < 100 ) && ( iy >= 0 && iy < 100 ) ) { QRectF labelRect = painter->boundingRect( QRectF( px[ix], py[iy], 1, 1 ), textFlags, pp->label() ); - + //Add some padding to labelRect + labelRect.adjust( -2, -2, 2, 2 ); + float r = sqrt( (ix-ix0)*(ix-ix0) + (iy-iy0)*(iy-iy0) ); float cost = rectCost( labelRect ) + 0.1*r; if ( cost < bestCost ) { bestRect = labelRect; bestCost = cost; + rbest = r; } } } @@ -333,10 +332,35 @@ void KPlotWidget::placeLabel( QPainter *painter, KPlotPoint *pp ) { painter->drawText( bestRect, textFlags, pp->label() ); - //DEBUG_LABEL_RECT - //painter->setBrush( QBrush() ); - //painter->drawRect( bestRect ); - + //Is a line needed to connect the label to the point? + if ( rbest > 2.0 ) { + //Draw a rectangle around the label + painter->setBrush( QBrush() ); + //QPen pen = painter->pen(); + //pen.setStyle( Qt::DotLine ); + //painter->setPen( pen ); + painter->drawRoundRect( bestRect ); + + //Now connect the label to the point with a line. + //The line is drawn from the center of the near edge of the rectangle + float xline = bestRect.center().x(); + if ( bestRect.left() > pos.x() ) + xline = bestRect.left(); + if ( bestRect.right() < pos.x() ) + xline = bestRect.right(); + + float yline = bestRect.center().y(); + if ( bestRect.top() > pos.y() ) + yline = bestRect.top(); + if ( bestRect.bottom() < pos.y() ) + yline = bestRect.bottom(); + + //DEBUG + kDebug() << pp->label() << ": ( " << xline << ", " << yline << " ) " << bestRect << endl; + + painter->drawLine( QPointF( xline, yline ), pos ); + } + //Mask the label's rectangle so other labels won't overlap it. maskRect( bestRect ); } -- 2.47.3