draw ticks pointing inwards while labels stay outside the plot area
Hi there,
I would like to have (or rather my boss wants it) a QwtPlot where the ticks of the scales point inwards while the labels stay outside like normal. So for the left yAxis it would be (left to right): label backbone ticks.
If I use
the labels will end up inside the plot area (ie. backbone ticks labels).
I have been thinking about using
Code:
yLeft->attach(&plot);
yLeft->setPosition(-1);
and having basically two scales, but I dont understand how to "attach" it to the left border of the plotarea.
Thanks a lot
Simon
Re: draw ticks pointing inwards while labels stay outside the plot area
I've never done what you're asking, but i guess that it would be simpler to reimplement QwtScaleDraw::drawTick() and/or QwtScaleDraw::drawLabel() to do what you want.
Re: draw ticks pointing inwards while labels stay outside the plot area
I would do my own type of plot item for the ticks. Simply copy the code from QwtPlotGrid and modify the drawLines methods to draw ticks instead of grid lines. Then disable drawing of the ticks for the scales and set the margin between the backbone and the canvas to 0 ( see QwtScaleDraw ).
But before doing it I would explain your boss that this is against the architecture of QwtPlot ( scales and canvas are different widgets ) and ask if he really insists on hacks like this one.
Uwe
Re: draw ticks pointing inwards while labels stay outside the plot area
I implemented it by subclassing QwtScaleDraw and modifying drawLabel and drawBackbone. Works quite well. The inspiration came from qtiplot, which uses the same approach. There is some gap between the non-major ticks and the grid, but I guess thats just not avoidable due to Scale and Plot being different widgets.
Here is the relevant code:
Code:
void ScaleDraw
::drawTick(QPainter *painter,
double value,
int len
) const { if (m_tickDirection == outwards)
if ( len <= 0 )
return;
int pw2 = qMin((int)painter->pen().width(), len) / 2;
if ( !metricsMap.isIdentity() )
{
/*
The perfect position of the ticks is important.
To avoid rounding errors we have to use
device coordinates.
*/
pos = metricsMap.layoutToDevice(pos);
if ( orientation() == Qt::Vertical )
{
scaleMap.setPaintInterval(
metricsMap.layoutToDeviceY((int)scaleMap.p1()),
metricsMap.layoutToDeviceY((int)scaleMap.p2())
);
len = metricsMap.layoutToDeviceX(len);
}
else
{
scaleMap.setPaintInterval(
metricsMap.layoutToDeviceX((int)scaleMap.p1()),
metricsMap.layoutToDeviceX((int)scaleMap.p2())
);
len = metricsMap.layoutToDeviceY(len);
}
}
const int tval = scaleMap.transform(value);
switch(alignment())
{
case LeftScale:
{
QwtPainter::drawLine(painter, pos.
x() - pw2
- majTickLength
(), tval,
pos.x() + len - majTickLength(), tval);
break;
}
case RightScale:
{
QwtPainter::drawLine(painter, pos.
x() + pw2
+ majTickLength
(), tval,
pos.x() - len + majTickLength(), tval);
break;
}
case BottomScale:
{
QwtPainter::drawLine(painter, tval, pos.
y() + pw2
+ majTickLength
(),
tval, pos.y() - len + majTickLength());
break;
}
case TopScale:
{
QwtPainter::drawLine(painter, tval, pos.
y() - pw2
- majTickLength
(),
tval, pos.y() - majTickLength() + len);
break;
}
}
QwtPainter::setMetricsMap(metricsMap
);
// restore metrics map }
/*!
Draws the baseline of the scale
\param painter Painter
\sa drawTick(), drawLabel()
*/
void ScaleDraw
::drawBackbone(QPainter *painter
) const {
if (m_tickDirection == outwards)
const int bw2 = painter->pen().width() / 2;
const QPoint &pos
= this
->pos
();
const int len = length() - 1;
switch(alignment())
{
case LeftScale: {
double leftShift = majTickLength();
QwtPainter::drawLine(painter, pos.
x() - bw2
- leftShift,
pos.y(), pos.x() - bw2 - leftShift, pos.y() + len );
break;
}
case RightScale: {
double rightShift = majTickLength();
QwtPainter::drawLine(painter, pos.
x() + bw2
+ rightShift,
pos.y(), pos.x() + bw2 + rightShift, pos.y() + len);
break;
}
case TopScale: {
double upShift = majTickLength();
QwtPainter::drawLine(painter, pos.
x(), pos.
y() - bw2
- upShift,
pos.x() + len, pos.y() - bw2 - upShift);
break;
}
case BottomScale: {
double downShift = majTickLength();
QwtPainter::drawLine(painter, pos.
x(), pos.
y() + bw2
+ downShift,
pos.x() + len, pos.y() + bw2 + downShift);
break;
}
}
}
This is still based on Qwt 5.x, I'll do the upgrade soon.
So thanks for you help!