Updating a Chart when appending to a Line Series.
-
Currently what I am doing is this:
// // Given the number of X values, choose a suitable interval for X axis tick marks // int size = static_cast<int>(files.size()); qreal interval{ 10'000.0 }; if (size <= 20) interval = 1.0; else if (size <= 100) interval = 5.0; else if (size <= 200) interval = 10.0; else if (size <= 1'000) interval = 50.0; else if (size <= 2'000) interval = 100.0; else if (size <= 10'000) interval = 500.0; else if (size <= 20'000) interval = 1'000.0; QHash<QXYSeries::PointConfiguration, QVariant> conf; conf[QXYSeries::PointConfiguration::Color] = QColor(Qt::green); conf[QXYSeries::PointConfiguration::Size] = 4; // // Add the score and update the score chart // if (nullptr != scoreSeries) scoreChart->removeSeries(scoreSeries); else { scoreSeries = new QLineSeries(this); scoreSeries->setName(tr("Score", "IDC_SCORE")); scoreSeries->setPointsVisible(true); connect(scoreSeries, &QLineSeries::hovered, this, &ChartTab::scoreHovered); } scoreSeries->append(x, fScore); scoreSeries->setPointConfiguration(static_cast<int>(x) - 1, conf); scoreChart->addSeries(scoreSeries); scoreChart->createDefaultAxes(); axes = scoreChart->axes(Qt::Horizontal); for (const auto& p : axes) { QValueAxis* axis{ dynamic_cast<QValueAxis*>(p) }; if (axis) { axis->setRange(1.0, size); axis->setTickAnchor(1.0); axis->setTickType(QValueAxis::TicksDynamic); axis->setTickInterval(interval); } }
It doesn't feel right that I should need to remove the series and then re-add it when appending a new point to the series. Is that actually necessary?
-
Hi @Perdrix, you can keep the series object and use QXYSeries::replace, which is mostly intended for that, for updating the points of your series.
From the doc
Note: This is much faster than replacing data points one by one, or first clearing all data, and then appending the new data. ...
-
@Gojir4 I don't think that addressed my primary issue.
The only way I have (so far) managed to get a Chart to refresh when adding a new point is to remove the current line series (without deleting it), append the new point to the series, and re-add the line series.
I have a similar issue if, after adding a point to the series I want to change its configuration using e.g.:
series->setPointConfiguration(i, conf);
as AFAICT that doesn't prod the chart to update itself.
My immediate feeling is that QChart needs a member function to tell it to update itself because the underlying data has changed.
My apologies if there is already such a call, it didn't jump out at me!!!
David
-
@Perdrix said in Updating a Chart when appending to a Line Series.:
The only way I have (so far) managed to get a Chart to refresh when adding a new point is to remove the current line series (without deleting it), append the new point to the series, and re-add the line series.
I have not used
QChart
s(!), but that would sound very surprising. You would not be able to e.g. append new points over time and have the chart display them, which does not sound right.I note that, for example,
QXYSeries
has signals void QXYSeries::pointReplaced(int index) or void QXYSeries::pointsReplaced() (and similarly for adding or removing points). (Note these are signals on the series, not on the whole chart.) One/I would have thought this would get used to cause the chart view to be refreshed? You might attach your own slots to some of these to check they are indeed being emitted. I presumeQChartView
is supposed to hook onto those signals itself.I have come across How to update/redraw QChart after data is added to QLineSeries?
Appending a value to QLineSeries using the operator << or the append method should repaint the graph. If it does not happen form some reason, you could trying calling the repaint method on the QChartView.
and
void QWidget::repaint() Repaints the widget directly by calling paintEvent() immediately, unless updates are disabled or the widget is hidden. We suggest only using repaint() if you need an immediate repaint, for example during animation. In almost all circumstances update() is better, as it permits Qt to optimize for speed and minimize flicker.
Also read Qt Chart is not updated after updating the series in this forum, where the OP says just as you do. And at the end the repsonder says:
ChartView should handle redraw and everything for you.
Finally I also encountered Updating QLineSeries in Chart doesnt work at all. A suggestion there is that it is a axes issue, do you use something like
createDefaultAxes()
? I think the "point" here [excuse the pun!] is that if the new point now lies outside of the current axes range it might be regarded as "off screen" and so need some extra work to get the axes rescaled to view.I cannot comment on
setPointConfiguration()
, that is a call introduced in Qt6.x so relatively new.P.S.
See also https://forum.qt.io/topic/145986/qchart-line-series-not-shown/3. -
-