10#include "qwt_plot_intervalcurve.h" 
   11#include "qwt_interval_symbol.h" 
   12#include "qwt_scale_map.h" 
   13#include "qwt_clipper.h" 
   14#include "qwt_painter.h" 
   15#include "qwt_graphic.h" 
   23    double xMin, 
double xMax, 
double yMin, 
double yMax )
 
   25    const double y = sample.
value;
 
   29    const bool isOffScreen = ( y < yMin ) || ( y > yMax )
 
   30        || ( x1 < xMin && x2 < xMin ) || ( x1 > xMax && x2 > xMax );
 
   36    double xMin, 
double xMax, 
double yMin, 
double yMax )
 
   38    const double x = sample.
value;
 
   42    const bool isOffScreen = ( x < xMin ) || ( x > xMax )
 
   43        || ( y1 < yMin && y2 < yMin ) || ( y1 > yMax && y2 > yMax );
 
   48static inline int qwtInterpolated( 
int from, 
int to, 
double ratio )
 
   50    return qRound( from + ratio * ( to - from ) );
 
   53static int qwtStartIndex( 
int from, 
double min, 
double max,
 
   64        inline bool operator()( 
const double value,
 
   67            return value < sample.
value;
 
   73        inline bool operator()( 
const double value,
 
   76            return value > sample.
value;
 
   84        idx = qwtUpperSampleIndex< QwtIntervalSample >(
 
   85            *samples, min, lessThan() );
 
   89        idx = qwtUpperSampleIndex< QwtIntervalSample >(
 
   90            *samples, max, greaterThan() );
 
   95        idx = qMax( from, idx );
 
  111        LinesRenderer( Qt::Orientation,
 
  123        bool append( 
int value, 
int min, 
int max );
 
  125        void addFillLineAt( 
int value, 
int min, 
int max );
 
  126        void addFillLines( 
int value, 
int min, 
int max );
 
  128        void addBorderLineAt( 
int value, 
int min, 
int max );
 
  129        void addBorderLine( 
int, 
int, 
int, 
int );
 
  131        const bool m_vertical;
 
  136        const bool m_inverting;
 
  141        int m_intvMin, m_intvMax;   
 
  142        int m_valueMin, m_valueMax; 
 
  148            inline void reset( 
int value )
 
  150                min = max = last = value;
 
  153            inline void extend( 
int value )
 
  157                else if ( value > max )
 
  168    LinesRenderer::LinesRenderer( Qt::Orientation orientation,
 
  170        : m_vertical( orientation == Qt::Vertical )
 
  171        , m_valueMap( m_vertical ? xMap : yMap )
 
  172        , m_intervalMap( m_vertical ? yMap : xMap )
 
  173        , m_inverting( m_intervalMap.isInverting() )
 
  179            r.setSize( QSizeF( r.height(), r.width() ) );
 
  181        m_intvMin = qFloor( r.top() );
 
  182        m_intvMax = qCeil( r.bottom() );
 
  184        m_valueMin = qFloor( r.left() );
 
  185        m_valueMax = qCeil( r.right() );
 
  187        const int steps = m_valueMax - m_valueMin + 1;
 
  190        fillLines.reserve( steps );
 
  197        borderLines.reserve( 4 * steps );
 
  200    void LinesRenderer::addSamples(
 
  203        const double v1 = m_valueMap.
invTransform( m_valueMin );
 
  204        const double v2 = m_valueMap.
invTransform( m_valueMax );
 
  206        from = qwtStartIndex( from, qMin( v1, v2 ), qMax( v1, v2 ), samples );
 
  210            for ( 
int i = from; i <= to; i++ )
 
  212                if ( addSample( samples->
sample( i ) ) )
 
  222        const double value = qRound( m_valueMap.
transform( sample.
value ) );
 
  227        return m_inverting ? append( value, max, min ) : append( value, max, min );
 
  230    inline bool LinesRenderer::append(
 
  231        const int value, 
const int lower, 
const int upper )
 
  236            m_lower.reset( lower );
 
  237            m_upper.reset( upper );
 
  244        if ( value != m_value )
 
  246            addFillLines( value, lower, upper );
 
  247            addBorderLineAt( m_value, m_lower.min, m_lower.max );
 
  248            addBorderLineAt( m_value, m_upper.min, m_upper.max );
 
  250            addBorderLine( m_value, m_lower.last, value, lower );
 
  251            addBorderLine( m_value, m_upper.last, value, upper );
 
  253            if ( ( value > m_value ) ? ( value > m_valueMax ) : ( value < m_valueMin ) )
 
  261            m_lower.reset( lower );
 
  262            m_upper.reset( upper );
 
  266            m_lower.extend( lower );
 
  267            m_upper.extend( upper );
 
  273    inline void LinesRenderer::flush()
 
  277            addFillLineAt( m_value, m_lower.min, m_upper.max );
 
  278            addBorderLineAt( m_value, m_lower.min, m_lower.max );
 
  279            addBorderLineAt( m_value, m_upper.min, m_upper.max );
 
  283    inline void LinesRenderer::addFillLines(
 
  284        const int value, 
const int lower, 
const int upper )
 
  286        addFillLineAt( m_value, m_lower.min, m_upper.max );
 
  288        const double delta = value - m_value;
 
  290        if ( value > m_value )
 
  292            for ( 
int v = m_value + 1; v < value; v++ )
 
  294                const double ratio = ( v - m_value ) / delta;
 
  297                    qwtInterpolated( m_lower.last, lower, ratio ),
 
  298                    qwtInterpolated( m_upper.last, upper, ratio ) );
 
  303            for ( 
int v = m_value - 1; v > value; v-- )
 
  305                const double ratio = ( v - m_value ) / delta;
 
  308                    qwtInterpolated( m_lower.last, lower, ratio ),
 
  309                    qwtInterpolated( m_upper.last, upper, ratio ) );
 
  314    inline void LinesRenderer::addFillLineAt( 
int value, 
int min, 
int max )
 
  316        if ( ( min != max ) && ( max > m_intvMin ) && ( min < m_intvMax ) )
 
  318            min = qMax( min, m_intvMin );
 
  319            max = qMin( max, m_intvMax );
 
  322                fillLines += QLine( value, min, value, max );
 
  324                fillLines += QLine( min, value, max, value );
 
  328    inline void LinesRenderer::addBorderLineAt( 
int value, 
int min, 
int max )
 
  331            addBorderLine( value, min, value, max );
 
  334    inline void LinesRenderer::addBorderLine( 
int x1, 
int y1, 
int x2, 
int y2 )
 
  337            borderLines += QLine( x1, y1, x2, y2 );
 
  339            borderLines += QLine( y1, x1, y2, x2 );
 
  343static void qwtDrawTubeLines(
 
  346    const QRectF& canvasRect, 
int from, 
int to)
 
  348    LinesRenderer renderer( curve->
orientation(), xMap, yMap, canvasRect );
 
  349    renderer.addSamples( curve->
data(), from, to );
 
  351    if ( curve->
brush().style() != Qt::NoBrush )
 
  355        painter->setPen( curve->
brush().color() );
 
  356        painter->setRenderHint( QPainter::Antialiasing, 
false );
 
  357        painter->drawLines( renderer.fillLines );
 
  362    if ( curve->
pen().style() != Qt::NoPen )
 
  366        painter->setPen( curve->
pen() );
 
  367        painter->drawLines( renderer.borderLines );
 
  373static void qwtDrawTube(
 
  376    const QRectF& canvasRect, 
int from, 
int to )
 
  382    const size_t size = to - from + 1;
 
  383    QPolygonF polygon( 2 * size );
 
  384    QPointF* points = polygon.data();
 
  386    for ( uint i = 0; i < size; i++ )
 
  388        QPointF& minValue = points[i];
 
  389        QPointF& maxValue = points[2 * size - 1 - i];
 
  432    if ( curve->
brush().style() != Qt::NoBrush )
 
  434        painter->setPen( QPen( Qt::NoPen ) );
 
  435        painter->setBrush( curve->
brush() );
 
  441                canvasRect.adjusted( -m, -m, m, m ), polygon, 
true );
 
  451    if ( curve->
pen().style() != Qt::NoPen )
 
  453        painter->setPen( curve->
pen() );
 
  454        painter->setBrush( Qt::NoBrush );
 
  459            const QRectF clipRect = canvasRect.adjusted( -pw, -pw, pw, pw );
 
  463            std::memcpy( p.data(), points, size * 
sizeof( QPointF ) );
 
  467            std::memcpy( p.data(), points + size, size * 
sizeof( QPointF ) );
 
  481class QwtPlotIntervalCurve::PrivateData
 
  493        pen.setCapStyle( Qt::FlatCap );
 
  542    m_data = 
new PrivateData;
 
 
  565        m_data->paintAttributes |= attribute;
 
  567        m_data->paintAttributes &= ~attribute;
 
 
  577    return ( m_data->paintAttributes & attribute );
 
 
  614    if ( 
style != m_data->style )
 
  616        m_data->style = 
style;
 
 
  629    return m_data->style;
 
 
  640    if ( 
symbol != m_data->symbol )
 
  642        delete m_data->symbol;
 
 
  656    return m_data->symbol;
 
 
  684    if ( 
pen != m_data->pen )
 
 
  712    if ( 
brush != m_data->brush )
 
  714        m_data->brush = 
brush;
 
 
  727    return m_data->brush;
 
 
  738        rect.setRect( rect.y(), rect.x(), rect.height(), rect.width() );
 
 
  758    const QRectF& canvasRect, 
int from, 
int to )
 const 
  769    if ( m_data->style == 
Tube )
 
  770        drawTube( painter, xMap, yMap, canvasRect, from, to );
 
  772    if ( m_data->symbol &&
 
  776            xMap, yMap, canvasRect, from, to );
 
 
  799    const QwtScaleMap& yMap, 
const QRectF& canvasRect, 
int from, 
int to)
 const 
  801    if ( ( m_data->pen.style() == Qt::NoPen ) &&
 
  802        ( m_data->brush.style() == Qt::NoBrush ) )
 
  811        qwtDrawTubeLines( 
this, painter, xMap, yMap, canvasRect, from, to );
 
  813        qwtDrawTube( 
this, painter, xMap, yMap, canvasRect, from, to );
 
 
  832    const QRectF& canvasRect, 
int from, 
int to )
 const 
  837    pen.setCapStyle( Qt::FlatCap );
 
  839    painter->setPen( 
pen );
 
  844    const double xMin = tr.left();
 
  845    const double xMax = tr.right();
 
  846    const double yMin = tr.top();
 
  847    const double yMax = tr.bottom();
 
  849    const bool doClip = m_data->paintAttributes & 
