Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Append negative CategoryAxis Labels
Forum Updated to NodeBB v4.3 + New Features

Append negative CategoryAxis Labels

Scheduled Pinned Locked Moved Solved QML and Qt Quick
6 Posts 2 Posters 792 Views 1 Watching
  • 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.
  • Z Offline
    Z Offline
    zansara
    wrote on last edited by zansara
    #1

    Hello everyone,

    I am trying to use a CategoryAxis to implement a sliding grid chart (this one). So far I got it to slide to the left, but I cannot make it sliding to the right for the simple reason that, according to the CategoryAxis documentation, I can only append new labels on top of the highest, but neither below the lowest one, nor in between existing ones. I tested if that behavior holds in the actual QML code, and indeed I cannot add any label whose value is smaller than the highest: the method fails silently.

    Did I overlook something? Is there any solution for this? I found nothing on the internet with regard to this issue.

    I attach a very simple QML showing the issue.

    import QtQuick 2.9
    import QtQuick.Layouts 1.0
    import QtQuick.Controls 2.0
    import QtCharts 2.1
    
    ApplicationWindow {
        visible: true
        width: 640
        height: 480
        title: "Append CategoryAxis Labels"
    
    
        ColumnLayout {
            anchors.rightMargin: 20
            anchors.leftMargin: 20
            anchors.bottomMargin: 20
            anchors.topMargin: 20
            anchors.fill: parent
    
            ChartView {
                id: chartView
                width: 631
                height: 400
                Layout.fillHeight: true
                Layout.fillWidth: true
                title: "Sliding Grid"
                antialiasing: true
                legend {
                    alignment: Qt.AlignBottom
                }
    
                CategoryAxis {
                    id: xAxis
                    min: 0
                    max: 10
    
                    labelsPosition: CategoryAxis.AxisLabelsPositionOnValue;
                }
    
                ValueAxis {
                    id: yAxis
                    min: 0
                    max: 10
    
                    tickCount: 5
                    minorTickCount: 5
                }
    
                LineSeries {
                    axisX: xAxis
                    axisY: yAxis
                    XYPoint { x: 0; y: 0 }
                    XYPoint { x: 1.5; y: 2.1 }
                    XYPoint { x: 3; y: 3.3 }
                    XYPoint { x: 4.5; y: 2.1 }
                    XYPoint { x: 6; y: 6.9 }
                    XYPoint { x: 7.5; y: 3.0 }
                    XYPoint { x: 9; y: 3.3 }
                    XYPoint { x: 10; y: 2.3 }
                }
    
            }
    
            RowLayout {
                id: rowLayout
                width: 100
                height: 100
    
                Button {
                    text: "Add this label to xAxis"
                    onClicked: xAxis.append( newLabel.text, newLabel.text);
                }
    
                TextField {
                    id: newLabel
                }
    
            }
    
        }
    }
    
    
    DiracsbracketD 1 Reply Last reply
    0
    • Z zansara

      Hello everyone,

      I am trying to use a CategoryAxis to implement a sliding grid chart (this one). So far I got it to slide to the left, but I cannot make it sliding to the right for the simple reason that, according to the CategoryAxis documentation, I can only append new labels on top of the highest, but neither below the lowest one, nor in between existing ones. I tested if that behavior holds in the actual QML code, and indeed I cannot add any label whose value is smaller than the highest: the method fails silently.

      Did I overlook something? Is there any solution for this? I found nothing on the internet with regard to this issue.

      I attach a very simple QML showing the issue.

      import QtQuick 2.9
      import QtQuick.Layouts 1.0
      import QtQuick.Controls 2.0
      import QtCharts 2.1
      
      ApplicationWindow {
          visible: true
          width: 640
          height: 480
          title: "Append CategoryAxis Labels"
      
      
          ColumnLayout {
              anchors.rightMargin: 20
              anchors.leftMargin: 20
              anchors.bottomMargin: 20
              anchors.topMargin: 20
              anchors.fill: parent
      
              ChartView {
                  id: chartView
                  width: 631
                  height: 400
                  Layout.fillHeight: true
                  Layout.fillWidth: true
                  title: "Sliding Grid"
                  antialiasing: true
                  legend {
                      alignment: Qt.AlignBottom
                  }
      
                  CategoryAxis {
                      id: xAxis
                      min: 0
                      max: 10
      
                      labelsPosition: CategoryAxis.AxisLabelsPositionOnValue;
                  }
      
                  ValueAxis {
                      id: yAxis
                      min: 0
                      max: 10
      
                      tickCount: 5
                      minorTickCount: 5
                  }
      
                  LineSeries {
                      axisX: xAxis
                      axisY: yAxis
                      XYPoint { x: 0; y: 0 }
                      XYPoint { x: 1.5; y: 2.1 }
                      XYPoint { x: 3; y: 3.3 }
                      XYPoint { x: 4.5; y: 2.1 }
                      XYPoint { x: 6; y: 6.9 }
                      XYPoint { x: 7.5; y: 3.0 }
                      XYPoint { x: 9; y: 3.3 }
                      XYPoint { x: 10; y: 2.3 }
                  }
      
              }
      
              RowLayout {
                  id: rowLayout
                  width: 100
                  height: 100
      
                  Button {
                      text: "Add this label to xAxis"
                      onClicked: xAxis.append( newLabel.text, newLabel.text);
                  }
      
                  TextField {
                      id: newLabel
                  }
      
              }
      
          }
      }
      
      
      DiracsbracketD Offline
      DiracsbracketD Offline
      Diracsbracket
      wrote on last edited by Diracsbracket
      #2

      @zansara
      A brute-force solution to your problem, but which still satisfies your stringent requirement of exclusively QML ( at most some JS )

      The following lets you add labels in arbitrary order:

                  Button {
                      text: "Add this label to xAxis"
      
                      property variant vals: []
      
                      onClicked: {
                          vals.push(parseFloat(newLabel.text))//or unshift, or...
                          vals.sort() //better: insert to array such that no sorting is needed...
      
                          //Remove all labels
                          var labels = xAxis.categoriesLabels
                          for (var i=xAxis.count-1; i>=0; --i){
                              xAxis.remove(labels[i])
                          }
      
                          //Add labels
                          for (i=0; i<vals.length; ++i){
                              xAxis.append(vals[i].toString(), vals[i]);
                          }
      
                          xAxis.min = vals[0]
                          xAxis.max = vals[vals.length-1]
                      }
                  }
      
      Z 2 Replies Last reply
      0
      • DiracsbracketD Diracsbracket

        @zansara
        A brute-force solution to your problem, but which still satisfies your stringent requirement of exclusively QML ( at most some JS )

        The following lets you add labels in arbitrary order:

                    Button {
                        text: "Add this label to xAxis"
        
                        property variant vals: []
        
                        onClicked: {
                            vals.push(parseFloat(newLabel.text))//or unshift, or...
                            vals.sort() //better: insert to array such that no sorting is needed...
        
                            //Remove all labels
                            var labels = xAxis.categoriesLabels
                            for (var i=xAxis.count-1; i>=0; --i){
                                xAxis.remove(labels[i])
                            }
        
                            //Add labels
                            for (i=0; i<vals.length; ++i){
                                xAxis.append(vals[i].toString(), vals[i]);
                            }
        
                            xAxis.min = vals[0]
                            xAxis.max = vals[vals.length-1]
                        }
                    }
        
        Z Offline
        Z Offline
        zansara
        wrote on last edited by
        #3

        @Diracsbracket
        Thanks for your reply. I tested your code by replacing the button into my above snippet and it works fine, even if I must admit it looks expensive if the labels are many and the data flows fast. However, given the API of CategoryAxis for QML, this is probably the only way to go.

        You specified that this is the only way to respect my requirements. Out of curiosity, are there other solutions you might suggest?

        Many thanks!

        DiracsbracketD 1 Reply Last reply
        0
        • DiracsbracketD Diracsbracket

          @zansara
          A brute-force solution to your problem, but which still satisfies your stringent requirement of exclusively QML ( at most some JS )

          The following lets you add labels in arbitrary order:

                      Button {
                          text: "Add this label to xAxis"
          
                          property variant vals: []
          
                          onClicked: {
                              vals.push(parseFloat(newLabel.text))//or unshift, or...
                              vals.sort() //better: insert to array such that no sorting is needed...
          
                              //Remove all labels
                              var labels = xAxis.categoriesLabels
                              for (var i=xAxis.count-1; i>=0; --i){
                                  xAxis.remove(labels[i])
                              }
          
                              //Add labels
                              for (i=0; i<vals.length; ++i){
                                  xAxis.append(vals[i].toString(), vals[i]);
                              }
          
                              xAxis.min = vals[0]
                              xAxis.max = vals[vals.length-1]
                          }
                      }
          
          Z Offline
          Z Offline
          zansara
          wrote on last edited by zansara
          #4

          @Diracsbracket
          In the meantime I have also found a possible trick to solve my issue: it was enough to set the xAxis reverse property to true. Then I mirror all the x values of the LineSeries to be positive and I prepend a minus sign to the categories labels, so that they "seems" to be growing in the negative direction. However, it really feels like I'm hacking this component a bit. I think CategoryAxis should allow inserting new categories in any position.

          I attach the code of the reverse solution:

          import QtQuick 2.9
          import QtQuick.Layouts 1.0
          import QtQuick.Controls 2.0
          import QtCharts 2.1
          
          ApplicationWindow {
              id: root
              visible: true
              width: 640
              height: 480
          
              property int numpoints: 628;
              property double step: 0.01;
          
              Timer {
                  id: timer;
                  interval: 1;
                  repeat: true;
                  onTriggered: {
                      draw( xAxis, yAxis, lineSeries, lineSeries.at(0).y );
                      if( xAxis.max - (-xAxis.categoriesLabels[xAxis.categoriesLabels.length -1]) > 1 ){  // --> Watch out for negatives
                          xAxis.append(("-"+xAxis.max.toFixed(0)), xAxis.max); 
                          xAxis.remove(xAxis.categoriesLabels[0]);
                      }
                  }
              }
          
              function draw(xax, yax, lineSeries, dataPoint){
                  lineSeries.remove(0);
                  xax.min = xax.min + step;
                  xax.max = xax.max + step;
          
                  var x = lineSeries.at(lineSeries.count-1).x + step ;
                  lineSeries.append( x, dataPoint );
                  if(dataPoint > yax.max){
                      yax.max = dataPoint +1;
                  } else if(dataPoint < yax.min){
                      yax.min = dataPoint -1;
                  }
              }
          
          
              ColumnLayout {
                  anchors.rightMargin: 20
                  anchors.leftMargin: 20
                  anchors.bottomMargin: 20
                  anchors.topMargin: 20
                  anchors.fill: parent
          
                  ChartView {
                      id: chartView
                      width: 631
                      height: 400
                      Layout.fillHeight: true
                      Layout.fillWidth: true
                      title: "Sliding Grid"
                      antialiasing: true
                      legend {
                          alignment: Qt.AlignBottom
                      }
          
                      CategoryAxis {
                          id: xAxis
                          reverse: true // ----> This is the important property!
                          min: 0
                          max: numpoints * step + (numpoints*step)/6;
          
                          labelsPosition: CategoryAxis.AxisLabelsPositionOnValue;
                          Component.onCompleted: {
                              for(var i=0; i<max+1; i++){
                                  xAxis.append( ("-"+i), i );
                              }
                          }
                      }
          
                      ValueAxis {
                          id: yAxis
                          min: 0
                          max: 10
          
                          tickCount: 5
                          minorTickCount: 5
                      }
          
                      LineSeries {
                          id: lineSeries
                          name: "Line Series"
                          axisX: xAxis
                          axisY: yAxis
          
                          Component.onCompleted: {
                              for (var i = 0; i < numpoints; i++) {
                                  lineSeries.append(i*step, Math.sin(i*step) * 3 + 5);
                              }
                              timer.start();
                          }
                      }
                  }
              }
          }
          
          1 Reply Last reply
          1
          • Z zansara

            @Diracsbracket
            Thanks for your reply. I tested your code by replacing the button into my above snippet and it works fine, even if I must admit it looks expensive if the labels are many and the data flows fast. However, given the API of CategoryAxis for QML, this is probably the only way to go.

            You specified that this is the only way to respect my requirements. Out of curiosity, are there other solutions you might suggest?

            Many thanks!

            DiracsbracketD Offline
            DiracsbracketD Offline
            Diracsbracket
            wrote on last edited by Diracsbracket
            #5

            @zansara said in Append negative CategoryAxis Labels:

            Out of curiosity, are there other solutions you might suggest

            Well, you mentioned it already in that other post of yours, which you reference above, i.e. go the C++ way and using e.g. a library like QCustomPlot which is completely customizable/hackable since it only consists of a single CPP file and a single h file. Then, you could try and import it in your QML app. Most QML types are defined in C++ after all...

            it was enough to set the xAxis reverse property to true

            Nice one!

            Z 1 Reply Last reply
            0
            • DiracsbracketD Diracsbracket

              @zansara said in Append negative CategoryAxis Labels:

              Out of curiosity, are there other solutions you might suggest

              Well, you mentioned it already in that other post of yours, which you reference above, i.e. go the C++ way and using e.g. a library like QCustomPlot which is completely customizable/hackable since it only consists of a single CPP file and a single h file. Then, you could try and import it in your QML app. Most QML types are defined in C++ after all...

              it was enough to set the xAxis reverse property to true

              Nice one!

              Z Offline
              Z Offline
              zansara
              wrote on last edited by
              #6

              @Diracsbracket said in Append negative CategoryAxis Labels:

              Well, you mentioned it already in that other post of yours, which you reference above, i.e. go the C++ way and using e.g. a library like QCustomPlot which is completely customizable/hackable since it only consists of a single CPP file and a single h file. Then, you could try and import it in your QML app.

              I think I will try this way as well. QtCharts feels very counter-intuitive even for the most basic operations... Thanks again!

              1 Reply Last reply
              0

              • Login

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