00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "KDChartTernaryCoordinatePlane.h"
00031 #include "KDChartTernaryCoordinatePlane_p.h"
00032
00033 #include <QtDebug>
00034 #include <QPainter>
00035
00036 #include "KDChartPaintContext.h"
00037 #include "KDChartPainterSaver_p.h"
00038 #include "KDChartTernaryAxis.h"
00039 #include "KDChartAbstractTernaryDiagram.h"
00040
00041 #include "TernaryConstants.h"
00042
00043 using namespace KDChart;
00044
00045 #define d d_func()
00046
00047 TernaryCoordinatePlane::Private::Private()
00048 : AbstractCoordinatePlane::Private()
00049 {
00050 }
00051
00052 TernaryCoordinatePlane::TernaryCoordinatePlane( Chart* parent )
00053 : AbstractCoordinatePlane( new Private(), parent )
00054 {
00055 }
00056
00057 TernaryCoordinatePlane::~TernaryCoordinatePlane()
00058 {
00059 }
00060
00061 void TernaryCoordinatePlane::init()
00062 {
00063 }
00064
00065 void TernaryCoordinatePlane::addDiagram( AbstractDiagram* diagram )
00066 {
00067 Q_ASSERT_X ( dynamic_cast<AbstractTernaryDiagram*>( diagram ),
00068 "TernaryCoordinatePlane::addDiagram", "Only ternary "
00069 "diagrams can be added to a ternary coordinate plane!" );
00070 AbstractCoordinatePlane::addDiagram ( diagram );
00071
00072
00073
00074 }
00075
00076 void TernaryCoordinatePlane::layoutDiagrams()
00077 {
00078
00079
00080 QRectF diagramNativeRectangle ( QPointF( 0.0, 0.0 ),
00081 QSizeF( TriangleWidth, TriangleHeight ) );
00082 QPair<QSizeF, QSizeF> margins = grid()->requiredMargins();
00083 d->diagramRect = areaGeometry();
00084 diagramNativeRectangle.adjust
00085 (-margins.first.width(), -margins.first.height(),
00086 margins.second.width(), margins.second.height() );
00087
00088
00089
00090 {
00091 QSizeF topleft( 0.0, 0.0 );
00092 QSizeF bottomRight( 0.0, 0.0 );
00093 Q_FOREACH( AbstractDiagram* abstractDiagram, diagrams() ) {
00094 AbstractTernaryDiagram* diagram =
00095 qobject_cast<AbstractTernaryDiagram*>( abstractDiagram );
00096 Q_ASSERT( diagram );
00097 Q_FOREACH( TernaryAxis* axis, diagram->axes() ) {
00098 QPair<QSizeF, QSizeF> margin = axis->requiredMargins();
00099 topleft = topleft.expandedTo( margin.first );
00100 bottomRight = bottomRight.expandedTo( margin.second );
00101 }
00102 }
00103 d->diagramRectContainer =
00104 d->diagramRect.adjusted( topleft.width(),
00105 topleft.height(),
00106 -bottomRight.width(),
00107 -bottomRight.height() );
00108 }
00109
00110
00111
00112 QPointF zeroZeroPoint = d->diagramRectContainer.bottomLeft();
00113 double w = d->diagramRectContainer.width();
00114 double h = d->diagramRectContainer.height();
00115 double usableWidth;
00116 double usableHeight;
00117
00118 if ( TriangleHeight * w > h ) {
00119
00120 usableWidth = h / diagramNativeRectangle.height();
00121 usableHeight = h;
00122 zeroZeroPoint.setX( zeroZeroPoint.x() + ( w - usableWidth ) / 2 );
00123 } else {
00124
00125 usableWidth = w;
00126 usableHeight = diagramNativeRectangle.height() * w;
00127 zeroZeroPoint.setY( zeroZeroPoint.y() - ( h - usableHeight ) / 2 );
00128 }
00129
00130
00131 d->xUnit = usableWidth / diagramNativeRectangle.width();
00132 d->yUnit = -usableHeight / diagramNativeRectangle.height();
00133
00134
00135 {
00136 double descent = diagramNativeRectangle.height() - TriangleHeight;
00137 double rightShift = -diagramNativeRectangle.x();
00138 zeroZeroPoint += QPointF( rightShift * d->xUnit, descent * d->yUnit );
00139 }
00140
00141 d->diagramRect.setBottomLeft( zeroZeroPoint );
00142 d->diagramRect.setTopRight( QPointF( usableWidth, -usableHeight ) + zeroZeroPoint );
00143 }
00144
00145 const QPointF TernaryCoordinatePlane::translate( const QPointF& point ) const
00146 {
00147 return QPointF( d->diagramRect.bottomLeft().x() + point.x() * d->xUnit,
00148 d->diagramRect.bottomLeft().y() + point.y() * d->yUnit );
00149 }
00150
00151 QSize TernaryCoordinatePlane::minimumSizeHint() const
00152 {
00153
00154 return QSize();
00155 }
00156
00157 QSizePolicy TernaryCoordinatePlane::sizePolicy() const
00158 {
00159 return QSizePolicy( QSizePolicy::MinimumExpanding,
00160 QSizePolicy::MinimumExpanding );
00161 }
00162
00163 void TernaryCoordinatePlane::paint( QPainter* painter )
00164 {
00165 PainterSaver s( painter );
00166
00167 painter->setRenderHint(QPainter::Antialiasing, true );
00168
00169
00170
00171
00172
00173 AbstractDiagramList diags = diagrams();
00174 if ( !diags.isEmpty() )
00175 {
00176 PaintContext ctx;
00177 ctx.setPainter ( painter );
00178 ctx.setCoordinatePlane ( this );
00179 const QRectF drawArea( areaGeometry() );
00180 ctx.setRectangle ( drawArea );
00181
00182
00183
00184
00185
00186
00187
00188 Q_ASSERT( d->grid != 0 );
00189 d->grid->drawGrid( &ctx );
00190
00191
00192 for ( int i = 0; i < diags.size(); i++ )
00193 {
00194 PainterSaver diagramPainterSaver( painter );
00195 diags[i]->paint ( &ctx );
00196 }
00197 }
00198 }
00199
00200 DataDimensionsList TernaryCoordinatePlane::getDataDimensionsList() const
00201 {
00202 return DataDimensionsList();
00203 }
00204
00205 TernaryGrid* TernaryCoordinatePlane::grid() const
00206 {
00207 TernaryGrid* ternaryGrid = static_cast<TernaryGrid*>( d->grid );
00208 Q_ASSERT( dynamic_cast<TernaryGrid*>( d->grid ) );
00209 return ternaryGrid;
00210 }
00211
00212 #undef d