Implementing Individual Y-Axis Zoom on Multi-Axis QChart - Need Help with Axis Position
-
Hello everyone,
I'm currently working on a feature within a QChart that contains multiple Y axes. I intend to implement a functionality where I can zoom in on a specific Y axis that the mouse is hovering over. However, I'm encountering an issue where I'm unable to determine the exact position of the individual Y axes.
Since QAbstractAxis does not inherit from QGraphicsItem, I'm unable to use the pos() method to find its position. Additionally, because the axis labels are dynamic and can get truncated, it's not feasible to calculate the position based on the length of the longest label.
Any suggestions or guidance on how to obtain the precise location of a Y axis within a QChart with multiple Y axes would be incredibly helpful.
Thank you in advance for your guidance!
Qt version: 6.5.0
-
@akikaede said in Implementing Individual Y-Axis Zoom on Multi-Axis QChart - Need Help with Axis Position:
I intend to implement a functionality where I can zoom in on a specific Y axis that the mouse is hovering over. However, I'm encountering an issue where I'm unable to determine the exact position of the individual Y axes.
IMO you should zoom on the
QChart
/ data and just update the axis afterwards.
Can you show how your chart looks like?QAbstractAxis
is indeed a plainQObject
and includes no visual represenation.
How the axis is drawn is handled internally (if I'm not mistaken, byChartPresenter
) -
@Pl45m4
Thank you for responding to my query! To clarify my goal, I've put together a demo that illustrates what I'm aiming to achieve. Attached is a screenshot along with the main source code, which you can find below.In the demo, users have the option to add either a value axis or a category axis via a button. The functionality I’m striving for is to allow users to hover over any Y axis, which would then trigger a zoom on that specific axis. As of now, I am only able to detect the entire area to the left of the plotArea. And I cannot get the width of the Y axis too. What I need is to pinpoint whether the mouse is over a particular Y axis to appropriately adjust its range for the zoom effect.
Any further assistance on how to detect the mouse position relative to a specific Y axis would be immensely helpful.
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { setFixedSize(800, 600); QWidget *mainWidget = new QWidget(this); QVBoxLayout *mainLayout = new QVBoxLayout(this); mainWidget->setLayout(mainLayout); CustomChartView *chartView = new CustomChartView(mainWidget); m_chart = new QChart; QValueAxis *axisX = new QValueAxis(this); QValueAxis *axisY = new QValueAxis(this); m_chart->addAxis(axisX, Qt::AlignBottom); m_chart->addAxis(axisY, Qt::AlignLeft); axisX->setTickType(QValueAxis::TicksDynamic); axisY->setTickType(QValueAxis::TicksDynamic); axisX->setRange(0, 2); axisY->setRange(0, 2); axisX->setTickInterval(1); axisY->setTickInterval(1); axisY->setTruncateLabels(false); QLineSeries *series = new QLineSeries; series->append(0, 1); series->append(1, 2); series->attachAxis(axisX); series->attachAxis(axisY); m_chart->addSeries(series); chartView->setChart(m_chart); m_chart->legend()->hide(); axisX->setGridLineVisible(false); axisY->setGridLineVisible(false); m_chart->layout()->setContentsMargins(0, 0, 0, 0); m_chart->setMargins(QMargins(0, 0, 0, 0)); mainLayout->addWidget(chartView); QPushButton *addBtn = new QPushButton("Add Value Axis", this); connect(addBtn, &QPushButton::clicked, this, [this, series](){ QValueAxis *axisY = new QValueAxis; axisY->setRange(0, 2); m_chart->addAxis(axisY, Qt::AlignLeft); axisY->setTruncateLabels(false); series->attachAxis(axisY); }); QPushButton *addCateBtn = new QPushButton("Add Category Axis", this); connect(addCateBtn, &QPushButton::clicked, this, [this, series](){ QCategoryAxis *axis = new QCategoryAxis; axis->append("Cx2_RL_window", 0); axis->append("Cx1_Engine_Speed_1", 1); axis->append("Cx4_Crash_Power_3", 2); axis->setRange(-1, 2); m_chart->addAxis(axis, Qt::AlignLeft); axis->setTruncateLabels(false); series->attachAxis(axis); }); mainLayout->addWidget(addBtn); mainLayout->addWidget(addCateBtn); setCentralWidget(mainWidget); }
void CustomChartView::wheelEvent(QWheelEvent *pEvent) { double axisRatio = 0.1; auto axisX = qobject_cast<QValueAxis *>(chart()->axes(Qt::Horizontal).constFirst()); qreal minX = axisX->min(); qreal maxX = axisX->max(); if (!chart()->axes(Qt::Horizontal).empty()) { if (pEvent->angleDelta().y() > 0) { if ((1 - axisRatio) * (maxX - minX) > 0.0005) { updateAxisInterval(axisX, maxX - axisRatio * (maxX - minX) - minX - axisRatio * (maxX - minX)); axisX->setRange(minX + axisRatio * (maxX - minX), maxX - axisRatio * (maxX - minX)); } } else { qreal min = qMax(minX - axisRatio * (maxX - minX), 0.0); updateAxisInterval(axisX, maxX - axisRatio * (maxX - minX) - min); axisX->setRange(min, maxX + axisRatio * (maxX - minX)); } } auto axisY = qobject_cast<QValueAxis *>(chart()->axes(Qt::Vertical).constFirst()); qreal minY = axisY->min(); qreal maxY = axisY->max(); if (pEvent->angleDelta().y() > 0) { if ((1 - axisRatio) * (maxY - minY) > 0.0005) { updateAxisInterval(axisY, maxY - axisRatio * (maxY - minY) - minY - axisRatio * (maxY - minY)); axisY->setRange(minY + axisRatio * (maxY - minY), maxY - axisRatio * (maxY - minY)); } } else { updateAxisInterval(axisY, maxY + axisRatio * (maxY - minY) - minY + axisRatio * (maxY - minY)); axisY->setRange(minY - axisRatio * (maxY - minY), maxY + axisRatio * (maxY - minY)); } return; }
Looking forward to your valuable input!
-
@akikaede
It may mean that. The first thing to do is to try to understand how it achieves the drawing of these items. From that code you might be able to see how you could achieve your goal. It might require using internal calls which are not exposed, or you might see a way to get at what you need without them.We are not saying this is either desirable or easy, but it may be the only way. If you are lucky someone will tell you how you can do what you want, but if you are not getting a further response that may indicate nobody knows or it cannot be done, and you are on your own.
I will mention that by common consent Qt Charts is perhaps not the nicest piece of code. There are other third-party chart drawing offerings for Qt (e.g. I believe Qwt). They might allow what you seek, or they might be worse.