You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
834 lines
0 B
834 lines
0 B
15 years ago
|
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
|
||
|
* Qwt Widget Library
|
||
|
* Copyright (C) 1997 Josef Wilgen
|
||
|
* Copyright (C) 2002 Uwe Rathmann
|
||
|
*
|
||
|
* This library is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the Qwt License, Version 1.0
|
||
|
*****************************************************************************/
|
||
|
|
||
|
#include <qpainter.h>
|
||
|
#if QT_VERSION < 0x040000
|
||
|
#include <qguardedptr.h>
|
||
|
#include <qfocusdata.h>
|
||
|
#else
|
||
|
#include <qpointer.h>
|
||
|
#include <qpaintengine.h>
|
||
|
#endif
|
||
|
#include <qapplication.h>
|
||
|
#include <qevent.h>
|
||
|
#include "qwt_plot.h"
|
||
|
#include "qwt_plot_dict.h"
|
||
|
#include "qwt_plot_layout.h"
|
||
|
#include "qwt_scale_widget.h"
|
||
|
#include "qwt_scale_engine.h"
|
||
|
#include "qwt_text_label.h"
|
||
|
#include "qwt_legend.h"
|
||
|
#include "qwt_dyngrid_layout.h"
|
||
|
#include "qwt_plot_canvas.h"
|
||
|
#include "qwt_paint_buffer.h"
|
||
|
|
||
|
class QwtPlot::PrivateData
|
||
|
{
|
||
|
public:
|
||
|
#if QT_VERSION < 0x040000
|
||
|
QGuardedPtr<QwtTextLabel> lblTitle;
|
||
|
QGuardedPtr<QwtPlotCanvas> canvas;
|
||
|
QGuardedPtr<QwtLegend> legend;
|
||
|
#else
|
||
|
QPointer<QwtTextLabel> lblTitle;
|
||
|
QPointer<QwtPlotCanvas> canvas;
|
||
|
QPointer<QwtLegend> legend;
|
||
|
#endif
|
||
|
QwtPlotLayout *layout;
|
||
|
|
||
|
bool autoReplot;
|
||
|
};
|
||
|
|
||
|
/*!
|
||
|
\brief Constructor
|
||
|
\param parent Parent widget
|
||
|
*/
|
||
|
QwtPlot::QwtPlot(QWidget *parent):
|
||
|
QFrame(parent)
|
||
|
{
|
||
|
initPlot(QwtText());
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Constructor
|
||
|
\param title Title text
|
||
|
\param parent Parent widget
|
||
|
*/
|
||
|
QwtPlot::QwtPlot(const QwtText &title, QWidget *parent):
|
||
|
QFrame(parent)
|
||
|
{
|
||
|
initPlot(title);
|
||
|
}
|
||
|
|
||
|
#if QT_VERSION < 0x040000
|
||
|
/*!
|
||
|
\brief Constructor
|
||
|
\param parent Parent widget
|
||
|
\param name Object name
|
||
|
*/
|
||
|
QwtPlot::QwtPlot(QWidget *parent, const char *name):
|
||
|
QFrame(parent, name)
|
||
14 years ago
|
{
|
||
15 years ago
|
initPlot(QwtText());
|
||
14 years ago
|
}
|
||
15 years ago
|
#endif
|
||
|
|
||
|
|
||
|
//! Destructor
|
||
|
QwtPlot::~QwtPlot()
|
||
|
{
|
||
|
detachItems(QwtPlotItem::Rtti_PlotItem, autoDelete());
|
||
|
|
||
|
delete d_data->layout;
|
||
|
deleteAxesData();
|
||
|
delete d_data;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Initializes a QwtPlot instance
|
||
|
\param title Title text
|
||
|
*/
|
||
|
void QwtPlot::initPlot(const QwtText &title)
|
||
|
{
|
||
|
d_data = new PrivateData;
|
||
|
|
||
|
#if QT_VERSION < 0x040000
|
||
|
setWFlags(Qt::WNoAutoErase);
|
||
14 years ago
|
#endif
|
||
15 years ago
|
|
||
|
d_data->layout = new QwtPlotLayout;
|
||
|
|
||
|
d_data->autoReplot = false;
|
||
|
|
||
|
d_data->lblTitle = new QwtTextLabel(title, this);
|
||
|
d_data->lblTitle->setFont(QFont(fontInfo().family(), 14, QFont::Bold));
|
||
|
|
||
|
QwtText text(title);
|
||
|
int flags = Qt::AlignCenter;
|
||
|
#if QT_VERSION < 0x040000
|
||
|
flags |= Qt::WordBreak | Qt::ExpandTabs;
|
||
|
#else
|
||
|
flags |= Qt::TextWordWrap;
|
||
|
#endif
|
||
|
text.setRenderFlags(flags);
|
||
|
d_data->lblTitle->setText(text);
|
||
|
|
||
|
d_data->legend = NULL;
|
||
|
|
||
|
initAxesData();
|
||
|
|
||
|
d_data->canvas = new QwtPlotCanvas(this);
|
||
|
d_data->canvas->setFrameStyle(QFrame::Panel|QFrame::Sunken);
|
||
|
d_data->canvas->setLineWidth(2);
|
||
|
d_data->canvas->setMidLineWidth(0);
|
||
|
|
||
|
updateTabOrder();
|
||
|
|
||
14 years ago
|
setSizePolicy(QSizePolicy::MinimumExpanding,
|
||
|
QSizePolicy::MinimumExpanding);
|
||
15 years ago
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Adds handling of layout requests
|
||
|
*/
|
||
|
bool QwtPlot::event(QEvent *e)
|
||
|
{
|
||
|
bool ok = QFrame::event(e);
|
||
14 years ago
|
switch(e->type()) {
|
||
15 years ago
|
#if QT_VERSION < 0x040000
|
||
14 years ago
|
case QEvent::LayoutHint:
|
||
15 years ago
|
#else
|
||
14 years ago
|
case QEvent::LayoutRequest:
|
||
15 years ago
|
#endif
|
||
14 years ago
|
updateLayout();
|
||
|
break;
|
||
15 years ago
|
#if QT_VERSION >= 0x040000
|
||
14 years ago
|
case QEvent::PolishRequest:
|
||
|
polish();
|
||
|
break;
|
||
15 years ago
|
#endif
|
||
14 years ago
|
default:
|
||
|
;
|
||
15 years ago
|
}
|
||
|
return ok;
|
||
|
}
|
||
|
|
||
|
//! Replots the plot if QwtPlot::autoReplot() is \c true.
|
||
|
void QwtPlot::autoRefresh()
|
||
|
{
|
||
|
if (d_data->autoReplot)
|
||
|
replot();
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Set or reset the autoReplot option
|
||
|
|
||
|
If the autoReplot option is set, the plot will be
|
||
|
updated implicitly by manipulating member functions.
|
||
|
Since this may be time-consuming, it is recommended
|
||
|
to leave this option switched off and call replot()
|
||
|
explicitly if necessary.
|
||
|
|
||
|
The autoReplot option is set to false by default, which
|
||
|
means that the user has to call replot() in order to make
|
||
|
changes visible.
|
||
|
\param tf \c true or \c false. Defaults to \c true.
|
||
|
\sa replot()
|
||
|
*/
|
||
|
void QwtPlot::setAutoReplot(bool tf)
|
||
|
{
|
||
|
d_data->autoReplot = tf;
|
||
|
}
|
||
|
|
||
|
//! \return true if the autoReplot option is set.
|
||
|
bool QwtPlot::autoReplot() const
|
||
|
{
|
||
14 years ago
|
return d_data->autoReplot;
|
||
15 years ago
|
}
|
||
|
|
||
|
/*!
|
||
|
Change the plot's title
|
||
|
\param title New title
|
||
|
*/
|
||
|
void QwtPlot::setTitle(const QString &title)
|
||
|
{
|
||
14 years ago
|
if ( title != d_data->lblTitle->text().text() ) {
|
||
15 years ago
|
d_data->lblTitle->setText(title);
|
||
|
updateLayout();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
Change the plot's title
|
||
|
\param title New title
|
||
|
*/
|
||
|
void QwtPlot::setTitle(const QwtText &title)
|
||
|
{
|
||
14 years ago
|
if ( title != d_data->lblTitle->text() ) {
|
||
15 years ago
|
d_data->lblTitle->setText(title);
|
||
|
updateLayout();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//! \return the plot's title
|
||
|
QwtText QwtPlot::title() const
|
||
|
{
|
||
|
return d_data->lblTitle->text();
|
||
|
}
|
||
|
|
||
|
//! \return the plot's title
|
||
|
QwtPlotLayout *QwtPlot::plotLayout()
|
||
|
{
|
||
|
return d_data->layout;
|
||
|
}
|
||
|
|
||
|
//! \return the plot's titel label.
|
||
|
const QwtPlotLayout *QwtPlot::plotLayout() const
|
||
|
{
|
||
|
return d_data->layout;
|
||
|
}
|
||
|
|
||
|
//! \return the plot's titel label.
|
||
|
QwtTextLabel *QwtPlot::titleLabel()
|
||
|
{
|
||
|
return d_data->lblTitle;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\return the plot's titel label.
|
||
|
*/
|
||
|
const QwtTextLabel *QwtPlot::titleLabel() const
|
||
|
{
|
||
|
return d_data->lblTitle;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\return the plot's legend
|
||
|
\sa insertLegend()
|
||
|
*/
|
||
|
QwtLegend *QwtPlot::legend()
|
||
14 years ago
|
{
|
||
15 years ago
|
return d_data->legend;
|
||
14 years ago
|
}
|
||
15 years ago
|
|
||
|
/*!
|
||
|
\return the plot's legend
|
||
|
\sa insertLegend()
|
||
|
*/
|
||
|
const QwtLegend *QwtPlot::legend() const
|
||
14 years ago
|
{
|
||
15 years ago
|
return d_data->legend;
|
||
14 years ago
|
}
|
||
15 years ago
|
|
||
|
|
||
|
/*!
|
||
|
\return the plot's canvas
|
||
|
*/
|
||
|
QwtPlotCanvas *QwtPlot::canvas()
|
||
14 years ago
|
{
|
||
15 years ago
|
return d_data->canvas;
|
||
14 years ago
|
}
|
||
15 years ago
|
|
||
|
/*!
|
||
|
\return the plot's canvas
|
||
|
*/
|
||
|
const QwtPlotCanvas *QwtPlot::canvas() const
|
||
14 years ago
|
{
|
||
15 years ago
|
return d_data->canvas;
|
||
|
}
|
||
|
|
||
|
//! Polish
|
||
|
void QwtPlot::polish()
|
||
|
{
|
||
|
replot();
|
||
|
|
||
|
#if QT_VERSION < 0x040000
|
||
|
QFrame::polish();
|
||
|
#endif
|
||
|
}
|
||
|
|
||
14 years ago
|
/*!
|
||
15 years ago
|
Return sizeHint
|
||
|
\sa minimumSizeHint()
|
||
|
*/
|
||
|
|
||
|
QSize QwtPlot::sizeHint() const
|
||
|
{
|
||
|
int dw = 0;
|
||
|
int dh = 0;
|
||
14 years ago
|
for ( int axisId = 0; axisId < axisCnt; axisId++ ) {
|
||
|
if ( axisEnabled(axisId) ) {
|
||
15 years ago
|
const int niceDist = 40;
|
||
|
const QwtScaleWidget *scaleWidget = axisWidget(axisId);
|
||
|
const QwtScaleDiv &scaleDiv = scaleWidget->scaleDraw()->scaleDiv();
|
||
|
const int majCnt = scaleDiv.ticks(QwtScaleDiv::MajorTick).count();
|
||
|
|
||
14 years ago
|
if ( axisId == yLeft || axisId == yRight ) {
|
||
|
int hDiff = (majCnt - 1) * niceDist
|
||
|
- scaleWidget->minimumSizeHint().height();
|
||
15 years ago
|
if ( hDiff > dh )
|
||
|
dh = hDiff;
|
||
14 years ago
|
} else {
|
||
|
int wDiff = (majCnt - 1) * niceDist
|
||
|
- scaleWidget->minimumSizeHint().width();
|
||
15 years ago
|
if ( wDiff > dw )
|
||
|
dw = wDiff;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return minimumSizeHint() + QSize(dw, dh);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Return a minimum size hint
|
||
|
*/
|
||
|
QSize QwtPlot::minimumSizeHint() const
|
||
|
{
|
||
|
QSize hint = d_data->layout->minimumSizeHint(this);
|
||
|
hint += QSize(2 * frameWidth(), 2 * frameWidth());
|
||
|
|
||
|
return hint;
|
||
|
}
|
||
|
|
||
|
//! Resize and update internal layout
|
||
|
void QwtPlot::resizeEvent(QResizeEvent *e)
|
||
|
{
|
||
|
QFrame::resizeEvent(e);
|
||
|
updateLayout();
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Redraw the plot
|
||
|
|
||
|
If the autoReplot option is not set (which is the default)
|
||
|
or if any curves are attached to raw data, the plot has to
|
||
|
be refreshed explicitly in order to make changes visible.
|
||
|
|
||
|
\sa setAutoReplot()
|
||
|
\warning Calls canvas()->repaint, take care of infinite recursions
|
||
|
*/
|
||
|
void QwtPlot::replot()
|
||
|
{
|
||
|
bool doAutoReplot = autoReplot();
|
||
|
setAutoReplot(false);
|
||
|
|
||
|
updateAxes();
|
||
|
|
||
|
/*
|
||
|
Maybe the layout needs to be updated, because of changed
|
||
|
axes labels. We need to process them here before painting
|
||
|
to avoid that scales and canvas get out of sync.
|
||
|
*/
|
||
|
#if QT_VERSION >= 0x040000
|
||
|
QApplication::sendPostedEvents(this, QEvent::LayoutRequest);
|
||
|
#else
|
||
|
QApplication::sendPostedEvents(this, QEvent::LayoutHint);
|
||
|
#endif
|
||
|
|
||
|
QwtPlotCanvas &canvas = *d_data->canvas;
|
||
|
|
||
|
canvas.invalidatePaintCache();
|
||
|
|
||
|
/*
|
||
|
In case of cached or packed painting the canvas
|
||
|
is repainted completely and doesn't need to be erased.
|
||
|
*/
|
||
14 years ago
|
const bool erase =
|
||
|
!canvas.testPaintAttribute(QwtPlotCanvas::PaintPacked)
|
||
15 years ago
|
&& !canvas.testPaintAttribute(QwtPlotCanvas::PaintCached);
|
||
|
|
||
|
#if QT_VERSION >= 0x040000
|
||
|
const bool noBackgroundMode = canvas.testAttribute(Qt::WA_NoBackground);
|
||
|
if ( !erase && !noBackgroundMode )
|
||
|
canvas.setAttribute(Qt::WA_NoBackground, true);
|
||
|
|
||
|
canvas.repaint(canvas.contentsRect());
|
||
|
|
||
|
if ( !erase && !noBackgroundMode )
|
||
|
canvas.setAttribute(Qt::WA_NoBackground, false);
|
||
|
#else
|
||
|
canvas.repaint(canvas.contentsRect(), erase);
|
||
|
#endif
|
||
|
|
||
|
setAutoReplot(doAutoReplot);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Adjust plot content to its current size.
|
||
|
\sa resizeEvent()
|
||
|
*/
|
||
|
void QwtPlot::updateLayout()
|
||
|
{
|
||
|
d_data->layout->activate(this, contentsRect());
|
||
|
|
||
|
//
|
||
|
// resize and show the visible widgets
|
||
|
//
|
||
14 years ago
|
if (!d_data->lblTitle->text().isEmpty()) {
|
||
15 years ago
|
d_data->lblTitle->setGeometry(d_data->layout->titleRect());
|
||
|
if (!d_data->lblTitle->isVisible())
|
||
|
d_data->lblTitle->show();
|
||
14 years ago
|
} else
|
||
15 years ago
|
d_data->lblTitle->hide();
|
||
|
|
||
14 years ago
|
for (int axisId = 0; axisId < axisCnt; axisId++ ) {
|
||
|
if (axisEnabled(axisId) ) {
|
||
15 years ago
|
axisWidget(axisId)->setGeometry(d_data->layout->scaleRect(axisId));
|
||
|
|
||
14 years ago
|
if ( axisId == xBottom || axisId == xTop ) {
|
||
15 years ago
|
QRegion r(d_data->layout->scaleRect(axisId));
|
||
|
if ( axisEnabled(yLeft) )
|
||
|
r = r.subtract(QRegion(d_data->layout->scaleRect(yLeft)));
|
||
|
if ( axisEnabled(yRight) )
|
||
|
r = r.subtract(QRegion(d_data->layout->scaleRect(yRight)));
|
||
14 years ago
|
r.translate(-d_data->layout->scaleRect(axisId).x(),
|
||
|
-d_data->layout->scaleRect(axisId).y());
|
||
15 years ago
|
|
||
|
axisWidget(axisId)->setMask(r);
|
||
|
}
|
||
|
if (!axisWidget(axisId)->isVisible())
|
||
|
axisWidget(axisId)->show();
|
||
14 years ago
|
} else
|
||
15 years ago
|
axisWidget(axisId)->hide();
|
||
|
}
|
||
|
|
||
14 years ago
|
if ( d_data->legend &&
|
||
|
d_data->layout->legendPosition() != ExternalLegend ) {
|
||
|
if (d_data->legend->itemCount() > 0) {
|
||
15 years ago
|
d_data->legend->setGeometry(d_data->layout->legendRect());
|
||
|
d_data->legend->show();
|
||
14 years ago
|
} else
|
||
15 years ago
|
d_data->legend->hide();
|
||
|
}
|
||
|
|
||
|
d_data->canvas->setGeometry(d_data->layout->canvasRect());
|
||
|
}
|
||
|
|
||
14 years ago
|
/*!
|
||
15 years ago
|
Update the focus tab order
|
||
|
|
||
|
The order is changed so that the canvas will be in front of the
|
||
|
first legend item, or behind the last legend item - depending
|
||
|
on the position of the legend.
|
||
|
*/
|
||
|
|
||
|
void QwtPlot::updateTabOrder()
|
||
|
{
|
||
|
#if QT_VERSION >= 0x040000
|
||
|
using namespace Qt; // QWidget::NoFocus/Qt::NoFocus
|
||
|
#else
|
||
|
if ( d_data->canvas->focusPolicy() == NoFocus )
|
||
|
return;
|
||
|
#endif
|
||
14 years ago
|
if ( d_data->legend.isNull()
|
||
|
|| d_data->layout->legendPosition() == ExternalLegend
|
||
|
|| d_data->legend->legendItems().count() == 0 ) {
|
||
15 years ago
|
return;
|
||
|
}
|
||
|
|
||
14 years ago
|
// Depending on the position of the legend the
|
||
15 years ago
|
// tab order will be changed that the canvas is
|
||
|
// next to the last legend item, or before
|
||
14 years ago
|
// the first one.
|
||
15 years ago
|
|
||
14 years ago
|
const bool canvasFirst =
|
||
15 years ago
|
d_data->layout->legendPosition() == QwtPlot::BottomLegend ||
|
||
|
d_data->layout->legendPosition() == QwtPlot::RightLegend;
|
||
|
|
||
14 years ago
|
QWidget *previous = NULL;
|
||
15 years ago
|
|
||
|
QWidget *w;
|
||
|
#if QT_VERSION >= 0x040000
|
||
|
w = d_data->canvas;
|
||
|
while ( ( w = w->nextInFocusChain() ) != d_data->canvas )
|
||
|
#else
|
||
|
if ( focusData() == NULL )
|
||
|
return;
|
||
|
|
||
|
while ( focusData()->next() != d_data->canvas );
|
||
|
while ( (w = focusData()->next()) != d_data->canvas )
|
||
|
#endif
|
||
|
{
|
||
|
bool isLegendItem = false;
|
||
14 years ago
|
if ( w->focusPolicy() != NoFocus
|
||
|
&& w->parent() && w->parent() == d_data->legend->contentsWidget() ) {
|
||
15 years ago
|
isLegendItem = true;
|
||
|
}
|
||
|
|
||
14 years ago
|
if ( canvasFirst ) {
|
||
15 years ago
|
if ( isLegendItem )
|
||
|
break;
|
||
|
|
||
|
previous = w;
|
||
14 years ago
|
} else {
|
||
15 years ago
|
if ( isLegendItem )
|
||
|
previous = w;
|
||
14 years ago
|
else {
|
||
15 years ago
|
if ( previous )
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( previous && previous != d_data->canvas)
|
||
|
setTabOrder(previous, d_data->canvas);
|
||
|
}
|
||
|
|
||
14 years ago
|
/*!
|
||
15 years ago
|
Redraw the canvas.
|
||
|
\param painter Painter used for drawing
|
||
|
|
||
|
\warning drawCanvas calls drawItems what is also used
|
||
|
for printing. Applications that like to add individual
|
||
|
plot items better overload drawItems()
|
||
|
\sa drawItems()
|
||
|
*/
|
||
|
void QwtPlot::drawCanvas(QPainter *painter)
|
||
|
{
|
||
|
QwtScaleMap maps[axisCnt];
|
||
|
for ( int axisId = 0; axisId < axisCnt; axisId++ )
|
||
|
maps[axisId] = canvasMap(axisId);
|
||
|
|
||
14 years ago
|
drawItems(painter,
|
||
|
d_data->canvas->contentsRect(), maps, QwtPlotPrintFilter());
|
||
15 years ago
|
}
|
||
|
|
||
14 years ago
|
/*!
|
||
15 years ago
|
Redraw the canvas items.
|
||
|
\param painter Painter used for drawing
|
||
|
\param rect Bounding rectangle where to paint
|
||
|
\param map QwtPlot::axisCnt maps, mapping between plot and paint device coordinates
|
||
|
\param pfilter Plot print filter
|
||
|
*/
|
||
|
|
||
14 years ago
|
void QwtPlot::drawItems(QPainter *painter, const QRect &rect,
|
||
|
const QwtScaleMap map[axisCnt],
|
||
|
const QwtPlotPrintFilter &pfilter) const
|
||
15 years ago
|
{
|
||
|
const QwtPlotItemList& itmList = itemList();
|
||
|
for ( QwtPlotItemIterator it = itmList.begin();
|
||
14 years ago
|
it != itmList.end(); ++it ) {
|
||
15 years ago
|
QwtPlotItem *item = *it;
|
||
14 years ago
|
if ( item && item->isVisible() ) {
|
||
15 years ago
|
if ( !(pfilter.options() & QwtPlotPrintFilter::PrintGrid)
|
||
14 years ago
|
&& item->rtti() == QwtPlotItem::Rtti_PlotGrid ) {
|
||
15 years ago
|
continue;
|
||
|
}
|
||
|
|
||
|
painter->save();
|
||
|
|
||
|
#if QT_VERSION >= 0x040000
|
||
|
painter->setRenderHint(QPainter::Antialiasing,
|
||
14 years ago
|
item->testRenderHint(QwtPlotItem::RenderAntialiased) );
|
||
15 years ago
|
#endif
|
||
|
|
||
14 years ago
|
item->draw(painter,
|
||
|
map[item->xAxis()], map[item->yAxis()],
|
||
|
rect);
|
||
15 years ago
|
|
||
|
painter->restore();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\param axisId Axis
|
||
|
\return Map for the axis on the canvas. With this map pixel coordinates can
|
||
|
translated to plot coordinates and vice versa.
|
||
|
\sa QwtScaleMap, transform(), invTransform()
|
||
14 years ago
|
|
||
15 years ago
|
*/
|
||
|
QwtScaleMap QwtPlot::canvasMap(int axisId) const
|
||
|
{
|
||
|
QwtScaleMap map;
|
||
|
if ( !d_data->canvas )
|
||
|
return map;
|
||
|
|
||
|
map.setTransformation(axisScaleEngine(axisId)->transformation());
|
||
|
|
||
|
const QwtScaleDiv *sd = axisScaleDiv(axisId);
|
||
|
map.setScaleInterval(sd->lBound(), sd->hBound());
|
||
|
|
||
14 years ago
|
if ( axisEnabled(axisId) ) {
|
||
15 years ago
|
const QwtScaleWidget *s = axisWidget(axisId);
|
||
14 years ago
|
if ( axisId == yLeft || axisId == yRight ) {
|
||
15 years ago
|
int y = s->y() + s->startBorderDist() - d_data->canvas->y();
|
||
|
int h = s->height() - s->startBorderDist() - s->endBorderDist();
|
||
|
map.setPaintInterval(y + h, y);
|
||
14 years ago
|
} else {
|
||
15 years ago
|
int x = s->x() + s->startBorderDist() - d_data->canvas->x();
|
||
|
int w = s->width() - s->startBorderDist() - s->endBorderDist();
|
||
|
map.setPaintInterval(x, x + w);
|
||
|
}
|
||
14 years ago
|
} else {
|
||
15 years ago
|
const int margin = plotLayout()->canvasMargin(axisId);
|
||
|
|
||
|
const QRect &canvasRect = d_data->canvas->contentsRect();
|
||
14 years ago
|
if ( axisId == yLeft || axisId == yRight ) {
|
||
|
map.setPaintInterval(canvasRect.bottom() - margin,
|
||
|
canvasRect.top() + margin);
|
||
|
} else {
|
||
|
map.setPaintInterval(canvasRect.left() + margin,
|
||
|
canvasRect.right() - margin);
|
||
15 years ago
|
}
|
||
|
}
|
||
|
return map;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
Change the margin of the plot. The margin is the space
|
||
|
around all components.
|
||
|
|
||
|
\param margin new margin
|
||
|
\sa QwtPlotLayout::setMargin(), margin(), plotLayout()
|
||
|
*/
|
||
|
void QwtPlot::setMargin(int margin)
|
||
|
{
|
||
|
if ( margin < 0 )
|
||
|
margin = 0;
|
||
|
|
||
14 years ago
|
if ( margin != d_data->layout->margin() ) {
|
||
15 years ago
|
d_data->layout->setMargin(margin);
|
||
|
updateLayout();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\return margin
|
||
|
\sa setMargin(), QwtPlotLayout::margin(), plotLayout()
|
||
|
*/
|
||
|
int QwtPlot::margin() const
|
||
|
{
|
||
|
return d_data->layout->margin();
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Change the background of the plotting area
|
||
14 years ago
|
|
||
|
Sets c to QColorGroup::Background of all colorgroups of
|
||
15 years ago
|
the palette of the canvas. Using canvas()->setPalette()
|
||
|
is a more powerful way to set these colors.
|
||
|
\param c new background color
|
||
|
*/
|
||
|
void QwtPlot::setCanvasBackground(const QColor &c)
|
||
|
{
|
||
|
QPalette p = d_data->canvas->palette();
|
||
|
|
||
14 years ago
|
for ( int i = 0; i < QPalette::NColorGroups; i++ ) {
|
||
15 years ago
|
#if QT_VERSION < 0x040000
|
||
|
p.setColor((QPalette::ColorGroup)i, QColorGroup::Background, c);
|
||
|
#else
|
||
|
p.setColor((QPalette::ColorGroup)i, QPalette::Background, c);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
canvas()->setPalette(p);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
Nothing else than: canvas()->palette().color(
|
||
|
QPalette::Normal, QColorGroup::Background);
|
||
14 years ago
|
|
||
15 years ago
|
\return the background color of the plotting area.
|
||
|
*/
|
||
|
const QColor & QwtPlot::canvasBackground() const
|
||
|
{
|
||
|
#if QT_VERSION < 0x040000
|
||
|
return canvas()->palette().color(
|
||
14 years ago
|
QPalette::Normal, QColorGroup::Background);
|
||
15 years ago
|
#else
|
||
|
return canvas()->palette().color(
|
||
14 years ago
|
QPalette::Normal, QPalette::Background);
|
||
15 years ago
|
#endif
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Change the border width of the plotting area
|
||
14 years ago
|
Nothing else than canvas()->setLineWidth(w),
|
||
15 years ago
|
left for compatibility only.
|
||
|
\param w new border width
|
||
|
*/
|
||
|
void QwtPlot::setCanvasLineWidth(int w)
|
||
|
{
|
||
|
canvas()->setLineWidth(w);
|
||
|
updateLayout();
|
||
|
}
|
||
14 years ago
|
|
||
|
/*!
|
||
|
Nothing else than: canvas()->lineWidth(),
|
||
15 years ago
|
left for compatibility only.
|
||
|
\return the border width of the plotting area
|
||
|
*/
|
||
|
int QwtPlot::canvasLineWidth() const
|
||
14 years ago
|
{
|
||
15 years ago
|
return canvas()->lineWidth();
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\return \c true if the specified axis exists, otherwise \c false
|
||
|
\param axisId axis index
|
||
|
*/
|
||
|
bool QwtPlot::axisValid(int axisId)
|
||
|
{
|
||
|
return ((axisId >= QwtPlot::yLeft) && (axisId < QwtPlot::axisCnt));
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
Called internally when the legend has been clicked on.
|
||
|
Emits a legendClicked() signal.
|
||
|
*/
|
||
|
void QwtPlot::legendItemClicked()
|
||
|
{
|
||
14 years ago
|
if ( d_data->legend && sender()->isWidgetType() ) {
|
||
|
QwtPlotItem *plotItem =
|
||
15 years ago
|
(QwtPlotItem*)d_data->legend->find((QWidget *)sender());
|
||
|
if ( plotItem )
|
||
|
emit legendClicked(plotItem);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
Called internally when the legend has been checked
|
||
|
Emits a legendClicked() signal.
|
||
|
*/
|
||
|
void QwtPlot::legendItemChecked(bool on)
|
||
|
{
|
||
14 years ago
|
if ( d_data->legend && sender()->isWidgetType() ) {
|
||
|
QwtPlotItem *plotItem =
|
||
15 years ago
|
(QwtPlotItem*)d_data->legend->find((QWidget *)sender());
|
||
|
if ( plotItem )
|
||
|
emit legendChecked(plotItem, on);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//! Remove all curves and markers
|
||
|
void QwtPlot::clear()
|
||
|
{
|
||
|
detachItems(QwtPlotItem::Rtti_PlotCurve);
|
||
|
detachItems(QwtPlotItem::Rtti_PlotMarker);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Insert a legend
|
||
|
|
||
|
If the position legend is \c QwtPlot::LeftLegend or \c QwtPlot::RightLegend
|
||
14 years ago
|
the legend will be organized in one column from top to down.
|
||
|
Otherwise the legend items will be placed in a table
|
||
15 years ago
|
with a best fit number of columns from left to right.
|
||
|
|
||
14 years ago
|
If pos != QwtPlot::ExternalLegend the plot widget will become
|
||
|
parent of the legend. It will be deleted when the plot is deleted,
|
||
15 years ago
|
or another legend is set with insertLegend().
|
||
14 years ago
|
|
||
15 years ago
|
\param legend Legend
|
||
|
\param pos The legend's position. For top/left position the number
|
||
|
of colums will be limited to 1, otherwise it will be set to
|
||
14 years ago
|
unlimited.
|
||
15 years ago
|
|
||
|
\param ratio Ratio between legend and the bounding rect
|
||
|
of title, canvas and axes. The legend will be shrinked
|
||
|
if it would need more space than the given ratio.
|
||
|
The ratio is limited to ]0.0 .. 1.0]. In case of <= 0.0
|
||
|
it will be reset to the default ratio.
|
||
|
The default vertical/horizontal ratio is 0.33/0.5.
|
||
|
|
||
14 years ago
|
\sa legend(), QwtPlotLayout::legendPosition(),
|
||
15 years ago
|
QwtPlotLayout::setLegendPosition()
|
||
|
*/
|
||
14 years ago
|
void QwtPlot::insertLegend(QwtLegend *legend,
|
||
|
QwtPlot::LegendPosition pos, double ratio)
|
||
15 years ago
|
{
|
||
|
d_data->layout->setLegendPosition(pos, ratio);
|
||
|
|
||
14 years ago
|
if ( legend != d_data->legend ) {
|
||
15 years ago
|
if ( d_data->legend && d_data->legend->parent() == this )
|
||
|
delete d_data->legend;
|
||
|
|
||
|
d_data->legend = legend;
|
||
|
|
||
14 years ago
|
if ( d_data->legend ) {
|
||
|
if ( pos != ExternalLegend ) {
|
||
|
if ( d_data->legend->parent() != this ) {
|
||
15 years ago
|
#if QT_VERSION < 0x040000
|
||
|
d_data->legend->reparent(this, QPoint(0, 0));
|
||
|
#else
|
||
|
d_data->legend->setParent(this);
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const QwtPlotItemList& itmList = itemList();
|
||
|
for ( QwtPlotItemIterator it = itmList.begin();
|
||
14 years ago
|
it != itmList.end(); ++it ) {
|
||
15 years ago
|
(*it)->updateLegend(d_data->legend);
|
||
|
}
|
||
|
|
||
|
QLayout *l = d_data->legend->contentsWidget()->layout();
|
||
14 years ago
|
if ( l && l->inherits("QwtDynGridLayout") ) {
|
||
15 years ago
|
QwtDynGridLayout *tl = (QwtDynGridLayout *)l;
|
||
14 years ago
|
switch(d_data->layout->legendPosition()) {
|
||
|
case LeftLegend:
|
||
|
case RightLegend:
|
||
|
tl->setMaxCols(1); // 1 column: align vertical
|
||
|
break;
|
||
|
case TopLegend:
|
||
|
case BottomLegend:
|
||
|
tl->setMaxCols(0); // unlimited
|
||
|
break;
|
||
|
case ExternalLegend:
|
||
|
break;
|
||
15 years ago
|
}
|
||
|
}
|
||
|
}
|
||
|
updateTabOrder();
|
||
|
}
|
||
|
|
||
|
updateLayout();
|
||
|
}
|