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