Back to index

salome-gui  6.5.0
Plot2d_PlotItems.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 //  File   : Plot2d_HistogramItem.cxx
00023 //  Author : Natalia ERMOLAEVA, Open CASCADE S.A.S. (natalia.donis@opencascade.com)
00024 
00025 #include "Plot2d_PlotItems.h"
00026 #include "Plot2d_Object.h"
00027 
00028 #include <QPainter>
00029 #include <QPalette>
00030 #include <QLayout>
00031 #include <QLine>
00032 #include <QVariant>
00033 #include <qwt_plot.h>
00034 #include <qwt_painter.h>
00035 #include <qwt_scale_map.h>
00036 #include <qwt_legend.h>
00037 #include <qwt_legend_item.h>
00038 #include <qwt_plot_dict.h>
00039 
00040 const char* yAxisLeft[] = {
00041   "12 12 2 1",
00042   "  c None",
00043   ". c #000000",
00044   "            ",
00045   "   .        ",
00046   "  ...       ",
00047   " . . .      ",
00048   "   .        ",
00049   "   .        ",
00050   "   .    .   ",
00051   "   .     .  ",
00052   "   ........ ",
00053   "         .  ",
00054   "        .   ",
00055   "            "};
00056 
00057 const char* yAxisRight[] = {
00058   "12 12 2 1",
00059   "  c None",
00060   ". c #000000",
00061   "            ",
00062   "        .   ",
00063   "       ...  ",
00064   "      . . . ",
00065   "        .   ",
00066   "        .   ",
00067   "   .    .   ",
00068   "  .     .   ",
00069   " ........   ",
00070   "  .         ",
00071   "   .        ",
00072   "            "};
00073 
00077 Plot2d_QwtLegendItem::Plot2d_QwtLegendItem( QWidget* parent ) :
00078   QwtLegendItem( parent ),
00079   myYAxisIdentifierMode( IM_None ),
00080   myIsSelected(false)
00081 {
00082   myYAxisLeftIcon = yAxisLeft;
00083   myYAxisRightIcon = yAxisRight;
00084   int anIconWidth = qMax( myYAxisLeftIcon.width(), myYAxisRightIcon.width() );
00085 
00086   mySpacingCollapsed = spacing();
00087   mySpacingExpanded = anIconWidth - mySpacingCollapsed;
00088 }
00089 
00093 Plot2d_QwtLegendItem::~Plot2d_QwtLegendItem()
00094 {
00095 }
00096 
00100 void Plot2d_QwtLegendItem::setYAxisIdentifierMode( const int theMode )
00101 {
00102   myYAxisIdentifierMode = theMode;
00103   setSpacing( theMode == IM_None ? mySpacingCollapsed : mySpacingExpanded );
00104 }
00105 
00109 void Plot2d_QwtLegendItem::drawIdentifier( QPainter* painter, const QRect& rect ) const
00110 {
00111   QwtLegendItem::drawIdentifier( painter, rect );
00112 
00113   if( myYAxisIdentifierMode != IM_None ) {
00114     QPixmap aPixmap( myYAxisIdentifierMode == IM_Left ? yAxisLeft : yAxisRight );
00115     painter->save();
00116     painter->drawPixmap( rect.topRight() + QPoint( mySpacingExpanded/2, mySpacingExpanded/2 ), aPixmap );
00117     painter->restore();
00118   }
00119 }
00120 
00124 void Plot2d_QwtLegendItem::updateHighlit() {
00125   QwtText txt = text();
00126   if(isSelected()) {
00127     QColor highlightColor = Plot2d_Object::selectionColor();
00128     if(highlightColor != txt.backgroundBrush().color()) {
00129       txt.setBackgroundBrush(highlightColor);
00130       setText(txt);
00131     }    
00132   } else if( QWidget* parent = qobject_cast<QWidget*>(this->parent()->parent()) ) {
00133     QPalette aPal = parent->palette();
00134     if(aPal.color(QPalette::Background) != txt.backgroundBrush().color()) {
00135       txt.setBackgroundBrush(aPal.color(QPalette::Background));
00136       setText(txt);
00137     }
00138   }
00139 }
00140 
00144 void Plot2d_QwtLegendItem::setSelected(const bool on) {
00145   myIsSelected = on;
00146 }
00147 
00151 bool Plot2d_QwtLegendItem::isSelected() const {
00152   return myIsSelected;
00153 }
00154 
00155 
00156 /*
00157   Draw text of the item.
00158 */
00159 void  Plot2d_QwtLegendItem::drawText(QPainter * painter, const QRect &rect) {
00160   painter->setPen( isSelected() ? Plot2d_Object::highlightedLegendTextColor() : 
00161                  getColorFromPalette( QPalette::Text) );
00162   
00163   QwtLegendItem::drawText( painter, rect );
00164 }
00165 
00166 /*
00167   Get color from the legend pallete by 'role' flag.
00168 */
00169 QColor Plot2d_QwtLegendItem::getColorFromPalette(QPalette::ColorRole role) {
00170   QWidget* pw = parentWidget(); 
00171   QColor  col = palette().color( role );
00172   while( pw ) {
00173     if ( qobject_cast<QwtLegend*>( pw ) ) {
00174       col = pw->palette().color(role );
00175       break;
00176     }
00177     pw = pw->parentWidget();
00178   } 
00179   return col;
00180 }
00181 /*
00182  * Internal class to store deviation data on the curve.
00183  */
00184 class Plot2d_QwtPlotCurve::Plot2d_DeviationData {
00185 public:
00186   Plot2d_DeviationData(const double *min, const double *max,const QList<int>& idx)
00187   { 
00188     foreach(int index,idx) {
00189       myMin[index] = min[index];
00190       myMax[index] = max[index];
00191     }
00192   }
00193   ~Plot2d_DeviationData(){}
00194 
00195   size_t size() const 
00196   { 
00197     return qwtMin(myMin.size(), myMax.size()); 
00198   }
00199   bool values(size_t i, double &min, double &max) {
00200     if(myMin.contains(i) && myMax.contains(i)) {
00201       min = myMin[i];
00202       max = myMax[i];
00203       return true;
00204     }
00205     return false;
00206   }
00207 private:
00208   QMap<int,double> myMin;
00209   QMap<int,double> myMax;
00210 };
00211 
00212 
00216 Plot2d_QwtPlotCurve::Plot2d_QwtPlotCurve( const QString& title,
00217                                           QwtPlot::Axis yAxis /*const int index*/ ) :
00218   Plot2d_SelectableItem(),                                       
00219   QwtPlotCurve( title ),
00220   myYAxis( yAxis ),
00221   myYAxisIdentifierEnabled( false ),
00222   myDeviationData(0)
00223 {  
00224 }
00225 
00229 Plot2d_QwtPlotCurve::~Plot2d_QwtPlotCurve()
00230 {
00231   clearDeviationData();
00232 }
00233 
00237 void Plot2d_QwtPlotCurve::setYAxisIdentifierEnabled( const bool on )
00238 {
00239   myYAxisIdentifierEnabled = on;
00240 }
00241 
00245 void Plot2d_QwtPlotCurve::updateLegend( QwtLegend* legend ) const
00246 {
00247   if ( !legend )
00248     return; 
00249 
00250   QWidget* widget = legend->find( this );
00251 
00252   if ( testItemAttribute(QwtPlotItem::Legend)) {   
00253 
00254     if ( widget == NULL ) {
00255       widget = legendItem();
00256       if ( widget ) {
00257        if ( widget->inherits("QwtLegendItem") ) {
00258          QwtLegendItem *label = (QwtLegendItem *)widget;
00259          label->setItemMode(legend->itemMode());
00260               
00261          if ( plot() ) {
00262            QObject::connect(label, SIGNAL(clicked()),
00263                           plot(), SLOT(legendItemClicked()));
00264            QObject::connect(label, SIGNAL(checked(bool)),
00265                           plot(), SLOT(legendItemChecked(bool)));
00266          }
00267        }
00268        legend->contentsWidget()->layout()->addWidget(widget);
00269        legend->insert(this, widget);
00270       }
00271     }
00272     
00273     QwtPlotCurve::updateLegend( legend );
00274     
00275     
00276     if( Plot2d_QwtLegendItem* anItem = dynamic_cast<Plot2d_QwtLegendItem*>( widget ) ) {
00277       int aMode = Plot2d_QwtLegendItem::IM_None;
00278       if( myYAxisIdentifierEnabled )
00279        aMode = myYAxis == QwtPlot::yRight ?
00280          Plot2d_QwtLegendItem::IM_Right :
00281          Plot2d_QwtLegendItem::IM_Left;
00282       anItem->setYAxisIdentifierMode( aMode );
00283       if(isSelected()) {
00284        anItem->setCurvePen(legendPen());
00285        anItem->setSymbol(legendSymbol());
00286       }
00287       anItem->setSelected(isSelected());
00288       anItem->updateHighlit();
00289     }
00290   }
00291 }
00292 
00296 QWidget* Plot2d_QwtPlotCurve::legendItem() const
00297 {
00298   return new Plot2d_QwtLegendItem;
00299 }
00300 
00304 void Plot2d_QwtPlotCurve::draw(QPainter *painter,
00305                                const QwtScaleMap &xMap, const QwtScaleMap &yMap, 
00306                                int from, int to) const
00307 {
00308   if (to < 0)
00309     to = dataSize() - 1;
00310   QwtPlotCurve::draw(painter, xMap, yMap, from, to);
00311 
00312   //draw deviation data
00313   if(hasDeviationData()) {    
00314     painter->save();
00315     int lineW = deviationMarkerLineWidth();
00316     int tickSz = deviationMarkerTickSize() + qRound(lineW/2);
00317     double min, max, xi, yi;
00318     int xp, ytop, ybtm, tickl, tickr;
00319     QColor c = isSelected() ? Plot2d_Object::selectionColor() : deviationMarkerColor(); 
00320     QPen p = QPen(c, lineW, Qt::SolidLine);
00321     painter->setPen(p);
00322     for (int i = from; i <= to; i++) {
00323       if(!myDeviationData->values(i,min,max)) continue;
00324       xi = x(i);
00325       yi = y(i);
00326       xp = xMap.transform(xi);
00327       ytop = yMap.transform(yi + max);
00328       ybtm = yMap.transform(yi - min);
00329       tickl = xp - tickSz;
00330       tickr = xp + tickSz;
00331       painter->drawLine(tickl,ytop,tickr,ytop);
00332       painter->drawLine(xp,ytop,xp,ybtm);
00333       painter->drawLine(tickl,ybtm,tickr,ybtm);
00334     }
00335          painter->restore();
00336   }
00337 }
00338 
00342 QColor Plot2d_QwtPlotCurve::deviationMarkerColor() const {
00343   QColor c(0, 0, 127);
00344   if(plot()) {
00345     QVariant var = plot()->property(PLOT2D_DEVIATION_COLOR);
00346     if(var.isValid())
00347       c = var.value<QColor>();
00348   }
00349   return c;
00350 }
00354 int Plot2d_QwtPlotCurve::deviationMarkerLineWidth() const {
00355   int lw = 1;
00356   if(plot()) {
00357     QVariant var = plot()->property(PLOT2D_DEVIATION_LW);
00358     if(var.isValid())
00359       lw = var.toInt();
00360   }
00361   return lw;
00362 }
00363 
00367 int Plot2d_QwtPlotCurve::deviationMarkerTickSize() const {
00368   int ts = 2;
00369   if(plot()) {
00370     QVariant var = plot()->property(PLOT2D_DEVIATION_TS);
00371     if(var.isValid())
00372       ts = var.toInt();
00373   }
00374   return ts;
00375 }
00376 
00380 void Plot2d_QwtPlotCurve::setDeviationData(const double* min, const double* max,const QList<int> &idx) {
00381   clearDeviationData();
00382   myDeviationData = new Plot2d_DeviationData(min,max,idx);
00383 }
00384 
00389 bool Plot2d_QwtPlotCurve::hasDeviationData() const {
00390   return myDeviationData != 0;
00391 }
00392 
00396 void Plot2d_QwtPlotCurve::clearDeviationData() 
00397 {
00398   if(myDeviationData)
00399     delete myDeviationData;
00400   myDeviationData = 0;
00401 }
00402 
00403 
00404 
00408 Plot2d_SelectableItem::Plot2d_SelectableItem():
00409   myIsSelected(false)
00410 { 
00411 }
00412 
00416 Plot2d_SelectableItem::~Plot2d_SelectableItem()
00417 { 
00418 }
00419 
00423 void Plot2d_SelectableItem::setSelected( const bool on) {
00424   myIsSelected = on;
00425 }
00426 
00430 bool Plot2d_SelectableItem::isSelected() const {
00431   return myIsSelected;
00432 }
00433 
00437 void Plot2d_SelectableItem::setLegendPen( const QPen & p) {
00438   myLegendPen = p;
00439 }
00440 
00444 QPen Plot2d_SelectableItem::legendPen() const {
00445   return myLegendPen;
00446 }
00447 
00451 void Plot2d_SelectableItem::setLegendSymbol(const QwtSymbol& s) {
00452   myLegendSymbol = s;
00453 }
00454 
00458 QwtSymbol Plot2d_SelectableItem::legendSymbol() const {
00459   return myLegendSymbol;
00460 }
00461 
00465 Plot2d_HistogramQwtItem::Plot2d_HistogramQwtItem( const QwtText& theTitle )
00466 : QwtPlotItem( theTitle )
00467 {
00468   init();
00469 }
00470 
00474 Plot2d_HistogramQwtItem::Plot2d_HistogramQwtItem( const QString& theTitle )
00475 : QwtPlotItem( QwtText( theTitle ) )
00476 {
00477   init();
00478 }
00479 
00483 Plot2d_HistogramQwtItem::~Plot2d_HistogramQwtItem()
00484 {
00485 }
00486 
00490 void Plot2d_HistogramQwtItem::init()
00491 {
00492   myReference = 0.0;
00493   myAttributes = Plot2d_HistogramQwtItem::Auto;
00494 
00495   setItemAttribute( QwtPlotItem::AutoScale, true );
00496   setItemAttribute( QwtPlotItem::Legend,    true );
00497 
00498   setZ( 20.0 );
00499 }
00500 
00505 void Plot2d_HistogramQwtItem::setBaseline( double theRef )
00506 {
00507   if ( myReference != theRef ) {
00508     myReference = theRef;
00509     itemChanged();
00510   }
00511 }
00512 
00516 double Plot2d_HistogramQwtItem::baseline() const
00517 {
00518   return myReference;
00519 }
00520 
00524 void Plot2d_HistogramQwtItem::setData( const QwtIntervalData& theData )
00525 {
00526   myData = theData;
00527   itemChanged();
00528 }
00529 
00533 const QwtIntervalData& Plot2d_HistogramQwtItem::data() const
00534 {
00535   return myData;
00536 }
00537 
00541 void Plot2d_HistogramQwtItem::setColor( const QColor& theColor )
00542 {
00543   if ( myColor != theColor ) {
00544     myColor = theColor;
00545     itemChanged();
00546   }
00547 }
00548 
00552 QColor Plot2d_HistogramQwtItem::color() const
00553 {
00554   return myColor;
00555 }
00556 
00560 QwtDoubleRect Plot2d_HistogramQwtItem::boundingRect() const
00561 {
00562   QwtDoubleRect aRect = myData.boundingRect();
00563   if ( !aRect.isValid() ) 
00564       return aRect;
00565 
00566   if ( myAttributes & Xfy ) {
00567     aRect = QwtDoubleRect( aRect.y(), aRect.x(),
00568                            aRect.height(), aRect.width() );
00569     if ( aRect.left() > myReference ) 
00570       aRect.setLeft( myReference );
00571     else if ( aRect.right() < myReference ) 
00572       aRect.setRight( myReference );
00573   } 
00574   else {
00575     if ( aRect.bottom() < myReference ) 
00576       aRect.setBottom( myReference );
00577     else if ( aRect.top() > myReference ) 
00578       aRect.setTop( myReference );
00579   }
00580   return aRect;
00581 }
00582 
00586 int Plot2d_HistogramQwtItem::rtti() const
00587 {
00588   return QwtPlotItem::Rtti_PlotHistogram;
00589 }
00590 
00594 void Plot2d_HistogramQwtItem::setHistogramAttribute( HistogramAttribute theAttr,
00595                                                bool isOn )
00596 {
00597   if ( testHistogramAttribute( theAttr ) != isOn ) {
00598     if ( isOn )
00599       myAttributes |= theAttr;
00600     else
00601       myAttributes &= ~theAttr;
00602     
00603     itemChanged();
00604   }
00605 }
00606 
00610 bool Plot2d_HistogramQwtItem::testHistogramAttribute( HistogramAttribute theAttr ) const
00611 {
00612   return myAttributes & theAttr;
00613 }
00614 
00618 void Plot2d_HistogramQwtItem::draw( QPainter* thePainter,
00619                                 const QwtScaleMap& theXMap, 
00620                                 const QwtScaleMap& theYMap,
00621                                 const QRect& ) const
00622 {
00623   thePainter->setPen( QPen( myColor ) );
00624 
00625   const int x0 = theXMap.transform( baseline() );
00626   const int y0 = theYMap.transform( baseline() );
00627 
00628   for ( int i = 0; i < (int)myData.size(); i++ ) {
00629     if ( myAttributes & Plot2d_HistogramQwtItem::Xfy ) {
00630       const int x2 = theXMap.transform( myData.value( i ) );
00631       if ( x2 == x0 )
00632         continue;
00633       int y1 = theYMap.transform( myData.interval( i ).minValue() );
00634       int y2 = theYMap.transform( myData.interval( i ).maxValue() );
00635       if ( y1 > y2 )
00636         qSwap( y1, y2 );
00637 
00638       if ( i < (int)myData.size() - 2 ) {
00639         const int yy1 = theYMap.transform( myData.interval(i+1).minValue() );
00640         const int yy2 = theYMap.transform( myData.interval(i+1).maxValue() );
00641         if ( y2 == qwtMin( yy1, yy2 ) ) {
00642           const int xx2 = theXMap.transform( myData.interval(i+1).minValue() );
00643           if ( xx2 != x0 && ( ( xx2 < x0 && x2 < x0 ) ||
00644                               ( xx2 > x0 && x2 > x0 ) ) ) {
00645             // One pixel distance between neighboured bars
00646             y2++;
00647           }
00648         }
00649       }
00650       drawBar( thePainter, Qt::Horizontal, QRect( x0, y1, x2 - x0, y2 - y1 ) );
00651     }
00652     else {
00653       const int y2 = theYMap.transform( myData.value( i ) );
00654       if ( y2 == y0 )
00655         continue;
00656       int x1 = theXMap.transform( myData.interval( i ).minValue() );
00657       int x2 = theXMap.transform( myData.interval( i ).maxValue() );
00658       if ( x1 > x2 )
00659         qSwap( x1, x2 );
00660 
00661       if ( i < (int)myData.size() - 2 ) {
00662         const int xx1 = theXMap.transform( myData.interval(i+1).minValue() );
00663         const int xx2 = theXMap.transform( myData.interval(i+1).maxValue() );
00664         if ( x2 == qwtMin( xx1, xx2 ) ) {
00665           const int yy2 = theYMap.transform( myData.value(i+1) );
00666           if ( yy2 != y0 && ( ( yy2 < y0 && y2 < y0 ) ||
00667                               ( yy2 > y0 && y2 > y0 ) ) ) {
00668             // One pixel distance between neighboured bars
00669             x2--;
00670           }
00671         }
00672       }
00673       drawBar( thePainter, Qt::Vertical, QRect( x1, y0, x2 - x1, y2 - y0 ) );
00674     }
00675   }
00676 }
00677 
00681 void Plot2d_HistogramQwtItem::drawBar( QPainter* thePainter,
00682                                    Qt::Orientation,
00683                                    const QRect& theRect ) const
00684 {
00685   thePainter->save();
00686 
00687   const QColor color( thePainter->pen().color() );
00688   QRect r = theRect.normalized();
00689 
00690   const int factor = 125;
00691   const QColor light( color.light( factor ) );
00692   const QColor dark( color.dark( factor ) );
00693 
00694   thePainter->setBrush( color );
00695   thePainter->setPen( Qt::NoPen );
00696   QwtPainter::drawRect( thePainter, r.x() + 1, r.y() + 1,
00697                         r.width() - 2, r.height() - 2 );
00698   thePainter->setBrush( Qt::NoBrush );
00699 
00700   thePainter->setPen( QPen( light, 2 ) );
00701   QwtPainter::drawLine( thePainter, r.left() + 1, r.top() + 2,
00702                         r.right() + 1, r.top() + 2 );
00703 
00704   thePainter->setPen( QPen( dark, 2 ) );
00705   QwtPainter::drawLine( thePainter, r.left() + 1, r.bottom(),
00706                         r.right() + 1, r.bottom() );
00707   thePainter->setPen( QPen( light, 1 ) );
00708 
00709   QwtPainter::drawLine( thePainter, r.left(), r.top() + 1,
00710                         r.left(), r.bottom() );
00711   QwtPainter::drawLine( thePainter, r.left() + 1, r.top() + 2,
00712                          r.left() + 1, r.bottom() - 1 );
00713   thePainter->setPen( QPen( dark, 1 ) );
00714 
00715   QwtPainter::drawLine( thePainter, r.right() + 1, r.top() + 1,
00716                         r.right() + 1, r.bottom() );
00717   QwtPainter::drawLine(thePainter, r.right(), r.top() + 2,
00718                         r.right(), r.bottom() - 1 );
00719   thePainter->restore();
00720 }
00721 
00725 Plot2d_HistogramItem::Plot2d_HistogramItem( const QwtText& theTitle )
00726 : Plot2d_HistogramQwtItem( theTitle ),
00727   Plot2d_SelectableItem(), 
00728   myCrossed( true )
00729 {
00730 }
00731 
00735 Plot2d_HistogramItem::Plot2d_HistogramItem( const QString& theTitle )
00736 : Plot2d_HistogramQwtItem( theTitle ),
00737   myCrossed( true )
00738 {
00739 }
00740 
00744 Plot2d_HistogramItem::~Plot2d_HistogramItem()
00745 {
00746 }
00747 
00751 QList<QRect> Plot2d_HistogramItem::getBars() const
00752 {
00753   return myBarItems;
00754 }
00755 
00759 void Plot2d_HistogramItem::updateLegend( QwtLegend* theLegend ) const
00760 {
00761   if ( !theLegend )
00762     return;
00763  
00764   Plot2d_HistogramQwtItem::updateLegend( theLegend );
00765 
00766   QWidget* theWidget = theLegend->find( this );
00767   if ( !theWidget || !theWidget->inherits( "QwtLegendItem" ) )
00768     return;
00769 
00770   Plot2d_QwtLegendItem* anItem = ( Plot2d_QwtLegendItem* )theWidget;
00771   QFontMetrics aFMetrics( anItem->font() );
00772   int aSize = aFMetrics.height();
00773   QwtSymbol aSymbol( QwtSymbol::Rect, QBrush( legendPen().color() ),
00774                      QPen( legendPen().color() ), QSize( aSize, aSize ) );
00775   anItem->setSymbol( aSymbol );
00776   anItem->setIdentifierMode( theLegend->identifierMode()
00777                           | QwtLegendItem::ShowSymbol ); 
00778   anItem->setSelected(isSelected());
00779   anItem->updateHighlit();
00780   anItem->update();
00781 }
00782 
00786 void Plot2d_HistogramItem::draw( QPainter* thePainter,
00787                              const QwtScaleMap& theXMap, 
00788                              const QwtScaleMap& theYMap,
00789                              const QRect& ) const
00790 {
00791   // nds: clear list of bar items
00792   Plot2d_HistogramItem* anItem = (Plot2d_HistogramItem*)this;
00793   anItem->myBarItems.clear();
00794 
00795   thePainter->setPen( QPen( color() ) );
00796   const int x0 = theXMap.transform( baseline() );
00797   const int y0 = theYMap.transform( baseline() );
00798 
00799   const QwtIntervalData& iData = data();
00800   
00801   for ( int i = 0; i < (int)iData.size(); i++ ) {
00802     if ( testHistogramAttribute( Plot2d_HistogramItem::Xfy ) ) {
00803       const int x2 = theXMap.transform( iData.value( i ) );
00804       if ( x2 == x0 )
00805         continue;
00806       int y1 = theYMap.transform( iData.interval( i ).minValue() );
00807       int y2 = theYMap.transform( iData.interval( i ).maxValue() );
00808       if ( y1 > y2 )
00809         qSwap( y1, y2 );
00810 
00811       if ( i < (int)iData.size() - 2 ) {
00812         const int yy1 = theYMap.transform( iData.interval(i+1).minValue() );
00813         const int yy2 = theYMap.transform( iData.interval(i+1).maxValue() );
00814         if ( y2 == qwtMin( yy1, yy2 ) ) {
00815           const int xx2 = theXMap.transform( iData.interval(i+1).minValue() );
00816           if ( xx2 != x0 && ( ( xx2 < x0 && x2 < x0 ) ||
00817                               ( xx2 > x0 && x2 > x0 ) ) ) {
00818             // One pixel distance between neighboured bars
00819             y2++;
00820           }
00821         }
00822       }
00823       // nds: draw rect with the other lower rects
00824       QRect aRect( x0, y1, x2 - x0, y2 - y1 );
00825       drawRectAndLowers( thePainter, Qt::Horizontal, aRect );
00826       anItem->myBarItems.append( aRect );
00827     }
00828     else {
00829       const int y2 = theYMap.transform( iData.value( i ) );
00830       if ( y2 == y0 )
00831         continue;
00832       int x1 = theXMap.transform( iData.interval( i ).minValue() );
00833       int x2 = theXMap.transform( iData.interval( i ).maxValue() );
00834       if ( x1 > x2 )
00835         qSwap( x1, x2 );
00836 
00837       if ( i < (int)iData.size() - 2 ) {
00838         const int xx1 = theXMap.transform( iData.interval(i+1).minValue() );
00839         const int xx2 = theXMap.transform( iData.interval(i+1).maxValue() );
00840         if ( x2 == qwtMin( xx1, xx2 ) ) {
00841           const int yy2 = theYMap.transform( iData.value(i+1) );
00842           if ( yy2 != y0 && ( ( yy2 < y0 && y2 < y0 ) ||
00843                               ( yy2 > y0 && y2 > y0 ) ) ) {
00844             // One pixel distance between neighboured bars
00845             x2--;
00846           }
00847         }
00848       }
00849       // nds: draw rect with the other lower rects
00850       QRect aRect(x1, y0, x2 - x1, y2 - y0 );
00851       drawRectAndLowers( thePainter, Qt::Vertical, aRect );
00852       anItem->myBarItems.append( aRect );
00853     }
00854   }
00855 }
00856 
00860 void Plot2d_HistogramItem::setCrossItems( bool theCross )
00861 {
00862   myCrossed = theCross;
00863 }
00864 
00868 bool Plot2d_HistogramItem::isCrossItems() const
00869 {
00870   return myCrossed;
00871 }
00872 
00876 QWidget* Plot2d_HistogramItem::legendItem() const
00877 {
00878   return new Plot2d_QwtLegendItem;
00879 }
00880 
00881 
00885 void Plot2d_HistogramItem::drawRectAndLowers( QPainter* thePainter,
00886                                          Qt::Orientation theOr,
00887                                          const QRect& theRect ) const
00888 {
00889   QRect aRect = theRect;
00890   // theRect has inversed coordinates on Y axis.
00891   // The top of the rect is bottom in standard QRect coordinates, 
00892   // and it bottom is the top.
00893   if ( myCrossed )//&& theOr == Qt::Horizontal )
00894     aRect.setTop( getCrossedTop( theRect ) );
00895 
00896   drawBar( thePainter, Qt::Horizontal, aRect );
00897 }
00898 
00904 int Plot2d_HistogramItem::getCrossedTop( const QRect& theRect ) const
00905 {
00906   int aRes = theRect.top();
00907   QwtPlot* aPlot = plot();
00908   // int aHeight = theRect.height();
00909   if ( aPlot ) {
00910     QwtPlotItemList anItems = aPlot->itemList();
00911     QwtPlotItemIterator anIt = anItems.begin(), aLast = anItems.end();
00912     Plot2d_HistogramItem* anItem;
00913     QList<QRect> aRects;
00914     for ( ; anIt != aLast; anIt++ ) {
00915       if ( !(*anIt)->rtti() == QwtPlotItem::Rtti_PlotHistogram )
00916         continue;
00917       anItem = dynamic_cast<Plot2d_HistogramItem*>( *anIt );
00918       if( !anItem || anItem == this )
00919         continue;
00920       aRects.clear();
00921       aRects = anItem->getBars();
00922       for ( int i = 0, aSize = aRects.size(); i < aSize; i++ ) {
00923         if ( qMax( theRect.x(), aRects[i].x() ) <=
00924              qMin( theRect.left(), aRects[i].left() ) ) {
00925           if ( theRect.bottom() < aRects[i].bottom() )
00926             if ( aRects[i].bottom() < aRes )
00927              aRes = aRects[i].bottom();
00928         }
00929       }
00930     }
00931   }
00932   return aRes;
00933 }