Skip to content

With ≥ 2× more categories than pixels, panning jumps straight to the first/last category #946

Description

@andersk

With pan: { enabled: true } on a category axis, if the chart has at over twice as many visible categories as its width in pixels, a tiny drag to the left or right snaps the visible range all the way to the first or last category, with no in-between.

This is due to incorrect rounding in panCategoryScale:

// The visible range. Ticks can be skipped, and thus not reliable.
const range = Math.max(max - min, 1);
// How many pixels of delta is required before making a step. stepSize, but limited to max 1/10 of the scale length.
const stepDelta = Math.round(scaleLength(scale) / Math.max(range, 10));
const stepSize = Math.round(Math.abs(delta / stepDelta));

When scaleLength / range < 0.5, stepDelta rounds to 0, and stepSize becomes Infinity.

There’s no reason to round stepDelta to an integer. It should be kept fractional to accurately reflect the fractional size of each category, which is significant when that size is small.

Reproduction

https://jsfiddle.net/anderskaseorg/vkcn85mp/

<canvas id="ctx">
<script type="module">
import { BarController, BarElement, CategoryScale, LinearScale, Chart } from "https://esm.sh/chart.js@4.5.1";
import zoomPlugin from "https://esm.sh/chartjs-plugin-zoom@2.2.0";
Chart.register(BarController, BarElement, CategoryScale, LinearScale, zoomPlugin);
const chart = new Chart(ctx, {
  type: "bar",
  data: {
    datasets: [{ data: [...Array(10000).keys()] }],
    labels: [...Array(10000).keys()],
  },
  options: { plugins: { zoom: { pan: { enabled: true } } } },
});
chart.zoom(1.25);
</script>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions