KDChartTernaryAxis.cpp

Go to the documentation of this file.
00001 /* -*- Mode: C++ -*-
00002    KDChart - a multi-platform charting engine
00003    */
00004 
00005 /****************************************************************************
00006  ** Copyright (C) 2005-2007 Klarälvdalens Datakonsult AB.  All rights reserved.
00007  **
00008  ** This file is part of the KD Chart library.
00009  **
00010  ** This file may be distributed and/or modified under the terms of the
00011  ** GNU General Public License version 2 as published by the Free Software
00012  ** Foundation and appearing in the file LICENSE.GPL included in the
00013  ** packaging of this file.
00014  **
00015  ** Licensees holding valid commercial KD Chart licenses may use this file in
00016  ** accordance with the KD Chart Commercial License Agreement provided with
00017  ** the Software.
00018  **
00019  ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020  ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021  **
00022  ** See http://www.kdab.net/kdchart for
00023  **   information about KD Chart Commercial License Agreements.
00024  **
00025  ** Contact info@kdab.net if any conditions of this
00026  ** licensing are not clear to you.
00027  **
00028  **********************************************************************/
00029 
00030 #include "KDChartTernaryAxis.h"
00031 
00032 #include <QPainter>
00033 
00034 #include <KDChartChart>
00035 #include <KDChartPaintContext>
00036 
00037 #include "TernaryConstants.h"
00038 #include "KDChartTernaryCoordinatePlane.h"
00039 #include "KDChartAbstractTernaryDiagram.h"
00040 
00041 
00042 #include "../src/KDChartLayoutItems.h"
00043 #include "PrerenderedElements/KDChartTextLabelCache.h"
00044 
00045 using namespace KDChart;
00046 
00047 // m_label and m_fifty do not have to be pointers, once the class is
00048 // pimpled (PrerenderedLabel is not published API)
00049 
00050 TernaryAxis::TernaryAxis ( AbstractTernaryDiagram* diagram)
00051     : AbstractAxis( diagram )
00052     , m_position( KDChartEnums::PositionUnknown )
00053     , m_label( new PrerenderedLabel )
00054     , m_fifty( new PrerenderedLabel )
00055 {
00056     resetTitleTextAttributes();
00057     setPosition( KDChartEnums::PositionSouth ); // arbitrary
00058     m_fifty->setText( QObject::tr( "50%" ) ); // const
00059     // FIXME is this consistent with other diagram/axis/plane implementations?
00060     diagram->addAxis( this );
00061 }
00062 
00063 TernaryAxis::~TernaryAxis()
00064 {
00065     delete m_label; m_label = 0;
00066     delete m_label; m_fifty = 0;
00067 }
00068 
00069 void  TernaryAxis::paintAll (QPainter &)
00070 {
00071     // not used
00072 }
00073 
00074 void  TernaryAxis::paint (QPainter *)
00075 {
00076     // not used
00077 }
00078 
00079 void  TernaryAxis::paintCtx (PaintContext * paintContext)
00080 {
00081     QPainter* p = paintContext->painter();
00082     TernaryCoordinatePlane* plane =
00083         (TernaryCoordinatePlane*) paintContext->coordinatePlane();
00084     // QObject* refArea = plane->parent();
00085     QRectF drawArea = paintContext->rectangle();
00086     QRectF titleArea;
00087 
00088     // paint the axis label (across the triangle, that one):
00089     QList<PrerenderedLabel*> labels;
00090     labels << m_label << m_fifty;
00091     Q_FOREACH( PrerenderedLabel* label, labels ) {
00092         const QPixmap& pixmap = label->pixmap();
00093         QPointF point = plane->translate( label->position() )
00094                         - label->referencePointLocation();
00095         p->drawPixmap( point, pixmap );
00096     }
00097 }
00098 
00099 bool TernaryAxis::isEmpty() const
00100 {
00101     // todo: what's this method for?
00102     return false;
00103 }
00104 
00105 QRect TernaryAxis::geometry () const
00106 {
00107     return m_geometry;
00108 }
00109 
00110 void TernaryAxis::setGeometry (const QRect &rect)
00111 {
00112     m_geometry = rect;
00113 }
00114 
00115 QSize  TernaryAxis::minimumSize () const
00116 {
00117     // todo: return realistic sizes
00118     return QSize( 100, 100 );
00119 }
00120 
00121 QSize  TernaryAxis::maximumSize () const
00122 {
00123     return QSize( 300, 200 );
00124 }
00125 
00126 QSize  TernaryAxis::sizeHint () const
00127 {
00128     return QSize( 150, 100 );
00129 }
00130 
00131 Qt::Orientations TernaryAxis::expandingDirections () const
00132 {
00133     return Qt::Vertical | Qt::Horizontal;
00134 }
00135 
00136 const Position TernaryAxis::position () const
00137 {
00138     return m_position;
00139 }
00140 
00141 void  TernaryAxis::setPosition (Position p)
00142 {
00143     if ( p == position() ) return;
00144 
00145     if ( p != KDChartEnums::PositionWest
00146          && p != KDChartEnums::PositionEast
00147          && p != KDChartEnums::PositionSouth )
00148     {
00149         qDebug() << "TernaryAxis::setPosition: only south, east and west are supported "
00150             "positions for ternary axes.";
00151         return;
00152     }
00153 
00154     if ( m_title.isEmpty() )
00155         switch( p.value() ) {
00156         case KDChartEnums::PositionSouth:
00157             m_label->setText( tr( "A" ) );
00158             break;
00159         case KDChartEnums::PositionWest:
00160             m_label->setText( tr( "C" ) );
00161             break;
00162         case KDChartEnums::PositionEast:
00163             m_label->setText( tr( "B" ) );
00164             break;
00165         default:
00166             break;
00167         }
00168 
00169     m_position = p;
00170     updatePrerenderedLabels(); // position has changed
00171 }
00172 
00173 void TernaryAxis::setTitleText( const QString& text )
00174 {
00175     m_title = text; // do not remove
00176     m_label->setText( text );
00177 }
00178 
00179 QString TernaryAxis::titleText() const
00180 {
00181     return m_label->text();
00182 }
00183 
00184 void TernaryAxis::setTitleTextAttributes( const TextAttributes &a )
00185 {
00186     m_titleAttributes = a;
00187     updatePrerenderedLabels();
00188 }
00189 
00190 TextAttributes TernaryAxis::titleTextAttributes() const
00191 {
00192     return m_titleAttributes;
00193 }
00194 
00195 void TernaryAxis::resetTitleTextAttributes()
00196 {
00197     TextAttributes a;
00198     m_titleAttributes = a;
00199     updatePrerenderedLabels();
00200 }
00201 
00202 bool TernaryAxis::hasDefaultTitleTextAttributes() const
00203 {
00204     TextAttributes a;
00205     return m_titleAttributes == a;
00206 }
00207 
00208 void TernaryAxis::updatePrerenderedLabels()
00209 {
00210     TextAttributes attributes = titleTextAttributes();
00211     double axisLabelAngle;
00212     double fiftyMarkAngle;
00213     QPointF axisLabelPosition;
00214     QPointF fiftyMarkPosition;
00215     KDChartEnums::PositionValue fiftyMarkReferencePoint;
00216 
00217     switch( position().value() ) {
00218     case KDChartEnums::PositionSouth:
00219         // this is the axis on the other side of A
00220         axisLabelAngle = 0.0;
00221         fiftyMarkAngle = 0.0;
00222         axisLabelPosition = TriangleTop;
00223         fiftyMarkPosition = 0.5 * AxisVector_B_C - RelMarkerLength * Norm_B_C;
00224         fiftyMarkReferencePoint = KDChartEnums::PositionNorth;
00225         break;
00226     case KDChartEnums::PositionEast:
00227         // this is the axis on the other side of B
00228         axisLabelAngle = 240.0;
00229         fiftyMarkAngle = 60;
00230         axisLabelPosition = TriangleBottomLeft;
00231         fiftyMarkPosition = AxisVector_B_C + 0.5 * AxisVector_C_A - RelMarkerLength * Norm_C_A;
00232         fiftyMarkReferencePoint = KDChartEnums::PositionSouth;
00233         break;
00234     case KDChartEnums::PositionWest:
00235         // this is the axis on the other side of C
00236         axisLabelAngle = 120.0;
00237         fiftyMarkAngle = 300.0;
00238         axisLabelPosition = TriangleBottomRight;
00239         fiftyMarkPosition = 0.5 * AxisVector_B_A + RelMarkerLength * Norm_B_A;
00240         fiftyMarkReferencePoint = KDChartEnums::PositionSouth;
00241         break;
00242     case KDChartEnums::PositionUnknown:
00243         break; // initial value
00244     default:
00245         qDebug() << "TernaryAxis::updatePrerenderedLabel: unknown location";
00246     };
00247 
00248     m_label->setFont( attributes.font() );
00249     // m_label->setText( titleText() ); // done by setTitleText()
00250     m_label->setAngle( axisLabelAngle );
00251     m_label->setPosition( axisLabelPosition );
00252     m_label->setReferencePoint( KDChartEnums::PositionSouth );
00253     QFont font = attributes.font();
00254     font.setPointSizeF( 0.85 * font.pointSizeF() );
00255     m_fifty->setFont( font );
00256     m_fifty->setAngle( fiftyMarkAngle );
00257     m_fifty->setPosition( fiftyMarkPosition );
00258     m_fifty->setReferencePoint( fiftyMarkReferencePoint );
00259 }
00260 
00261 QPair<QSizeF, QSizeF> TernaryAxis::requiredMargins() const
00262 {
00263     QSizeF topleft( 0.0, 0.0 );
00264     QSizeF bottomRight( 0.0, 0.0 );
00265 
00266     switch( position().value() ) {
00267     case KDChartEnums::PositionSouth:
00268         // the label of the south axis is, in fact, up north.
00269         topleft.setHeight( m_label->pixmap().height() );
00270         bottomRight.setHeight( m_fifty->pixmap().height() );
00271         break;
00272     case KDChartEnums::PositionWest:
00273         bottomRight.setWidth( m_label->pixmap().width()
00274                               - m_label->referencePointLocation().x() );
00275         bottomRight.setHeight( m_label->pixmap().height()
00276                                - m_label->referencePointLocation().y() );
00277         break;
00278     case KDChartEnums::PositionEast:
00279         topleft.setWidth( m_label->pixmap().width()
00280                           - ( m_label->pixmap().width()
00281                               - m_label->referencePointLocation().x() ) );
00282         bottomRight.setHeight( m_label->pixmap().height()
00283                                - ( m_label->pixmap().height()
00284                                    - m_label->referencePointLocation().y() ) );
00285         break;
00286     default:
00287         qDebug() << "TernaryAxis::requiredMargins: unknown location";
00288     }
00289 //     qDebug() << "TernaryAxis::requiredMargins:" << topleft << bottomRight;
00290     return QPair<QSizeF, QSizeF>( topleft, bottomRight );
00291 }

Generated on Thu Mar 4 23:19:12 2010 for KD Chart 2 by  doxygen 1.5.4