Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QChartView/QChart custom Zoom In/Out
QtWS25 Last Chance

QChartView/QChart custom Zoom In/Out

Scheduled Pinned Locked Moved Unsolved General and Desktop
qchartqchartviewzoomingzoomqcharts
4 Posts 2 Posters 418 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    Joe von Habsburg
    wrote on 25 Nov 2024, 06:17 last edited by
    #1

    hello, i created a custom QChartView class and i want to perform zoom in/out operations on it. unfortunately i didn't get the result i wanted. when i do the zoom operation, it zooms according to the center of the chart. what i want is to apply the zoom operation according to the mouse position. how can i do this?


    Chart::Chart(QGraphicsItem *parent, Qt::WindowFlags wFlags) : QChart(parent, wFlags)
    {
        qDebug() << "Chart::Chart()";
        legend()->hide();
        setMargins(QMargins(1,1,1,1));
    }
    
    Chart::~Chart()
    {
        qDebug() << "Chart::~Chart()";
    }
    
    

    ChartView::ChartView(QWidget *parent) : QChartView(parent)
    {
        qDebug() << "ChartView::ChartView()";
        setMouseTracking(true);
        setDragMode(QGraphicsView::ScrollHandDrag);
        setStyleSheet("background-color:white");
    }
    
    ChartView::~ChartView()
    {
        qDebug() << "ChartView::~ChartView()";
    }
    
    void ChartView::wheelEvent(QWheelEvent *event)
    {
        qDebug() << "ChartView::wheelEvent";
    
        if (event->angleDelta().y() > 0) {
            chart()->zoom(1.05); // Zoom In
        } else {
            chart()->zoom(1 / 1.05); // Zoom Out
        }
    
        event->accept();
    }
    
    J 1 Reply Last reply 25 Nov 2024, 10:20
    0
    • J Joe von Habsburg
      25 Nov 2024, 06:17

      hello, i created a custom QChartView class and i want to perform zoom in/out operations on it. unfortunately i didn't get the result i wanted. when i do the zoom operation, it zooms according to the center of the chart. what i want is to apply the zoom operation according to the mouse position. how can i do this?


      Chart::Chart(QGraphicsItem *parent, Qt::WindowFlags wFlags) : QChart(parent, wFlags)
      {
          qDebug() << "Chart::Chart()";
          legend()->hide();
          setMargins(QMargins(1,1,1,1));
      }
      
      Chart::~Chart()
      {
          qDebug() << "Chart::~Chart()";
      }
      
      

      ChartView::ChartView(QWidget *parent) : QChartView(parent)
      {
          qDebug() << "ChartView::ChartView()";
          setMouseTracking(true);
          setDragMode(QGraphicsView::ScrollHandDrag);
          setStyleSheet("background-color:white");
      }
      
      ChartView::~ChartView()
      {
          qDebug() << "ChartView::~ChartView()";
      }
      
      void ChartView::wheelEvent(QWheelEvent *event)
      {
          qDebug() << "ChartView::wheelEvent";
      
          if (event->angleDelta().y() > 0) {
              chart()->zoom(1.05); // Zoom In
          } else {
              chart()->zoom(1 / 1.05); // Zoom Out
          }
      
          event->accept();
      }
      
      J Online
      J Online
      JonB
      wrote on 25 Nov 2024, 10:20 last edited by JonB
      #2

      @Joe-von-Habsburg
      I don't know about QChartView but I presume it behaves the same as QGraphicsView. And for that you need to use setTransformationAnchor(AnchorUnderMouse) prior to scale().

      FWIW, I paste the code I am using in some code of mine.

      /*virtual*/ void BaizeView::wheelEvent(QWheelEvent *event) /*override*/
      {
          // Do a wheel-based zoom about the cursor position
          // (Adapted from https://stackoverflow.com/questions/19113532/qgraphicsview-zooming-in-and-out-under-mouse-position-using-mouse-wheel)
          event->accept();
      
          int zoomBy = event->angleDelta().y() / 120;
          qreal currentZoom = transform().m11();
          qreal factor;
          if (zoomBy > 0 && currentZoom < 3.0)
              factor = 1.1;
          else if (zoomBy < 0 && currentZoom > 0.333)
              factor = 1.0 / 1.1;
          else
              return;
      
          if (false)
          {
              // moves scroll position to odd place
              const ViewportAnchor anchor = transformationAnchor();
              setTransformationAnchor(AnchorUnderMouse);
              scale(factor, factor);
              setTransformationAnchor(anchor);
          }
          else
          {
              // seems to get it right
              auto targetViewportPos = event->position();
              auto targetScenePos = mapToScene(event->position().toPoint());
              scale(factor, factor);
              centerOn(targetScenePos);
              QPointF deltaViewportPos = targetViewportPos - QPointF(viewport()->width() / 2.0, viewport()->height() / 2.0);
              QPointF viewportCenter = mapFromScene(targetScenePos) - deltaViewportPos;
              centerOn(mapToScene(viewportCenter.toPoint()));
          }
          emit viewCoordinatesChanged();
      }
      

      It may be a bit different from what you want, I am maintaining a scroll position on my QGraphicsView which may not apply to you. So you should try the if (false) route first.

      For QChartView I note the following very old post: https://interest.qt-project.narkive.com/5wgzvCSD/handling-zooming-in-qtcharts. That confirms:

      Because QChart is derived from QGraphicsView, you can also set the
      setTransformationAnchor() to
      QGraphicsView::AnchorUnderMouse and then scale() it.

      But if that is not right the OP there ended up saying:

      I was able to find a way to zoom centred on the mouse. What I did was
      make use of the QChart::plotArea() function. With that function by
      using ChartView::wheelEvent(), I could get where in the chart the zoom
      is happening. I then did some math and set the new zoom for the chart
      by adjusting the range for the chart's x and y axis.

      J 1 Reply Last reply 25 Nov 2024, 11:14
      0
      • J JonB
        25 Nov 2024, 10:20

        @Joe-von-Habsburg
        I don't know about QChartView but I presume it behaves the same as QGraphicsView. And for that you need to use setTransformationAnchor(AnchorUnderMouse) prior to scale().

        FWIW, I paste the code I am using in some code of mine.

        /*virtual*/ void BaizeView::wheelEvent(QWheelEvent *event) /*override*/
        {
            // Do a wheel-based zoom about the cursor position
            // (Adapted from https://stackoverflow.com/questions/19113532/qgraphicsview-zooming-in-and-out-under-mouse-position-using-mouse-wheel)
            event->accept();
        
            int zoomBy = event->angleDelta().y() / 120;
            qreal currentZoom = transform().m11();
            qreal factor;
            if (zoomBy > 0 && currentZoom < 3.0)
                factor = 1.1;
            else if (zoomBy < 0 && currentZoom > 0.333)
                factor = 1.0 / 1.1;
            else
                return;
        
            if (false)
            {
                // moves scroll position to odd place
                const ViewportAnchor anchor = transformationAnchor();
                setTransformationAnchor(AnchorUnderMouse);
                scale(factor, factor);
                setTransformationAnchor(anchor);
            }
            else
            {
                // seems to get it right
                auto targetViewportPos = event->position();
                auto targetScenePos = mapToScene(event->position().toPoint());
                scale(factor, factor);
                centerOn(targetScenePos);
                QPointF deltaViewportPos = targetViewportPos - QPointF(viewport()->width() / 2.0, viewport()->height() / 2.0);
                QPointF viewportCenter = mapFromScene(targetScenePos) - deltaViewportPos;
                centerOn(mapToScene(viewportCenter.toPoint()));
            }
            emit viewCoordinatesChanged();
        }
        

        It may be a bit different from what you want, I am maintaining a scroll position on my QGraphicsView which may not apply to you. So you should try the if (false) route first.

        For QChartView I note the following very old post: https://interest.qt-project.narkive.com/5wgzvCSD/handling-zooming-in-qtcharts. That confirms:

        Because QChart is derived from QGraphicsView, you can also set the
        setTransformationAnchor() to
        QGraphicsView::AnchorUnderMouse and then scale() it.

        But if that is not right the OP there ended up saying:

        I was able to find a way to zoom centred on the mouse. What I did was
        make use of the QChart::plotArea() function. With that function by
        using ChartView::wheelEvent(), I could get where in the chart the zoom
        is happening. I then did some math and set the new zoom for the chart
        by adjusting the range for the chart's x and y axis.

        J Offline
        J Offline
        Joe von Habsburg
        wrote on 25 Nov 2024, 11:14 last edited by Joe von Habsburg
        #3

        @JonB said in QChartView/QChart custom Zoom In/Out:

        For QChartView I note the following very old post: https://interest.qt-project.narkive.com/5wgzvCSD/handling-zooming-in-qtcharts. That confirms:

        there is a problem here as there is with me.


        @JonB said in QChartView/QChart custom Zoom In/Out:

        I don't know about QChartView but I presume it behaves the same as QGraphicsView.

        Is it possible to draw lineseries without using qchart and qchartview? if possible, how can it be done?


        @JonB said in QChartView/QChart custom Zoom In/Out:

        FWIW, I paste the code I am using in some code of mine.

        I added to my code. here it behaves like a picture. shouldn't the axes be fixed?

        Zoom Out
        8994bb21-53fb-4d83-bbc7-f3550c14d924-Screenshot from 2024-11-25 14-18-42.png

        Zoom In
        a3aae68c-7680-4e51-99f7-48e0e1f8b992-image.png

        J 1 Reply Last reply 25 Nov 2024, 12:35
        0
        • J Joe von Habsburg
          25 Nov 2024, 11:14

          @JonB said in QChartView/QChart custom Zoom In/Out:

          For QChartView I note the following very old post: https://interest.qt-project.narkive.com/5wgzvCSD/handling-zooming-in-qtcharts. That confirms:

          there is a problem here as there is with me.


          @JonB said in QChartView/QChart custom Zoom In/Out:

          I don't know about QChartView but I presume it behaves the same as QGraphicsView.

          Is it possible to draw lineseries without using qchart and qchartview? if possible, how can it be done?


          @JonB said in QChartView/QChart custom Zoom In/Out:

          FWIW, I paste the code I am using in some code of mine.

          I added to my code. here it behaves like a picture. shouldn't the axes be fixed?

          Zoom Out
          8994bb21-53fb-4d83-bbc7-f3550c14d924-Screenshot from 2024-11-25 14-18-42.png

          Zoom In
          a3aae68c-7680-4e51-99f7-48e0e1f8b992-image.png

          J Online
          J Online
          JonB
          wrote on 25 Nov 2024, 12:35 last edited by
          #4

          @Joe-von-Habsburg
          Yes you can draw lines on a QGraphicsScene, I never suggested you not use a QChart (or equivalent, QChart is not considered wonderful and it is being replaced by QtGraphs, for all I know that may be better here) for drawing charts, there is a reason that is its own component.

          Since I don't know anything about QCharts and zooming I would not know about axes and what the consequences might be. I only know what I wrote and the links I referred you to, which may have alternative approaches.

          1 Reply Last reply
          0

          1/4

          25 Nov 2024, 06:17

          • Login

          • Login or register to search.
          1 out of 4
          • First post
            1/4
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved