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