Hi
I had a problem with my graph that the major x-axis is not drawn in the graph but the y-axis line is drawn (see attached image).
missingxaxis.jpg
I updated my Qwt version 5.2.3 to 6.1.6. At first the Plot Grid is missing also with the x and y -axis which was already solved in my previous post that the draw method must be overriden.
plotview.jpg
Commenting out the line of code to attach the PlotGrid removes the plot grid as well as the main y-axis.
m_plotGrid = new PlotGrid;
//m_plotGrid->attach(m_plot);
Below is the source codes that initializes the Graph elements (removed other non-related methods/implementations)
//PlotPanel.cpp
PlotPanel
::PlotPanel(PlotStyle plotStyle, RulerType rulerType,
QWidget *parent
) : m_plot(0),
m_plotBackground(0),
m_plotGrid(0),
m_plotRulerPanel(0)
{
setFixedSize(StyleInfo::PLOT_PANEL_WIDTH, StyleInfo::PLOT_PANEL_HEIGHT);
m_plot = new Plot(plotStyle, this);
m_plot->move(PLOT_HORIZONTAL_BORDER, PLOT_TOP_BORDER);
m_plotRulerPanel = new PlotRulerPanel(rulerType, this);
m_plotRulerPanel->move(PLOT_HORIZONTAL_BORDER, 0);
m_plotRulerPanel->setPlot(m_plot);
m_plotBackground = new PlotBackground;
m_plotBackground->attach(m_plot);
m_plotGrid = new PlotGrid;
m_plotGrid->attach(m_plot);
}
//PlotPanel.cpp
PlotPanel::PlotPanel(PlotStyle plotStyle, RulerType rulerType, QWidget *parent) :
QWidget(parent),
m_plot(0),
m_plotBackground(0),
m_plotGrid(0),
m_plotRulerPanel(0)
{
setFixedSize(StyleInfo::PLOT_PANEL_WIDTH, StyleInfo::PLOT_PANEL_HEIGHT);
m_plot = new Plot(plotStyle, this);
m_plot->move(PLOT_HORIZONTAL_BORDER, PLOT_TOP_BORDER);
m_plotRulerPanel = new PlotRulerPanel(rulerType, this);
m_plotRulerPanel->move(PLOT_HORIZONTAL_BORDER, 0);
m_plotRulerPanel->setPlot(m_plot);
m_plotBackground = new PlotBackground;
m_plotBackground->attach(m_plot);
m_plotGrid = new PlotGrid;
m_plotGrid->attach(m_plot);
}
To copy to clipboard, switch view to plain text mode
The PlotPanel class is the one that initializes other plot classes that is used by the class that displays the graph.
//Plot.cpp
Plot
::Plot(PlotStyle plotStyle,
QWidget *parent
) : m_xBottomScaleDraw(0),
m_xTopScaleDraw(0),
m_yLeftScaleDraw(0),
m_yRightScaleDraw(0)
{
setFixedSize(StyleInfo::PLOT_WIDTH, StyleInfo::PLOT_HEIGHT);
plotLayout()->setAlignCanvasToScales(true);
plotLayout()->setSpacing(0);
for (int i=0; i<QwtPlot::axisCnt; i++)
{
if (scaleWidget)
{
scaleWidget->setSpacing(0);
scaleWidget->setMargin(0);
scaleWidget->setMinBorderDist(0, 0);
{
color = StyleInfo::skinColor(StyleInfo::SKIN_COLOR_PLOT_ONE);
}
{
color = StyleInfo::skinColor(StyleInfo::SKIN_COLOR_PLOT_TWO);
}
else
{
color = StyleInfo::skinColor(StyleInfo::SKIN_COLOR_PLOT_THREE);
}
QPalette palette
= scaleWidget
->palette
();
palette.
setColor(QPalette::Text, color
);
palette.
setColor(QPalette::WindowText, color
);
scaleWidget->setPalette(palette);
}
QFont font
= StyleInfo
::font(StyleInfo
::FONT_SIZE_SMALL);
setAxisFont(i, font);
}
if (plotStyle == TIME_PLOT)
{
m_xBottomScaleDraw = new PlotTimeScaleDraw; // will be deleted by QwtPlot
}
else
{
m_xBottomScaleDraw = new PlotScaleDraw; // will be deleted by QwtPlot
}
m_xBottomScaleDraw->setSpacing(X_SPACING);
m_xBottomScaleDraw->setMinimumExtent(X_BOTTOM_EXTENT);
setAxisScaleDraw
(QwtPlot::xBottom, m_xBottomScaleDraw
);
m_xTopScaleDraw = new PlotScaleDraw; // will be deleted by QwtPlot
m_xTopScaleDraw->setSpacing(X_SPACING);
m_xTopScaleDraw->setMinimumExtent(X_TOP_EXTENT);
setAxisScaleDraw
(QwtPlot::xTop, m_xTopScaleDraw
);
m_yLeftScaleDraw = new PlotScaleDraw; // will be deleted by QwtPlot
m_yLeftScaleDraw->setSpacing(Y_SPACING);
m_yLeftScaleDraw->setMinimumExtent(Y_LEFT_EXTENT);
setAxisScaleDraw
(QwtPlot::yLeft, m_yLeftScaleDraw
);
m_yRightScaleDraw = new PlotScaleDraw; // will be deleted by QwtPlot
m_yRightScaleDraw->setSpacing(Y_SPACING);
m_yRightScaleDraw->setMinimumExtent(Y_RIGHT_EXTENT);
setAxisScaleDraw
(QwtPlot::yRight, m_yRightScaleDraw
);
for (int i=0; i<QwtPlot::axisCnt; i++)
{
axisScaleDraw
(i
)->setTickLength
(QwtScaleDiv::MinorTick, TICK_LENGTH
);
axisScaleDraw
(i
)->setTickLength
(QwtScaleDiv::MediumTick, TICK_LENGTH
);
axisScaleDraw
(i
)->setTickLength
(QwtScaleDiv::MajorTick, TICK_LENGTH
);
enableAxis(i);
}
setAxisMaxMajor
(QwtPlot::xBottom, MAX_MAJOR_TICKS
);
setAxisMaxMinor
(QwtPlot::xBottom, MAX_MINOR_TICKS
);
setAxisMaxMajor
(QwtPlot::xTop, MAX_MAJOR_TICKS
);
setAxisMaxMinor
(QwtPlot::xTop, MAX_MINOR_TICKS
);
setAxisMaxMajor
(QwtPlot::yLeft, MAX_MAJOR_TICKS
);
setAxisMaxMinor
(QwtPlot::yLeft, MAX_MINOR_TICKS
);
setAxisMaxMajor
(QwtPlot::yRight, MAX_MAJOR_TICKS
);
setAxisMaxMinor
(QwtPlot::yRight, MAX_MINOR_TICKS
);
}
Plot::~Plot()
{
}
void Plot::showAxis(Axis axis, bool show)
{
if (scaleDraw)
{
}
updateAxes();
}
int Plot::scaleWidth(Axis axis) const
{
if ((axis >
= 0) && (axis <
QwtPlot::axisCnt)) {
if (scaleWidget)
{
return scaleWidget->width();
}
}
return 0;
}
int Plot::scaleHeight(Axis axis) const
{
if ((axis >
= 0) && (axis <
QwtPlot::axisCnt)) {
if (scaleWidget)
{
return scaleWidget->height();
}
}
return 0;
}
//Plot.cpp
Plot::Plot(PlotStyle plotStyle, QWidget *parent) :
QwtPlot(parent),
m_xBottomScaleDraw(0),
m_xTopScaleDraw(0),
m_yLeftScaleDraw(0),
m_yRightScaleDraw(0)
{
setFixedSize(StyleInfo::PLOT_WIDTH, StyleInfo::PLOT_HEIGHT);
((QwtPlotCanvas*)canvas())->setFrameStyle(QFrame::Box | QFrame::Plain);
((QwtPlotCanvas*)canvas())->setLineWidth(0);
((QwtPlotCanvas*)canvas())->unsetCursor();
plotLayout()->setAlignCanvasToScales(true);
plotLayout()->setSpacing(0);
for (int i=0; i<QwtPlot::axisCnt; i++)
{
QwtScaleWidget *scaleWidget = axisWidget(i);
if (scaleWidget)
{
scaleWidget->setSpacing(0);
scaleWidget->setMargin(0);
scaleWidget->setMinBorderDist(0, 0);
QColor color;
if (i == QwtPlot::yLeft)
{
color = StyleInfo::skinColor(StyleInfo::SKIN_COLOR_PLOT_ONE);
}
else if (i == QwtPlot::yRight)
{
color = StyleInfo::skinColor(StyleInfo::SKIN_COLOR_PLOT_TWO);
}
else
{
color = StyleInfo::skinColor(StyleInfo::SKIN_COLOR_PLOT_THREE);
}
QPalette palette = scaleWidget->palette();
palette.setColor(QPalette::Text, color);
palette.setColor(QPalette::WindowText, color);
scaleWidget->setPalette(palette);
}
QFont font = StyleInfo::font(StyleInfo::FONT_SIZE_SMALL);
setAxisFont(i, font);
}
if (plotStyle == TIME_PLOT)
{
m_xBottomScaleDraw = new PlotTimeScaleDraw; // will be deleted by QwtPlot
}
else
{
m_xBottomScaleDraw = new PlotScaleDraw; // will be deleted by QwtPlot
}
m_xBottomScaleDraw->setSpacing(X_SPACING);
m_xBottomScaleDraw->setMinimumExtent(X_BOTTOM_EXTENT);
setAxisScaleDraw(QwtPlot::xBottom, m_xBottomScaleDraw);
m_xTopScaleDraw = new PlotScaleDraw; // will be deleted by QwtPlot
m_xTopScaleDraw->setSpacing(X_SPACING);
m_xTopScaleDraw->setMinimumExtent(X_TOP_EXTENT);
setAxisScaleDraw(QwtPlot::xTop, m_xTopScaleDraw);
m_yLeftScaleDraw = new PlotScaleDraw; // will be deleted by QwtPlot
m_yLeftScaleDraw->setSpacing(Y_SPACING);
m_yLeftScaleDraw->setMinimumExtent(Y_LEFT_EXTENT);
setAxisScaleDraw(QwtPlot::yLeft, m_yLeftScaleDraw);
m_yRightScaleDraw = new PlotScaleDraw; // will be deleted by QwtPlot
m_yRightScaleDraw->setSpacing(Y_SPACING);
m_yRightScaleDraw->setMinimumExtent(Y_RIGHT_EXTENT);
setAxisScaleDraw(QwtPlot::yRight, m_yRightScaleDraw);
for (int i=0; i<QwtPlot::axisCnt; i++)
{
axisScaleDraw(i)->setTickLength(QwtScaleDiv::MinorTick, TICK_LENGTH);
axisScaleDraw(i)->setTickLength(QwtScaleDiv::MediumTick, TICK_LENGTH);
axisScaleDraw(i)->setTickLength(QwtScaleDiv::MajorTick, TICK_LENGTH);
enableAxis(i);
}
setAxisMaxMajor(QwtPlot::xBottom, MAX_MAJOR_TICKS);
setAxisMaxMinor(QwtPlot::xBottom, MAX_MINOR_TICKS);
setAxisMaxMajor(QwtPlot::xTop, MAX_MAJOR_TICKS);
setAxisMaxMinor(QwtPlot::xTop, MAX_MINOR_TICKS);
setAxisMaxMajor(QwtPlot::yLeft, MAX_MAJOR_TICKS);
setAxisMaxMinor(QwtPlot::yLeft, MAX_MINOR_TICKS);
setAxisMaxMajor(QwtPlot::yRight, MAX_MAJOR_TICKS);
setAxisMaxMinor(QwtPlot::yRight, MAX_MINOR_TICKS);
showAxis(QwtPlot::xBottom, true);
showAxis(QwtPlot::xTop, false);
showAxis(QwtPlot::yLeft, true);
showAxis(QwtPlot::yRight, false);
}
Plot::~Plot()
{
}
void Plot::showAxis(Axis axis, bool show)
{
QwtScaleDraw *scaleDraw = axisScaleDraw(axis);
if (scaleDraw)
{
scaleDraw->enableComponent(QwtScaleDraw::Backbone, false);
scaleDraw->enableComponent(QwtScaleDraw::Labels, show);
scaleDraw->enableComponent(QwtScaleDraw::Ticks, show);
}
updateAxes();
}
int Plot::scaleWidth(Axis axis) const
{
if ((axis >= 0) && (axis < QwtPlot::axisCnt))
{
const QwtScaleWidget *scaleWidget = axisWidget(axis);
if (scaleWidget)
{
return scaleWidget->width();
}
}
return 0;
}
int Plot::scaleHeight(Axis axis) const
{
if ((axis >= 0) && (axis < QwtPlot::axisCnt))
{
const QwtScaleWidget *scaleWidget = axisWidget(axis);
if (scaleWidget)
{
return scaleWidget->height();
}
}
return 0;
}
To copy to clipboard, switch view to plain text mode
PlotGrid::PlotGrid() :
{
}
{
Q_ASSERT(painter);
painter->save();
painter->setOpacity(0.2);
painter
->setPen
(QPen(StyleInfo
::skinColor(StyleInfo
::SKIN_COLOR_PLOT_THREE)));
drawLines(painter, rect, Qt::Vertical, xMap,
painter
->setPen
(QPen(StyleInfo
::skinColor(StyleInfo
::SKIN_COLOR_PLOT_ONE)));
drawLines(painter, rect, Qt::Horizontal, yMap,
painter->setOpacity(1.0);
// paint scale backbones
painter->setPen(StyleInfo::skinColor(StyleInfo::SKIN_COLOR_PLOT_ONE));
painter->drawLine((int)rect.left(), (int)rect.top(), (int)rect.left(), (int)rect.bottom());
painter->setPen(StyleInfo::skinColor(StyleInfo::SKIN_COLOR_PLOT_THREE));
painter->drawLine((int)rect.left(), (int)rect.bottom(), (int)rect.right(), (int)rect.bottom());
painter->restore();
}
{
m_xScaleDiv = xScaleDiv;
m_yScaleDiv = yScaleDiv;
}
void PlotGrid::update(void)
{
// todo: is there a better way to force an update??
{
if (plotCanvas)
{
plotCanvas->invalidateBackingStore();
plotCanvas->update();
}
}
}
Qt
::Orientation orientation,
const QwtScaleMap &scaleMap,
const QList<double> &values) const
{
Q_ASSERT(painter);
const int x1 = (int)rect.left();
const int x2 = (int)rect.right();
const int y1 = (int)rect.top();
const int y2 = (int)rect.bottom();
for (uint i = 0; i < (uint)values.count(); i++)
{
const int value = qRound(scaleMap.transform(values[i]));
if (orientation == Qt::Horizontal)
{
if ((value >= y1) && (value <= y2))
{
painter->drawLine(x1, value, x2, value);
}
}
else
{
if ((value >= x1) && (value < x2)) // suppress last line on the right
{
painter->drawLine(value, y1, value, y2);
}
}
}
}
PlotGrid::PlotGrid() :
QwtPlotGrid()
{
}
void PlotGrid::draw(QPainter *painter, const QwtScaleMap &xMap,
const QwtScaleMap &yMap, const QRectF &rect) const
{
Q_ASSERT(painter);
painter->save();
painter->setOpacity(0.2);
painter->setPen(QPen(StyleInfo::skinColor(StyleInfo::SKIN_COLOR_PLOT_THREE)));
drawLines(painter, rect, Qt::Vertical, xMap,
m_xScaleDiv.ticks(QwtScaleDiv::MajorTick));
painter->setPen(QPen(StyleInfo::skinColor(StyleInfo::SKIN_COLOR_PLOT_ONE)));
drawLines(painter, rect, Qt::Horizontal, yMap,
m_yScaleDiv.ticks(QwtScaleDiv::MajorTick));
painter->setOpacity(1.0);
// paint scale backbones
painter->setPen(StyleInfo::skinColor(StyleInfo::SKIN_COLOR_PLOT_ONE));
painter->drawLine((int)rect.left(), (int)rect.top(), (int)rect.left(), (int)rect.bottom());
painter->setPen(StyleInfo::skinColor(StyleInfo::SKIN_COLOR_PLOT_THREE));
painter->drawLine((int)rect.left(), (int)rect.bottom(), (int)rect.right(), (int)rect.bottom());
painter->restore();
}
void PlotGrid::updateScaleDiv(const QwtScaleDiv &xScaleDiv, const QwtScaleDiv &yScaleDiv)
{
m_xScaleDiv = xScaleDiv;
m_yScaleDiv = yScaleDiv;
}
void PlotGrid::update(void)
{
// todo: is there a better way to force an update??
QwtPlot *qwtPlot = plot();
if (qwtPlot)
{
QwtPlotCanvas *plotCanvas = (QwtPlotCanvas*)qwtPlot->canvas();
if (plotCanvas)
{
plotCanvas->invalidateBackingStore();
plotCanvas->update();
}
}
}
void PlotGrid::drawLines(QPainter *painter, const QRectF &rect,
Qt::Orientation orientation, const QwtScaleMap &scaleMap,
const QList<double> &values) const
{
Q_ASSERT(painter);
const int x1 = (int)rect.left();
const int x2 = (int)rect.right();
const int y1 = (int)rect.top();
const int y2 = (int)rect.bottom();
for (uint i = 0; i < (uint)values.count(); i++)
{
const int value = qRound(scaleMap.transform(values[i]));
if (orientation == Qt::Horizontal)
{
if ((value >= y1) && (value <= y2))
{
painter->drawLine(x1, value, x2, value);
}
}
else
{
if ((value >= x1) && (value < x2)) // suppress last line on the right
{
painter->drawLine(value, y1, value, y2);
}
}
}
}
To copy to clipboard, switch view to plain text mode
The PlotGrid class displays the Plot grids as well as the x and y-axis. As you can see with qwt 6.1.6, I need to cast the qwtscalemap transform method to integer using qRound as a fix and also the QRectF value to int but I am not sure if there is a problem why the major x-axis is missing with these conversions but the y-axis is drawn okay.
Please let me know if the code I added is enough to determine why the x-axis is missing.
Regards,
olredi
Bookmarks