#include "qwt_plot.h"
class QwtPlotBarChart;
class LabelScaleDraw;
{
Q_OBJECT
public:
explicit Widget
(QWidget *parent
= 0);
private:
void setLabels(qreal step, const QList<QwtText> &labels, LabelScaleDraw &scaleDraw);
private slots:
void setData();
private:
QwtPlotBarChart *_barChart;
LabelScaleDraw *_scaleDraw;
};
#include "qwt_plot.h"
class QwtPlotBarChart;
class LabelScaleDraw;
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
bool eventFilter(QObject *watched, QEvent *ev);
private:
void setLabels(qreal step, const QList<QwtText> &labels, LabelScaleDraw &scaleDraw);
private slots:
void setData();
private:
QwtPlot *_plot;
QwtPlotBarChart *_barChart;
LabelScaleDraw *_scaleDraw;
};
To copy to clipboard, switch view to plain text mode
and
#include "widget.h"
#include "qwt_plot_barchart.h"
#include "qwt_plot_layout.h"
#include "qwt_scale_widget.h"
#include <QTimer>
#include <QResizeEvent>
#include <QVBoxLayout>
#include <QPushButton>
#include <QDebug>
{
public:
LabelScaleDraw(){}
{
const int index = qRound(value);
if (index % _sampleStep == 0)
return _labelTexts.value(index);
else
}
QList<QwtText> labelTexts() const
{
return _labelTexts;
}
void setLabelTexts(const QList<QwtText> &texts, int sampleStep = 1)
{
_labelTexts = texts;
_sampleStep = sampleStep > 1 ? sampleStep : 1;
invalidateCache();
}
private:
QList<QwtText> _labelTexts;
int _sampleStep = 1;
};
{
_plot
->axisWidget
(QwtPlot::xBottom)->installEventFilter
(this);
_plot->setAutoReplot(false);
_plot->plotLayout()->setAlignCanvasToScales(true);
_scaleDraw = new LabelScaleDraw();
_plot
->setAxisScaleDraw
(QwtPlot::xBottom, _scaleDraw
);
_barChart = new QwtPlotBarChart();
_barChart->attach(_plot);
vLayout->addWidget(_plot);
vLayout->addWidget(button);
setLayout(vLayout);
QTimer::singleShot(300,
this,
SLOT(setData
()));
// setData();
// connect(button, &QPushButton::clicked, this, &Widget::setData);
}
{
if (watched
== _plot
->axisWidget
(QwtPlot::xBottom) && ev
->type
() == QEvent::Resize) {
qreal scaleMajorInterval = xMap.transform(1) - xMap.transform(0);
setLabels(scaleMajorInterval, _scaleDraw->labelTexts(), *_scaleDraw);
_plot->replot();
}
return QWidget::eventFilter(watched, ev
);
}
void Widget::setLabels(qreal step, const QList<QwtText> &labels, LabelScaleDraw &scaleDraw)
{
if (labels.isEmpty())
return;
qDebug() << "------------" << step;
qreal maxLabelWidth = 0;
{
QSizeF textSize
= text.
textSize();
if (textSize.width() > maxLabelWidth)
maxLabelWidth = textSize.width();
}
if (maxLabelWidth > step * 1.5)
{
scaleDraw.setLabelRotation(-90);
scaleDraw.setLabelAlignment(Qt::AlignLeft);
}
else if (maxLabelWidth < step * 1.5 && maxLabelWidth > step * 0.9)
{
scaleDraw.setLabelRotation(-45);
scaleDraw.setLabelAlignment(Qt::AlignLeft);
}
else
{
scaleDraw.setLabelRotation(0);
scaleDraw.setLabelAlignment(Qt::AlignHCenter);
}
scaleDraw.setLabelTexts(labels);
}
void Widget::setData()
{
const int numSamples = 10;
QVector<double> series;
QList<double> ticks;
QList<QwtText> labels;
for (int i = 0; i < numSamples; ++i)
{
series << 2 + i * 3;
ticks << i;
}
//setSample
_barChart->setSamples(series);
//setScaleDiv
_plot
->setAxisScaleDiv
(QwtPlot::xBottom, xScaleDiv
);
//setLabels
qreal scaleMajorInterval = xMap.transform(1) - xMap.transform(0);
setLabels(scaleMajorInterval, labels, *_scaleDraw);
_plot->replot();
}
#include "widget.h"
#include "qwt_plot_barchart.h"
#include "qwt_plot_layout.h"
#include "qwt_scale_widget.h"
#include <QTimer>
#include <QResizeEvent>
#include <QVBoxLayout>
#include <QPushButton>
#include <QDebug>
class LabelScaleDraw: public QwtScaleDraw
{
public:
LabelScaleDraw(){}
QwtText label(double value) const
{
const int index = qRound(value);
if (index % _sampleStep == 0)
return _labelTexts.value(index);
else
return QwtText();
}
QList<QwtText> labelTexts() const
{
return _labelTexts;
}
void setLabelTexts(const QList<QwtText> &texts, int sampleStep = 1)
{
_labelTexts = texts;
_sampleStep = sampleStep > 1 ? sampleStep : 1;
invalidateCache();
}
private:
QList<QwtText> _labelTexts;
int _sampleStep = 1;
};
Widget::Widget(QWidget *parent) :
QWidget(parent)
{
_plot = new QwtPlot();
_plot->axisWidget(QwtPlot::xBottom)->installEventFilter(this);
_plot->setAutoReplot(false);
_plot->plotLayout()->setAlignCanvasToScales(true);
_scaleDraw = new LabelScaleDraw();
_plot->setAxisScaleDraw(QwtPlot::xBottom, _scaleDraw);
_barChart = new QwtPlotBarChart();
_barChart->attach(_plot);
QPushButton *button = new QPushButton("Push");
QVBoxLayout *vLayout = new QVBoxLayout();
vLayout->addWidget(_plot);
vLayout->addWidget(button);
setLayout(vLayout);
QTimer::singleShot(300, this, SLOT(setData()));
// setData();
// connect(button, &QPushButton::clicked, this, &Widget::setData);
}
bool Widget::eventFilter(QObject *watched, QEvent *ev)
{
if (watched == _plot->axisWidget(QwtPlot::xBottom) && ev->type() == QEvent::Resize)
{
QwtScaleMap xMap = _plot->canvasMap(QwtPlot::xBottom);
qreal scaleMajorInterval = xMap.transform(1) - xMap.transform(0);
setLabels(scaleMajorInterval, _scaleDraw->labelTexts(), *_scaleDraw);
_plot->replot();
}
return QWidget::eventFilter(watched, ev);
}
void Widget::setLabels(qreal step, const QList<QwtText> &labels, LabelScaleDraw &scaleDraw)
{
if (labels.isEmpty())
return;
qDebug() << "------------" << step;
qreal maxLabelWidth = 0;
for (const QwtText &text : labels)
{
QSizeF textSize = text.textSize();
if (textSize.width() > maxLabelWidth)
maxLabelWidth = textSize.width();
}
if (maxLabelWidth > step * 1.5)
{
scaleDraw.setLabelRotation(-90);
scaleDraw.setLabelAlignment(Qt::AlignLeft);
}
else if (maxLabelWidth < step * 1.5 && maxLabelWidth > step * 0.9)
{
scaleDraw.setLabelRotation(-45);
scaleDraw.setLabelAlignment(Qt::AlignLeft);
}
else
{
scaleDraw.setLabelRotation(0);
scaleDraw.setLabelAlignment(Qt::AlignHCenter);
}
scaleDraw.setLabelTexts(labels);
}
void Widget::setData()
{
const int numSamples = 10;
QVector<double> series;
QList<double> ticks;
QList<QwtText> labels;
for (int i = 0; i < numSamples; ++i)
{
series << 2 + i * 3;
ticks << i;
labels << QwtText("SteelBlue");
}
//setSample
_barChart->setSamples(series);
//setScaleDiv
QwtScaleDiv xScaleDiv(- 0.5, numSamples - 0.5);
xScaleDiv.setTicks(QwtScaleDiv::MajorTick, ticks);
_plot->setAxisScaleDiv(QwtPlot::xBottom, xScaleDiv);
//setLabels
QwtScaleMap xMap = _plot->canvasMap(QwtPlot::xBottom);
qreal scaleMajorInterval = xMap.transform(1) - xMap.transform(0);
setLabels(scaleMajorInterval, labels, *_scaleDraw);
_plot->replot();
}
To copy to clipboard, switch view to plain text mode
What it doesn't work before is I set auto plot to true, without the explicit
Bookmarks