2

I am trying to find the currently visible data points following a zoom event using chartjs-plugin-zoom. Following examples I came up with the following onZoomComplete callback, but it is not working.

function getVisibleValues({chart}) {
    const x = chart.scales.x;
    let visible = chart.data.datasets[0].data.slice(x.minIndex, x.maxIndex + 1);
  }

One immediate issue is that chart.data doesn't seem to exist (when using console.log(chart.data) it comes back undefined). Same with x.minIndex and x.maxIndex... Any ideas on what I'm doing wrong would be much appreciated.

Below is how I setup the chart (data is an array of x,y pairs):

ctx = new Chart(document.getElementById(ctx_id), {
  type: "scatter",
  data: {
    datasets: [
      {
        label: "Data",
        lineTension: 0,
        showLine: true,
        data: data,
      },
    ],
  },
  options: {
    animation: false,
    plugins: {
      zoom: {
        zoom: {
          mode: "x",
          drag: {
            enabled: true,
            borderColor: "rgb(54, 162, 235)",
            borderWidth: 1,
            backgroundColor: "rgba(54, 162, 235, 0.3)",
          },
          onZoomComplete: getVisibleValues,
        },
      },
    },
  },
});
Mario Petrovic
  • 7,500
  • 14
  • 42
  • 62
makr83
  • 21
  • 2

1 Answers1

0

You can access the c.chart.scales["x-axis-0"]._startValue and c.chart.scales["x-axis-0"]._valueRange. These two give the first and last visible values respectively.

These values can be used to get the dataset data available at c.chart.config.data.datasets[0].data, or the label names at c.chart.config.data.labels.

If you only need to get the visible tick labels, you can do this by simply accessing the chart.scales["x-axis-0"].ticks object.

function getVisibleValues(c) {
  document.getElementById("visibleTicks").textContent = JSON.stringify(
    c.chart.scales["x-axis-0"].ticks // This is one way to obtain the visible ticks
  );

  const start = c.chart.scales["x-axis-0"]._startValue // This is first visible value
  const end = start + c.chart.scales["x-axis-0"]._valueRange // This is the last visible value

  document.getElementById("visibleValues").textContent = JSON.stringify(
    c.chart.config.data.datasets[0].data.slice(start, end + 1) // Access chart datasets
    //Note: You can also get the labels from here, these are available at `c.chart.config.data.labels`
  );
}

var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
  type: "line",
  data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [{
      label: "# of Votes",
      data: [12, 19, 3, 5, 2, 3]
    }]
  },
  options: {
    scales: {
      yAxes: [{
        ticks: {
          beginAtZero: true
        }
      }]
    },
    plugins: {
      zoom: {
        zoom: {
          // Boolean to enable zooming
          enabled: true,

          // Zooming directions. Remove the appropriate direction to disable
          // Eg. 'y' would only allow zooming in the y direction
          mode: "x",
          onZoomComplete: getVisibleValues
        }
      }
    }
  }
});
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-zoom@0.7.5/dist/chartjs-plugin-zoom.min.js"></script>
<html>

<body>
  Visible ticks: <span id="visibleTicks">Begin zooming</span><br/>Visible data: <span id="visibleValues">Begin zooming</span>
  <div class="myChartDiv" style="width: 400px;">
    <canvas id="myChart"></canvas>
  </div>
</body>

</html>
adelriosantiago
  • 7,762
  • 7
  • 38
  • 71
  • You should not be using properties starting with _. Same as here can be achieved with scales.min and max or scales.start and end, but they give min and max of the data values, not index as the OP is asking. So if you zoom to range 0.1 to 0.9, those will be the min and max values. – Boat Apr 04 '23 at 10:36