[Chartjs]-Chartjs with zoom plugin zooms too much with wheel just with single turn

2👍

This is because of your limits you set and the scroll speed.
In your limits you told the x to go to max 10 and you made the scroll speed 10 times the default. Setting this to the default and removing the verry aggresive limit on the x axis it works fine:

//data creation
let ChartDataArray = [];
let labels2 = [];
let data2 = []
i = 0
k = 0

let data3 = [];
data3 = data2;
let labels3 = [];
labels3 = labels2;
const colorset = ["red", "blue", "red"]
let backgroundColorArr = [];
let backgroundColorArr2 = [];



//data creation
while (k < 15000) {
  if (i <= 4999) {
    // let last_hall = 600
    // data2.push(last_hall)
    // labels2.push(k);
    // i++
    let time = Date.now() + k * 1000
    var date = new Date(time)
    ChartDataArray.push({
      x: date,
      y: 600
    });
    i++;
    backgroundColorArr.push(colorset[k % 3]);
  }

  if (i >= 5000) {

    let time = Date.now() + k * 1000
    var date = new Date(time)
    ChartDataArray.push({
      x: date,
      y: 450
    });
    i++;
    backgroundColorArr.push(colorset[k % 3]);
    if (i == 12000) {
      console.log("k: " + k)
      ChartDataArray.push({
        x: date,
        y: 450
      });
      ChartDataArray.push({
        x: date,
        y: 450
      });
      k += 2;
      console.log("k: " + k)
      for (let j = 0; j < 2000; j++) {
        //let last_hall = getRandomInt(800, 1300)
        // let last_hall = 1000
        // data2.push(last_hall)
        // labels2.push(k);
        let time = Date.now() + k * 1000
        var date = new Date(time)
        ChartDataArray.push({
          x: date,
          y: 1000
        });
        backgroundColorArr.push(colorset[k % 3]);
        k++
      }
      console.log("k: " + k)
      for (let j = 0; j < 800; j++) {

        let time = Date.now() + k * 1000
        var date = new Date(time)
        ChartDataArray.push({
          x: date,
          y: 1000 + j
        });
        backgroundColorArr.push(colorset[k % 3]);
        k++
      }
      for (let j = 0; j < 100; j++) {

        let time = Date.now() + k * 1000
        var date = new Date(time)
        ChartDataArray.push({
          x: date,
          y: 1000 - 2 * j
        });
        backgroundColorArr.push(colorset[k % 3]);
        k++
      }
      for (let j = 0; j < 100; j++) {

        let time = Date.now() + k * 1000
        var date = new Date(time)
        ChartDataArray.push({
          x: date,
          y: 1000 + j
        });
        backgroundColorArr.push(colorset[k % 3]);
        k++
      }
      console.log("k: " + k)
      i = 0
    }


  }

  k++
}



var ctx = document.getElementById('myChart2').getContext('2d');
var ctx2 = document.getElementById('myChart3').getContext('2d');


const up = (ctx, value) => ctx.p0.parsed.y >= ctx.p1.parsed.y ? value : undefined;
const down = (ctx, value) => ctx.p0.parsed.y < ctx.p1.parsed.y ? value : undefined;
const up2 = (ctx2, value) => ctx2.p0.parsed.y >= ctx2.p1.parsed.y ? value : undefined;
const down2 = (ctx2, value) => ctx2.p0.parsed.y < ctx2.p1.parsed.y ? value : undefined;




//Decimation

if (ChartDataArray.length > 1000) {
  var datastep = Math.ceil(ChartDataArray.length / 1000) //always show 1000 values from all data
  console.log(datastep);
  for (i = 0; i < 1000; i++) {
    let index = i * datastep
    ChartDataArray[i] = ChartDataArray[index];
    backgroundColorArr[i] = backgroundColorArr[index];
    //labels3[i] = labels3[i * datastep];

  }

}

ChartDataArray = ChartDataArray.slice(0, 937);
backgroundColorArr = backgroundColorArr.slice(0, 937);

for (let index = 0; index < ChartDataArray.length - 1; index++) {
  data2[index] = (ChartDataArray[index]["y"]);
}

var chartData = {
  datasets: [{
    label: "values",
    data: ChartDataArray,
    lineTension: 0.1,
    fill: true,
    //backgroundColor: backgroundColorArr[ctx.p0DataIndex],
    segment: {
      borderColor: ctx => backgroundColorArr[ctx.p0DataIndex], //up(ctx, 'rgba(75,192,192,1)') || down(ctx, "red"),
      backgroundColor: ctx => backgroundColorArr[ctx.p0DataIndex]

    },
  }]
};

