#include <KDChartCartesianAxis.h>
For being useful, axes need to be assigned to a diagram, see AbstractCartesianDiagram::addAxis and AbstractCartesianDiagram::takeAxis.
Definition at line 48 of file KDChartCartesianAxis.h.
Public Types | |
enum | Position { Bottom, Top, Right, Left } |
Public Slots | |
void | setCachedSizeDirty () const |
int | tickLength (bool subUnitTicks=false) const |
void | update () |
Signals | |
void | positionChanged (AbstractArea *) |
Public Member Functions | |
void | alignToReferencePoint (const RelativePosition &position) |
QMap< double, QString > | annotations () const |
Returns the currently set axis annotations. | |
BackgroundAttributes | backgroundAttributes () const |
virtual int | bottomOverlap (bool doNotRecalculate=false) const |
This is called at layout time by KDChart:AutoSpacerLayoutItem::sizeHint(). | |
CartesianAxis (AbstractCartesianDiagram *diagram=0) | |
C'tor of the class for cartesian axes. | |
bool | compare (const AbstractAreaBase *other) const |
Returns true if both areas have the same settings. | |
bool | compare (const AbstractAxis *other) const |
Returns true if both axes have the same settings. | |
bool | compare (const CartesianAxis *other) const |
Returns true if both axes have the same settings. | |
virtual void | connectSignals () |
Wireing the signal/slot connections. | |
const AbstractCoordinatePlane * | coordinatePlane () const |
Convenience function, returns the coordinate plane, in which this axis is used. | |
void | createObserver (AbstractDiagram *diagram) |
virtual const QString | customizedLabel (const QString &label) const |
Implement this method if you want to adjust axis labels before they are printed. | |
void | deleteObserver (AbstractDiagram *diagram) |
const AbstractDiagram * | diagram () const |
virtual Qt::Orientations | expandingDirections () const |
pure virtual in QLayoutItem | |
FrameAttributes | frameAttributes () const |
virtual QRect | geometry () const |
pure virtual in QLayoutItem | |
void | getFrameLeadings (int &left, int &top, int &right, int &bottom) const |
bool | hasDefaultTitleTextAttributes () const |
virtual bool | isAbscissa () const |
virtual bool | isEmpty () const |
pure virtual in QLayoutItem | |
virtual bool | isOrdinate () const |
QStringList | labels () const |
Returns a list of strings, that are used as axis labels, as set via setLabels. | |
virtual void | layoutPlanes () |
virtual int | leftOverlap (bool doNotRecalculate=false) const |
This is called at layout time by KDChart::AutoSpacerLayoutItem::sizeHint(). | |
virtual QSize | maximumSize () const |
pure virtual in QLayoutItem | |
virtual QSize | minimumSize () const |
pure virtual in QLayoutItem | |
bool | observedBy (AbstractDiagram *diagram) const |
virtual void | paint (QPainter *) |
reimpl | |
virtual void | paintAll (QPainter &painter) |
Call paintAll, if you want the background and the frame to be drawn before the normal paint() is invoked automatically. | |
virtual void | paintBackground (QPainter &painter, const QRect &rectangle) |
virtual void | paintCtx (PaintContext *) |
reimpl | |
virtual void | paintFrame (QPainter &painter, const QRect &rectangle) |
virtual void | paintIntoRect (QPainter &painter, const QRect &rect) |
Draws the background and frame, then calls paint(). | |
QLayout * | parentLayout () |
virtual const Position | position () const |
void | removeFromParentLayout () |
void | resetTitleTextAttributes () |
Reset the title text attributes to the built-in default:. | |
virtual int | rightOverlap (bool doNotRecalculate=false) const |
This is called at layout time by KDChart::AutoSpacerLayoutItem::sizeHint(). | |
RulerAttributes | rulerAttributes () const |
Returns the attributes to be used for painting the rulers. | |
void | setAnnotations (const QMap< double, QString > &annotations) |
Sets the axis annotations to annotations. | |
void | setBackgroundAttributes (const BackgroundAttributes &a) |
void | setFrameAttributes (const FrameAttributes &a) |
virtual void | setGeometry (const QRect &r) |
pure virtual in QLayoutItem | |
void | setLabels (const QStringList &list) |
Use this to specify your own set of strings, to be used as axis labels. | |
void | setParentLayout (QLayout *lay) |
virtual void | setParentWidget (QWidget *widget) |
Inform the item about its widget: This enables the item, to trigger that widget's update, whenever the size of the item's contents has changed. | |
virtual void | setPosition (Position p) |
void | setRulerAttributes (const RulerAttributes &a) |
Use this to specify the attributes used to paint the axis ruler. | |
void | setShortLabels (const QStringList &list) |
Use this to specify your own set of strings, to be used as axis labels, in case the normal labels are too long. | |
void | setTextAttributes (const TextAttributes &a) |
Use this to specify the text attributes to be used for axis labels. | |
void | setTitleText (const QString &text) |
void | setTitleTextAttributes (const TextAttributes &a) |
QStringList | shortLabels () const |
Returns a list of strings, that are used as axis labels, as set via setShortLabels. | |
virtual QSize | sizeHint () const |
pure virtual in QLayoutItem | |
virtual void | sizeHintChanged () const |
Report changed size hint: ask the parent widget to recalculate the layout. | |
TextAttributes | textAttributes () const |
Returns the text attributes to be used for axis labels. | |
QString | titleText () const |
TextAttributes | titleTextAttributes () const |
Returns the text attributes that will be used for displaying the title text. | |
virtual int | topOverlap (bool doNotRecalculate=false) const |
This is called at layout time by KDChart::AutoSpacerLayoutItem::sizeHint(). | |
~CartesianAxis () | |
Static Public Member Functions | |
static void | paintBackgroundAttributes (QPainter &painter, const QRect &rectangle, const KDChart::BackgroundAttributes &attributes) |
static void | paintFrameAttributes (QPainter &painter, const QRect &rectangle, const KDChart::FrameAttributes &attributes) |
Protected Slots | |
virtual void | delayedInit () |
called for initializing after the c'tor has completed | |
Protected Member Functions | |
virtual QRect | areaGeometry () const |
QRect | innerRect () const |
virtual void | positionHasChanged () |
Protected Attributes | |
QWidget * | mParent |
QLayout * | mParentLayout |
CartesianAxis::CartesianAxis | ( | AbstractCartesianDiagram * | diagram = 0 |
) | [explicit] |
C'tor of the class for cartesian axes.
Definition at line 56 of file KDChartCartesianAxis.cpp.
References StockDiagram::init().
00057 : AbstractAxis ( new Private( diagram, this ), diagram ) 00058 { 00059 init(); 00060 }
CartesianAxis::~CartesianAxis | ( | ) |
Definition at line 62 of file KDChartCartesianAxis.cpp.
References d, KDChart::AbstractAxis::diagram(), and KDChart::AbstractCartesianDiagram::takeAxis().
00063 { 00064 // when we remove the first axis it will unregister itself and 00065 // propagate the next one to the primary, thus the while loop 00066 while ( d->mDiagram ) { 00067 AbstractCartesianDiagram *cd = qobject_cast<AbstractCartesianDiagram*>( d->mDiagram ); 00068 cd->takeAxis( this ); 00069 } 00070 Q_FOREACH( AbstractDiagram *diagram, d->secondaryDiagrams ) { 00071 AbstractCartesianDiagram *cd = qobject_cast<AbstractCartesianDiagram*>( diagram ); 00072 cd->takeAxis( this ); 00073 } 00074 }
void AbstractAreaBase::alignToReferencePoint | ( | const RelativePosition & | position | ) | [inherited] |
Definition at line 91 of file KDChartAbstractAreaBase.cpp.
00092 { 00093 Q_UNUSED( position ); 00094 // PENDING(kalle) FIXME 00095 qWarning( "Sorry, not implemented: void AbstractAreaBase::alignToReferencePoint( const RelativePosition& position )" ); 00096 }
QMap< double, QString > CartesianAxis::annotations | ( | ) | const |
Returns the currently set axis annotations.
Definition at line 1769 of file KDChartCartesianAxis.cpp.
References d.
Referenced by paintCtx().
01770 { 01771 return d->annotations; 01772 }
QRect AbstractArea::areaGeometry | ( | ) | const [protected, virtual, inherited] |
Implements KDChart::AbstractAreaBase.
Definition at line 150 of file KDChartAbstractArea.cpp.
Referenced by KDChart::CartesianCoordinatePlane::drawingArea(), KDChart::TernaryCoordinatePlane::layoutDiagrams(), KDChart::PolarCoordinatePlane::layoutDiagrams(), KDChart::TernaryCoordinatePlane::paint(), paint(), KDChart::AbstractArea::paintAll(), and paintCtx().
BackgroundAttributes AbstractAreaBase::backgroundAttributes | ( | ) | const [inherited] |
Definition at line 121 of file KDChartAbstractAreaBase.cpp.
References d.
Referenced by KDChart::AbstractAreaBase::compare(), and updateCommonBrush().
00122 { 00123 return d->backgroundAttributes; 00124 }
int AbstractArea::bottomOverlap | ( | bool | doNotRecalculate = false |
) | const [virtual, inherited] |
This is called at layout time by KDChart:AutoSpacerLayoutItem::sizeHint().
The method triggers AbstractArea::sizeHint() to find out the amount of overlap at the bottom edge of the area.
Definition at line 101 of file KDChartAbstractArea.cpp.
References d.
Referenced by KDChart::AutoSpacerLayoutItem::sizeHint().
00102 { 00103 // Re-calculate the sizes, 00104 // so we also get the amountOf..Overlap members set newly: 00105 if( ! doNotRecalculate ) 00106 sizeHint(); 00107 return d->amountOfBottomOverlap; 00108 }
bool AbstractAreaBase::compare | ( | const AbstractAreaBase * | other | ) | const [inherited] |
Returns true if both areas have the same settings.
Definition at line 76 of file KDChartAbstractAreaBase.cpp.
References KDChart::AbstractAreaBase::backgroundAttributes(), and KDChart::AbstractAreaBase::frameAttributes().
00077 { 00078 if( other == this ) return true; 00079 if( ! other ){ 00080 //qDebug() << "CartesianAxis::compare() cannot compare to Null pointer"; 00081 return false; 00082 } 00083 /* 00084 qDebug() << "AbstractAreaBase:" << (frameAttributes() == other->frameAttributes()) 00085 << (backgroundAttributes() == other->backgroundAttributes()) << "\n"; 00086 */ 00087 return (frameAttributes() == other->frameAttributes()) && 00088 (backgroundAttributes() == other->backgroundAttributes()); 00089 }
bool AbstractAxis::compare | ( | const AbstractAxis * | other | ) | const [inherited] |
Returns true if both axes have the same settings.
Definition at line 142 of file KDChartAbstractAxis.cpp.
References KDChart::AbstractAxis::labels(), KDChart::AbstractAxis::shortLabels(), and KDChart::AbstractAxis::textAttributes().
00143 { 00144 if( other == this ) return true; 00145 if( ! other ){ 00146 //qDebug() << "CartesianAxis::compare() cannot compare to Null pointer"; 00147 return false; 00148 } 00149 /* 00150 qDebug() << (textAttributes() == other->textAttributes()); 00151 qDebug() << (labels() == other->labels()); 00152 qDebug() << (shortLabels() == other->shortLabels()); 00153 */ 00154 return ( static_cast<const AbstractAreaBase*>(this)->compare( other ) ) && 00155 (textAttributes() == other->textAttributes()) && 00156 (labels() == other->labels()) && 00157 (shortLabels() == other->shortLabels()); 00158 }
bool CartesianAxis::compare | ( | const CartesianAxis * | other | ) | const |
Returns true if both axes have the same settings.
Definition at line 83 of file KDChartCartesianAxis.cpp.
References position(), titleText(), and titleTextAttributes().
00084 { 00085 if( other == this ) return true; 00086 if( ! other ){ 00087 //qDebug() << "CartesianAxis::compare() cannot compare to Null pointer"; 00088 return false; 00089 } 00090 /* 00091 qDebug() << (position() == other->position()); 00092 qDebug() << (titleText() == other->titleText()); 00093 qDebug() << (titleTextAttributes() == other->titleTextAttributes()); 00094 */ 00095 return ( static_cast<const AbstractAxis*>(this)->compare( other ) ) && 00096 ( position() == other->position() ) && 00097 ( titleText() == other->titleText() ) && 00098 ( titleTextAttributes() == other->titleTextAttributes() ); 00099 }
void AbstractAxis::connectSignals | ( | ) | [virtual, inherited] |
Wireing the signal/slot connections.
This method gets called automatically, each time, when you assign the axis to a diagram, either by passing a diagram* to the c'tor, or by calling the diagram's setAxis method, resp.
If overwriting this method in derived classes, make sure to call this base method AbstractAxis::connectSignals(), so your axis gets connected to the diagram's built-in signals.
Definition at line 211 of file KDChartAbstractAxis.cpp.
References d, and KDChart::AbstractAxis::update().
Referenced by KDChart::AbstractAxis::createObserver().
00212 { 00213 if( d->observer ){ 00214 connect( d->observer, SIGNAL( diagramDataChanged( AbstractDiagram *) ), 00215 this, SLOT( update() ) ); 00216 } 00217 }
const AbstractCoordinatePlane * AbstractAxis::coordinatePlane | ( | ) | const [inherited] |
Convenience function, returns the coordinate plane, in which this axis is used.
If the axis is not used in a coordinate plane, the return value is Zero.
Definition at line 349 of file KDChartAbstractAxis.cpp.
References d.
Referenced by KDChart::CartesianCoordinatePlane::sharedAxisMasterPlane().
00350 { 00351 if( d->diagram() ) 00352 return d->diagram()->coordinatePlane(); 00353 return 0; 00354 }
void AbstractAxis::createObserver | ( | AbstractDiagram * | diagram | ) | [inherited] |
Definition at line 177 of file KDChartAbstractAxis.cpp.
References KDChart::AbstractAxis::connectSignals(), and d.
Referenced by KDChart::AbstractCartesianDiagram::addAxis().
00178 { 00179 if( d->setDiagram( diagram ) ) 00180 connectSignals(); 00181 }
const QString AbstractAxis::customizedLabel | ( | const QString & | label | ) | const [virtual, inherited] |
Implement this method if you want to adjust axis labels before they are printed.
KD Chart is calling this method immediately before drawing the text, this means: What you return here will be drawn without further modifications.
label | The text of the label as KD Chart has calculated it automatically (or as it was taken from a QStringList provided by you, resp.) |
label
. Definition at line 161 of file KDChartAbstractAxis.cpp.
Referenced by KDChart::LeveyJenningsAxis::paintAsOrdinate(), and paintCtx().
void AbstractAxis::delayedInit | ( | ) | [protected, virtual, slot, inherited] |
called for initializing after the c'tor has completed
Definition at line 134 of file KDChartAbstractAxis.cpp.
References d.
Referenced by KDChart::AbstractAxis::AbstractAxis().
00135 { 00136 // We call setDiagram() here, because the c'tor of Private 00137 // only has stored the pointers, but it did not call setDiagram(). 00138 if( d ) 00139 d->setDiagram( 0, true /* delayedInit */ ); 00140 }
void AbstractAxis::deleteObserver | ( | AbstractDiagram * | diagram | ) | [inherited] |
Definition at line 193 of file KDChartAbstractAxis.cpp.
References d.
Referenced by KDChart::AbstractCartesianDiagram::takeAxis(), and KDChart::AbstractCartesianDiagram::~AbstractCartesianDiagram().
00194 { 00195 d->unsetDiagram( diagram ); 00196 }
const AbstractDiagram * KDChart::AbstractAxis::diagram | ( | ) | const [inherited] |
Definition at line 356 of file KDChartAbstractAxis.cpp.
References d.
Referenced by paintCtx(), ~CartesianAxis(), and KDChart::LeveyJenningsAxis::~LeveyJenningsAxis().
00357 { 00358 return d->diagram(); 00359 }
Qt::Orientations CartesianAxis::expandingDirections | ( | ) | const [virtual] |
pure virtual in QLayoutItem
Definition at line 1400 of file KDChartCartesianAxis.cpp.
References Bottom, Left, position(), Right, and Top.
01401 { 01402 Qt::Orientations ret; 01403 switch ( position() ) 01404 { 01405 case Bottom: 01406 case Top: 01407 ret = Qt::Horizontal; 01408 break; 01409 case Left: 01410 case Right: 01411 ret = Qt::Vertical; 01412 break; 01413 default: 01414 Q_ASSERT( false ); // all positions need to be handeld 01415 break; 01416 }; 01417 return ret; 01418 }
FrameAttributes AbstractAreaBase::frameAttributes | ( | ) | const [inherited] |
Definition at line 107 of file KDChartAbstractAreaBase.cpp.
References d.
Referenced by KDChart::Legend::clone(), KDChart::AbstractAreaBase::compare(), and updateCommonBrush().
00108 { 00109 return d->frameAttributes; 00110 }
QRect CartesianAxis::geometry | ( | ) | const [virtual] |
pure virtual in QLayoutItem
Implements KDChart::AbstractAxis.
Definition at line 1748 of file KDChartCartesianAxis.cpp.
References d.
Referenced by KDChart::LeveyJenningsAxis::paintAsAbscissa(), KDChart::LeveyJenningsAxis::paintAsOrdinate(), and paintCtx().
01749 { 01750 return d->geometry; 01751 }
void AbstractAreaBase::getFrameLeadings | ( | int & | left, | |
int & | top, | |||
int & | right, | |||
int & | bottom | |||
) | const [inherited] |
Definition at line 213 of file KDChartAbstractAreaBase.cpp.
References d.
Referenced by KDChart::AbstractAreaBase::innerRect(), and KDChart::AbstractAreaWidget::paintAll().
00214 { 00215 if( d && d->frameAttributes.isVisible() ){ 00216 const int padding = qMax( d->frameAttributes.padding(), 0 ); 00217 left = padding; 00218 top = padding; 00219 right = padding; 00220 bottom = padding; 00221 }else{ 00222 left = 0; 00223 top = 0; 00224 right = 0; 00225 bottom = 0; 00226 } 00227 }
bool CartesianAxis::hasDefaultTitleTextAttributes | ( | ) | const |
Definition at line 138 of file KDChartCartesianAxis.cpp.
References d.
Referenced by titleTextAttributes().
00139 { 00140 return d->useDefaultTextAttributes; 00141 }
QRect AbstractAreaBase::innerRect | ( | ) | const [protected, inherited] |
Definition at line 229 of file KDChartAbstractAreaBase.cpp.
References KDChart::AbstractAreaBase::areaGeometry(), and KDChart::AbstractAreaBase::getFrameLeadings().
Referenced by KDChart::TextArea::paintAll(), and KDChart::AbstractArea::paintAll().
00230 { 00231 int left; 00232 int top; 00233 int right; 00234 int bottom; 00235 getFrameLeadings( left, top, right, bottom ); 00236 return 00237 QRect( QPoint(0,0), areaGeometry().size() ) 00238 .adjusted( left, top, -right, -bottom ); 00239 }
bool CartesianAxis::isAbscissa | ( | ) | const [virtual] |
Definition at line 216 of file KDChartCartesianAxis.cpp.
References Bottom, d, Left, position(), referenceDiagramIsBarDiagram(), Right, and Top.
Referenced by KDChart::LeveyJenningsAxis::paintAsAbscissa(), paintCtx(), KDChart::CartesianCoordinatePlane::sharedAxisMasterPlane(), and tickLength().
00217 { 00218 const Qt::Orientation diagramOrientation = referenceDiagramIsBarDiagram( d->diagram() ) ? ((BarDiagram*)(d->diagram()))->orientation() 00219 : Qt::Vertical; 00220 return diagramOrientation == Qt::Vertical ? position() == Bottom || position() == Top 00221 : position() == Left || position() == Right; 00222 }
bool CartesianAxis::isEmpty | ( | ) | const [virtual] |
pure virtual in QLayoutItem
Definition at line 1395 of file KDChartCartesianAxis.cpp.
Referenced by paintCtx().
bool CartesianAxis::isOrdinate | ( | ) | const [virtual] |
Definition at line 224 of file KDChartCartesianAxis.cpp.
References Bottom, d, Left, position(), referenceDiagramIsBarDiagram(), Right, and Top.
Referenced by KDChart::LeveyJenningsAxis::paintAsOrdinate(), KDChart::LeveyJenningsAxis::paintCtx(), paintCtx(), and KDChart::CartesianCoordinatePlane::sharedAxisMasterPlane().
00225 { 00226 const Qt::Orientation diagramOrientation = referenceDiagramIsBarDiagram( d->diagram() ) ? ((BarDiagram*)(d->diagram()))->orientation() 00227 : Qt::Vertical; 00228 return diagramOrientation == Qt::Vertical ? position() == Left || position() == Right 00229 : position() == Bottom || position() == Top; 00230 }
QStringList AbstractAxis::labels | ( | ) | const [inherited] |
Returns a list of strings, that are used as axis labels, as set via setLabels.
Definition at line 306 of file KDChartAbstractAxis.cpp.
References d.
Referenced by KDChart::AbstractAxis::compare(), KDChart::LeveyJenningsAxis::paintAsOrdinate(), KDChart::TernaryAxis::paintCtx(), and paintCtx().
00307 { 00308 return d->hardLabels; 00309 }
void CartesianAxis::layoutPlanes | ( | ) | [virtual] |
Definition at line 158 of file KDChartCartesianAxis.cpp.
References d, and KDChart::AbstractCoordinatePlane::layoutPlanes().
Referenced by resetTitleTextAttributes(), setPosition(), setTitleText(), and setTitleTextAttributes().
00159 { 00160 //qDebug() << "CartesianAxis::layoutPlanes()"; 00161 if( ! d->diagram() || ! d->diagram()->coordinatePlane() ) { 00162 //qDebug() << "CartesianAxis::layoutPlanes(): Sorry, found no plane."; 00163 return; 00164 } 00165 AbstractCoordinatePlane* plane = d->diagram()->coordinatePlane(); 00166 if( plane ){ 00167 plane->layoutPlanes(); 00168 //qDebug() << "CartesianAxis::layoutPlanes() OK"; 00169 } 00170 }
int AbstractArea::leftOverlap | ( | bool | doNotRecalculate = false |
) | const [virtual, inherited] |
This is called at layout time by KDChart::AutoSpacerLayoutItem::sizeHint().
The method triggers AbstractArea::sizeHint() to find out the amount of overlap at the left edge of the area.
Definition at line 77 of file KDChartAbstractArea.cpp.
References d.
Referenced by KDChart::AutoSpacerLayoutItem::sizeHint().
00078 { 00079 // Re-calculate the sizes, 00080 // so we also get the amountOf..Overlap members set newly: 00081 if( ! doNotRecalculate ) 00082 sizeHint(); 00083 return d->amountOfLeftOverlap; 00084 }
QSize CartesianAxis::maximumSize | ( | ) | const [virtual] |
pure virtual in QLayoutItem
Definition at line 1452 of file KDChartCartesianAxis.cpp.
References d.
Referenced by minimumSize(), and sizeHint().
01453 { 01454 if( ! d->cachedMaximumSize.isValid() ) 01455 d->cachedMaximumSize = d->calculateMaximumSize(); 01456 return d->cachedMaximumSize; 01457 }
QSize CartesianAxis::minimumSize | ( | ) | const [virtual] |
pure virtual in QLayoutItem
Definition at line 1730 of file KDChartCartesianAxis.cpp.
References maximumSize().
01731 { 01732 return maximumSize(); 01733 }
bool KDChart::AbstractAxis::observedBy | ( | AbstractDiagram * | diagram | ) | const [inherited] |
Definition at line 361 of file KDChartAbstractAxis.cpp.
References d.
00362 { 00363 return d->hasDiagram( diagram ); 00364 }
void CartesianAxis::paint | ( | QPainter * | painter | ) | [virtual] |
reimpl
Implements KDChart::AbstractLayoutItem.
Definition at line 232 of file KDChartCartesianAxis.cpp.
References KDChart::AbstractArea::areaGeometry(), d, paintCtx(), KDChart::PaintContext::setCoordinatePlane(), KDChart::PaintContext::setPainter(), and KDChart::PaintContext::setRectangle().
00233 { 00234 if( ! d->diagram() || ! d->diagram()->coordinatePlane() ) return; 00235 PaintContext ctx; 00236 ctx.setPainter ( painter ); 00237 ctx.setCoordinatePlane( d->diagram()->coordinatePlane() ); 00238 const QRect rect( areaGeometry() ); 00239 00240 //qDebug() << "CartesianAxis::paint( QPainter* painter ) " << " areaGeometry()():" << rect << " sizeHint():" << sizeHint(); 00241 00242 ctx.setRectangle( 00243 QRectF ( 00244 //QPointF(0, 0), 00245 QPointF(rect.left(), rect.top()), 00246 QSizeF(rect.width(), rect.height() ) ) ); 00247 // enabling clipping so that we're not drawing outside 00248 QRegion clipRegion( rect.adjusted( -1, -1, 1, 1 ) ); 00249 painter->save(); 00250 painter->setClipRegion( clipRegion ); 00251 paintCtx( &ctx ); 00252 painter->restore(); 00253 //qDebug() << "KDChart::CartesianAxis::paint() done."; 00254 }
void AbstractArea::paintAll | ( | QPainter & | painter | ) | [virtual, inherited] |
Call paintAll, if you want the background and the frame to be drawn before the normal paint() is invoked automatically.
Reimplemented from KDChart::AbstractLayoutItem.
Reimplemented in KDChart::TernaryAxis.
Definition at line 123 of file KDChartAbstractArea.cpp.
References KDChart::AbstractArea::areaGeometry(), d, KDChart::AbstractAreaBase::innerRect(), KDChart::AbstractLayoutItem::paint(), KDChart::AbstractAreaBase::paintBackground(), and KDChart::AbstractAreaBase::paintFrame().
Referenced by KDChart::AbstractArea::paintIntoRect().
00124 { 00125 // Paint the background and frame 00126 const QRect overlappingArea( geometry().adjusted( 00127 -d->amountOfLeftOverlap, 00128 -d->amountOfTopOverlap, 00129 d->amountOfRightOverlap, 00130 d->amountOfBottomOverlap ) ); 00131 paintBackground( painter, overlappingArea ); 00132 paintFrame( painter, overlappingArea ); 00133 00134 // temporarily adjust the widget size, to be sure all content gets calculated 00135 // to fit into the inner rectangle 00136 const QRect oldGeometry( areaGeometry() ); 00137 QRect inner( innerRect() ); 00138 inner.moveTo( 00139 oldGeometry.left() + inner.left(), 00140 oldGeometry.top() + inner.top() ); 00141 const bool needAdjustGeometry = oldGeometry != inner; 00142 if( needAdjustGeometry ) 00143 setGeometry( inner ); 00144 paint( &painter ); 00145 if( needAdjustGeometry ) 00146 setGeometry( oldGeometry ); 00147 //qDebug() << "AbstractAreaWidget::paintAll() done."; 00148 }
void AbstractAreaBase::paintBackground | ( | QPainter & | painter, | |
const QRect & | rectangle | |||
) | [virtual, inherited] |
Definition at line 197 of file KDChartAbstractAreaBase.cpp.
References d, and KDChart::AbstractAreaBase::paintBackgroundAttributes().
Referenced by KDChart::TextArea::paintAll(), KDChart::AbstractAreaWidget::paintAll(), and KDChart::AbstractArea::paintAll().
00198 { 00199 Q_ASSERT_X ( d != 0, "AbstractAreaBase::paintBackground()", 00200 "Private class was not initialized!" ); 00201 paintBackgroundAttributes( painter, rect, d->backgroundAttributes ); 00202 }
void AbstractAreaBase::paintBackgroundAttributes | ( | QPainter & | painter, | |
const QRect & | rectangle, | |||
const KDChart::BackgroundAttributes & | attributes | |||
) | [static, inherited] |
Definition at line 128 of file KDChartAbstractAreaBase.cpp.
References KDChart::BackgroundAttributes::BackgroundPixmapModeCentered, KDChart::BackgroundAttributes::BackgroundPixmapModeNone, KDChart::BackgroundAttributes::BackgroundPixmapModeScaled, KDChart::BackgroundAttributes::BackgroundPixmapModeStretched, KDChart::BackgroundAttributes::brush(), KDChart::BackgroundAttributes::isVisible(), m, KDChart::BackgroundAttributes::pixmap(), and KDChart::BackgroundAttributes::pixmapMode().
Referenced by KDChart::AbstractAreaBase::paintBackground().
00130 { 00131 if( !attributes.isVisible() ) return; 00132 00133 /* first draw the brush (may contain a pixmap)*/ 00134 if( Qt::NoBrush != attributes.brush().style() ) { 00135 KDChart::PainterSaver painterSaver( &painter ); 00136 painter.setPen( Qt::NoPen ); 00137 const QPointF newTopLeft( painter.deviceMatrix().map( rect.topLeft() ) ); 00138 painter.setBrushOrigin( newTopLeft ); 00139 painter.setBrush( attributes.brush() ); 00140 painter.drawRect( rect.adjusted( 0, 0, -1, -1 ) ); 00141 } 00142 /* next draw the backPixmap over the brush */ 00143 if( !attributes.pixmap().isNull() && 00144 attributes.pixmapMode() != BackgroundAttributes::BackgroundPixmapModeNone ) { 00145 QPointF ol = rect.topLeft(); 00146 if( BackgroundAttributes::BackgroundPixmapModeCentered == attributes.pixmapMode() ) 00147 { 00148 ol.setX( rect.center().x() - attributes.pixmap().width() / 2 ); 00149 ol.setY( rect.center().y() - attributes.pixmap().height()/ 2 ); 00150 painter.drawPixmap( ol, attributes.pixmap() ); 00151 } else { 00152 QMatrix m; 00153 double zW = (double)rect.width() / (double)attributes.pixmap().width(); 00154 double zH = (double)rect.height() / (double)attributes.pixmap().height(); 00155 switch( attributes.pixmapMode() ) { 00156 case BackgroundAttributes::BackgroundPixmapModeScaled: 00157 { 00158 double z; 00159 z = qMin( zW, zH ); 00160 m.scale( z, z ); 00161 } 00162 break; 00163 case BackgroundAttributes::BackgroundPixmapModeStretched: 00164 m.scale( zW, zH ); 00165 break; 00166 default: 00167 ; // Cannot happen, previously checked 00168 } 00169 QPixmap pm = attributes.pixmap().transformed( m ); 00170 ol.setX( rect.center().x() - pm.width() / 2 ); 00171 ol.setY( rect.center().y() - pm.height()/ 2 ); 00172 painter.drawPixmap( ol, pm ); 00173 } 00174 } 00175 }
void CartesianAxis::paintCtx | ( | PaintContext * | context | ) | [virtual] |
reimpl
Reimplemented from KDChart::AbstractLayoutItem.
Reimplemented in KDChart::LeveyJenningsAxis.
Definition at line 451 of file KDChartCartesianAxis.cpp.
References annotations(), KDChart::AbstractArea::areaGeometry(), Bottom, calculateNextLabel(), KDChart::PaintContext::coordinatePlane(), KDChart::AbstractAxis::customizedLabel(), d, KDChart::AbstractAxis::diagram(), KDChart::DataDimension::distance(), KDChart::TextLayoutItem::geometry(), geometry(), KDChart::RulerAttributes::hasTickMarkPenAt(), KDChart::TextLayoutItem::intersects(), isAbscissa(), KDChart::DataDimension::isCalculated, isEmpty(), isOrdinate(), KDChart::TextAttributes::isVisible(), KDChart::AbstractAxis::labels(), Left, KDChart::AbstractCoordinatePlane::Logarithmic, KDChart::RulerAttributes::majorTickMarkPen(), KDChartEnums::MeasureOrientationMinimum, KDChart::BarDiagram::orientation(), p, KDChart::TextLayoutItem::paint(), KDChart::GlobalMeasureScaling::paintDevice(), KDChart::PaintContext::painter(), KDChart::TextAttributes::pen(), position(), KDChart::TextLayoutItem::realFont(), KDChart::AbstractCartesianDiagram::referenceDiagram(), referenceDiagramNeedsCenteredAbscissaTicks(), Right, KDChart::TextAttributes::rotation(), KDChart::AbstractAxis::rulerAttributes(), KDChart::PrintingParameters::scalePen(), KDChart::TextLayoutItem::setGeometry(), KDChart::TextLayoutItem::setText(), KDChart::AbstractAxis::shortLabels(), KDChart::RulerAttributes::showMajorTickMarks(), KDChart::RulerAttributes::showMinorTickMarks(), KDChart::TextLayoutItem::sizeHint(), KDChart::TextLayoutItem::sizeHintAndRotatedCorners(), KDChart::TextLayoutItem::sizeHintUnrotated(), KDChart::TextLayoutItem::text(), KDChart::AbstractAxis::textAttributes(), tickLength(), KDChart::RulerAttributes::tickMarkPen(), titleText(), Top, KDChart::AbstractDiagram::unitPrefix(), and KDChart::AbstractDiagram::unitSuffix().
Referenced by paint(), and KDChart::LeveyJenningsAxis::paintAsAbscissa().
00452 { 00453 00454 Q_ASSERT_X ( d->diagram(), "CartesianAxis::paint", 00455 "Function call not allowed: The axis is not assigned to any diagram." ); 00456 00457 CartesianCoordinatePlane* plane = dynamic_cast<CartesianCoordinatePlane*>(context->coordinatePlane()); 00458 Q_ASSERT_X ( plane, "CartesianAxis::paint", 00459 "Bad function call: PaintContext::coodinatePlane() NOT a cartesian plane." ); 00460 00461 // note: Not having any data model assigned is no bug 00462 // but we can not draw an axis then either. 00463 if( ! d->diagram()->model() ) 00464 return; 00465 00466 // Determine the diagram that specifies the orientation of the diagram we're painting here 00467 // That diagram is the reference diagram, if it exists, or otherwise the diagram itself. 00468 // Note: In KDChart 2.3 or earlier, only a bar diagram can be vertical instead of horizontal. 00469 const AbstractCartesianDiagram * refDiagram = qobject_cast< const AbstractCartesianDiagram * >( d->diagram() ); 00470 if( refDiagram && refDiagram->referenceDiagram() ) 00471 refDiagram = refDiagram->referenceDiagram(); 00472 const BarDiagram *barDiagram = qobject_cast< const BarDiagram* >( refDiagram ); 00473 const Qt::Orientation diagramOrientation = barDiagram ? barDiagram->orientation() : Qt::Vertical; 00474 const bool diagramIsVertical = diagramOrientation == Qt::Vertical; 00475 00476 /* 00477 * let us paint the labels at a 00478 * smaller resolution 00479 * Same mini pixel value as for 00480 * Cartesian Grid 00481 */ 00482 //const qreal MinimumPixelsBetweenRulers = 1.0; 00483 DataDimensionsList dimensions( plane->gridDimensionsList() ); 00484 //qDebug("CartesianAxis::paintCtx() gets DataDimensionsList.first(): start: %f end: %f stepWidth: %f", dimensions.first().start, dimensions.first().end, dimensions.first().stepWidth); 00485 00486 // test for programming errors: critical 00487 Q_ASSERT_X ( dimensions.count() == 2, "CartesianAxis::paint", 00488 "Error: plane->gridDimensionsList() did not return exactly two dimensions." ); 00489 DataDimension dimX, dimY; 00490 DataDimension dim; 00491 // If the diagram is horizontal, we need to inverse the x/y ranges 00492 if ( diagramIsVertical ) { 00493 /*double yStart = dimY.start; 00494 double yEnd = dimY.end; 00495 dimY.start = dimX.start; 00496 dimY.end = dimX.end; 00497 dimX.start = yStart; 00498 dimX.end = yEnd;*/ 00499 dimX = AbstractGrid::adjustedLowerUpperRange( dimensions.first(), true, true ); 00500 dimY = AbstractGrid::adjustedLowerUpperRange( dimensions.last(), true, true ); 00501 00502 // FIXME 00503 // Ugly workaround for dimensions being bound to both, the x coordinate direction and the abscissa 00504 //if ( referenceDiagramIsPercentLyingBarDiagram ) { 00505 // dimY.stepWidth = 10.0; 00506 // dimY.subStepWidth = 2.0; 00507 //} 00508 } else { 00509 dimX = AbstractGrid::adjustedLowerUpperRange( dimensions.last(), true, true ); 00510 dimY = AbstractGrid::adjustedLowerUpperRange( dimensions.first(), true, true ); 00511 } 00512 dim = (isAbscissa() ? dimX : dimY); 00513 00514 /* 00515 if(isAbscissa()) 00516 qDebug() << " " << "Abscissa:" << dimX.start <<".."<<dimX.end <<" step"<<dimX.stepWidth<<" sub step"<<dimX.subStepWidth; 00517 else 00518 qDebug() << " " << "Ordinate:" << dimY.start <<".."<<dimY.end <<" step"<<dimY.stepWidth<<" sub step"<<dimY.subStepWidth; 00519 */ 00520 00521 00522 00523 /* 00524 * let us paint the labels at a 00525 * smaller resolution 00526 * Same mini pixel value as for 00527 * Cartesian Grid 00528 */ 00529 const qreal MinimumPixelsBetweenRulers = qMin( dimX.stepWidth, dimY.stepWidth );//1.0; 00530 00531 // preparations: 00532 // - calculate the range that will be displayed: 00533 const qreal absRange = qAbs( dim.distance() ); 00534 00535 qreal numberOfUnitRulers; 00536 if ( isAbscissa() ) { 00537 if( dimX.isCalculated ) 00538 numberOfUnitRulers = absRange / qAbs( dimX.stepWidth ) + 1.0; 00539 else 00540 numberOfUnitRulers = d->diagram()->model()->rowCount(d->diagram()->rootIndex()) - 1.0; 00541 }else{ 00542 numberOfUnitRulers = absRange / qAbs( dimY.stepWidth ) + 1.0; 00543 } 00544 00545 // qDebug() << "absRange" << absRange << "dimY.stepWidth:" << dimY.stepWidth << "numberOfUnitRulers:" << numberOfUnitRulers; 00546 00547 qreal numberOfSubUnitRulers; 00548 if ( isAbscissa() ){ 00549 if( dimX.isCalculated ) 00550 numberOfSubUnitRulers = absRange / qAbs( dimX.subStepWidth ) + 1.0; 00551 else 00552 numberOfSubUnitRulers = dimX.subStepWidth>0 ? absRange / qAbs( dimX.subStepWidth ) + 1.0 : 0.0; 00553 }else{ 00554 numberOfSubUnitRulers = absRange / qAbs( dimY.subStepWidth ) + 1.0; 00555 } 00556 00557 // - calculate the absolute range in screen pixels: 00558 const QPointF p1 = plane->translate( diagramIsVertical ? QPointF(dimX.start, dimY.start) : QPointF(dimY.start, dimX.start) ); 00559 const QPointF p2 = plane->translate( diagramIsVertical ? QPointF(dimX.end, dimY.end) : QPointF(dimY.end, dimX.end ) ); 00560 00561 double screenRange; 00562 if ( isAbscissa() ) 00563 { 00564 screenRange = qAbs ( p1.x() - p2.x() ); 00565 } else { 00566 screenRange = qAbs ( p1.y() - p2.y() ); 00567 } 00568 00569 const bool useItemCountLabels = isAbscissa() && ! dimX.isCalculated; 00570 00571 // attributes used to customize ruler appearance 00572 const RulerAttributes rulerAttr = rulerAttributes(); 00573 00574 const bool drawUnitRulers = rulerAttr.showMajorTickMarks() && (screenRange / ( numberOfUnitRulers / dimX.stepWidth ) > MinimumPixelsBetweenRulers); 00575 const bool drawSubUnitRulers = rulerAttr.showMinorTickMarks() && 00576 (numberOfSubUnitRulers != 0.0) && 00577 (screenRange / numberOfSubUnitRulers > MinimumPixelsBetweenRulers); 00578 00579 const TextAttributes labelTA = textAttributes(); 00580 const bool drawLabels = labelTA.isVisible(); 00581 00582 // - find the reference point at which to start drawing and the increment (line distance); 00583 QPointF rulerRef; 00584 const QRect areaGeoRect( areaGeometry() ); 00585 const QRect geoRect( geometry() ); 00586 QRectF rulerRect; 00587 double rulerWidth; 00588 double rulerHeight; 00589 00590 QPainter* const ptr = context->painter(); 00591 00592 //for debugging: if( isAbscissa() )ptr->drawRect(areaGeoRect.adjusted(0,0,-1,-1)); 00593 //qDebug() << " " << (isAbscissa() ? "Abscissa":"Ordinate") << "axis painting with geometry" << areaGeoRect; 00594 00595 // FIXME references are of course different for all locations: 00596 rulerWidth = areaGeoRect.width(); 00597 rulerHeight = areaGeoRect.height(); 00598 switch( position() ) 00599 { 00600 case Top: 00601 rulerRef.setX( areaGeoRect.topLeft().x() ); 00602 rulerRef.setY( areaGeoRect.topLeft().y() + rulerHeight ); 00603 break; 00604 case Bottom: 00605 rulerRef.setX( areaGeoRect.bottomLeft().x() ); 00606 rulerRef.setY( areaGeoRect.bottomLeft().y() - rulerHeight ); 00607 break; 00608 case Right: 00609 rulerRef.setX( areaGeoRect.bottomRight().x() - rulerWidth ); 00610 rulerRef.setY( areaGeoRect.bottomRight().y() ); 00611 break; 00612 case Left: 00613 rulerRef.setX( areaGeoRect.bottomLeft().x() + rulerWidth ); 00614 rulerRef.setY( areaGeoRect.bottomLeft().y() ); 00615 break; 00616 } 00617 00618 // set up the lines to paint: 00619 00620 // set up a map of integer positions, 00621 00622 // - starting with the fourth 00623 // - the the halfs 00624 // - then the tens 00625 // this will override all halfs and fourth that hit a higher-order ruler 00626 // MAKE SURE TO START AT (0, 0)! 00627 00628 // set up a reference point, a step vector and a unit vector for the drawing: 00629 00630 const qreal minValueY = dimY.start; 00631 const qreal maxValueY = dimY.end; 00632 const qreal minValueX = dimX.start; 00633 const qreal maxValueX = dimX.end; 00634 const bool isLogarithmicX = (dimX.calcMode == AbstractCoordinatePlane::Logarithmic ); 00635 const bool isLogarithmicY = (dimY.calcMode == AbstractCoordinatePlane::Logarithmic ); 00636 //#define AXES_PAINTING_DEBUG 1 00637 #ifdef AXES_PAINTING_DEBUG 00638 qDebug() << "CartesianAxis::paint: reference values:" << endl 00639 << "-- range x/y: " << dimX.distance() << "/" << dimY.distance() << endl 00640 << "-- absRange: " << absRange << endl 00641 << "-- numberOfUnitRulers: " << numberOfUnitRulers << endl 00642 << "-- screenRange: " << screenRange << endl 00643 << "-- drawUnitRulers: " << drawUnitRulers << endl 00644 << "-- drawLabels: " << drawLabels << endl 00645 << "-- ruler reference point:: " << rulerRef << endl 00646 << "-- minValueX: " << minValueX << " maxValueX: " << maxValueX << endl 00647 << "-- minValueY: " << minValueY << " maxValueY: " << maxValueY << endl 00648 ; 00649 #endif 00650 00651 // solving issue #4075 in a quick way: 00652 ptr->setPen ( PrintingParameters::scalePen( labelTA.pen() ) ); // perhaps we want to add a setter method later? 00653 00654 //ptr->setPen ( Qt::black ); 00655 00656 const QObject* referenceArea = plane->parent(); 00657 00658 // that QVector contains all drawn x-ticks (so no subticks are drawn there also) 00659 QVector< int > drawnAbscissaTicks; 00660 // and that does the same for the y-ticks 00661 QVector< int > drawnYTicks; 00662 00663 /* 00664 * Find out if it is a bar diagram 00665 * bar diagrams display their data per column 00666 * we need to handle the last label another way 00667 * 1 - Last label == QString null ( Header Labels ) 00668 * 2 - Display labels and ticks in the middle of the column 00669 */ 00670 00671 const bool centerAbscissaTicks = referenceDiagramNeedsCenteredAbscissaTicks( d->diagram() ); 00672 00673 // this draws the unit rulers 00674 if ( drawUnitRulers ) { 00675 const QStringList labelsList( labels() ); 00676 const QStringList shortLabelsList( shortLabels() ); 00677 const int hardLabelsCount = labelsList.count(); 00678 const int shortLabelsCount = shortLabelsList.count(); 00679 bool useShortLabels = false; 00680 00681 00682 bool useConfiguredStepsLabels = false; 00683 QStringList headerLabels; 00684 if( useItemCountLabels ){ 00685 //qDebug() << (isOrdinate() ? "is Ordinate" : "is Abscissa"); 00686 headerLabels = 00687 isOrdinate() 00688 ? d->diagram()->datasetLabels() 00689 : d->diagram()->itemRowLabels(); 00690 //qDebug() << numberOfUnitRulers; 00691 // check if configured stepWidth 00692 useConfiguredStepsLabels = isAbscissa() && 00693 dimX.stepWidth && 00694 (( (headerLabels.count() - 1)/ dimX.stepWidth ) != numberOfUnitRulers); 00695 if( useConfiguredStepsLabels ) { 00696 numberOfUnitRulers = ( headerLabels.count() - 1 )/ dimX.stepWidth; 00697 // we need to register data values for the steps 00698 // in case it is configured by the user 00699 QStringList configuredStepsLabels; 00700 double value = dimX.start;// headerLabels.isEmpty() ? 0.0 : headerLabels.first().toDouble(); 00701 configuredStepsLabels << QString::number( value ); 00702 00703 for( int i = 0; i < numberOfUnitRulers; i++ ) 00704 { 00705 //qDebug() << value; 00706 value += dimX.stepWidth; 00707 configuredStepsLabels.append( d->diagram()->unitPrefix( i, diagramIsVertical ? Qt::Horizontal : Qt::Vertical, true ) + 00708 QString::number( value ) + 00709 d->diagram()->unitSuffix( i, diagramIsVertical ? Qt::Horizontal : Qt::Vertical, true ) ); 00710 } 00711 headerLabels = configuredStepsLabels; 00712 } 00713 00714 if ( centerAbscissaTicks ) 00715 headerLabels.append( QString::null ); 00716 } 00717 00718 00719 const int headerLabelsCount = headerLabels.count(); 00720 //qDebug() << "headerLabelsCount" << headerLabelsCount; 00721 00722 TextLayoutItem* labelItem = 00723 drawLabels 00724 ? new TextLayoutItem( QString::number( minValueY ), 00725 labelTA, 00726 referenceArea, 00727 KDChartEnums::MeasureOrientationMinimum, 00728 Qt::AlignLeft ) 00729 : 0; 00730 TextLayoutItem* labelItem2 = 00731 drawLabels 00732 ? new TextLayoutItem( QString::number( minValueY ), 00733 labelTA, 00734 referenceArea, 00735 KDChartEnums::MeasureOrientationMinimum, 00736 Qt::AlignLeft ) 00737 : 0; 00738 const QFontMetricsF met( 00739 drawLabels 00740 ? labelItem->realFont() 00741 : QFontMetricsF( QApplication::font(), GlobalMeasureScaling::paintDevice() ) ); 00742 const qreal halfFontHeight = met.height() * 0.5; 00743 const qreal halfFontWidth = met.averageCharWidth() * 0.5; 00744 00745 if ( isAbscissa() ) { 00746 00747 if( !d->annotations.isEmpty() ) 00748 { 00749 const QList< double > values = d->annotations.keys(); 00750 KDAB_FOREACH( const double v, values ) 00751 { 00752 QPointF topPoint = diagramIsVertical ? QPointF( v, 0.0 ) : QPointF( 0.0, v ); 00753 QPointF bottomPoint = topPoint; 00754 topPoint = plane->translate( topPoint ); 00755 bottomPoint = plane->translate( bottomPoint ); 00756 if ( diagramIsVertical ) { 00757 topPoint.setY( rulerRef.y() + tickLength() ); 00758 bottomPoint.setY( rulerRef.y() ); 00759 } else { 00760 topPoint.setX( rulerRef.x() + tickLength() ); 00761 bottomPoint.setX( rulerRef.x() ); 00762 } 00763 00764 labelItem->setText( d->annotations[ v ] ); 00765 const QSize size( labelItem->sizeHint() ); 00766 if ( diagramIsVertical ) { 00767 labelItem->setGeometry( 00768 QRect( 00769 QPoint( 00770 static_cast<int>( topPoint.x() - size.width() / 2.0 ), 00771 static_cast<int>( topPoint.y() + 00772 ( position() == Bottom 00773 ? halfFontHeight 00774 : ((halfFontHeight + size.height()) * -1.0) ) ) ), 00775 size ) ); 00776 } else { 00777 labelItem->setGeometry( 00778 QRect( 00779 QPoint( 00780 static_cast<int>( bottomPoint.x() + 00781 ( position() == Right 00782 ? halfFontWidth 00783 : (-halfFontWidth - size.width()) ) ), 00784 00785 static_cast<int>( topPoint.y() - ( size.height() ) * 0.5 ) ), 00786 size ) ); 00787 } 00788 00789 QRect labelGeo = labelItem->geometry(); 00790 // if our item would only half fit, we disable clipping for that one 00791 if( labelGeo.left() < geoRect.left() && labelGeo.right() > geoRect.left() ) 00792 ptr->setClipping( false ); 00793 else if( labelGeo.left() < geoRect.right() && labelGeo.right() > geoRect.right() ) 00794 ptr->setClipping( false ); 00795 00796 labelItem->paint( ptr ); 00797 } 00798 } 00799 00800 qreal labelDiff = dimX.stepWidth; 00801 const int precision = ( QString::number( labelDiff ).section( QLatin1Char('.'), 1, 2 ) ).length(); 00802 00803 // If we have a labels list AND a short labels list, we first find out, 00804 // if there is enough space for showing ALL of the long labels: 00805 // If not, use the short labels. 00806 if( drawLabels && hardLabelsCount > 0 && shortLabelsCount > 0 && d->annotations.isEmpty() ){ 00807 bool labelsAreOverlapping = false; 00808 int iLabel = 0; 00809 qreal i = minValueX; 00810 while ( i < maxValueX-1 && !labelsAreOverlapping ) 00811 { 00812 if ( dimX.stepWidth != 1.0 && ! dim.isCalculated ) 00813 { 00814 // Check intersects for the header label - we need to pass the full string 00815 // here and not only the i value. 00816 if( useConfiguredStepsLabels ){ 00817 labelItem->setText( customizedLabel(headerLabels[ iLabel ]) ); 00818 labelItem2->setText(customizedLabel(headerLabels[ iLabel+1 ]) ); 00819 }else{ 00820 //qDebug() << "i + labelDiff " << i + labelDiff; 00821 labelItem->setText( customizedLabel(headerLabelsCount > i && i >= 0 ? 00822 headerLabels[static_cast<int>(i)] : 00823 QString::number( i, 'f', precision )) ); 00824 // qDebug() << "1 - labelItem->text() " << labelItem->text(); 00825 //qDebug() << "labelDiff" << labelDiff 00826 // << " index" << i+labelDiff << " count" << headerLabelsCount; 00827 labelItem2->setText( customizedLabel(headerLabelsCount > i + labelDiff && i + labelDiff >= 0 ? 00828 headerLabels[static_cast<int>(i+labelDiff)] : 00829 QString::number( i + labelDiff, 'f', precision )) ); 00830 //qDebug() << "2 - labelItem->text() " << labelItem->text(); 00831 //qDebug() << "labelItem2->text() " << labelItem2->text(); 00832 } 00833 } else { 00834 //qDebug() << iLabel << i << "("<<hardLabelsCount<<") :"; 00835 const int idx = (iLabel < hardLabelsCount ) ? iLabel : 0; 00836 const int idx2= (iLabel < hardLabelsCount - 1) ? iLabel + 1 : 0; 00837 const int shortIdx = (iLabel < shortLabelsCount ) ? iLabel : 0; 00838 const int shortIdx2 = (iLabel < shortLabelsCount - 1) ? iLabel + 1 : 0; 00839 labelItem->setText( customizedLabel( 00840 useShortLabels ? shortLabelsList[ shortIdx ] : labelsList[ idx ] ) ); 00841 labelItem2->setText( customizedLabel( 00842 useShortLabels ? shortLabelsList[ shortIdx2 ] : labelsList[ idx2 ] ) ); 00843 } 00844 00845 QPointF firstPos = diagramIsVertical ? QPointF( i, 0.0 ) : QPointF( 0.0, i ); 00846 firstPos = plane->translate( firstPos ); 00847 00848 QPointF secondPos = diagramIsVertical ? QPointF( i + labelDiff, 0.0 ) : QPointF( 0.0, i + labelDiff ); 00849 secondPos = plane->translate( secondPos ); 00850 00851 labelsAreOverlapping = labelItem->intersects( *labelItem2, firstPos, secondPos ); 00852 00853 00854 //qDebug() << labelsAreOverlapping; 00855 if ( ++iLabel > hardLabelsCount - 1 ) 00856 iLabel = 0; 00857 if ( isLogarithmicX ) 00858 i *= 10.0; 00859 else 00860 i += dimX.stepWidth; 00861 00862 //qDebug() << iLabel << i << labelsAreOverlapping << firstPos << secondPos.x()-firstPos .x() << labelItem->text() << labelItem2->text(); 00863 } 00864 //qDebug() << "-----------------------"; 00865 00866 useShortLabels = labelsAreOverlapping; 00867 } 00868 00869 // qDebug() << "initial labelDiff " << labelDiff; 00870 if ( drawLabels && d->annotations.isEmpty() ) 00871 { 00872 qreal i = minValueX; 00873 int iLabel = 0; 00874 00875 while ( i + labelDiff < maxValueX ) 00876 { 00877 //qDebug() << "drawLabels" << drawLabels << " hardLabelsCount" << hardLabelsCount 00878 // << " dimX.stepWidth" << dimX.stepWidth << " dim.isCalculated" << dim.isCalculated; 00879 if ( !drawLabels || hardLabelsCount < 1 || ( dimX.stepWidth != 1.0 && ! dim.isCalculated ) ) 00880 { 00881 // Check intersects for the header label - we need to pass the full string 00882 // here and not only the i value. 00883 if( useConfiguredStepsLabels ){ 00884 labelItem->setText( customizedLabel(headerLabels[ iLabel ]) ); 00885 labelItem2->setText(customizedLabel(headerLabels[ iLabel+1 ]) ); 00886 }else{ 00887 //qDebug() << "i + labelDiff " << i + labelDiff; 00888 labelItem->setText( customizedLabel(headerLabelsCount > i && i >= 0 ? 00889 headerLabels[static_cast<int>(i)] : 00890 QString::number( i, 'f', precision )) ); 00891 // qDebug() << "1 - labelItem->text() " << labelItem->text(); 00892 //qDebug() << "labelDiff" << labelDiff 00893 // << " index" << i+labelDiff << " count" << headerLabelsCount; 00894 labelItem2->setText( customizedLabel(headerLabelsCount > i + labelDiff && i + labelDiff >= 0 ? 00895 headerLabels[static_cast<int>(i+labelDiff)] : 00896 QString::number( i + labelDiff, 'f', precision )) ); 00897 //qDebug() << "2 - labelItem->text() " << labelItem->text(); 00898 //qDebug() << "labelItem2->text() " << labelItem2->text(); 00899 } 00900 } else { 00901 const int idx = (iLabel < hardLabelsCount ) ? iLabel : 0; 00902 const int idx2= (iLabel < hardLabelsCount - 1) ? iLabel + 1 : 0; 00903 const int shortIdx = (iLabel < shortLabelsCount ) ? iLabel : 0; 00904 const int shortIdx2 = (iLabel < shortLabelsCount - 1) ? iLabel + 1 : 0; 00905 labelItem->setText( customizedLabel( 00906 useShortLabels ? shortLabelsList[ shortIdx ] : labelsList[ idx ] ) ); 00907 labelItem2->setText( customizedLabel( 00908 useShortLabels ? shortLabelsList[ shortIdx2 ] : labelsList[ idx2 ] ) ); 00909 } 00910 00911 QPointF firstPos = diagramIsVertical ? QPointF( i, 0.0 ) : QPointF( 0.0, i ); 00912 firstPos = plane->translate( firstPos ); 00913 00914 QPointF secondPos = diagramIsVertical ? QPointF( i + labelDiff, 0.0 ) : QPointF( 0.0, i + labelDiff ); 00915 secondPos = plane->translate( secondPos ); 00916 00917 00918 if ( labelItem->intersects( *labelItem2, firstPos, secondPos ) ) 00919 { 00920 i = minValueX; 00921 00922 // fix for issue #4179: 00923 labelDiff *= 10.0; 00924 // old code: 00925 // labelDiff += labelDiff; 00926 00927 iLabel = 0; 00928 //qDebug() << firstPos << secondPos.x()-firstPos .x() << labelItem->text() << labelItem2->text(); 00929 //qDebug() << labelDiff; 00930 } 00931 else 00932 { 00933 i += labelDiff; 00934 //qDebug() << firstPos << secondPos.x()-firstPos .x() << labelItem->text() << labelItem2->text(); 00935 //qDebug() << "ok"; 00936 } 00937 00938 if ( (++iLabel > hardLabelsCount - 1) && !useConfiguredStepsLabels ) 00939 { 00940 iLabel = 0; 00941 } 00942 } 00943 // fixing bugz issue #5018 without breaking issue #4179: 00944 if( minValueX + labelDiff > maxValueX ) 00945 labelDiff = maxValueX - minValueX; 00946 // This makes sure the first and the last X label are drawn 00947 // if there is not enouth place to draw some more of them 00948 // according to labelDiff calculation performed above. 00949 } 00950 00951 int idxLabel = 0; 00952 qreal iLabelF = minValueX; 00953 //qDebug() << iLabelF; 00954 qreal i = minValueX; 00955 qreal labelStep = 0.0; 00956 // qDebug() << "dimX.stepWidth:" << dimX.stepWidth << "labelDiff:" << labelDiff; 00957 //dimX.stepWidth = 0.5; 00958 while( i <= maxValueX && d->annotations.isEmpty() ) 00959 { 00960 // Line charts: we want the first tick to begin at 0.0 not at 0.5 otherwise labels and 00961 // values does not fit each others 00962 QPointF topPoint = diagramIsVertical ? QPointF( i + ( centerAbscissaTicks ? 0.5 : 0.0 ), 0.0 ) : QPointF( 0.0, i + ( centerAbscissaTicks ? 0.5 : 0.0 ) ); 00963 QPointF bottomPoint ( topPoint ); 00964 topPoint = plane->translate( topPoint ); 00965 bottomPoint = plane->translate( bottomPoint ); 00966 if ( diagramIsVertical ) { 00967 topPoint.setY( rulerRef.y() + tickLength() ); 00968 bottomPoint.setY( rulerRef.y() ); 00969 } else { 00970 bottomPoint.setX( rulerRef.x() - (position() == Left ? tickLength() : -tickLength()) ); 00971 topPoint.setX( rulerRef.x() ); 00972 } 00973 00974 const qreal translatedValue = diagramIsVertical ? topPoint.x() : topPoint.y(); 00975 bool bIsVisibleLabel; 00976 if ( diagramIsVertical ) 00977 bIsVisibleLabel = ( translatedValue >= geoRect.left() && translatedValue <= geoRect.right() && !isLogarithmicX || i != 0.0 ); 00978 else 00979 bIsVisibleLabel = ( translatedValue >= geoRect.top() && translatedValue <= geoRect.bottom() && !isLogarithmicX || i != 0.0 ); 00980 00981 // fix for issue #4179: 00982 bool painttick = bIsVisibleLabel && labelStep <= 0;; 00983 // old code: 00984 // bool painttick = true; 00985 00986 //Dont paint more ticks than we need 00987 //when diagram type is Bar 00988 if ( centerAbscissaTicks && i == maxValueX ) 00989 painttick = false; 00990 00991 if ( bIsVisibleLabel && painttick ) { 00992 ptr->save(); 00993 if ( rulerAttr.hasTickMarkPenAt( i ) ) 00994 ptr->setPen( rulerAttr.tickMarkPen( i ) ); 00995 else 00996 ptr->setPen( rulerAttr.majorTickMarkPen() ); 00997 ptr->drawLine( topPoint, bottomPoint ); 00998 ptr->restore(); 00999 } 01000 01001 drawnAbscissaTicks.append( static_cast<int>( diagramIsVertical ? topPoint.x() : topPoint.y() ) ); 01002 if( drawLabels ) { 01003 if( bIsVisibleLabel ){ 01004 if ( isLogarithmicX ) 01005 labelItem->setText( customizedLabel(QString::number( i ) ) ); 01006 /* We don't need that 01007 * it causes header labels to be skipped even if there is enough 01008 * space for them to displayed. 01009 * Commenting for now - I need to test more in details - Let me know if I am wrong here. 01010 */ 01011 /* 01012 else if( (dimX.stepWidth != 1.0) && ! dimX.isCalculated ) { 01013 labelItem->setText( customizedLabel(QString::number( i, 'f', 0 )) ); 01014 } 01015 */ 01016 else { 01017 int idx = idxLabel + static_cast<int>(minValueX); 01018 if( hardLabelsCount ){ 01019 if( useShortLabels ){ 01020 if( idx >= shortLabelsList.count() ) 01021 idx = 0; 01022 }else{ 01023 if( idx >= labelsList.count() ) 01024 idx = 0; 01025 } 01026 } 01027 labelItem->setText( 01028 customizedLabel( 01029 hardLabelsCount 01030 ? ( useShortLabels ? shortLabelsList[ idx ] : labelsList[ idx ] ) 01031 : ( headerLabelsCount ? headerLabels[ idx ] : QString::number( iLabelF )))); 01032 //qDebug() << "x - labelItem->text() " << labelItem->text() << headerLabelsCount; 01033 } 01034 // No need to call labelItem->setParentWidget(), since we are using 01035 // the layout item temporarily only. 01036 if( labelStep <= 0 ) { 01037 const PainterSaver p( ptr ); 01038 //const QSize size( labelItem->sizeHint() ); 01039 QPoint topLeft, topRight, bottomRight, bottomLeft; 01040 const QSize size( 01041 labelItem->sizeHintAndRotatedCorners( 01042 topLeft, topRight, bottomRight, bottomLeft) ); 01043 const QSize sizeUnrotated( labelItem->sizeHintUnrotated() ); 01044 const int rotation = labelTA.rotation(); 01045 const bool rotPositive = (rotation > 0 && rotation < 180); 01046 QPoint midOfSide(0,0); 01047 int dX = 0; 01048 int dY = 0; 01049 if( rotation ){ 01050 if( rotPositive ){ 01051 midOfSide = (topLeft + bottomLeft) / 2; 01052 dX = topLeft.x() - midOfSide.x(); 01053 dY = bottomLeft.y() - midOfSide.y(); 01054 }else{ 01055 midOfSide = (topRight + bottomRight) / 2; 01056 dX = midOfSide.x() - topLeft.x(); 01057 dY = midOfSide.y() - topRight.y(); 01058 } 01059 } 01060 /* 01061 if( i == 2 ){ 01062 qDebug()<<"------"<<size<<topPoint<<topLeft<<topRight<<bottomRight<<bottomLeft<<" m:"<<midOfSide<<" dx"<<dX<<" dy"<<dY; 01063 ptr->setPen( Qt::black ); 01064 QRectF rect(topPoint, QSizeF(sizeUnrotated)); 01065 ptr->drawRect( rect ); 01066 ptr->drawRect( QRectF(topPoint, QSizeF(2,2)) ); 01067 ptr->drawRect( QRectF(topPoint+topLeft, QSizeF(2,2)) ); 01068 ptr->drawRect( QRectF(topPoint+bottomLeft, QSizeF(2,2)) ); 01069 ptr->drawRect( QRectF(topPoint+bottomRight, QSizeF(2,2)) ); 01070 ptr->drawRect( QRectF(topPoint+topRight, QSizeF(2,2)) ); 01071 ptr->drawRect( QRectF(topPoint+midOfSide, QSizeF(2,2)) ); 01072 ptr->setPen( Qt::green ); 01073 rect = QRectF(topPoint, QSizeF(size)); 01074 ptr->drawRect( rect ); 01075 ptr->drawRect( QRectF(QPointF((rect.topLeft() + rect.bottomLeft()) / 2.0 - QPointF(2.0,2.0)), QSizeF(3.0,3.0)) ); 01076 //ptr->drawRect( QRectF(QPointF((rect.topRight() + rect.bottomRight()) / 2.0 - QPointF(2.0,2.0)), QSizeF(3.0,3.0)) ); 01077 } 01078 */ 01079 QPoint topLeftPt; 01080 if( diagramIsVertical ){ 01081 if( rotation ){ 01082 topLeftPt = QPoint( 01083 static_cast<int>( topPoint.x() ) - dX, 01084 static_cast<int>( topPoint.y() - dY + 01085 ( position() == Bottom 01086 ? halfFontHeight 01087 : ((halfFontHeight + size.height()) * -1.0) ) ) ); 01088 }else{ 01089 topLeftPt = QPoint( 01090 static_cast<int>( topPoint.x() - size.width() / 2.0 ), 01091 static_cast<int>( topPoint.y() + 01092 ( position() == Bottom 01093 ? halfFontHeight 01094 : ((halfFontHeight + size.height()) * -1.0) ) ) ); 01095 } 01096 }else{ 01097 if( rotation ){ 01098 topLeftPt = QPoint( 01099 static_cast<int>( topPoint.x() ) + dX, 01100 static_cast<int>( topPoint.y() - dY + 01101 ( position() == Bottom 01102 ? halfFontHeight 01103 : ((halfFontHeight + size.height()) * -1.0) ) ) ); 01104 }else{ 01105 topLeftPt = QPoint( 01106 static_cast<int>( bottomPoint.x() + 01107 ( position() == Right 01108 ? halfFontWidth 01109 : (-halfFontWidth - size.width()) ) ), 01110 static_cast<int>( topPoint.y() - ( size.height() ) * 0.5 ) ); 01111 } 01112 } 01113 labelItem->setGeometry( QRect(topLeftPt, size) ); 01114 01115 QRect labelGeo = labelItem->geometry(); 01116 //ptr->drawRect(labelGeo); 01117 // if our item would only half fit, we disable clipping for that one 01118 if( labelGeo.left() < geoRect.left() && labelGeo.right() > geoRect.left() ) 01119 ptr->setClipping( false ); 01120 else if( labelGeo.left() < geoRect.right() && labelGeo.right() > geoRect.right() ) 01121 ptr->setClipping( false ); 01122 01123 01124 if( !isLogarithmicX ) 01125 labelStep = labelDiff - dimX.stepWidth; 01126 01127 // if our item would only half fit, we disable clipping for that one 01128 if( labelGeo.left() < geoRect.left() && labelGeo.right() > geoRect.left() ) 01129 ptr->setClipping( false ); 01130 else if( labelGeo.left() < geoRect.right() && labelGeo.right() > geoRect.right() ) 01131 ptr->setClipping( false ); 01132 01133 labelItem->paint( ptr ); 01134 01135 // do not call customizedLabel() again: 01136 labelItem2->setText( labelItem->text() ); 01137 01138 } else { 01139 labelStep -= dimX.stepWidth; 01140 } 01141 } 01142 01143 if( hardLabelsCount ) { 01144 if( useShortLabels && idxLabel >= shortLabelsCount - 1 ) 01145 idxLabel = 0; 01146 else if( !useShortLabels && idxLabel >= hardLabelsCount - 1 ) 01147 idxLabel = 0; 01148 else{ 01149 idxLabel += static_cast<int>(dimX.stepWidth); 01150 //qDebug() << "dimX.stepWidth:" << dimX.stepWidth << " idxLabel:" << idxLabel; 01151 } 01152 } else if( headerLabelsCount ) { 01153 if( ++idxLabel > headerLabelsCount - 1 ) { 01154 idxLabel = 0; 01155 } 01156 } else { 01157 iLabelF += dimX.stepWidth; 01158 } 01159 } 01160 if ( isLogarithmicX ) 01161 { 01162 i *= 10.0; 01163 if( i == 0.0 ) 01164 { 01165 const qreal j = dimensions.first().start; 01166 i = j == 0.0 ? 1.0 : pow( 10.0, floor( log10( j ) ) ); 01167 } 01168 } 01169 else 01170 { 01171 i += dimX.stepWidth; 01172 } 01173 } 01174 } else { 01175 const PainterSaver p( ptr ); 01176 const double maxLimit = maxValueY; 01177 const double steg = dimY.stepWidth; 01178 int maxLabelsWidth = 0; 01179 qreal labelValue; 01180 if( drawLabels && position() == Right ){ 01181 // Find the widest label, so we to know how much we need to right-shift 01182 // our labels, to get them drawn right aligned: 01183 labelValue = minValueY; 01184 while ( labelValue <= maxLimit ) { 01185 const QString labelText = diagram()->unitPrefix( static_cast< int >( labelValue ), diagramOrientation, true ) + 01186 QString::number( labelValue ) + 01187 diagram()->unitSuffix( static_cast< int >( labelValue ), diagramOrientation, true ); 01188 labelItem->setText( customizedLabel( labelText ) ); 01189 maxLabelsWidth = qMax( maxLabelsWidth, diagramIsVertical ? labelItem->sizeHint().width() : labelItem->sizeHint().height() ); 01190 01191 calculateNextLabel( labelValue, steg, isLogarithmicY, dimensions.last().start ); 01192 } 01193 } 01194 01195 labelValue = minValueY; 01196 qreal step = steg; 01197 bool nextLabel = false; 01198 //qDebug("minValueY: %f maxLimit: %f steg: %f", minValueY, maxLimit, steg); 01199 01200 if( drawLabels ) 01201 { 01202 // first calculate the steps depending on labels colision 01203 while( labelValue <= maxLimit ) { 01204 QPointF leftPoint = plane->translate( diagramIsVertical ? QPointF( 0, labelValue ) : QPointF( labelValue, 0 ) ); 01205 const qreal translatedValue = diagramIsVertical ? leftPoint.y() : leftPoint.x(); 01206 //qDebug() << "geoRect:" << geoRect << " geoRect.top()" << geoRect.top() 01207 //<< "geoRect.bottom()" << geoRect.bottom() << " translatedValue:" << translatedValue; 01208 const bool bTranslatedValueIsWithinRange = diagramIsVertical ? translatedValue > geoRect.top() && translatedValue <= geoRect.bottom() 01209 : translatedValue > geoRect.left() && translatedValue <= geoRect.right(); 01210 if( bTranslatedValueIsWithinRange ){ 01211 const QString labelText = diagram()->unitPrefix( static_cast< int >( labelValue ), diagramOrientation, true ) + 01212 QString::number( labelValue ) + 01213 diagram()->unitSuffix( static_cast< int >( labelValue ), diagramOrientation, true ); 01214 const QString label2Text = diagram()->unitPrefix( static_cast< int >( labelValue + step ), diagramOrientation, true ) + 01215 QString::number( labelValue + step ) + 01216 diagram()->unitSuffix( static_cast< int >( labelValue + step ), diagramOrientation, true ); 01217 labelItem->setText( customizedLabel( labelText ) ); 01218 labelItem2->setText( customizedLabel( QString::number( labelValue + step ) ) ); 01219 QPointF nextPoint = plane->translate( diagramIsVertical ? QPointF( 0, labelValue + step ) : QPointF( labelValue + step, 0 ) ); 01220 if ( labelItem->intersects( *labelItem2, leftPoint, nextPoint ) ) 01221 { 01222 step += steg; 01223 nextLabel = false; 01224 }else{ 01225 nextLabel = true; 01226 } 01227 }else{ 01228 nextLabel = true; 01229 } 01230 01231 if ( nextLabel || isLogarithmicY ) 01232 calculateNextLabel( labelValue, step, isLogarithmicY, dimensions.last().start ); 01233 else 01234 labelValue = minValueY; 01235 } 01236 01237 // Second - Paint the labels 01238 labelValue = minValueY; 01239 //qDebug() << "axis labels starting at" << labelValue << "step width" << step; 01240 if( !d->annotations.isEmpty() ) 01241 { 01242 const QList< double > annotations = d->annotations.keys(); 01243 KDAB_FOREACH( const double annotation, annotations ) 01244 { 01245 QPointF annoPoint = (diagramIsVertical ? QPointF( 0.0, annotation ) : QPointF( annotation, 0.0 )); 01246 QPointF leftPoint = plane->translate( annoPoint ); 01247 QPointF rightPoint = plane->translate( annoPoint ); 01248 01249 if ( diagramIsVertical ) { 01250 leftPoint.setX( rulerRef.x() + tickLength() ); 01251 rightPoint.setX( rulerRef.x() ); 01252 } else { 01253 leftPoint.setY( rulerRef.y() + ((position() == Bottom) ? tickLength() : -tickLength()) ); 01254 rightPoint.setY( rulerRef.y() ); 01255 } 01256 01257 const qreal translatedValue = diagramIsVertical ? rightPoint.y() : rightPoint.x(); 01258 const bool bIsVisibleLabel = diagramIsVertical ? 01259 ( translatedValue >= geoRect.top() && translatedValue <= geoRect.bottom() && !isLogarithmicY || labelValue != 0.0 ) 01260 : ( translatedValue >= geoRect.left() && translatedValue <= geoRect.right() && !isLogarithmicY || labelValue != 0.0 ); 01261 01262 if( bIsVisibleLabel ) 01263 { 01264 ptr->save(); 01265 if ( rulerAttr.hasTickMarkPenAt( annotation ) ) 01266 ptr->setPen( rulerAttr.tickMarkPen( annotation ) ); 01267 else 01268 ptr->setPen( rulerAttr.majorTickMarkPen() ); 01269 ptr->drawLine( leftPoint, rightPoint ); 01270 ptr->restore(); 01271 01272 labelItem->setText( d->annotations[ annotation ] ); 01273 const QSize labelSize( labelItem->sizeHint() ); 01274 int x, y; 01275 if ( diagramIsVertical ) { 01276 x = static_cast<int>( leftPoint.x() + met.height() * ( position() == Left ? -0.5 : 0.5) 01277 - ( position() == Left ? labelSize.width() : 0.0 ) ); 01278 y = static_cast<int>( leftPoint.y() - ( met.ascent() + met.descent() ) * 0.6 ); 01279 } else { 01280 const qreal halfFontHeight = met.height() * 0.5; 01281 x = static_cast<int>( leftPoint.x() - labelSize.width() * 0.5 ); 01282 y = static_cast<int>( (position() == Bottom ? leftPoint.y() : rightPoint.y()) + 01283 + ( position() == Bottom ? halfFontHeight : -(halfFontHeight + labelSize.height()) ) ); 01284 } 01285 labelItem->setGeometry( QRect( QPoint( x, y ), labelSize ) ); 01286 01287 QRect labelGeo = labelItem->geometry(); 01288 // if our item would only half fit, we disable clipping for that one 01289 if( labelGeo.left() < geoRect.left() && labelGeo.right() > geoRect.left() ) 01290 ptr->setClipping( false ); 01291 else if( labelGeo.left() < geoRect.right() && labelGeo.right() > geoRect.right() ) 01292 ptr->setClipping( false ); 01293 01294 labelItem->paint( ptr ); 01295 } 01296 } 01297 } 01298 else 01299 { 01300 while( labelValue <= maxLimit ) { 01301 //qDebug() << "value now" << labelValue; 01302 const QString labelText = diagram()->unitPrefix( static_cast< int >( labelValue ), diagramOrientation, true ) + 01303 QString::number( labelValue ) + 01304 diagram()->unitSuffix( static_cast< int >( labelValue ), diagramOrientation, true ); 01305 labelItem->setText( customizedLabel( labelText ) ); 01306 QPointF leftPoint = plane->translate( diagramIsVertical ? QPointF( 0, labelValue ) : QPointF( labelValue, 0 ) ); 01307 QPointF rightPoint = leftPoint; 01308 01309 if ( diagramIsVertical ) { 01310 leftPoint.setX( rulerRef.x() + tickLength() ); 01311 rightPoint.setX( rulerRef.x() ); 01312 } else { 01313 leftPoint.setY( rulerRef.y() + ((position() == Bottom) ? tickLength() : -tickLength()) ); 01314 rightPoint.setY( rulerRef.y() ); 01315 } 01316 01317 bool bIsVisibleLabel; 01318 const qreal translatedValue = diagramIsVertical ? rightPoint.y() : rightPoint.x(); 01319 if ( diagramIsVertical) 01320 bIsVisibleLabel = ( translatedValue >= geoRect.top() && translatedValue <= geoRect.bottom() && !isLogarithmicY || labelValue != 0.0 ); 01321 else 01322 bIsVisibleLabel = ( translatedValue >= geoRect.left() && translatedValue <= geoRect.right() && !isLogarithmicY || labelValue != 0.0 ); 01323 01324 if( bIsVisibleLabel ){ 01325 ptr->save(); 01326 if ( rulerAttr.hasTickMarkPenAt( labelValue ) ) 01327 ptr->setPen( rulerAttr.tickMarkPen( labelValue ) ); 01328 else 01329 ptr->setPen( rulerAttr.majorTickMarkPen() ); 01330 ptr->drawLine( leftPoint, rightPoint ); 01331 ptr->restore(); 01332 01333 drawnYTicks.append( static_cast<int>( diagramIsVertical ? leftPoint.y() : leftPoint.x() ) ); 01334 const QSize labelSize( labelItem->sizeHint() ); 01335 01336 int x, y; 01337 if ( diagramIsVertical ) { 01338 x = static_cast<int>( leftPoint.x() + met.height() * ( position() == Left ? -0.5 : 0.5) ) 01339 - ( position() == Left ? labelSize.width() : (labelSize.width() - maxLabelsWidth) ); 01340 y = static_cast<int>( leftPoint.y() - ( met.ascent() + met.descent() ) * 0.6 ); 01341 } else { 01342 const qreal halfFontHeight = met.height() * 0.5; 01343 x = static_cast<int>( leftPoint.x() - labelSize.width() * 0.5 ); 01344 y = static_cast<int>( (position() == Bottom ? leftPoint.y() : rightPoint.y()) + 01345 + ( position() == Bottom ? halfFontHeight : -(halfFontHeight + labelSize.height()) ) ); 01346 } 01347 01348 labelItem->setGeometry( QRect( QPoint( x, y ), labelSize ) ); 01349 const QRect labelGeo = labelItem->geometry(); 01350 const bool hadClipping = ptr->hasClipping(); 01351 if( labelGeo.top() < geoRect.top() && labelGeo.bottom() > geoRect.top() ) 01352 ptr->setClipping( false ); 01353 else if( labelGeo.top() < geoRect.bottom() && labelGeo.bottom() > geoRect.bottom() ) 01354 ptr->setClipping( false ); 01355 01356 01357 // if our item would only half fit, we disable clipping for that one 01358 if( labelGeo.left() < geoRect.left() && labelGeo.right() > geoRect.left() ) 01359 ptr->setClipping( false ); 01360 else if( labelGeo.left() < geoRect.right() && labelGeo.right() > geoRect.right() ) 01361 ptr->setClipping( false ); 01362 01363 labelItem->paint( ptr ); 01364 ptr->setClipping( hadClipping ); 01365 } 01366 01367 //qDebug() << step; 01368 calculateNextLabel( labelValue, step, isLogarithmicY, dimensions.last().start ); 01369 } 01370 } 01371 } 01372 } 01373 delete labelItem; 01374 delete labelItem2; 01375 } 01376 01377 // this draws the subunit rulers 01378 if ( drawSubUnitRulers && d->annotations.isEmpty() ) { 01379 ptr->save(); 01380 01381 d->drawSubUnitRulers( ptr, plane, dim, rulerRef, isAbscissa() ? drawnAbscissaTicks : drawnYTicks, diagramIsVertical, rulerAttr ); 01382 01383 ptr->restore(); 01384 } 01385 01386 if( ! titleText().isEmpty() ){ 01387 d->drawTitleText( ptr, plane, areaGeoRect ); 01388 } 01389 01390 //qDebug() << "KDChart::CartesianAxis::paintCtx() done."; 01391 }
void AbstractAreaBase::paintFrame | ( | QPainter & | painter, | |
const QRect & | rectangle | |||
) | [virtual, inherited] |
Definition at line 205 of file KDChartAbstractAreaBase.cpp.
References d, and KDChart::AbstractAreaBase::paintFrameAttributes().
Referenced by KDChart::TextArea::paintAll(), KDChart::AbstractAreaWidget::paintAll(), and KDChart::AbstractArea::paintAll().
00206 { 00207 Q_ASSERT_X ( d != 0, "AbstractAreaBase::paintFrame()", 00208 "Private class was not initialized!" ); 00209 paintFrameAttributes( painter, rect, d->frameAttributes ); 00210 }
void AbstractAreaBase::paintFrameAttributes | ( | QPainter & | painter, | |
const QRect & | rectangle, | |||
const KDChart::FrameAttributes & | attributes | |||
) | [static, inherited] |
Definition at line 178 of file KDChartAbstractAreaBase.cpp.
References KDChart::FrameAttributes::isVisible(), KDChart::FrameAttributes::pen(), and KDChart::PrintingParameters::scalePen().
Referenced by KDChart::AbstractAreaBase::paintFrame().
00180 { 00181 00182 if( !attributes.isVisible() ) return; 00183 00184 // Note: We set the brush to NoBrush explicitly here. 00185 // Otherwise we might get a filled rectangle, so any 00186 // previously drawn background would be overwritten by that area. 00187 00188 const QPen oldPen( painter.pen() ); 00189 const QBrush oldBrush( painter.brush() ); 00190 painter.setPen( PrintingParameters::scalePen( attributes.pen() ) ); 00191 painter.setBrush( Qt::NoBrush ); 00192 painter.drawRect( rect.adjusted( 0, 0, -1, -1 ) ); 00193 painter.setBrush( oldBrush ); 00194 painter.setPen( oldPen ); 00195 }
void AbstractArea::paintIntoRect | ( | QPainter & | painter, | |
const QRect & | rect | |||
) | [virtual, inherited] |
Draws the background and frame, then calls paint().
In most cases there is no need to overwrite this method in a derived class, but you would overwrite AbstractLayoutItem::paint() instead.
Definition at line 111 of file KDChartAbstractArea.cpp.
References KDChart::AbstractArea::paintAll().
00112 { 00113 const QRect oldGeometry( geometry() ); 00114 if( oldGeometry != rect ) 00115 setGeometry( rect ); 00116 painter.translate( rect.left(), rect.top() ); 00117 paintAll( painter ); 00118 painter.translate( -rect.left(), -rect.top() ); 00119 if( oldGeometry != rect ) 00120 setGeometry( oldGeometry ); 00121 }
QLayout* KDChart::AbstractLayoutItem::parentLayout | ( | ) | [inherited] |
const CartesianAxis::Position CartesianAxis::position | ( | ) | const [virtual] |
Definition at line 153 of file KDChartCartesianAxis.cpp.
References d.
Referenced by compare(), expandingDirections(), isAbscissa(), isOrdinate(), KDChart::LeveyJenningsAxis::paintAsAbscissa(), KDChart::LeveyJenningsAxis::paintAsOrdinate(), paintCtx(), and tickLength().
00154 { 00155 return d->position; 00156 }
void KDChart::AbstractArea::positionChanged | ( | AbstractArea * | ) | [signal, inherited] |
Referenced by KDChart::AbstractArea::positionHasChanged().
void AbstractArea::positionHasChanged | ( | ) | [protected, virtual, inherited] |
Reimplemented from KDChart::AbstractAreaBase.
Definition at line 155 of file KDChartAbstractArea.cpp.
References KDChart::AbstractArea::positionChanged().
00156 { 00157 emit positionChanged( this ); 00158 }
void KDChart::AbstractLayoutItem::removeFromParentLayout | ( | ) | [inherited] |
Definition at line 83 of file KDChartLayoutItems.h.
Referenced by KDChart::Chart::takeCoordinatePlane().
00084 { 00085 if( mParentLayout ){ 00086 if( widget() ) 00087 mParentLayout->removeWidget( widget() ); 00088 else 00089 mParentLayout->removeItem( this ); 00090 } 00091 }
void CartesianAxis::resetTitleTextAttributes | ( | ) |
Reset the title text attributes to the built-in default:.
Same font and pen as AbstractAxis::textAttributes() and 1.5 times their size.
Definition at line 132 of file KDChartCartesianAxis.cpp.
References d, and layoutPlanes().
00133 { 00134 d->useDefaultTextAttributes = true; 00135 layoutPlanes(); 00136 }
int AbstractArea::rightOverlap | ( | bool | doNotRecalculate = false |
) | const [virtual, inherited] |
This is called at layout time by KDChart::AutoSpacerLayoutItem::sizeHint().
The method triggers AbstractArea::sizeHint() to find out the amount of overlap at the right edge of the area.
Definition at line 85 of file KDChartAbstractArea.cpp.
References d.
Referenced by KDChart::AutoSpacerLayoutItem::sizeHint().
00086 { 00087 // Re-calculate the sizes, 00088 // so we also get the amountOf..Overlap members set newly: 00089 if( ! doNotRecalculate ) 00090 sizeHint(); 00091 return d->amountOfRightOverlap; 00092 }
RulerAttributes AbstractAxis::rulerAttributes | ( | ) | const [inherited] |
Returns the attributes to be used for painting the rulers.
Definition at line 270 of file KDChartAbstractAxis.cpp.
References d.
Referenced by paintCtx().
00271 { 00272 return d->rulerAttributes; 00273 }
void CartesianAxis::setAnnotations | ( | const QMap< double, QString > & | annotations | ) |
Sets the axis annotations to annotations.
Annotations are a QMap of doubles and QStrings defining special markers and their position. If you use annotations, the normal ticks and values will be invisible. To unset the annotations, pass an empty QMap.
Definition at line 1774 of file KDChartCartesianAxis.cpp.
References d, and KDChart::AbstractAxis::update().
01775 { 01776 if( d->annotations == annotations ) 01777 return; 01778 01779 d->annotations = annotations; 01780 update(); 01781 }
void AbstractAreaBase::setBackgroundAttributes | ( | const BackgroundAttributes & | a | ) | [inherited] |
Definition at line 112 of file KDChartAbstractAreaBase.cpp.
References d, and KDChart::AbstractAreaBase::positionHasChanged().
00113 { 00114 if( d->backgroundAttributes == a ) 00115 return; 00116 00117 d->backgroundAttributes = a; 00118 positionHasChanged(); 00119 }
void CartesianAxis::setCachedSizeDirty | ( | ) | const [slot] |
Definition at line 1446 of file KDChartCartesianAxis.cpp.
References d.
Referenced by setGeometry().
01447 { 01448 d->cachedMaximumSize = QSize(); 01449 }
void AbstractAreaBase::setFrameAttributes | ( | const FrameAttributes & | a | ) | [inherited] |
Definition at line 98 of file KDChartAbstractAreaBase.cpp.
References d, and KDChart::AbstractAreaBase::positionHasChanged().
Referenced by KDChart::Legend::clone().
00099 { 00100 if( d->frameAttributes == a ) 00101 return; 00102 00103 d->frameAttributes = a; 00104 positionHasChanged(); 00105 }
void CartesianAxis::setGeometry | ( | const QRect & | r | ) | [virtual] |
pure virtual in QLayoutItem
Implements KDChart::AbstractAxis.
Definition at line 1740 of file KDChartCartesianAxis.cpp.
References d, and setCachedSizeDirty().
01741 { 01742 // qDebug() << "KDChart::CartesianAxis::setGeometry(" << r << ") called" 01743 // << (isAbscissa() ? "for Abscissa":"for Ordinate") << "axis"; 01744 d->geometry = r; 01745 setCachedSizeDirty(); 01746 }
void AbstractAxis::setLabels | ( | const QStringList & | list | ) | [inherited] |
Use this to specify your own set of strings, to be used as axis labels.
Labels specified via setLabels take precedence: If a non-empty list is passed, KD Chart will use these strings as axis labels, instead of calculating them.
If you a smaller number of strings than the number of labels drawn at this axis, KD Chart will iterate over the list, repeating the strings, until all labels are drawn. As an example you could specify the seven days of the week as abscissa labels, which would be repeatedly used then.
By passing an empty QStringList you can reset the default behaviour.
Definition at line 292 of file KDChartAbstractAxis.cpp.
References d, and KDChart::AbstractAxis::update().
Referenced by KDChart::LeveyJenningsAxis::paintAsAbscissa().
00293 { 00294 if( d->hardLabels == list ) 00295 return; 00296 00297 d->hardLabels = list; 00298 update(); 00299 }
void KDChart::AbstractLayoutItem::setParentLayout | ( | QLayout * | lay | ) | [inherited] |
void KDChart::AbstractLayoutItem::setParentWidget | ( | QWidget * | widget | ) | [virtual, inherited] |
Inform the item about its widget: This enables the item, to trigger that widget's update, whenever the size of the item's contents has changed.
Thus, you need to call setParentWidget on every item, that has a non-fixed size.
Definition at line 65 of file KDChartLayoutItems.cpp.
References KDChart::AbstractLayoutItem::mParent.
Referenced by KDChart::HeaderFooter::setParent(), and KDChart::AbstractCartesianDiagram::takeAxis().
00066 { 00067 mParent = widget; 00068 }
void CartesianAxis::setPosition | ( | Position | p | ) | [virtual] |
Definition at line 144 of file KDChartCartesianAxis.cpp.
References d, and layoutPlanes().
00145 { 00146 d->position = p; 00147 layoutPlanes(); 00148 }
void AbstractAxis::setRulerAttributes | ( | const RulerAttributes & | a | ) | [inherited] |
Use this to specify the attributes used to paint the axis ruler.
Every axis has a default set of ruler attributes that is exactly the same among them. Use this method to specify your own attributes.
Definition at line 259 of file KDChartAbstractAxis.cpp.
References d, and KDChart::AbstractAxis::update().
void AbstractAxis::setShortLabels | ( | const QStringList & | list | ) | [inherited] |
Use this to specify your own set of strings, to be used as axis labels, in case the normal labels are too long.
Definition at line 322 of file KDChartAbstractAxis.cpp.
References d, and KDChart::AbstractAxis::update().
00323 { 00324 if( d->hardShortLabels == list ) 00325 return; 00326 00327 d->hardShortLabels = list; 00328 update(); 00329 }
void AbstractAxis::setTextAttributes | ( | const TextAttributes & | a | ) | [inherited] |
Use this to specify the text attributes to be used for axis labels.
By default, the reference area will be set at painting time. It will be the then-valid coordinate plane's parent widget, so normally, it will be the KDChart::Chart. Thus the labels of all of your axes in all of your diagrams within that Chart will be drawn in same font size, by default.
Definition at line 231 of file KDChartAbstractAxis.cpp.
References d, and KDChart::AbstractAxis::update().
Referenced by KDChart::LeveyJenningsAxis::setType().
00232 { 00233 if( d->textAttributes == a ) 00234 return; 00235 00236 d->textAttributes = a; 00237 update(); 00238 }
void CartesianAxis::setTitleText | ( | const QString & | text | ) |
Definition at line 102 of file KDChartCartesianAxis.cpp.
References d, and layoutPlanes().
00103 { 00104 d->titleText = text; 00105 layoutPlanes(); 00106 }
void CartesianAxis::setTitleTextAttributes | ( | const TextAttributes & | a | ) |
Definition at line 113 of file KDChartCartesianAxis.cpp.
References d, and layoutPlanes().
00114 { 00115 d->titleTextAttributes = a; 00116 d->useDefaultTextAttributes = false; 00117 layoutPlanes(); 00118 }
QStringList AbstractAxis::shortLabels | ( | ) | const [inherited] |
Returns a list of strings, that are used as axis labels, as set via setShortLabels.
Definition at line 339 of file KDChartAbstractAxis.cpp.
References d.
Referenced by KDChart::AbstractAxis::compare(), and paintCtx().
00340 { 00341 return d->hardShortLabels; 00342 }
QSize CartesianAxis::sizeHint | ( | ) | const [virtual] |
pure virtual in QLayoutItem
Definition at line 1735 of file KDChartCartesianAxis.cpp.
References maximumSize().
01736 { 01737 return maximumSize(); 01738 }
void KDChart::AbstractLayoutItem::sizeHintChanged | ( | ) | const [virtual, inherited] |
Report changed size hint: ask the parent widget to recalculate the layout.
Definition at line 87 of file KDChartLayoutItems.cpp.
References KDChart::AbstractLayoutItem::mParent.
Referenced by KDChart::TextLayoutItem::sizeHintAndRotatedCorners().
00088 { 00089 // This is exactly like what QWidget::updateGeometry does. 00090 // qDebug("KDChart::AbstractLayoutItem::sizeHintChanged() called"); 00091 if( mParent ) { 00092 if ( mParent->layout() ) 00093 mParent->layout()->invalidate(); 00094 else 00095 QApplication::postEvent( mParent, new QEvent( QEvent::LayoutRequest ) ); 00096 } 00097 }
TextAttributes AbstractAxis::textAttributes | ( | ) | const [inherited] |
Returns the text attributes to be used for axis labels.
Definition at line 245 of file KDChartAbstractAxis.cpp.
References d.
Referenced by KDChart::AbstractAxis::compare(), KDChart::LeveyJenningsAxis::paintAsAbscissa(), KDChart::LeveyJenningsAxis::paintAsOrdinate(), paintCtx(), KDChart::LeveyJenningsAxis::setType(), and titleTextAttributes().
00246 { 00247 return d->textAttributes; 00248 }
int CartesianAxis::tickLength | ( | bool | subUnitTicks = false |
) | const [slot] |
Definition at line 1753 of file KDChartCartesianAxis.cpp.
References isAbscissa(), Left, position(), and Top.
Referenced by paintCtx().
01754 { 01755 int result = 0; 01756 01757 if ( isAbscissa() ) { 01758 result = position() == Top ? -4 : 3; 01759 } else { 01760 result = position() == Left ? -4 : 3; 01761 } 01762 01763 if ( subUnitTicks ) 01764 result = result < 0 ? result + 1 : result - 1; 01765 01766 return result; 01767 }
QString CartesianAxis::titleText | ( | ) | const |
Definition at line 108 of file KDChartCartesianAxis.cpp.
References d.
Referenced by compare(), and paintCtx().
00109 { 00110 return d->titleText; 00111 }
TextAttributes CartesianAxis::titleTextAttributes | ( | ) | const |
Returns the text attributes that will be used for displaying the title text.
This is either the text attributes as specified by setTitleTextAttributes, or (if setTitleTextAttributes() was not called) the default text attributes.
Definition at line 120 of file KDChartCartesianAxis.cpp.
References d, KDChart::TextAttributes::fontSize(), hasDefaultTitleTextAttributes(), KDChart::TextAttributes::setFontSize(), and KDChart::AbstractAxis::textAttributes().
Referenced by compare().
00121 { 00122 if( hasDefaultTitleTextAttributes() ){ 00123 TextAttributes ta( textAttributes() ); 00124 Measure me( ta.fontSize() ); 00125 me.setValue( me.value() * 1.5 ); 00126 ta.setFontSize( me ); 00127 return ta; 00128 } 00129 return d->titleTextAttributes; 00130 }
int AbstractArea::topOverlap | ( | bool | doNotRecalculate = false |
) | const [virtual, inherited] |
This is called at layout time by KDChart::AutoSpacerLayoutItem::sizeHint().
The method triggers AbstractArea::sizeHint() to find out the amount of overlap at the top edge of the area.
Definition at line 93 of file KDChartAbstractArea.cpp.
References d.
Referenced by KDChart::AutoSpacerLayoutItem::sizeHint().
00094 { 00095 // Re-calculate the sizes, 00096 // so we also get the amountOf..Overlap members set newly: 00097 if( ! doNotRecalculate ) 00098 sizeHint(); 00099 return d->amountOfTopOverlap; 00100 }
void KDChart::AbstractAxis::update | ( | ) | [slot, inherited] |
Definition at line 366 of file KDChartAbstractAxis.cpp.
References d.
Referenced by KDChart::AbstractAxis::connectSignals(), setAnnotations(), KDChart::AbstractAxis::setLabels(), KDChart::AbstractAxis::setRulerAttributes(), KDChart::AbstractAxis::setShortLabels(), and KDChart::AbstractAxis::setTextAttributes().
QWidget* KDChart::AbstractLayoutItem::mParent [protected, inherited] |
QLayout* KDChart::AbstractLayoutItem::mParentLayout [protected, inherited] |
Definition at line 94 of file KDChartLayoutItems.h.
Referenced by KDChart::AutoSpacerLayoutItem::paint().