239
246
double pTextsW = 0.0;
240
247
double pTextsH = 0.0;
241
248
int textAlign = Qt::AlignHCenter | Qt::AlignVCenter;
242
KDChartAxesPainter::calculateLabelTexts( *painter,
245
KDChartAxisParams::AxisPosCircular,
250
// start of reference parameters
259
labelTexts = ( QStringList* ) paraCircular.axisLabelTexts();
260
if( paraCircular.axisLabelsVisible() ) {
261
// calculate font size
262
actFont = paraCircular.axisLabelsFont();
263
if ( paraCircular.axisLabelsFontUseRelSize() ) {
264
actFont.setPointSizeFloat( nTxtHeight );
266
QFontMetrics fm( actFont );
268
int maxLabelsWidth = 0;
269
for ( QStringList::Iterator it = labelTexts->begin();
270
it != labelTexts->end();
272
if ( fm.width( *it ) > maxLabelsWidth ) {
273
maxLabelsWidth = fm.width( *it );
277
while ( fm.width( strMax ) > pTextsW
278
&& 6.0 < nTxtHeight ) {
280
actFont.setPointSizeFloat( nTxtHeight );
281
fm = QFontMetrics( actFont );
283
painter->setFont( actFont );
286
double radiusDelta = pDelimDelta;
289
? labelTexts->count()
292
currentRadiusPPU = -radiusDelta;
293
for( int iLabel = 0; iLabel < labels; ++iLabel ) {
294
//while( currentRadius < maxValue ) {
295
//double currentRadiusPPU = currentRadius;
296
currentRadiusPPU += radiusDelta;
297
double currentRadiusPPU2 = currentRadiusPPU * 2;
298
int circularAxisAngle = static_cast < int > (4.0 * radiusPPU / currentRadiusPPU);
299
if( paraCircular.axisShowGrid() ) {
300
painter->setPen( QPen( paraCircular.axisGridColor(),
301
circularGridLineWidth ) );
302
painter->drawEllipse( center.x() - currentRadiusPPU,
303
center.y() - currentRadiusPPU,
304
currentRadiusPPU2, currentRadiusPPU2 );
306
if( paraCircular.axisVisible() ) {
307
painter->setPen( QPen( paraCircular.axisLineColor(),
308
circularLineWidth ) );
309
if( params()->polarDelimAtPos( KDChartEnums::PosTopCenter ) )
310
painter->drawArc( center.x() - currentRadiusPPU,
311
center.y() - currentRadiusPPU,
312
currentRadiusPPU2, currentRadiusPPU2,
313
(90 - circularAxisAngle/2) * 16,
314
circularAxisAngle * 16 );
315
if( params()->polarDelimAtPos( KDChartEnums::PosBottomCenter ) )
316
painter->drawArc( center.x() - currentRadiusPPU,
317
center.y() - currentRadiusPPU,
318
currentRadiusPPU2, currentRadiusPPU2,
319
(270 - circularAxisAngle/2) * 16,
320
circularAxisAngle * 16 );
322
if( params()->polarDelimAtPos( KDChartEnums::PosCenterRight ) )
323
painter->drawArc( center.x() - currentRadiusPPU,
324
center.y() - currentRadiusPPU,
325
currentRadiusPPU2, currentRadiusPPU2,
326
(0 - circularAxisAngle/2) * 16,
327
circularAxisAngle * 16 );
328
if( params()->polarDelimAtPos( KDChartEnums::PosCenterLeft ) )
329
painter->drawArc( center.x() - currentRadiusPPU,
330
center.y() - currentRadiusPPU,
331
currentRadiusPPU2, currentRadiusPPU2,
332
(180 - circularAxisAngle/2) * 16,
333
circularAxisAngle * 16 );
335
if( params()->polarDelimAtPos( KDChartEnums::PosTopRight ) )
336
painter->drawArc( center.x() - currentRadiusPPU,
337
center.y() - currentRadiusPPU,
338
currentRadiusPPU2, currentRadiusPPU2,
339
(45 - circularAxisAngle/2) * 16,
340
circularAxisAngle * 16 );
341
if( params()->polarDelimAtPos( KDChartEnums::PosBottomLeft ) )
342
painter->drawArc( center.x() - currentRadiusPPU,
343
center.y() - currentRadiusPPU,
344
currentRadiusPPU2, currentRadiusPPU2,
345
(225 - circularAxisAngle/2) * 16,
346
circularAxisAngle * 16 );
348
if( params()->polarDelimAtPos( KDChartEnums::PosBottomRight ) )
349
painter->drawArc( center.x() - currentRadiusPPU,
350
center.y() - currentRadiusPPU,
351
currentRadiusPPU2, currentRadiusPPU2,
352
(315 - circularAxisAngle/2) * 16,
353
circularAxisAngle * 16 );
354
if( params()->polarDelimAtPos( KDChartEnums::PosTopLeft ) )
355
painter->drawArc( center.x() - currentRadiusPPU,
356
center.y() - currentRadiusPPU,
357
currentRadiusPPU2, currentRadiusPPU2,
358
(135 - circularAxisAngle/2) * 16,
359
circularAxisAngle * 16 );
361
if( paraCircular.axisLabelsVisible() ) {
362
const bool rotate = params()->polarRotateCircularLabels();
363
QPoint shiftCenter = center + _dataRect.topLeft();
364
painter->setPen( QPen( paraCircular.axisLabelsColor(),
365
circularLineWidth ) );
366
const QString& txt = (*labelTexts)[ iLabel ];
367
if( params()->polarLabelsAtPos( KDChartEnums::PosTopCenter ) )
368
paintCircularAxisLabel( painter, rotate, 90, shiftCenter, currentRadiusPPU, txt,
369
Qt::AlignBottom | Qt::AlignHCenter, iLabel );
371
if( params()->polarLabelsAtPos( KDChartEnums::PosBottomCenter ) )
372
paintCircularAxisLabel( painter, rotate, 270, shiftCenter, currentRadiusPPU, txt,
373
Qt::AlignTop | Qt::AlignHCenter, iLabel );
375
if( params()->polarLabelsAtPos( KDChartEnums::PosCenterRight ) )
376
paintCircularAxisLabel( painter, rotate, 0, shiftCenter, currentRadiusPPU, txt,
377
Qt::AlignVCenter | Qt::AlignRight, iLabel );
379
if( params()->polarLabelsAtPos( KDChartEnums::PosCenterLeft ) )
380
paintCircularAxisLabel( painter, rotate, 180, shiftCenter, currentRadiusPPU, txt,
381
Qt::AlignVCenter | Qt::AlignLeft, iLabel );
383
if( params()->polarLabelsAtPos( KDChartEnums::PosTopRight ) )
384
paintCircularAxisLabel( painter, rotate, 45, shiftCenter, currentRadiusPPU, txt,
385
Qt::AlignBottom | Qt::AlignRight, iLabel );
387
if( params()->polarLabelsAtPos( KDChartEnums::PosBottomLeft ) )
388
paintCircularAxisLabel( painter, rotate, 225, shiftCenter, currentRadiusPPU, txt,
389
Qt::AlignTop | Qt::AlignLeft, iLabel );
391
if( params()->polarLabelsAtPos( KDChartEnums::PosBottomRight ) )
392
paintCircularAxisLabel( painter, rotate, 315, shiftCenter, currentRadiusPPU, txt,
393
Qt::AlignTop | Qt::AlignRight, iLabel );
395
if( params()->polarLabelsAtPos( KDChartEnums::PosTopLeft ) )
396
paintCircularAxisLabel( painter, rotate, 135, shiftCenter, currentRadiusPPU, txt,
397
Qt::AlignBottom | Qt::AlignLeft, iLabel );
403
double circularSpan = params()->polarChartSubType() == KDChartParams::PolarPercent
405
: paraCircular.trueAxisHigh() - paraCircular.trueAxisLow();
406
double radius = currentRadiusPPU;
408
|| params()->polarChartSubType() == KDChartParams::PolarPercent )
409
radius = (position.width() / 2.0) * 1000.0 / 1250.0;
411
if( params()->polarChartSubType() != KDChartParams::PolarPercent )
412
pixelsPerUnit = labels ? currentRadiusPPU / circularSpan
413
: (position.height() / maxValue / 2.0) * 1000.0 / 1250.0;
415
pixelsPerUnit = (position.height() / 100.0 / 2.0) * 1000.0 / 1250.0;
417
// draw the saggital grid and axis lines
418
if( paraSaggital.axisShowGrid()
419
|| paraSaggital.axisVisible()
420
|| paraSaggital.axisLabelsVisible() ) {
422
// calculate label texts
423
QStringList* labelTexts = 0;
424
bool onlyDefaultLabels = true;
425
if( paraSaggital.axisLabelsVisible() ) {
426
((KDChartParams*)params())->setAxisArea( KDChartAxisParams::AxisPosSaggital,
429
static_cast < int > ( 2.0 * M_PI * radius ),
430
static_cast < int > ( 0.5 * radius ) ) );
431
double delimLen = 20.0 * minSizeP1000; // per mille of area
432
KDChartAxisParams::AxisPos basicPos;
434
KDChartAxesPainter::findInfos( minSizeP1000,
436
KDChartAxisParams::AxisPosSaggital,
440
double nSubDelimFactor = 0.0;
441
double pDelimDelta = 0.0;
442
double nTxtHeight = 0.0;
443
double pTextsX = 0.0;
444
double pTextsY = 0.0;
445
double pTextsW = 0.0;
446
double pTextsH = 0.0;
447
int textAlign = Qt::AlignCenter;
448
KDChartAxesPainter::calculateLabelTexts( *painter,
451
KDChartAxisParams::AxisPosSaggital,
456
// start of reference parameters
465
labelTexts = ( QStringList* ) paraSaggital.axisLabelTexts();
466
// calculate font size
467
actFont = paraSaggital.axisLabelsFont();
468
if ( paraSaggital.axisLabelsFontUseRelSize() ) {
469
actFont.setPointSizeFloat( nTxtHeight );
471
QFontMetrics fm( actFont );
473
int maxLabelsWidth = 0;
474
for ( QStringList::Iterator it = labelTexts->begin();
475
it != labelTexts->end();
477
if ( fm.width( *it ) > maxLabelsWidth ) {
478
maxLabelsWidth = fm.width( *it );
481
if ( !(*it).startsWith( "Item ") )
482
onlyDefaultLabels = false;
484
while ( fm.width( strMax ) > pTextsW && 6.0 < nTxtHeight ) {
486
actFont.setPointSizeFloat( nTxtHeight );
487
fm = QFontMetrics( actFont );
489
painter->setFont( actFont );
492
int currentAngle = params()->polarZeroDegreePos();
493
if( -360 > currentAngle
494
|| 360 < currentAngle )
496
if( 0 > currentAngle )
498
int r1 = static_cast < int > ( radius * 1050 / 1000 );
499
int r2 = static_cast < int > ( radius * 1100 / 1000 );
500
int r3 = static_cast < int > ( radius * 1175 / 1000 );
501
QPoint pt1, pt2, pt3;
502
uint nLabels = labelTexts->count();
503
int angleBetweenRays = 360 / nLabels;
504
for( uint value = 0; value < nLabels; ++value ) {
505
pt1 = center + polarToXY( r1, currentAngle );
506
pt2 = center + polarToXY( r2, currentAngle );
507
pt3 = center + polarToXY( r3, currentAngle );
508
if( paraSaggital.axisShowGrid() ) {
509
painter->setPen( QPen( paraSaggital.axisGridColor(),
510
saggitalGridLineWidth ) );
511
painter->drawLine( center, pt1 );
513
if( paraSaggital.axisVisible() ) {
514
painter->setPen( QPen( paraSaggital.axisLineColor(),
515
saggitalLineWidth ) );
516
painter->drawLine( pt1, pt2 );
518
if( paraSaggital.axisLabelsVisible()
520
&& labelTexts->count() > value ) {
521
painter->setPen( QPen( paraSaggital.axisLabelsColor(),
522
saggitalLineWidth ) );
523
QString label( onlyDefaultLabels
524
? QString::number( currentAngle )
525
: (*labelTexts)[ value ] );
527
KDDrawText::drawRotatedText( painter,
529
pt3 + _dataRect.topLeft(),
534
currentAngle += angleBetweenRays;
540
int dataLinesWidth = 0 <= params()->polarLineWidth()
541
? params()->polarLineWidth()
542
: -1 * static_cast < int > ( params()->polarLineWidth()
544
painter->setBrush( Qt::NoBrush );
545
for ( int dataset = datasetStart; dataset <= datasetEnd; dataset++ ) {
546
painter->setPen( QPen( params()->dataColor( dataset ),
548
QPointArray points( numValues );
550
double valueTotal = 0.0; // Will only be used for Percent
551
int angleBetweenRays = 360 / numValues;
552
for ( uint value = 0; value < numValues; value++ ) {
553
if( params()->polarChartSubType() == KDChartParams::PolarPercent )
554
valueTotal = data->colAbsSum( value );
555
// the value determines the angle, the dataset only the color
556
if ( data->cell( dataset, value ).isDouble() ) {
557
double cellValue = data->cell( dataset, value ).doubleValue();
559
if ( params()->polarChartSubType() == KDChartParams::PolarStacked )
560
drawValue = ( cellValue + currentValueSums[ value ] ) * pixelsPerUnit;
561
else if( params()->polarChartSubType() == KDChartParams::PolarPercent ) {
562
drawValue = ( ( cellValue + currentValueSums[ value ] )
563
/ valueTotal * static_cast<double>( radius ) );
565
drawValue = cellValue * pixelsPerUnit;
567
// record the point for drawing the polygon later
568
int drawAngle = value * angleBetweenRays;
569
QPoint drawPoint( center + polarToXY( static_cast<int>( drawValue ),
571
points.setPoint( totalPoints, drawPoint );
574
// the marker can be drawn now
575
if( params()->polarMarker() ) {
576
drawMarker( painter, params()->polarMarkerStyle( dataset ),
577
params()->dataColor( dataset ),
579
dataset, value, chart, minSizeP1000, region );
249
bool isLogarithmic = false; // value not used for KD Chart 1.0.0
250
bool isDateTime = false;
251
bool autoDtLabels = false;
254
KDChartAxisParams::ValueScale dtDeltaScale;
255
KDChartAxesPainter::calculateLabelTexts( *data,
257
KDChartAxisParams::AxisPosCircular,
260
// start of reference parameters
264
dDummy,dDummy,dDummy,dDummy,
279
labelTexts = ( QStringList* ) paraCircular.axisLabelTexts();
280
if( paraCircular.axisLabelsVisible() ) {
281
//qDebug("\nnTxtHeight: "+QString::number(nTxtHeight));
282
// calculate font size
283
actFont = paraCircular.axisLabelsFont();
284
if ( paraCircular.axisLabelsFontUseRelSize() ) {
285
//qDebug("paraCircular.axisLabelsFontUseRelSize() is TRUE");
286
actFont.setPointSizeFloat( nTxtHeight );
288
QFontMetrics fm( actFont );
290
int maxLabelsWidth = 0;
291
for ( QStringList::Iterator it = labelTexts->begin();
292
it != labelTexts->end();
294
if ( fm.width( *it ) > maxLabelsWidth ) {
295
maxLabelsWidth = fm.width( *it );
299
while ( fm.width( strMax ) > pTextsW
300
&& 6.0 < nTxtHeight ) {
302
actFont.setPointSizeFloat( nTxtHeight );
303
fm = QFontMetrics( actFont );
305
painter->setFont( actFont );
308
double radiusDelta = pDelimDelta;
311
? labelTexts->count()
314
currentRadiusPPU = -radiusDelta;
315
for( int iLabel = 0; iLabel < labels; ++iLabel ) {
316
//while( currentRadius < maxValue ) {
317
//double currentRadiusPPU = currentRadius;
318
currentRadiusPPU += radiusDelta;
319
double currentRadiusPPU2 = currentRadiusPPU * 2;
320
int circularAxisAngle = ( currentRadiusPPU != 0.0 ) ? ( static_cast < int > (4.0 * radiusPPU / currentRadiusPPU) ) : 0;
321
if( paraCircular.axisShowGrid() ) {
322
painter->setPen( QPen( paraCircular.axisGridColor(),
323
circularGridLineWidth ) );
324
painter->drawEllipse( static_cast<int>( center.x() - currentRadiusPPU ),
325
static_cast<int>( center.y() - currentRadiusPPU ),
326
static_cast<int>( currentRadiusPPU2 ), static_cast<int>( currentRadiusPPU2 ) );
328
if( paraCircular.axisVisible() ) {
329
painter->setPen( QPen( paraCircular.axisLineColor(),
330
circularLineWidth ) );
331
if( params()->polarDelimAtPos( KDChartEnums::PosTopCenter ) )
332
painter->drawArc( static_cast<int>( center.x() - currentRadiusPPU ),
333
static_cast<int>( center.y() - currentRadiusPPU ),
334
static_cast<int>( currentRadiusPPU2 ), static_cast<int>( currentRadiusPPU2 ),
335
(90 - circularAxisAngle/2) * 16,
336
circularAxisAngle * 16 );
337
if( params()->polarDelimAtPos( KDChartEnums::PosBottomCenter ) )
338
painter->drawArc( static_cast<int>( center.x() - currentRadiusPPU ),
339
static_cast<int>( center.y() - currentRadiusPPU ),
340
static_cast<int>( currentRadiusPPU2 ), static_cast<int>( currentRadiusPPU2 ),
341
(270 - circularAxisAngle/2) * 16,
342
circularAxisAngle * 16 );
344
if( params()->polarDelimAtPos( KDChartEnums::PosCenterRight ) )
345
painter->drawArc( static_cast<int>( center.x() - currentRadiusPPU ),
346
static_cast<int>( center.y() - currentRadiusPPU ),
347
static_cast<int>( currentRadiusPPU2 ), static_cast<int>( currentRadiusPPU2 ),
348
(0 - circularAxisAngle/2) * 16,
349
circularAxisAngle * 16 );
350
if( params()->polarDelimAtPos( KDChartEnums::PosCenterLeft ) )
351
painter->drawArc( static_cast<int>( center.x() - currentRadiusPPU ),
352
static_cast<int>( center.y() - currentRadiusPPU ),
353
static_cast<int>( currentRadiusPPU2 ), static_cast<int>( currentRadiusPPU2 ),
354
(180 - circularAxisAngle/2) * 16,
355
circularAxisAngle * 16 );
357
if( params()->polarDelimAtPos( KDChartEnums::PosTopRight ) )
358
painter->drawArc( static_cast<int>( center.x() - currentRadiusPPU ),
359
static_cast<int>( center.y() - currentRadiusPPU ),
360
static_cast<int>( currentRadiusPPU2 ), static_cast<int>( currentRadiusPPU2 ),
361
(45 - circularAxisAngle/2) * 16,
362
circularAxisAngle * 16 );
363
if( params()->polarDelimAtPos( KDChartEnums::PosBottomLeft ) )
364
painter->drawArc( static_cast<int>( center.x() - currentRadiusPPU ),
365
static_cast<int>( center.y() - currentRadiusPPU ),
366
static_cast<int>( currentRadiusPPU2 ), static_cast<int>( currentRadiusPPU2 ),
367
(225 - circularAxisAngle/2) * 16,
368
circularAxisAngle * 16 );
370
if( params()->polarDelimAtPos( KDChartEnums::PosBottomRight ) )
371
painter->drawArc( static_cast<int>( center.x() - currentRadiusPPU ),
372
static_cast<int>( center.y() - currentRadiusPPU ),
373
static_cast<int>( currentRadiusPPU2 ), static_cast<int>( currentRadiusPPU2 ),
374
(315 - circularAxisAngle/2) * 16,
375
circularAxisAngle * 16 );
376
if( params()->polarDelimAtPos( KDChartEnums::PosTopLeft ) )
377
painter->drawArc( static_cast<int>( center.x() - currentRadiusPPU ),
378
static_cast<int>( center.y() - currentRadiusPPU ),
379
static_cast<int>( currentRadiusPPU2 ), static_cast<int>( currentRadiusPPU2 ),
380
(135 - circularAxisAngle/2) * 16,
381
circularAxisAngle * 16 );
383
if( paraCircular.axisLabelsVisible() ) {
384
const bool rotate = params()->polarRotateCircularLabels();
385
QPoint shiftCenter = center + _dataRect.topLeft();
386
painter->setPen( QPen( paraCircular.axisLabelsColor(),
387
circularLineWidth ) );
388
const QString& txt = (*labelTexts)[ iLabel ];
389
if( params()->polarLabelsAtPos( KDChartEnums::PosTopCenter ) )
390
paintCircularAxisLabel( painter, rotate, 90, shiftCenter, currentRadiusPPU, txt,
391
Qt::AlignBottom | Qt::AlignHCenter, iLabel );
393
if( params()->polarLabelsAtPos( KDChartEnums::PosBottomCenter ) )
394
paintCircularAxisLabel( painter, rotate, 270, shiftCenter, currentRadiusPPU, txt,
395
Qt::AlignTop | Qt::AlignHCenter, iLabel );
397
if( params()->polarLabelsAtPos( KDChartEnums::PosCenterRight ) )
398
paintCircularAxisLabel( painter, rotate, 0, shiftCenter, currentRadiusPPU, txt,
399
Qt::AlignVCenter | Qt::AlignRight, iLabel );
401
if( params()->polarLabelsAtPos( KDChartEnums::PosCenterLeft ) )
402
paintCircularAxisLabel( painter, rotate, 180, shiftCenter, currentRadiusPPU, txt,
403
Qt::AlignVCenter | Qt::AlignLeft, iLabel );
405
if( params()->polarLabelsAtPos( KDChartEnums::PosTopRight ) )
406
paintCircularAxisLabel( painter, rotate, 45, shiftCenter, currentRadiusPPU, txt,
407
Qt::AlignBottom | Qt::AlignRight, iLabel );
409
if( params()->polarLabelsAtPos( KDChartEnums::PosBottomLeft ) )
410
paintCircularAxisLabel( painter, rotate, 225, shiftCenter, currentRadiusPPU, txt,
411
Qt::AlignTop | Qt::AlignLeft, iLabel );
413
if( params()->polarLabelsAtPos( KDChartEnums::PosBottomRight ) )
414
paintCircularAxisLabel( painter, rotate, 315, shiftCenter, currentRadiusPPU, txt,
415
Qt::AlignTop | Qt::AlignRight, iLabel );
417
if( params()->polarLabelsAtPos( KDChartEnums::PosTopLeft ) )
418
paintCircularAxisLabel( painter, rotate, 135, shiftCenter, currentRadiusPPU, txt,
419
Qt::AlignBottom | Qt::AlignLeft, iLabel );
425
double circularSpan = params()->polarChartSubType() == KDChartParams::PolarPercent
427
: paraCircular.trueAxisHigh() - paraCircular.trueAxisLow();
428
double radius = currentRadiusPPU;
430
|| params()->polarChartSubType() == KDChartParams::PolarPercent )
431
radius = (position.width() / 2.0) * 1000.0 / 1250.0;
433
if( params()->polarChartSubType() != KDChartParams::PolarPercent )
434
pixelsPerUnit = labels ? currentRadiusPPU / circularSpan
435
: (position.height() / maxValue / 2.0) * 1000.0 / 1250.0;
437
pixelsPerUnit = (position.height() / 100.0 / 2.0) * 1000.0 / 1250.0;
439
// draw the sagittal grid and axis lines
440
if( paraSagittal.axisShowGrid()
441
|| paraSagittal.axisVisible()
442
|| paraSagittal.axisLabelsVisible() ) {
444
// calculate label texts
445
QStringList* labelTexts = 0;
446
bool onlyDefaultLabels = true;
447
if( paraSagittal.axisLabelsVisible() ) {
448
((KDChartParams*)params())->setAxisArea( KDChartAxisParams::AxisPosSagittal,
451
static_cast < int > ( 2.0 * M_PI * radius ),
452
static_cast < int > ( 0.5 * radius ) ) );
453
double delimLen = 20.0 * minSizeP1000; // per mille of area
454
KDChartAxisParams::AxisPos basicPos;
457
double nSubDelimFactor = 0.0;
458
double pDelimDelta = 0.0;
459
double nTxtHeight = 0.0;
460
double pTextsX = 0.0;
461
double pTextsY = 0.0;
462
double pTextsW = 0.0;
463
double pTextsH = 0.0;
464
int textAlign = Qt::AlignCenter;
465
bool isLogarithmic = false; // value not used for KD Chart 1.0.0
466
bool isDateTime = false;
467
bool autoDtLabels = false;
470
KDChartAxisParams::ValueScale dtDeltaScale;
471
KDChartAxesPainter::calculateLabelTexts( *data,
473
KDChartAxisParams::AxisPosSagittal,
476
// start of reference parameters
480
dDummy,dDummy,dDummy,dDummy,
495
labelTexts = ( QStringList* ) paraSagittal.axisLabelTexts();
496
// calculate font size
497
actFont = paraSagittal.axisLabelsFont();
498
if ( paraSagittal.axisLabelsFontUseRelSize() ) {
499
actFont.setPointSizeFloat( nTxtHeight );
501
QFontMetrics fm( actFont );
503
int maxLabelsWidth = 0;
504
for ( QStringList::Iterator it = labelTexts->begin();
505
it != labelTexts->end();
507
if ( fm.width( *it ) > maxLabelsWidth ) {
508
maxLabelsWidth = fm.width( *it );
511
if ( !(*it).startsWith( "Item ") )
512
onlyDefaultLabels = false;
514
while ( fm.width( strMax ) > pTextsW && 6.0 < nTxtHeight ) {
516
actFont.setPointSizeFloat( nTxtHeight );
517
fm = QFontMetrics( actFont );
519
painter->setFont( actFont );
522
int currentAngle = params()->polarZeroDegreePos();
523
if( -360 > currentAngle
524
|| 360 < currentAngle )
526
if( 0 > currentAngle )
528
int r1 = static_cast < int > ( radius * 1050 / 1000 );
529
int r2 = static_cast < int > ( radius * 1100 / 1000 );
530
int r3 = static_cast < int > ( radius * 1175 / 1000 );
531
QPoint pt1, pt2, pt3;
532
uint nLabels = labelTexts->count();
533
int angleBetweenRays = 360 / nLabels;
534
for( uint value = 0; value < nLabels; ++value ) {
535
pt1 = center + polarToXY( r1, currentAngle );
536
pt2 = center + polarToXY( r2, currentAngle );
537
pt3 = center + polarToXY( r3, currentAngle );
538
if( paraSagittal.axisShowGrid() ) {
539
painter->setPen( QPen( paraSagittal.axisGridColor(),
540
sagittalGridLineWidth ) );
541
painter->drawLine( center, pt1 );
543
if( paraSagittal.axisVisible() ) {
544
painter->setPen( QPen( paraSagittal.axisLineColor(),
545
sagittalLineWidth ) );
546
painter->drawLine( pt1, pt2 );
548
if( paraSagittal.axisLabelsVisible()
550
&& labelTexts->count() > value ) {
551
painter->setPen( QPen( paraSagittal.axisLabelsColor(),
552
sagittalLineWidth ) );
553
QString label( onlyDefaultLabels
554
? QString::number( currentAngle )
555
: (*labelTexts)[ value ] );
557
KDDrawText::drawRotatedText( painter,
559
pt3 + _dataRect.topLeft(),
564
currentAngle += angleBetweenRays;
570
int dataLinesWidth = 0 <= params()->polarLineWidth()
571
? params()->polarLineWidth()
572
: -1 * static_cast < int > ( params()->polarLineWidth()
574
painter->setBrush( Qt::NoBrush );
575
for ( unsigned int dataset = datasetStart; dataset <= datasetEnd; dataset++ ) {
580
576
painter->setPen( QPen( params()->dataColor( dataset ),
584
KDChartDataRegion* datReg = new KDChartDataRegion( region,
588
datReg->points[ KDChartEnums::PosTopLeft ] =
589
drawPoint + _dataRect.topLeft();
591
datReg->points[ KDChartEnums::PosTopCenter ] =
592
datReg->points[ KDChartEnums::PosTopLeft ];
593
datReg->points[ KDChartEnums::PosTopRight ] =
594
datReg->points[ KDChartEnums::PosTopLeft ];
595
datReg->points[ KDChartEnums::PosBottomLeft ] =
596
datReg->points[ KDChartEnums::PosTopLeft ];
597
datReg->points[ KDChartEnums::PosBottomCenter ] =
598
datReg->points[ KDChartEnums::PosTopLeft ];
599
datReg->points[ KDChartEnums::PosBottomRight ] =
600
datReg->points[ KDChartEnums::PosTopLeft ];
601
datReg->points[ KDChartEnums::PosCenterLeft ] =
602
datReg->points[ KDChartEnums::PosTopLeft ];
603
datReg->points[ KDChartEnums::PosCenter ] =
604
datReg->points[ KDChartEnums::PosTopLeft ];
605
datReg->points[ KDChartEnums::PosCenterRight ] =
606
datReg->points[ KDChartEnums::PosTopLeft ];
608
// test the center positions:
609
painter->drawEllipse( datReg->points[ KDChartEnums::PosCenterLeft ].x() - 2,
610
datReg->points[ KDChartEnums::PosCenterLeft ].y() - 2, 5, 5);
612
datReg->startAngle = drawAngle;
613
datReg->angleLen = drawAngle;
614
regions->append( datReg );
616
// calculate running sum for stacked and percent
617
if ( params()->polarChartSubType() == KDChartParams::PolarStacked ||
618
params()->polarChartSubType() == KDChartParams::PolarPercent )
619
currentValueSums[ value ] += cellValue;
622
painter->drawPolygon( points );
625
painter->translate( -_dataRect.x(), -_dataRect.y() );
630
Helper methode being called by KDChartPolarPainter::paintData()
632
void KDChartPolarPainter::paintCircularAxisLabel( QPainter* painter,
636
double currentRadiusPPU,
641
if( !rotate && (0 != (align & (Qt::AlignLeft | Qt::AlignRight) ) ) )
642
currentRadiusPPU += center.x()*0.01;
643
KDDrawText::drawRotatedText(
645
rotate ? txtAngle - 90 : 0,
646
step ? center - polarToXY( currentRadiusPPU, txtAngle )
650
step ? (rotate ? Qt::AlignBottom | Qt::AlignHCenter : align)
656
Draws the marker for one data point according to the specified style.
658
\param painter the painter to draw on
659
\param style what kind of marker is drawn (square, diamond or circle)
660
\param color the color in which to draw the marker
661
\param p the center of the marker
662
\param dataset the dataset which this marker represents
663
\param value the value which this marker represents
664
\param regions a list of regions for data points, a new region for the new
665
marker will be appended to this list if it is not 0
667
void KDChartPolarPainter::drawMarker( QPainter* painter,
668
KDChartParams::PolarMarkerStyle style,
669
const QColor& color, const QPoint& p,
670
uint dataset, uint value, uint chart,
674
int xsize = params()->polarMarkerSize().width();
676
xsize = -1 * static_cast < int > ( xsize * minSizeP1000 );
677
int ysize = params()->polarMarkerSize().height();
679
ysize = -1 * static_cast < int > ( ysize * minSizeP1000 );
680
int xsize2 = xsize / 2;
681
int ysize2 = ysize / 2;
682
painter->setPen( color );
684
case KDChartParams::PolarMarkerSquare: {
686
painter->setBrush( color );
687
QRect rect( QPoint( p.x() - xsize2, p.y() - ysize2 ), QPoint( p.x() + xsize2, p.y() + ysize2 ) );
688
painter->drawRect( rect );
689
// Don't use rect for drawing after this!
690
rect.moveBy( _dataRect.x(), _dataRect.y() );
691
region = QRegion( rect );
695
case KDChartParams::PolarMarkerDiamond: {
697
painter->setBrush( color );
698
QPointArray points( 4 );
699
points.setPoint( 0, p.x() - xsize2, p.y() );
700
points.setPoint( 1, p.x(), p.y() - ysize2 );
701
points.setPoint( 2, p.x() + xsize2, p.y() );
702
points.setPoint( 3, p.x(), p.y() + ysize2 );
703
painter->drawPolygon( points );
704
// Don't use points for drawing after this!
705
points.translate( _dataRect.x(), _dataRect.y() );
706
region = QRegion( points );
710
case KDChartParams::PolarMarkerCircle:
713
painter->setBrush( color );
714
painter->drawEllipse( p.x() - xsize2, p.y() - ysize2, xsize, ysize );
716
points.makeEllipse( p.x() - xsize2, p.y() - ysize2, xsize, ysize );
717
// Don't use points for drawing after this!
718
points.translate( _dataRect.x(), _dataRect.y() );
719
if( points.size() > 0 )
720
region = QRegion( points );
578
QPointArray points( numValues );
580
double valueTotal = 0.0; // Will only be used for Percent
581
int angleBetweenRays = 360 / numValues;
582
for ( int value = 0; value < numValues; value++ ) {
583
if( params()->polarChartSubType() == KDChartParams::PolarPercent )
584
valueTotal = data->colAbsSum( value );
585
// the value determines the angle, the dataset only the color
586
if ( data->cell( dataset, value ).isDouble() ) {
587
double cellValue = data->cell( dataset, value ).doubleValue();
589
if ( params()->polarChartSubType() == KDChartParams::PolarStacked )
590
drawValue = ( cellValue + currentValueSums[ value ] ) * pixelsPerUnit;
591
else if( params()->polarChartSubType() == KDChartParams::PolarPercent ) {
592
drawValue = ( ( cellValue + currentValueSums[ value ] )
593
/ valueTotal * static_cast<double>( radius ) );
595
drawValue = cellValue * pixelsPerUnit;
597
// record the point for drawing the polygon later
598
int drawAngle = value * angleBetweenRays;
599
QPoint drawPoint( center + polarToXY( static_cast<int>( drawValue ),
601
points.setPoint( totalPoints, drawPoint );
604
// the marker can be drawn now
605
if( params()->polarMarker() ) {
606
drawMarker( painter, params()->polarMarkerStyle( dataset ),
607
params()->dataColor( dataset ),
609
dataset, value, chart, minSizeP1000, region );
610
painter->setPen( QPen( params()->dataColor( dataset ),
614
KDChartDataRegion* datReg = new KDChartDataRegion( region,
618
datReg->points[ KDChartEnums::PosTopLeft ] =
619
drawPoint + _dataRect.topLeft();
621
datReg->points[ KDChartEnums::PosTopCenter ] =
622
datReg->points[ KDChartEnums::PosTopLeft ];
623
datReg->points[ KDChartEnums::PosTopRight ] =
624
datReg->points[ KDChartEnums::PosTopLeft ];
625
datReg->points[ KDChartEnums::PosBottomLeft ] =
626
datReg->points[ KDChartEnums::PosTopLeft ];
627
datReg->points[ KDChartEnums::PosBottomCenter ] =
628
datReg->points[ KDChartEnums::PosTopLeft ];
629
datReg->points[ KDChartEnums::PosBottomRight ] =
630
datReg->points[ KDChartEnums::PosTopLeft ];
631
datReg->points[ KDChartEnums::PosCenterLeft ] =
632
datReg->points[ KDChartEnums::PosTopLeft ];
633
datReg->points[ KDChartEnums::PosCenter ] =
634
datReg->points[ KDChartEnums::PosTopLeft ];
635
datReg->points[ KDChartEnums::PosCenterRight ] =
636
datReg->points[ KDChartEnums::PosTopLeft ];
638
// test the center positions:
639
painter->drawEllipse( datReg->points[ KDChartEnums::PosCenterLeft ].x() - 2,
640
datReg->points[ KDChartEnums::PosCenterLeft ].y() - 2, 5, 5);
642
datReg->startAngle = drawAngle;
643
datReg->angleLen = drawAngle;
644
regions->append( datReg );
646
// calculate running sum for stacked and percent
647
if ( params()->polarChartSubType() == KDChartParams::PolarStacked ||
648
params()->polarChartSubType() == KDChartParams::PolarPercent )
649
currentValueSums[ value ] += cellValue;
652
painter->drawPolygon( points );
655
painter->translate( -_dataRect.x(), -_dataRect.y() );
660
Helper methode being called by KDChartPolarPainter::paintData()
662
void KDChartPolarPainter::paintCircularAxisLabel( QPainter* painter,
666
double currentRadiusPPU,
671
if( !rotate && (0 != (align & (Qt::AlignLeft | Qt::AlignRight) ) ) )
672
currentRadiusPPU += center.x()*0.01;
673
KDDrawText::drawRotatedText(
675
rotate ? txtAngle - 90 : 0,
676
step ? center - polarToXY( static_cast<int>( currentRadiusPPU ), txtAngle )
680
step ? (rotate ? Qt::AlignBottom | Qt::AlignHCenter : align)
686
Draws the marker for one data point according to the specified style.
688
\param painter the painter to draw on
689
\param style what kind of marker is drawn (square, diamond or circle)
690
\param color the color in which to draw the marker
691
\param p the center of the marker
692
\param dataset the dataset which this marker represents
693
\param value the value which this marker represents
694
\param regions a list of regions for data points, a new region for the new
695
marker will be appended to this list if it is not 0
697
void KDChartPolarPainter::drawMarker( QPainter* painter,
698
KDChartParams::PolarMarkerStyle style,
699
const QColor& color, const QPoint& p,
700
uint /*dataset*/, uint /*value*/, uint /*chart*/,
704
int xsize = params()->polarMarkerSize().width();
706
xsize = -1 * static_cast < int > ( xsize * minSizeP1000 );
707
int ysize = params()->polarMarkerSize().height();
709
ysize = -1 * static_cast < int > ( ysize * minSizeP1000 );
710
int xsize2 = xsize / 2;
711
int ysize2 = ysize / 2;
712
painter->setPen( color );
714
case KDChartParams::PolarMarkerSquare: {
716
painter->setBrush( color );
717
QRect rect( QPoint( p.x() - xsize2, p.y() - ysize2 ), QPoint( p.x() + xsize2, p.y() + ysize2 ) );
718
painter->drawRect( rect );
719
// Don't use rect for drawing after this!
720
rect.moveBy( _dataRect.x(), _dataRect.y() );
721
region = QRegion( rect );
725
case KDChartParams::PolarMarkerDiamond: {
727
painter->setBrush( color );
728
QPointArray points( 4 );
729
points.setPoint( 0, p.x() - xsize2, p.y() );
730
points.setPoint( 1, p.x(), p.y() - ysize2 );
731
points.setPoint( 2, p.x() + xsize2, p.y() );
732
points.setPoint( 3, p.x(), p.y() + ysize2 );
733
painter->drawPolygon( points );
734
// Don't use points for drawing after this!
735
points.translate( _dataRect.x(), _dataRect.y() );
736
region = QRegion( points );
740
case KDChartParams::PolarMarkerCircle:
743
painter->setBrush( color );
744
painter->drawEllipse( p.x() - xsize2, p.y() - ysize2, xsize, ysize );
746
points.makeEllipse( p.x() - xsize2, p.y() - ysize2, xsize, ysize );
747
// Don't use points for drawing after this!
748
points.translate( _dataRect.x(), _dataRect.y() );
749
if( points.size() > 0 )
750
region = QRegion( points );
728
758
#define DEGTORAD(d) (d)*M_PI/180
730
QPoint KDChartPolarPainter::polarToXY( int radius, int angle )
732
double anglerad = DEGTORAD( static_cast<double>( angle ) );
733
QPoint ret( cos( anglerad ) * radius,
734
sin( anglerad ) * radius );
740
This method is a specialization that returns a fallback legend text
741
appropriate for polar charts where the fallbacks should come from
742
the values, not from the datasets.
744
This method is only used when automatic legends are used, because
745
manual and first-column legends do not need fallback texts.
747
\param uint dataset the dataset number for which to generate a
749
\return the fallback text to use for describing the specified
750
dataset in the legend
752
QString KDChartPolarPainter::fallbackLegendText( uint dataset ) const
754
return QObject::tr( "Series " ) + QString::number( dataset + 1 );
759
This methods returns the number of elements to be shown in the
760
legend in case fallback texts are used.
762
This method is only used when automatic legends are used, because
763
manual and first-column legends do not need fallback texts.
765
\return the number of fallback texts to use
767
uint KDChartPolarPainter::numLegendFallbackTexts( KDChartTableData* data ) const
769
return data->usedRows();
760
QPoint KDChartPolarPainter::polarToXY( int radius, int angle )
762
double anglerad = DEGTORAD( static_cast<double>( angle ) );
763
QPoint ret( static_cast<int>( cos( anglerad ) * radius ),
764
static_cast<int>( sin( anglerad ) * radius ) );
770
This method is a specialization that returns a fallback legend text
771
appropriate for polar charts where the fallbacks should come from
772
the values, not from the datasets.
774
This method is only used when automatic legends are used, because
775
manual and first-column legends do not need fallback texts.
777
\param uint dataset the dataset number for which to generate a
779
\return the fallback text to use for describing the specified
780
dataset in the legend
782
QString KDChartPolarPainter::fallbackLegendText( uint dataset ) const
784
return QObject::tr( "Series " ) + QString::number( dataset + 1 );
789
This methods returns the number of elements to be shown in the
790
legend in case fallback texts are used.
792
This method is only used when automatic legends are used, because
793
manual and first-column legends do not need fallback texts.
795
\return the number of fallback texts to use
797
uint KDChartPolarPainter::numLegendFallbackTexts( KDChartTableDataBase* data ) const
799
return data->usedRows();