Reputation: 3796
I am using QtCharts.
I need both axes to be rescaled after appending values. The values I appended are not between 0 and 1 and also not from the year 1970.
Constructor code of my dialog looks like this:
m_series = new QLineSeries;
m_series->setName(name);
auto chart = new QChart;
chart->legend()->setVisible(false);
chart->addSeries(m_series);
m_axisX = new QDateTimeAxis;
//m_axisX->setFormat("HH:mm:ss");
m_axisX->setTitleText(tr("Zeitpunkt"));
chart->addAxis(m_axisX, Qt::AlignBottom);
m_series->attachAxis(m_axisX);
auto axisY = new QValueAxis;
axisY->setTitleText(unit);
chart->addAxis(axisY, Qt::AlignLeft);
m_series->attachAxis(axisY);
auto chartView = new QChartView(chart, this);
chartView->setRenderHint(QPainter::Antialiasing);
My MainWindow emits signals containg new values. Multiple opened chart dialogs are connected to that signal.
void ChartDialog::liveUpdate(const RealTimeMeasureRegisters ®isters)
{
auto result = ((®isters)->*m_methodPtr)();
m_series->append(registers.timestamp(), result);
}
Is there some easy way to tell QDateTimeAxis (in my case m_axisX
) to automatically adjust to the new values?
QDateTimeAxis::setRange() does not look good, because I need to set a minimum and maximum.
Upvotes: 9
Views: 13577
Reputation: 643
QLineSeries inherits from QXYSeries, which implements certain signals that you can exploit as follow :
connect(m_series, &QXYSeries::pointAdded,
this, &MyForm::autoScaleChart);
in your form or model, better define chart and series as members, so that you can acces them from a member method called autoScaleChart (no need for a slot in Qt5)
#include <QMainWindow>
#include <QtCharts/QtCharts>
#include <math>
...
class MyForm :: QMainWindow
{
Q_OBJECT
public:
....
private:
QLineSeries* _series;
QValueAxis* _xaxis;
QValueAxis* _yaxis;
QChart* _chart;
void MyForm::autoScaleChart()
{
const QVector<QPointF>& dataVector = _tempSeries.pointsVector();
double xMin = std::numeric_limits<double>::max();
double xMax = std::numeric_limits<double>::min();
double yMin = xMin;
double yMax = xMax;
for (auto p : dataVector)
{
xMin = qMin(xMin, p.x());
xMax = qMax(xMax, p.x());
yMin = qMin(yMin, p.y());
yMax = qMax(yMax, p.y());
}
double xMargin = (xMax-xMin)/10.0;
_xaxis.setRange(xMin-xMargin,xMax+xMargin);
double yMargin = (yMax-yMin)/10.0;
_yaxis.setRange(yMin-yMargin,yMax+yMargin);
}
}
You can adapt the algorithm for more comprehensive one or datetime axis.
Upvotes: 0
Reputation: 11
About the first parameter in m_series->append(). Use "qint64 QDateTime::toMSecsSincPoch()" is better.... like:
...
m_series->append(QDateTime::currentDateTime().toMSecsSincPoch(), result);
Upvotes: 0
Reputation: 279
I don't know about a way to adjust automatically but you could look at this example which add points to the chart dynamically : http://doc.qt.io/qt-5/qtcharts-dynamicspline-example.html
Although in this example the range has been limited when adding points so to go further it would require to re-adjust the range when the next point is out of it.
As you say the setRange requires a min and a max but you could update it in your liveUpdate.
Upvotes: 1