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

Generated on Mon Sep 17 16:16:50 2007 for KD Chart 2 by  doxygen 1.5.1