KD Chart 2
[rev.2.5]
|
00001 /**************************************************************************** 00002 ** Copyright (C) 2001-2012 Klaralvdalens Datakonsult AB. All rights reserved. 00003 ** 00004 ** This file is part of the KD Chart library. 00005 ** 00006 ** Licensees holding valid commercial KD Chart licenses may use this file in 00007 ** accordance with the KD Chart Commercial License Agreement provided with 00008 ** the Software. 00009 ** 00010 ** 00011 ** This file may be distributed and/or modified under the terms of the 00012 ** GNU General Public License version 2 and version 3 as published by the 00013 ** Free Software Foundation and appearing in the file LICENSE.GPL.txt included. 00014 ** 00015 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00016 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00017 ** 00018 ** Contact info@kdab.com if any conditions of this licensing are not 00019 ** clear to you. 00020 ** 00021 **********************************************************************/ 00022 00023 #include "KDChartTernaryPointDiagram.h" 00024 #include "KDChartTernaryPointDiagram_p.h" 00025 00026 #include <limits> 00027 00028 #include <QPainter> 00029 00030 #include <KDChartPaintContext.h> 00031 00032 #include "TernaryPoint.h" 00033 #include "TernaryConstants.h" 00034 00035 using namespace KDChart; 00036 00037 #define d d_func() 00038 00039 TernaryPointDiagram::Private::Private() 00040 : AbstractTernaryDiagram::Private() 00041 { 00042 } 00043 00044 TernaryPointDiagram::TernaryPointDiagram ( QWidget* parent, 00045 TernaryCoordinatePlane* plane ) 00046 : AbstractTernaryDiagram( new Private(), parent, plane ) 00047 { 00048 init(); 00049 setDatasetDimensionInternal( 3 ); // the third column is implicit 00050 } 00051 00052 TernaryPointDiagram::~TernaryPointDiagram() 00053 { 00054 } 00055 00056 void TernaryPointDiagram::init() 00057 { 00058 d->reverseMapper.setDiagram( this ); 00059 } 00060 00061 void TernaryPointDiagram::resize (const QSizeF& area) 00062 { 00063 Q_UNUSED( area ); 00064 } 00065 00066 void TernaryPointDiagram::paint (PaintContext *paintContext) 00067 { 00068 d->reverseMapper.clear(); 00069 00070 d->paint( paintContext ); 00071 00072 // sanity checks: 00073 if ( model() == 0 ) return; 00074 00075 QPainter* p = paintContext->painter(); 00076 PainterSaver s( p ); 00077 00078 TernaryCoordinatePlane* plane = 00079 static_cast< TernaryCoordinatePlane* >( paintContext->coordinatePlane() ); 00080 Q_ASSERT( plane ); 00081 00082 qreal x, y, z; 00083 00084 00085 // for some reason(?) TernaryPointDiagram is using per-diagram DVAs only: 00086 const DataValueAttributes attrs( dataValueAttributes() ); 00087 00088 d->forgetAlreadyPaintedDataValues(); 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, rootIndex() ); // checked 00097 // see if there is data otherwise skip 00098 if( ! model()->data( base ).isNull() ) 00099 { 00100 p->setPen( PrintingParameters::scalePen( pen( base ) ) ); 00101 p->setBrush( brush( base ) ); 00102 00103 // retrieve data 00104 x = qMax( model()->data( model()->index( row, column+0, rootIndex() ) ).toReal(), // checked 00105 0.0 ); 00106 y = qMax( model()->data( model()->index( row, column+1, rootIndex() ) ).toReal(), // checked 00107 0.0 ); 00108 z = qMax( model()->data( model()->index( row, column+2, rootIndex() ) ).toReal(), // checked 00109 0.0 ); 00110 00111 // fix messed up data values (paint as much as possible) 00112 qreal total = x + y + z; 00113 if ( fabs( total ) > 3 * std::numeric_limits<qreal>::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, rootIndex() ), widgetLocation ); // checked 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, attrs, widgetLocation, true, text, true ); 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