# KDChartTernaryPointDiagram.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 <limits>
    00031
    00032 #include <QPainter>
    00033
    00034 #include <KDChartPaintContext>
    00035
    00036 #include "TernaryPoint.h"
    00037 #include "TernaryConstants.h"
    00038 #include "KDChartTernaryPointDiagram.h"
    00039 #include "KDChartTernaryPointDiagram_p.h"
    00040
    00041 using namespace KDChart;
    00042
    00043 #define d d_func()
    00044
    00045 TernaryPointDiagram::Private::Private()
    00046     : AbstractTernaryDiagram::Private()
    00047 {
    00048 }
    00049
    00050 TernaryPointDiagram::TernaryPointDiagram ( QWidget* parent,
    00051                                            TernaryCoordinatePlane* plane )
    00052     : AbstractTernaryDiagram( new Private(), parent, plane )
    00053 {
    00054     init();
    00055     setDatasetDimension( 3 ); // the third column is implicit
    00056 }
    00057
    00058 TernaryPointDiagram::~TernaryPointDiagram()
    00059 {
    00060 }
    00061
    00062 void TernaryPointDiagram::init()
    00063 {
    00064     d->reverseMapper.setDiagram( this );
    00065 }
    00066
    00067 void  TernaryPointDiagram::resize (const QSizeF& area)
    00068 {
    00069     Q_UNUSED( area );
    00070 }
    00071
    00072 void  TernaryPointDiagram::paint (PaintContext *paintContext)
    00073 {
    00074     d->reverseMapper.clear();
    00075
    00076     d->paint( paintContext );
    00077
    00078     // sanity checks:
    00079     if ( model() == 0 ) return;
    00080
    00081     QPainter* p = paintContext->painter();
    00082     PainterSaver s( p );
    00083
    00084     TernaryCoordinatePlane* plane =
    00085         (TernaryCoordinatePlane*) paintContext->coordinatePlane();
    00086     Q_ASSERT( plane );
    00087
    00088     double x, y, z;
    00089
    00090     int columnCount = model()->columnCount( rootIndex() );
    00091     for(int column=0; column<columnCount; column+=datasetDimension() )
    00092     {
    00093         int numrows = model()->rowCount( rootIndex() );
    00094         for( int row = 0; row < numrows; row++ )
    00095         {
    00096             QModelIndex base = model()->index( row, column );
    00097             // see if there is data otherwise skip
    00098             if( ! model()->data( model()->index( row, column+0 ) ).isNull() )
    00099             {
    00100                 p->setPen( pen( base ) );
    00101                 p->setBrush( brush( base ) );
    00102
    00103                 // retrieve data
    00104                 x = qMax( model()->data( model()->index( row, column+0 ) ).toDouble(),
    00105                           0.0 );
    00106                 y = qMax( model()->data( model()->index( row, column+1 ) ).toDouble(),
    00107                           0.0 );
    00108                 z = qMax( model()->data( model()->index( row, column+2 ) ).toDouble(),
    00109                           0.0 );
    00110
    00111                 // fix messed up data values (paint as much as possible)
    00112                 double total = x + y + z;
    00113                 if ( fabs( total ) > 3 * std::numeric_limits<double>::epsilon() ) {
    00114                     TernaryPoint tPunkt( x / total, y / total );
    00115                     QPointF diagramLocation = translate( tPunkt );
    00116                     QPointF widgetLocation = plane->translate( diagramLocation );
    00117
    00118                     paintMarker( p, model()->index( row, column ), widgetLocation );
    00119                     QString text = tr( "(%1, %2, %3)" )
    00120                                    .arg( x * 100, 0, 'f', 0 )
    00121                                    .arg( y * 100, 0, 'f', 0 )
    00122                                    .arg( z * 100, 0, 'f', 0 );
    00123                     d->paintDataValueText( p, base, widgetLocation, text );
    00124                 } else {
    00125                     // ignore and do not paint this point, garbage data
    00126                     qDebug() << "TernaryPointDiagram::paint: data point x/y/z:"
    00127                              << x << "/" << y << "/" << z << "ignored, unusable.";
    00128                 }
    00129             }
    00130         }
    00131     }
    00132 }
    00133
    00134 const QPair< QPointF, QPointF >  TernaryPointDiagram::calculateDataBoundaries () const
    00135 {
    00136     // this is a constant, because we defined it to be one:
    00137     static QPair<QPointF, QPointF> Boundaries(
    00138         TriangleBottomLeft,
    00139         QPointF( TriangleBottomRight.x(), TriangleHeight ) );
    00140     return Boundaries;
    00141 }
    00142