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 #if defined KDAB_EVAL
00030 #include "../evaldialog/evaldialog.h"
00031 #endif
00032
00036 #include <KDChart.h>
00037 #include <KDChartPainter.h>
00038 #include <KDChartParams.h>
00039 #include <KDChartGlobal.h>
00040 #include <KDChartAxisParams.h>
00041
00042 #include <qglobal.h>
00043 #include <qpainter.h>
00044 #include <qpaintdevice.h>
00045 #include <qpaintdevicemetrics.h>
00046
00047 #ifdef QSA
00048 #if 0 // Disabled by ingwa to make it compile
00049 #include <qsinterpreter.h>
00050 #include "KDChartWrapperFactory.h"
00051 #include "KDChartObjectFactory.h"
00052 #endif
00053 #endif
00054
00075 KDChartParams* KDChart::oldParams = 0;
00076 KDChartPainter* KDChart::cpainter = 0;
00077 KDChartPainter* KDChart::cpainter2 = 0;
00078 KDChartParams::ChartType KDChart::cpainterType = KDChartParams::NoType;
00079 KDChartParams::ChartType KDChart::cpainterType2 = KDChartParams::NoType;
00080
00085 void cleanupPainter();
00086
00087
00088 bool hasCartesianAxes( KDChartParams::ChartType chartType )
00089 {
00090 switch( chartType ){
00091 case KDChartParams::NoType: return false;
00092 case KDChartParams::Bar: return true;
00093 case KDChartParams::Line: return true;
00094 case KDChartParams::Area: return true;
00095 case KDChartParams::Pie: return false;
00096 case KDChartParams::HiLo: return true;
00097 case KDChartParams::Ring: return false;
00098 case KDChartParams::Polar: return false;
00099 case KDChartParams::BoxWhisker: return true;
00100 default:
00101 qDebug("\n\n\n\nKDCHART ERROR: Type missing in KDChart.cpp hasCartesianAxes()\n"
00102 "=============================================================\n"
00103 "=============================================================\n\n\n\n");
00104 }
00105 return false;
00106 }
00107
00108
00122 bool KDChart::painterToDrawRect( QPainter* painter, QRect& drawRect )
00123 {
00124 if( painter ){
00125 QPaintDeviceMetrics painterMetrics( painter->device() );
00126 drawRect = QRect( 0, 0, painterMetrics.width(), painterMetrics.height() );
00127 drawRect.setWidth( drawRect.width() -2 );
00128 drawRect.setHeight( drawRect.height()-2 );
00129 return true;
00130 }else{
00131 drawRect = QRect( QPoint(0,0), QSize(0,0) );
00132 qDebug("ERROR: KDChartPainter::painterToDrawRect() was called with *no* painter.");
00133 return false;
00134 }
00135 }
00136
00137
00156 bool KDChart::setupGeometry( QPainter* painter,
00157 KDChartParams* params,
00158 KDChartTableDataBase* data,
00159 const QRect& drawRect )
00160 {
00161
00162 if( !params ){
00163 qDebug("ERROR: setupGeometry::paint() was called with *no* params.");
00164 return false;
00165 }
00166 if( !data ){
00167 qDebug("ERROR: setupGeometry::paint() was called with *no* data.");
00168 return false;
00169 }
00170
00171 #ifdef Q_WS_WIN
00172 QPixmap::setDefaultOptimization(QPixmap::MemoryOptim);
00173 #endif
00174
00175
00176
00177
00178 static bool bFirstCleanUpInstall = true;
00179 if( bFirstCleanUpInstall ) {
00180 bFirstCleanUpInstall = false;
00181 qAddPostRoutine( cleanupPainter );
00182 }
00183
00184
00185
00186 bool paramsHasChanged = ( params != oldParams );
00187 if( paramsHasChanged )
00188 oldParams = params;
00189
00190
00191
00192
00193 if ( paramsHasChanged || !cpainter || cpainterType != params->chartType() )
00194 {
00195 delete cpainter;
00196
00197
00198 cpainter = KDChartPainter::create( params, false );
00199 cpainterType = params->chartType();
00200 }
00201
00202
00203
00204
00205 if ( paramsHasChanged || !cpainter2 || cpainterType2 != params->additionalChartType() )
00206 {
00207 delete cpainter2;
00208
00209
00210 if( hasCartesianAxes( params->chartType() )
00211 && hasCartesianAxes( params->additionalChartType() ) ){
00212 cpainter2 = KDChartPainter::create( params, true );
00213 cpainterType2 = params->additionalChartType();
00214 }else{
00215 cpainter2 = 0;
00216 cpainterType2 = KDChartParams::NoType;
00217 }
00218 }
00219
00220 if ( cpainter ){
00221 cpainter->setupGeometry( painter, data, drawRect );
00222 }
00223
00224 if ( cpainter2 ){
00225 cpainter2->setupGeometry( painter, data, drawRect );
00226 }
00227
00228 return true;
00229 }
00230
00256 void KDChart::paint( QPainter* painter,
00257 KDChartParams* paraParams,
00258 KDChartTableDataBase* paraData,
00259 KDChartDataRegionList* regions,
00260 const QRect* rect,
00261 bool mustCalculateGeometry )
00262 {
00263
00264 #if defined KDAB_EVAL
00265 EvalDialog::checkEvalLicense( "KD Chart" );
00266 #endif
00267
00268
00269 if( regions )
00270 regions->clear();
00271
00272 KDChartParams* params = paraParams;
00273 KDChartTableDataBase* data = paraData;
00274 if( !paraParams && !paraData ){
00275 qDebug("-----");
00276 qDebug("Note: KDChart::paint() was called without \"params\" and without \"data\".");
00277 qDebug("----- Showing a default bar chart.");
00278 params = new KDChartParams();
00279 params->setDatasetGap(3 * params->valueBlockGap());
00280 params->setPrintDataValues( false );
00281 params->setLegendPosition( KDChartParams::NoLegend );
00282 params->setAxisLabelsVisible( KDChartAxisParams::AxisPosBottom, false );
00283 params->setAxisShowGrid( KDChartAxisParams::AxisPosBottom, false );
00284 params->setHeader1Text( "KDChartWidget" );
00285 data = new KDChartTableData( 3, 1 );
00286
00287 data->setCell( 0, 0, 12.5 );
00288
00289 data->setCell( 1, 0, 8.0 );
00290
00291 data->setCell( 2, 0, 15.0 );
00292 }
00293
00294 QRect drawRect;
00295 bool bOk = true;
00296 if( mustCalculateGeometry || !cpainter || cpainter->outermostRect().isNull() ){
00297 if( rect )
00298 drawRect = *rect;
00299 else if( !painterToDrawRect( painter, drawRect ) ){
00300 qDebug("ERROR: KDChart::paint() could not calculate a drawing area.");
00301 bOk = false;
00302 }
00303
00304 if( (params || data) && !setupGeometry( painter, params, data, drawRect ) ){
00305 qDebug("ERROR: KDChart::paint() could not calculate the chart geometry.");
00306 bOk = false;
00307 }
00308 }else{
00309 drawRect = cpainter->outermostRect();
00310 }
00311
00312
00313
00314 if( bOk ){
00315
00316
00317
00318
00319
00320 bool paintFirst = true;
00321 bool paintLast = ! ( cpainter && cpainter2 );
00322 if ( cpainter ) {
00323
00324 cpainter->paint( painter, data, paintFirst, paintLast, regions, &drawRect, false );
00325
00326 paintFirst = false;
00327 }
00328 paintLast = true;
00329 if ( cpainter2 )
00330 cpainter2->paint( painter, data, paintFirst, paintLast, regions, &drawRect, false );
00331 }
00332
00333 if( !paraParams && !paraData ){
00334 delete params;
00335 delete data;
00336 }
00337 KDChartAutoColor::freeInstance();
00338 }
00339
00340
00354 void KDChart::print( QPainter* painter, KDChartParams* params,
00355 KDChartTableDataBase* data,
00356 KDChartDataRegionList* regions,
00357 const QRect* rect,
00358 bool mustCalculateGeometry )
00359 {
00360 bool oldOpt=true;
00361 if( params ){
00362 oldOpt = params->optimizeOutputForScreen();
00363 params->setOptimizeOutputForScreen( false );
00364 }
00365 paint( painter, params, data, regions, rect, mustCalculateGeometry );
00366 if( params )
00367 params->setOptimizeOutputForScreen( oldOpt );
00368 }
00369
00370
00371
00372
00373
00374
00375 void cleanupPainter()
00376 {
00377 delete KDChart::cpainter;
00378 delete KDChart::cpainter2;
00379 KDChart::oldParams = 0;
00380 }
00381
00382 #ifdef QSA
00383 void KDChart::initInterpreter( QSInterpreter* interpreter )
00384 {
00385 privateInitInterpreter( interpreter );
00386 interpreter->evaluate( globals() );
00387 }
00388
00389 void KDChart::initProject( QSProject* project )
00390 {
00391 project->createScript( QString::fromLatin1( "KDCHART_Globals" ), globals() );
00392 privateInitInterpreter( project->interpreter() );
00393 }
00394
00395 QString KDChart::globals()
00396 {
00397 QString globals;
00398 QMap<char*, double> intMap;
00399
00400 intMap.insert( "KDCHART_POS_INFINITE", KDCHART_POS_INFINITE );
00401 intMap.insert( "KDCHART_NEG_INFINITE", KDCHART_NEG_INFINITE );
00402 intMap.insert( "KDCHART_AlignAuto", KDCHART_AlignAuto );
00403 intMap.insert( "KDCHART_ALL_AXES", KDCHART_ALL_AXES );
00404 intMap.insert( "KDCHART_NO_AXIS", KDCHART_NO_AXIS );
00405 intMap.insert( "KDCHART_ALL_DATASETS", KDCHART_ALL_DATASETS );
00406 intMap.insert( "KDCHART_NO_DATASET", KDCHART_NO_DATASET );
00407 intMap.insert( "KDCHART_UNKNOWN_CHART", KDCHART_UNKNOWN_CHART );
00408 intMap.insert( "KDCHART_ALL_CHARTS", KDCHART_ALL_CHARTS );
00409 intMap.insert( "KDCHART_NO_CHART", KDCHART_NO_CHART );
00410 intMap.insert( "KDCHART_GLOBAL_LINE_STYLE", KDCHART_GLOBAL_LINE_STYLE );
00411 intMap.insert( "KDCHART_AUTO_SIZE", KDCHART_AUTO_SIZE );
00412 intMap.insert( "KDCHART_DATA_VALUE_AUTO_DIGITS", KDCHART_DATA_VALUE_AUTO_DIGITS );
00413 intMap.insert( "KDCHART_SAGITTAL_ROTATION", KDCHART_SAGITTAL_ROTATION );
00414 intMap.insert( "KDCHART_TANGENTIAL_ROTATION", KDCHART_TANGENTIAL_ROTATION );
00415 intMap.insert( "KDCHART_PROPSET_NORMAL_DATA", KDCHART_PROPSET_NORMAL_DATA );
00416 intMap.insert( "KDCHART_PROPSET_TRANSPARENT_DATA", KDCHART_PROPSET_TRANSPARENT_DATA );
00417 intMap.insert( "KDCHART_PROPSET_HORI_LINE", KDCHART_PROPSET_HORI_LINE );
00418 intMap.insert( "KDCHART_PROPSET_VERT_LINE", KDCHART_PROPSET_VERT_LINE );
00419 intMap.insert( "KDCHART_SAGGITAL_ROTATION", KDCHART_SAGGITAL_ROTATION );
00420 intMap.insert( "KDCHART_CNT_ORDINATES", KDCHART_CNT_ORDINATES );
00421 intMap.insert( "KDCHART_MAX_POLAR_DELIMS_AND_LABELS_POS", KDCHART_MAX_POLAR_DELIMS_AND_LABELS_POS );
00422 intMap.insert( "KDCHART_MAX_AXES", KDCHART_MAX_AXES );
00423 intMap.insert( "KDCHART_AXIS_LABELS_AUTO_DELTA", KDCHART_AXIS_LABELS_AUTO_DELTA );
00424 intMap.insert( "KDCHART_AXIS_LABELS_AUTO_LEAVEOUT", KDCHART_AXIS_LABELS_AUTO_LEAVEOUT );
00425 intMap.insert( "KDCHART_AXIS_LABELS_AUTO_DIGITS", KDCHART_AXIS_LABELS_AUTO_DIGITS );
00426 intMap.insert( "KDCHART_AXIS_GRID_AUTO_LINEWIDTH", KDCHART_AXIS_GRID_AUTO_LINEWIDTH );
00427 intMap.insert( "KDCHART_AXIS_IGNORE_EMPTY_INNER_SPAN", KDCHART_AXIS_IGNORE_EMPTY_INNER_SPAN );
00428 intMap.insert( "KDCHART_DONT_CHANGE_EMPTY_INNER_SPAN_NOW", KDCHART_DONT_CHANGE_EMPTY_INNER_SPAN_NOW );
00429 intMap.insert( "DBL_MIN", DBL_MIN );
00430 intMap.insert( "DBL_MAX", DBL_MAX );
00431
00432 for( QMapIterator<char*,double> it= intMap.begin(); it != intMap.end(); ++it ) {
00433
00434 globals += QString::fromLatin1( "const " );
00435 globals += it.key();
00436 globals += " = ";
00437 globals += QString::number( it.data() );
00438 globals += ";\n";
00439 }
00440
00441 globals += QString::fromLatin1( "const KDCHART_AXIS_LABELS_AUTO_DATETIME_FORMAT=\"%1\";\n" )
00442 .arg( QString::fromLatin1( KDCHART_AXIS_LABELS_AUTO_DATETIME_FORMAT ) );
00443 globals += QString::fromLatin1( "const KDCHART_AXIS_LABELS_AUTO_LIMIT = 140319.64;\n" );
00444 globals += QString::fromLatin1( "const KDCHART_DEFAULT_AXIS_GRID_COLOR = new Color(\"%1\");\n" )
00445 .arg(KDCHART_DEFAULT_AXIS_GRID_COLOR.name());
00446 globals += QString::fromLatin1( "const KDCHART_DATA_VALUE_AUTO_COLOR = new Color(\"%1\");\n" )
00447 .arg( (KDCHART_DATA_VALUE_AUTO_COLOR)->name());
00448
00449
00450 QMap<char*,QColor> colorMap;
00451 colorMap.insert( "Qt.color0", Qt::color0 );
00452 colorMap.insert( "Qt.color1", Qt::color1 );
00453 colorMap.insert( "Qt.black", Qt::black );
00454 colorMap.insert( "Qt.white", Qt::white );
00455 colorMap.insert( "Qt.darkGray", Qt::darkGray );
00456 colorMap.insert( "Qt.gray", Qt::gray );
00457 colorMap.insert( "Qt.lightGray", Qt::lightGray );
00458 colorMap.insert( "Qt.red", Qt::red );
00459 colorMap.insert( "Qt.green", Qt::green );
00460 colorMap.insert( "Qt.blue", Qt::blue );
00461 colorMap.insert( "Qt.cyan", Qt::cyan );
00462 colorMap.insert( "Qt.magenta", Qt::magenta );
00463 colorMap.insert( "Qt.yellow", Qt::yellow );
00464 colorMap.insert( "Qt.darkRed", Qt::darkRed );
00465 colorMap.insert( "Qt.darkGreen", Qt::darkGreen );
00466 colorMap.insert( "Qt.darkBlue", Qt::darkBlue );
00467 colorMap.insert( "Qt.darkCyan", Qt::darkCyan );
00468 colorMap.insert( "Qt.darkMagenta", Qt::darkMagenta );
00469 colorMap.insert( "Qt.darkYellow", Qt::darkYellow );
00470 for( QMapIterator<char*,QColor> it2= colorMap.begin(); it2 != colorMap.end(); ++it2 ) {
00471
00472 globals += QString::fromLatin1( it2.key() );
00473 globals += QString::fromLatin1( " = new Color( " );
00474 globals += QString::number( it2.data().red() );
00475 globals += ',';
00476 globals += QString::number( it2.data().green() );
00477 globals += ',';
00478 globals += QString::number( it2.data().blue() );
00479 globals += QString::fromLatin1( " );\n" );
00480 }
00481
00482 return globals;
00483 }
00484
00485 void KDChart::privateInitInterpreter( QSInterpreter* interpreter )
00486 {
00487 interpreter->addWrapperFactory( new KDChartWrapperFactory );
00488 interpreter->addObjectFactory ( new KDChartObjectFactory );
00489 }
00490
00491 #endif