ClipSymbol;
 
  851    for ( 
int i = from; i <= to; i++ )
 
  857            if ( !doClip || qwtIsVSampleInside( s, xMin, xMax, yMin, yMax ) )
 
  864                    QPointF( x, y1 ), QPointF( x, y2 ) );
 
  869            if ( !doClip || qwtIsHSampleInside( s, xMin, xMax, yMin, yMax ) )
 
  876                    QPointF( x1, y ), QPointF( x2, y ) );
 
 
  897    int index, 
const QSizeF& size )
 const 
  901    if ( size.isEmpty() )
 
  908    QPainter painter( &icon );
 
  909    painter.setRenderHint( QPainter::Antialiasing,
 
  912    if ( m_data->style == 
Tube )
 
  914        QRectF r( 0, 0, size.width(), size.height() );
 
  915        painter.fillRect( r, m_data->brush );
 
  918    if ( m_data->symbol &&
 
  921        QPen 
pen = m_data->symbol->
pen();
 
  922        pen.setWidthF( 
pen.widthF() );
 
  923        pen.setCapStyle( Qt::FlatCap );
 
  925        painter.setPen( 
pen );
 
  926        painter.setBrush( m_data->symbol->
brush() );
 
  930            const double x = 0.5 * size.width();
 
  933                QPointF( x, 0 ), QPointF( x, size.height() - 1.0 ) );
 
  937            const double y = 0.5 * size.height();
 
  940                QPointF( 0.0, y ), QPointF( size.width() - 1.0, y ) );
 
 