let chart3 = new Chart(ctx, {
  type: 'line',
  data: chartData,

  options: {


    showLines: false,
    elements: {
      line: {
        tension: 0 // disables bezier curves
      }
    },

    scales: {
      x: {
        type: "time",
        ticks: {
          maxTicksLimit: 10,

          //////////////
          autoSkip: false,
          suggestedMin: 20,
          min: 20,
          sampleSize: 20,
          autoSkip: false,
          maxRotation: 20,
          minRotation: 20
          /////////////////

        },

      },
      y: {

        beginAtZero: true,
        min: Math.min.apply(Math, data2) - 200,
        max: Math.max.apply(Math, data2) + 200
      }

    },

    datasets: {
      parsing: false,

      line: {
        pointRadius: 0 // disable for all `'line'` datasets
      }

    },
    plugins: {
      // decimation: {
      //     algorithm: 'lttb',
      //     enabled: true,
      //     samples: 20
      // },
      zoom: {
        limits: {
          y: {
            min: 0,
            max: 10
          },

        },
        // rangeMin: {
        //     x: 10,
        //     y: 200

        // },
        pan: {
          enabled: true,
          mode: 'x',
          speed: 15,
          threshold: 5,
          rangeMin: {
            x: Date.parse((ChartDataArray[0]["x"]))
          },
          rangeMax: {
            y: Math.max.apply(Math, data2)
          }
        },
        zoom: {
          wheel: {
            enabled: true,
            speed: 0.1
          },
          pinch: {
            enabled: true
          },
          mode: "x",
          speed: 0.1,
          threshold: 2,
          sensitivity: 3,
        }
      },
      afterRender: function(c) {
        console.log("afterRender called");
        var ctx = c.chart.ctx;
        ctx.save();
        // This line is apparently essential to getting the
        // fill to go behind the drawn graph, not on top of it.
        // Technique is taken from:
        // https://stackoverflow.com/a/50126796/165164
        ctx.globalCompositeOperation = 'destination-over';
        ctx.fillStyle = 'white';
        ctx.fillRect(0, 0, c.chart.width, c.chart.height);
        ctx.restore();
      }
    }
  }
});






function resetZoom() {
  chart2.resetZoom();

}

function resetZoom2() {
  chart3.resetZoom();

}

function zoomButton() {
  chart2.zoom(1.1);

}

function zoomButton2() {
  chart3.zoom(1.3);

}

function zoomOutButton() {
  chart2.zoom(0.9);

}

function zoomOutButton2() {
  chart3.zoom(0.7);

}

function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min) + min); //The maximum is exclusive and the minimum is inclusive
}
<!DOCTYPE html>
<html lang="en" dir="ltr">

<head>
  <meta charset="utf-8">
  <title>Charts, Charts, Charts</title>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
  <link rel="stylesheet" type="text/css" href="mystyle.css">
  <script src="https://cdn.jsdelivr.net/npm/chart.js@3.7.1"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js" integrity="sha512-UXumZrZNiOwnTcZSHLOfcTs0aos2MzBWHXOHOuB0J/R44QB0dwY5JgfbvljXcklVf65Gc4El6RjZ+lnwd2az2g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/1.2.0/chartjs-plugin-zoom.min.js" integrity="sha512-TT0wAMqqtjXVzpc48sI0G84rBP+oTkBZPgeRYIOVRGUdwJsyS3WPipsNh///ay2LJ+onCM23tipnz6EvEy2/UA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  <script src="https://cdn.jsdelivr.net/npm/moment@^2"></script>
  <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment@^1"></script>
</head>

<body>
  <button onclick="download_csv_file()"> Download CSV </button>
  <h1>Charts, Charts, Charts</h1>
  <div class="container">
    <div class="row">

      <div class="col-6 chart">
        <canvas id="myChart2" width="1000" height="800"></canvas>
        <button onclick="resetZoom2()"> Reset </button>
        <button onclick="zoomOutButton2()"> Zoom Out </button>
        <button onclick="zoomButton2()"> Zoom In</button>
      </div>
    </div>
    <div class="row">
      <div class="col-6 chart">
        <canvas id="myChart3" width="1000" height="800"></canvas>

        <button onclick="resetZoom()"> Reset </button>

        <button onclick="zoomButton()"> Zoom In</button>
        <button onclick="zoomOutButton()"> Zoom Out</button>

      </div>
      <div class="col-6 chart">
        <canvas id="myChart4" width="500" height="400"></canvas>
      </div>
    </div>
  </div>
  <script src="script.js"></script>
</body>

</html>

Leave a comment