29#include "KDChartRingPainter.h"
33#include <tqvaluestack.h>
37#define DEGTORAD(d) (d)*M_PI/180
83 uint chart = paint2nd ? 1 : 0;
85 TQRect ourClipRect( _dataRect );
87 const TQWMatrix & world = painter->worldMatrix();
88 ourClipRect = world.mapRect( ourClipRect );
89 ourClipRect.setTop(ourClipRect.top()-1);
90 ourClipRect.setLeft(ourClipRect.left()-1);
91 ourClipRect.setBottom(ourClipRect.bottom()+1);
92 ourClipRect.setRight(ourClipRect.right()+1);
93 painter->setClipRect( ourClipRect );
95 uint datasetStart, datasetEnd;
96 if ( params()->neverUsedSetChartSourceMode()
97 || !params()->findDataset( KDChartParams::DataEntry,
101 uint maxRow, maxRowMinus1;
111 maxRowMinus1 = maxRow - 1;
113 datasetStart = paint2nd ? maxRow
115 datasetEnd = paint2nd ? maxRow
116 : ( ( KDChartParams::NoType
121 uint datasetNum = abs( (
int)( datasetEnd - datasetStart ) + 1 );
126 if ( params()->numValues() != -1 )
132 _size = TQMIN( _dataRect.width(), _dataRect.height() );
135 if ( params()->explode() ) {
136 double doubleSize = ( double ) _size;
138 _size = ( int ) doubleSize;
141 int x = ( _dataRect.width() == _size ) ? 0 : ( ( _dataRect.width() - _size ) / 2 );
142 int y = ( _dataRect.height() == _size ) ? 0 : ( ( _dataRect.height() - _size ) / 2 );
143 _position = TQRect( x, y, _size, _size );
144 _position.moveBy( _dataRect.left(), _dataRect.top() );
148 TQMemArray<double> rowsums;
149 double totalSum = 0.0;
150 rowsums.resize( datasetEnd+1 );
151 for(
int d1 = (
int)datasetStart; d1 <= (int)datasetEnd; d1++ ) {
152 rowsums[d1] = data->rowAbsSum( d1 );
153 totalSum += rowsums[d1];
156 TQMemArray<int> ringthicknesses;
157 ringthicknesses.resize( datasetEnd+1 );
160 int ringthickness = _size / ( datasetNum * 2 );
163 if( ringthickness > ( _size/10 ) )
164 ringthickness = _size / 10;
166 for(
int d2 = (
int)datasetStart; d2 <= (int)datasetEnd; d2++ )
170 ringthicknesses[d2] = (uint)floor( (rowsums[d2] / totalSum) *
171 ( 2.0 * (double)ringthickness ) + 0.5 );
173 ringthicknesses[d2] = ringthickness;
176 int currentouterradius = _size/2;
179 for(
int dataset = (
int)datasetStart; dataset <= (int)datasetEnd; dataset++ ) {
180 double sectorsPerValue = 5760.0 / rowsums[dataset];
182 double currentstartpos = (double)params()->
ringStart() * 16.0;
185 for(
int value = 0; value < _numValues; value++ ) {
187 double cellValue = 0.0;
188 if( data->
cellCoord( dataset, value, vValY, 1 ) &&
189 TQVariant::Double == vValY.type() ){
190 cellValue = fabs( vValY.toDouble() );
197 bool explode = params()->
explode() &&
198 ( dataset == (int)datasetStart ) &&
199 ( ( explodeList.count() == 0 ) ||
200 ( explodeList.find( value ) != explodeList.end() ) );
202 drawOneSegment( painter,
204 currentouterradius-ringthicknesses[dataset],
206 sectorsPerValue * cellValue,
207 dataset, value, chart, explode, regions );
209 currentstartpos += sectorsPerValue * cellValue;
211 currentouterradius -= ringthicknesses[dataset];
217void KDChartRingPainter::drawOneSegment( TQPainter* painter,
229 if( angles == 5760.0 )
232 painter->setPen( TQPen( params()->outlineDataColor(),
233 params()->outlineDataLineWidth() ) );
234 painter->setBrush( params()->dataColor( value ) );
236 uint outerRadius2 = outerRadius * 2;
237 uint innerRadius2 = innerRadius * 2;
239 TQRect drawPosition = _position;
242 double explodeAngle = ( startAngle + angles / 2.0 ) / 16.0;
243 double explodeAngleRad = DEGTORAD( explodeAngle );
244 double cosAngle = cos( explodeAngleRad );
245 double sinAngle = -sin( explodeAngleRad );
248 double explodeFactor = 0.0;
250 if( !explodeFactors.contains( value ) )
253 explodeFactor = explodeFactors[value];
255 double explodeX = explodeFactor * _size * cosAngle;
256 double explodeY = explodeFactor * _size * sinAngle;
257 drawPosition.moveBy(
static_cast<int>( explodeX ),
static_cast<int>( explodeY ) );
260 TQRect outerRect( drawPosition.x() +
261 ( drawPosition.width() - outerRadius2 ) / 2,
263 ( drawPosition.height() - outerRadius2 ) / 2,
264 outerRadius2, outerRadius2 );
265 TQRect innerRect( drawPosition.x() +
266 ( drawPosition.width() - innerRadius2 ) / 2,
268 ( drawPosition.height() - innerRadius2 ) / 2,
269 innerRadius2, innerRadius2 );
272 TQPointArray innerArc;
273 makeArc( innerArc, innerRect, startAngle, angles );
276 TQPointArray outerArc;
277 makeArc( outerArc, outerRect, startAngle, angles );
281 uint innerArcPoints = innerArc.size();
282 uint outerArcPoints = outerArc.size();
283 innerArc.resize( innerArcPoints + outerArcPoints );
284 for (
int i = outerArcPoints - 1; i >= 0; i-- ) {
285 innerArc.setPoint( innerArcPoints+outerArcPoints-i-1,
286 outerArc.point( i ) );
289 painter->drawPolygon( innerArc );
291 KDChartDataRegion* datReg =
new KDChartDataRegion( dataset,
296 const int aA =
static_cast<int>( startAngle );
297 const int aM =
static_cast<int>( startAngle + angles / 2.0 );
298 const int aZ =
static_cast<int>( startAngle + angles );
300 datReg->points[ KDChartEnums::PosTopLeft ]
301 = pointOnCircle( outerRect, aZ );
302 datReg->points[ KDChartEnums::PosTopCenter ]
303 = pointOnCircle( outerRect, aM );
304 datReg->points[ KDChartEnums::PosTopRight ]
305 = pointOnCircle( outerRect, aA );
307 datReg->points[ KDChartEnums::PosBottomLeft ]
308 = pointOnCircle( innerRect, aZ );
309 datReg->points[ KDChartEnums::PosBottomCenter ]
310 = pointOnCircle( innerRect, aM );
311 datReg->points[ KDChartEnums::PosBottomRight ]
312 = pointOnCircle( innerRect, aA );
314 datReg->points[ KDChartEnums::PosCenterLeft ]
315 = TQPoint( ( datReg->points[ KDChartEnums::PosTopLeft ].x()
316 + datReg->points[ KDChartEnums::PosBottomLeft ].x() ) / 2,
317 ( datReg->points[ KDChartEnums::PosTopLeft ].y()
318 + datReg->points[ KDChartEnums::PosBottomLeft ].y() ) / 2 );
319 datReg->points[ KDChartEnums::PosCenter ]
320 = TQPoint( ( datReg->points[ KDChartEnums::PosTopCenter ].x()
321 + datReg->points[ KDChartEnums::PosBottomCenter ].x() ) / 2,
322 ( datReg->points[ KDChartEnums::PosTopCenter ].y()
323 + datReg->points[ KDChartEnums::PosBottomCenter ].y() ) / 2 );
324 datReg->points[ KDChartEnums::PosCenterRight ]
325 = TQPoint( ( datReg->points[ KDChartEnums::PosTopRight ].x()
326 + datReg->points[ KDChartEnums::PosBottomRight ].x() ) / 2,
327 ( datReg->points[ KDChartEnums::PosTopRight ].y()
328 + datReg->points[ KDChartEnums::PosBottomRight ].y() ) / 2 );
356 datReg->startAngle =
static_cast<int>( startAngle );
357 datReg->angleLen =
static_cast<int>( angles );
358 regions->append( datReg );
378 return TQObject::tr(
"Item " ) + TQString::number( dataset + 1 );
Header for all common chart parameters.
The collection class used by KD Chart to store data region information.
An abstract base class that defines an interface for classes that implement chart drawing.
Bundles the display parameters of a chart.
ExplodeFactorsMap explodeFactors() const
Returns the list of explode factors.
bool relativeRingThickness() const
Returns whether the ring thickness is relative to the sum of values in the dataset that the ring repr...
int numValues() const
Returns how many of the values should be shown.
ChartType additionalChartType() const
Returns the additional chart type configured in this params object.
TQValueList< int > explodeValues() const
Returns which values are exploded in a pie or ring chart.
bool explode() const
Returns whether the pie or ring chart should be exploding or not.
int ringStart() const
Returns the starting point of the ring circle.
double explodeFactor() const
Returns the default explode factor, i.e., the explode factor used for those segments which should be ...
virtual ~KDChartRingPainter()
Destructor.
virtual void paintData(TQPainter *painter, KDChartTableDataBase *data, bool paint2nd, KDChartDataRegionList *regions=0)
Paints the actual data area.
virtual TQString fallbackLegendText(uint dataset) const
This method is a specialization that returns a fallback legend text appropriate for rings where the f...
KDChartRingPainter(KDChartParams *params)
Constructor.
virtual uint numLegendFallbackTexts(KDChartTableDataBase *data) const
This methods returns the number of elements to be shown in the legend in case fallback texts are used...
KD Chart's build-in table data for an easy way of storing data values.
virtual uint usedCols() const
Returns the number of cols in the table that actually contain data.
virtual bool cellCoord(uint _row, uint _col, TQVariant &_value, int coordinate=1) const =0
Returns one of the coordinate data value(s) stored in a cell.
virtual uint usedRows() const
Returns the number of rows in the table that actually contain data.