Are you able to offset a secondary y-axis in ChartJS, by a decimal value, whilst keeping the same scale for both y-axes?

๐Ÿ‘:1

Solution below after much fiddling. offset in the getTickArray() function specifies the left-hand axis value that coincides with 0 on the right hand axis. I think the afterBuildTicks and beforeUpdate keys then allow you to position ticks with more precision (I think).

https://jsfiddle.net/zjxukf57/47/

    function getRandomDataset(lowerBound, upperBound, count) {
        let output = [];
      
      for (let index = 0; index < count; index++) {
        let newPoint = Math.floor((Math.random() * upperBound) + lowerBound);
        output.push(newPoint);
        }
        
      return output;
    }
    
    function arrayMin(arr) {
      var len = arr.length, min = Infinity;
      while (len--) {
        if (arr[len] < min) {
          min = arr[len];
        }
      }
      return min;
    }
    
    function arrayMax(arr) {
      var len = arr.length, max = -Infinity;
      while (len--) {
        if (arr[len] > max) {
          max = arr[len];
        }
      }
      return max;
    }
    
    function getTickArray(offset, increment, leftData, rightData) {
        let ticksLeft = [];
      let ticksRight = [];
      
      let leftMin = arrayMin(leftData);
      let leftMax = arrayMax(leftData);
      let rightMin = arrayMin(rightData);
      let rightMax = arrayMax(rightData);
      
      let tick = leftMin;
      let tickRight = tick - offset;
      let wholeTick = Math.ceil(tick); // ? Gets first left-hand integer above minimum tick value
      let wholeTickRight = Math.ceil(tickRight); // ? Gets first right-hand integer above minimum tick value
      let maxValue = leftMax > rightMax + offset ? leftMax : rightMax + offset;
      
      // ? Push minimum decimal ticks
      ticksLeft.push(tick);
      ticksRight.push(tickRight);
      
      while (wholeTick < maxValue) {
        ticksLeft.push(wholeTick);
        ticksRight.push(wholeTickRight);
        
        wholeTick = wholeTick + 1*increment;
        wholeTickRight = wholeTickRight + 1*increment;
      }
      
      // ? Push minimum decimal ticks
      ticksLeft.push(maxValue);
      ticksRight.push(maxValue - offset);
      
        return [ ticksLeft, ticksRight ];
    }
    
    
    let datasetOne = getRandomDataset(8, 15, 10); // ? Ten random numbers between 8 and 15
    let datasetTwo = getRandomDataset(0, 7, 10); // ? Ten random numbers between 0 and 7
    
    var ticks = getTickArray(11.76, 2, datasetOne, datasetTwo);
    console.log(ticks)
    
    var ticks1 = ticks[0];
    var ticks2 = ticks[1];
    
    console.log(datasetOne);
    console.log(datasetTwo);
    
    // ? Chart Config
    var ctx = document.getElementById("myChart");
    var myChart = new Chart(ctx, {
      type: 'line',
      data: {
        labels: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
        datasets: [{
          data: datasetOne,
          yAxisID: 'A',
          label: "left",
          borderColor: "#FF0000",
          backgroundColor: 'rgba(0, 0, 0, 0)'
        },
        {
          data: datasetTwo,
          yAxisID: 'B',
          label: "right",
          borderColor: "#348632",
          backgroundColor: 'rgba(0, 0, 0, 0)'
        }]
      },
      options: {
        scales: {
          yAxes: [{
            id: 'A',
            ticks: {
              autoSkip: false,
              min: ticks1[ticks1.length - 1],
              max: ticks1[0]
            },
            afterBuildTicks: function(scale) {
              scale.ticks = ticks1;
              return;
            },
            beforeUpdate: function(oScale) {
              return;
            },
            gridLines: {
                       color: "#FF0000"
                    }
          },
          {
            id: 'B',
            ticks: {
              autoSkip: false,
              min: ticks2[ticks2.length - 1],
              max: ticks2[0],
              callback: function(value, index, values) {
                            return value;
                        }
            },
            afterBuildTicks: function(scale) {
              scale.ticks = ticks2;
              return;
            },
            beforeUpdate: function(oScale) {
              return;
            },
            position: "right",
            gridLines: {
                       color: "#348632"
                    }
          }]
        }
      }
    });

Leave a comment