QChart如何获取放大时显示的点
QChart how to get points that are displayed while zoomed in
QChart 包含一些系列。
是否可以在图表放大时检索图表上当前可见的点列表?
表示得到实际显示点数中的list/vector点。
从 Kuba 答案中消化和简化:
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/Whosebugn/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();
}
有关映射本身,请参阅 。
QChart 包含一些系列。
是否可以在图表放大时检索图表上当前可见的点列表?
表示得到实际显示点数中的list/vector点。
从 Kuba 答案中消化和简化:
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/Whosebugn/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();
}
有关映射本身,请参阅