Template class for data, that is organized as QVector.
A paint device for scalable graphics.
void setRenderHint(RenderHint, bool on=true)
void setDefaultSize(const QSizeF &)
Set a default size.
A sample of the types (x1-x2, y) or (x, y1-y2)
QwtInterval interval
Interval.
A drawing primitive for displaying an interval like an error bar.
virtual void draw(QPainter *, Qt::Orientation, const QPointF &from, const QPointF &to) const
@ NoSymbol
No Style. The symbol cannot be drawn.
const QBrush & brush() const
static void drawPolygon(QPainter *, const QPolygonF &)
Wrapper for QPainter::drawPolygon()
static void drawPolyline(QPainter *, const QPolygonF &)
Wrapper for QPainter::drawPolyline()
static qreal effectivePenWidth(const QPen &)
static bool roundingAlignment()
QwtPlotIntervalCurve represents a series of samples, where each value is associated with an interval ...
virtual int rtti() const override
virtual ~QwtPlotIntervalCurve()
Destructor.
QFlags< PaintAttribute > PaintAttributes
void setBrush(const QBrush &)
QwtPlotIntervalCurve(const QString &title=QString())
@ ClipSymbol
Check if a symbol is on the plot canvas before painting it.
void setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
virtual QwtGraphic legendIcon(int index, const QSizeF &) const override
virtual QRectF boundingRect() const override
void setSymbol(const QwtIntervalSymbol *)
void setStyle(CurveStyle style)
void init()
Initialize internal members.
const QBrush & brush() const
virtual void drawSymbols(QPainter *, const QwtIntervalSymbol &, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
CurveStyle
Curve styles. The default setting is QwtPlotIntervalCurve::Tube.
const QwtIntervalSymbol * symbol() const
void setPaintAttribute(PaintAttribute, bool on=true)
void setSamples(const QVector< QwtIntervalSample > &)
virtual void drawTube(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
virtual void drawSeries(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const override
bool testPaintAttribute(PaintAttribute) const
virtual void legendChanged()
void setZ(double z)
Set the z value.
void setItemAttribute(ItemAttribute, bool on=true)
@ Rtti_PlotIntervalCurve
For QwtPlotIntervalCurve.
@ RenderAntialiased
Enable antialiasing.
bool testRenderHint(RenderHint) const
virtual void itemChanged()
@ Legend
The item is represented on the legend.
Base class for plot items representing a series of samples.
Qt::Orientation orientation() const
virtual QRectF boundingRect() const override
double transform(double s) const
double invTransform(double p) const
virtual T sample(size_t i) const =0
T sample(int index) const
virtual size_t dataSize() const override
QwtSeriesData< T > * data()
void setData(QwtSeriesData< QwtIntervalSample > *series)
A class representing a text.
QWT_EXPORT QPolygonF clippedPolygonF(const QRectF &, const QPolygonF &, bool closePolygon=false)