QChart содержит несколько серий.
Можно ли получить список точек, которые в настоящее время видны на диаграмме, когда диаграмма увеличена?
Означает получение списка / вектора точек фактически отображаемых точек.
Переварено и упрощено из ответа Кубы:
QList<QVector<QPointF>> XXX::getDisplayedPoints(QChart *chart)
{
QList<QVector<QPointF>> result;
foreach (QAbstractSeries * series, chart->series())
{
QVector<QPointF> vector;
auto inScene = chart->plotArea();
auto inChart = chart->mapFromScene(inScene);
auto inChartRect = inChart.boundingRect();
auto inItem1 = chart->mapToValue(inChartRect.topLeft(), series);
auto inItem2 = chart->mapToValue(inChartRect.bottomRight(), series);
QRectF rect = QRectF(inItem1, inItem2).normalized();
const QVector<QPointF> points = static_cast<QLineSeries*>(series)->pointsVector();
std::copy_if (points.begin(), points.end(), std::back_inserter(vector),
[rect](QPointF const &p) { return rect.contains(p); });
result.append(vector);
}
return result;
}
Может быть вызван из сигнала
connect(static_cast<QValueAxis *>(m_chart->axisX()), &QValueAxis::rangeChanged, this, &XXX::on_zoomUpdated);





Вам необходимо сопоставить координаты противоположных углов plotArea диаграммы с мировой системой координат отображаемого ряда, а затем выполнить итерацию ряда для извлечения точек, соответствующих этому прямоугольнику.
// https://github.com/KubaO/stackoverflown/tree/master/questionschart-visible-points-52777058
#include <QtCharts>
#include <algorithm>
#include <cmath>
auto seriesRect(QChart *chart, QAbstractSeries *series = nullptr) {
auto inScene = chart->plotArea();
auto inChart = chart->mapFromScene(inScene);
auto inChartRect = inChart.boundingRect();
auto inItem1 = chart->mapToValue(inChartRect.topLeft(), series);
auto inItem2 = chart->mapToValue(inChartRect.bottomRight(), series);
return QRectF(inItem1, inItem2).normalized();
}
auto pointsInRect(QXYSeries *series, const QRectF &rect) {
QVector<QPointF> result;
auto const points = series->pointsVector();
std::copy_if (points.begin(), points.end(), std::back_inserter(result),
[rect](auto &p) { return rect.contains(p); });
return result;
}
Остальная часть примера:
auto data() {
QVector<QPointF> result;
for (auto x = 0.; x < 10.; x += 0.1) result.append({x, exp(x)});
return result;
}
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QWidget ui;
QVBoxLayout layout(&ui);
QChartView view1, view2;
QLabel status;
layout.addWidget(&view1);
layout.addWidget(&view2);
layout.addWidget(&status);
layout.setMargin(4);
QLineSeries series;
series.replace(data());
auto *chart = view1.chart();
chart->addSeries(&series);
view1.setRubberBand(QChartView::RectangleRubberBand);
QLineSeries subSeries;
subSeries.setPointsVisible(true);
auto *subChart = view2.chart();
subChart->addSeries(&subSeries);
for (auto *chart : {view1.chart(), view2.chart()}) {
chart->legend()->hide();
chart->createDefaultAxes();
chart->layout()->setContentsMargins(0, 0, 0, 0);
}
auto update = [&] {
auto rect = seriesRect(chart, &series);
auto const points = pointsInRect(&series, rect);
status.setText(QStringLiteral("Visible Range: (%1,%2)-(%3,%4)")
.arg(rect.left())
.arg(rect.top())
.arg(rect.right())
.arg(rect.bottom()));
subSeries.replace(points);
subChart->axisX(&subSeries)->setRange(rect.left(), rect.right());
subChart->axisY(&subSeries)->setRange(rect.top(), rect.bottom());
};
QObject::connect(chart, &QChart::plotAreaChanged, update);
ui.setMinimumSize(400, 400);
ui.show();
return a.exec();
}
Для самого отображения см. этот ответ.
Использование сигнала изменения диапазона оси, похоже, решает эту проблему connect (static_cast <QValueAxis *> (m_chart-> axisX ()), & QValueAxis :: rangeChanged, this, & TimeChartForm :: on_zoomUpdated);
Это действительно работает, спасибо. Но QChart :: plotAreaChanged не всегда срабатывает, не знаю почему.