1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : Plot2d_Histogram.cxx
23 // Author : Natalia ERMOLAEVA, Open CASCADE S.A.S. (natalia.donis@opencascade.com)
25 #include "Plot2d_Histogram.h"
26 #include "Plot2d_PlotItems.h"
28 #include <qwt_plot_curve.h>
30 const int MAX_ATTEMPTS = 10; // max attempts
35 Plot2d_Histogram::Plot2d_Histogram()
46 Plot2d_Histogram::~Plot2d_Histogram()
51 Copy constructor. Makes deep copy of data.
53 Plot2d_Histogram::Plot2d_Histogram( const Plot2d_Histogram& hist )
54 : Plot2d_Object( hist )
56 myColor = hist.myColor;
57 myWidth = hist.myWidth;
58 myDefWidth = hist.myDefWidth;
62 operator=. Makes deep copy of data.
64 Plot2d_Histogram& Plot2d_Histogram::operator=( const Plot2d_Histogram& hist )
66 Plot2d_Object::operator=(hist);
67 myColor = hist.myColor;
68 myWidth = hist.myWidth;
69 myDefWidth = hist.myDefWidth;
74 Get typeid for the plot2d histogram class
76 int Plot2d_Histogram::rtti()
78 return QwtPlotItem::Rtti_PlotHistogram;
82 Create plot object for the histogram
84 QwtPlotItem* Plot2d_Histogram::createPlotItem()
86 Plot2d_HistogramItem* anItem = new Plot2d_HistogramItem();
87 updatePlotItem( anItem );
92 Auto fill parameters of object by plot view
94 void Plot2d_Histogram::autoFill( const QwtPlot* thePlot )
96 setColor( getNextColor( thePlot ) );
100 Updates histogram fields
102 void Plot2d_Histogram::updatePlotItem( QwtPlotItem* theItem )
104 if ( theItem->rtti() != rtti() )
107 Plot2d_HistogramItem* anItem = dynamic_cast<Plot2d_HistogramItem*>( theItem );
111 Plot2d_Object::updatePlotItem( theItem );
113 anItem->setData( getData() );
114 anItem->setLegendPen(getColor());
115 anItem->setSelected(isSelected());
116 anItem->setColor( isSelected() ? Plot2d_Object::selectionColor() : getColor() );
122 void Plot2d_Histogram::setData( const QList<double>& theXVals,
123 const QList<double>& theYVals )
126 int aSize = theXVals.size();
127 for ( int i = 0; i < aSize; i++ )
128 aPoints.append( Plot2d_Point( theXVals[i], theYVals[i] ) );
129 setPointList( aPoints );
131 myDefWidth = getMinInterval( theXVals )*(2./3.);
132 myWidth = 0; // myDefWidth // VSR: width should not be automatically reset to myDefWidth
138 QwtIntervalData Plot2d_Histogram::getData() const
140 pointList aPoints = getPointList();
141 int aSize = aPoints.size();
143 QwtArray<QwtDoubleInterval> anIntervals( aSize );
144 QwtArray<double> aValues( aSize );
146 double aWidth = myWidth <= 0 ? myDefWidth : myWidth; // VSR: width is either manually assigned or auto-calculated
147 for ( int i = 0; i < aSize; i++ ) {
149 anIntervals[i] = QwtDoubleInterval( aX - aWidth/2, aX + aWidth/2 );
150 aValues[i] = aPoints[i].y;
153 return QwtIntervalData( anIntervals, aValues );
157 Sets color of histogram
159 void Plot2d_Histogram::setColor( const QColor& theColor )
162 setAutoAssign( false );
166 Returns color of histogram
168 QColor Plot2d_Histogram::getColor() const
174 Sets custom width of a histogram bar
176 void Plot2d_Histogram::setWidth( const double theWidth )
179 //setAutoAssign( false ); // VSR: width attribute is not auto-assigned
183 Returns custom or automatic width for a histogram bar
185 double Plot2d_Histogram::getWidth( const bool isDef ) const
187 return isDef ? myDefWidth : myWidth;
191 Gets new unique marker for item if possible
193 QColor Plot2d_Histogram::getNextColor( const QwtPlot* thePlot )
199 int aRed = (int)( 256.0 * rand() / RAND_MAX); // generate random color
200 int aGreen = (int)( 256.0 * rand() / RAND_MAX); // ...
201 int aBlue = (int)( 256.0 * rand() / RAND_MAX); // ...
202 aColor = QColor( aRed, aGreen, aBlue );
203 bOk = ( ++cnt == MAX_ATTEMPTS ) || !existColor( thePlot, aColor );
209 Checks if color is already user by other histogram entity
211 bool Plot2d_Histogram::existColor( const QwtPlot* thePlot, const QColor& theColor )
215 QColor bgColor = thePlot->palette().color( QPalette::Background );
216 if ( Plot2d::closeColors( theColor, bgColor ) ) {
220 QwtPlotItemList anItems = thePlot->itemList();
221 QwtPlotItemIterator anIt = anItems.begin(), aLast = anItems.end();
223 for( ; anIt != aLast && !ok; anIt++ ) {
227 if ( anItem->rtti() == rtti() ) {
228 Plot2d_HistogramItem* aHItem = dynamic_cast<Plot2d_HistogramItem*>( anItem );
229 ok = aHItem && Plot2d::closeColors( theColor, aHItem->color() );
231 else if ( anItem->rtti() == QwtPlotItem::Rtti_PlotCurve ) {
232 QwtPlotCurve* aCurve = dynamic_cast<QwtPlotCurve*>( anItem );
233 ok = aCurve && Plot2d::closeColors( theColor, aCurve->pen().color() );
241 Return min interval from values
243 double Plot2d_Histogram::getMinInterval( const QList<double>& theVals )
246 int aSize = theVals.size();
248 aValue = qAbs( theVals[1] - theVals[0] );
250 for ( int i = 2; i < aSize; i++ ) {
251 aDelta = qAbs( theVals[i] - theVals[i-1] );
252 aValue = qMin( aValue, qMax( aDelta, 0. ) );