Thanks for all your help, Uwe. I was able to resolve it with your suggestions.
graph2.JPG
What I did was:
1. extend QwtPlot class to store reference to external scale widget
2. overload canvasMap function to use external scale widget to calculate mapping.
{
protected:
public:
MyQwtPlot
(QWidget *parent
= NULL) : QwtPlot(parent
), m_pXAxis
(NULL), m_pYAxis
(NULL) {
enableAxis
(QwtPlot::xBottom,
false);
}
};
{
if ( cv == NULL )
return map;
if ( axisId
== QwtPlot::xBottom && m_pXAxis
!= NULL ) {
map.setTransformation(axisScaleEngine(axisId)->transformation());
map.setScaleInterval(sd.lowerBound(), sd.upperBound());
int x = axisWidget(axisId)->x() + m_pXAxis->startBorderDist() - cv->x();
int w = m_pXAxis->width() - m_pXAxis->startBorderDist() - m_pXAxis->endBorderDist();
map.setPaintInterval(x, x + w);
} else if ( axisId
== QwtPlot::yLeft && m_pYAxis
!= NULL ) {
map.setTransformation(axisScaleEngine(axisId)->transformation());
map.setScaleInterval(sd.lowerBound(), sd.upperBound());
int y = m_pYAxis->startBorderDist() - cv->y();
int h = m_pYAxis->height() - m_pYAxis->startBorderDist() - m_pYAxis->endBorderDist();
map.setPaintInterval(y + h, y);
} else
return map;
}
class MyQwtPlot : public QwtPlot
{
protected:
QwtScaleWidget *m_pXAxis;
QwtScaleWidget *m_pYAxis;
public:
MyQwtPlot (QWidget *parent = NULL) :
QwtPlot(parent), m_pXAxis(NULL), m_pYAxis(NULL)
{
enableAxis(QwtPlot::xBottom, false);
enableAxis(QwtPlot::yLeft, false);
}
virtual QwtScaleMap canvasMap (int axisId) const;
void SetExternalScaleWidget(int axisId, QwtScaleWidget *scaleWidget);
};
QwtScaleMap MyQwtPlot::canvasMap (int axisId) const
{
QwtScaleMap map;
const QwtPlotCanvas *cv = canvas();
if ( cv == NULL )
return map;
if ( axisId == QwtPlot::xBottom && m_pXAxis != NULL )
{
map.setTransformation(axisScaleEngine(axisId)->transformation());
QwtScaleDiv sd = m_pXAxis->scaleDraw()->scaleDiv();
map.setScaleInterval(sd.lowerBound(), sd.upperBound());
int x = axisWidget(axisId)->x() + m_pXAxis->startBorderDist() - cv->x();
int w = m_pXAxis->width() - m_pXAxis->startBorderDist() - m_pXAxis->endBorderDist();
map.setPaintInterval(x, x + w);
} else if ( axisId == QwtPlot::yLeft && m_pYAxis != NULL )
{
map.setTransformation(axisScaleEngine(axisId)->transformation());
QwtScaleDiv sd = m_pYAxis->scaleDraw()->scaleDiv();
map.setScaleInterval(sd.lowerBound(), sd.upperBound());
int y = m_pYAxis->startBorderDist() - cv->y();
int h = m_pYAxis->height() - m_pYAxis->startBorderDist() - m_pYAxis->endBorderDist();
map.setPaintInterval(y + h, y);
} else
return QwtPlot::canvasMap(axisId);
return map;
}
To copy to clipboard, switch view to plain text mode
3. extend QwtPlotGrid class to remove updateScaleDiv function
{
public:
// take out auto update, use setXDiv, setYDiv to update divider tick
};
class MyPlotGrid : public QwtPlotGrid
{
public:
GalilPlotGrid() : QwtPlotGrid() {}
// take out auto update, use setXDiv, setYDiv to update divider tick
virtual void updateScaleDiv(const QwtScaleDiv &xMap, const QwtScaleDiv &yMap) {}
};
To copy to clipboard, switch view to plain text mode
4. have SyncScale slot connect to scaleDivChanged
connect(m_pLowerPlot
->axisWidget
(QwtPlot::xBottom),
SIGNAL(scaleDivChanged
()),
this,
SLOT(SyncScale
()));
connect(m_pTopPlot
->axisWidget
(QwtPlot::xBottom),
SIGNAL(scaleDivChanged
()),
this,
SLOT(SyncScale
()));
connect(m_pLowerPlot
->axisWidget
(QwtPlot::yLeft),
SIGNAL(scaleDivChanged
()),
this,
SLOT(SyncScale
()));
connect(m_pTopPlot
->axisWidget
(QwtPlot::yLeft),
SIGNAL(scaleDivChanged
()),
this,
SLOT(SyncScale
()));
void MyWidget::SyncScale ()
{
int start, end;
m_pXAxis
->setScaleDiv
(m_pPlotMag
->axisScaleEngine
(QwtPlot::xBottom)->transformation
(),
m_pTopPlot
->axisScaleDraw
(QwtPlot::xBottom)->scaleDiv
());
m_pXAxis->getBorderDistHint(start, end);
m_pXAxis->setBorderDist(start, end);
div = m_pXAxis->scaleDraw()->scaleDiv();
m_pTopPlot->setXDiv(div);
m_pLowerPlot->setXDiv(div);
m_pYTop
->setScaleDiv
(m_pTopPlot
->axisScaleEngine
(QwtPlot::yLeft)->transformation
(),
m_pTopPlot
->axisScaleDraw
(QwtPlot::yLeft)->scaleDiv
());
m_pYTop->getBorderDistHint(start, end);
m_pYTop->setBorderDist(start, end);
div = m_pYTop->scaleDraw()->scaleDiv();
m_pGridTop->setYDiv(div);
m_pYLower
->setScaleDiv
(m_pLowerPlot
->axisScaleEngine
(QwtPlot::yLeft)->transformation
(),
m_pLowerPlot
->axisScaleDraw
(QwtPlot::yLeft)->scaleDiv
());
m_pYLower->getBorderDistHint(start, end);
m_pYLower->setBorderDist(start, end);
div = m_pYLower->scaleDraw()->scaleDiv();
m_pGridLower->setYDiv(div);
}
connect(m_pLowerPlot->axisWidget(QwtPlot::xBottom), SIGNAL(scaleDivChanged()), this, SLOT(SyncScale()));
connect(m_pTopPlot->axisWidget(QwtPlot::xBottom), SIGNAL(scaleDivChanged()), this, SLOT(SyncScale()));
connect(m_pLowerPlot->axisWidget(QwtPlot::yLeft), SIGNAL(scaleDivChanged()), this, SLOT(SyncScale()));
connect(m_pTopPlot->axisWidget(QwtPlot::yLeft), SIGNAL(scaleDivChanged()), this, SLOT(SyncScale()));
void MyWidget::SyncScale ()
{
int start, end;
QwtScaleDiv div;
m_pXAxis->setScaleDiv(m_pPlotMag->axisScaleEngine(QwtPlot::xBottom)->transformation(),
m_pTopPlot->axisScaleDraw(QwtPlot::xBottom)->scaleDiv());
m_pXAxis->getBorderDistHint(start, end);
m_pXAxis->setBorderDist(start, end);
div = m_pXAxis->scaleDraw()->scaleDiv();
m_pTopPlot->setXDiv(div);
m_pLowerPlot->setXDiv(div);
m_pYTop->setScaleDiv(m_pTopPlot->axisScaleEngine(QwtPlot::yLeft)->transformation(),
m_pTopPlot->axisScaleDraw(QwtPlot::yLeft)->scaleDiv());
m_pYTop->getBorderDistHint(start, end);
m_pYTop->setBorderDist(start, end);
div = m_pYTop->scaleDraw()->scaleDiv();
m_pGridTop->setYDiv(div);
m_pYLower->setScaleDiv(m_pLowerPlot->axisScaleEngine(QwtPlot::yLeft)->transformation(),
m_pLowerPlot->axisScaleDraw(QwtPlot::yLeft)->scaleDiv());
m_pYLower->getBorderDistHint(start, end);
m_pYLower->setBorderDist(start, end);
div = m_pYLower->scaleDraw()->scaleDiv();
m_pGridLower->setYDiv(div);
}
To copy to clipboard, switch view to plain text mode
Thx again
Bookmarks