如何使用 Chart.js 进行自动平移

How to do automatic pan with Chart.js

我正在使用 chart.js 实时绘制数据。目前,随着新数据点的进入和绘制,旧数据点仍然存在,这增加了每次迭代必须绘制的点数 chart.js。我想要最大数量的可见点,比如说 20,在图表上有 20 个点之后,平移每次迭代。我正在使用缩放和平移插件。这是我现在的代码

if (ticks > 20) {
    flukeChart.pan({x: 1, y: 0}, 'active');
    flukeChart.update();
}

ticks 是一个整数,每次有新数据进入时它都会递增。 另外需要注意的是,X 轴是时间戳。我正在使用来自传入数据源的时间戳,而不是计算 JS 中的当前时间。我感觉 .pan 方法中的增量不应该为 1,因为 x 轴不是整数而是时间戳。

您可以获得时间戳值的像素。如果您随后减去第一个和第二个可见的像素,您可以用该数量的像素平移图表。

const options = {
  type: 'line',
  data: {
    datasets: [{
      label: '# of Votes',
      data: [],
      borderColor: 'pink'
    }]
  },
  options: {
    scales: {
      x: {
        type: 'time'
      }
    },
  }
}

const ctx = document.getElementById('chartJSContainer').getContext('2d');
const chart = new Chart(ctx, options);
let dataPointsCounter = -1;

const interVal = setInterval(() => {
  chart.data.datasets[0].data.push({
    x: new Date(),
    y: Math.random()
  });
  dataPointsCounter++;

  if (dataPointsCounter > 20) {
    const diff = chart.scales.x.getPixelForValue(chart.data.datasets[0].data[dataPointsCounter - 21].x) - chart.scales.x.getPixelForValue(chart.data.datasets[0].data[dataPointsCounter - 20].x)
    chart.pan({
      x: diff
    }, undefined, 'default');
  }
  chart.update();
}, 500)
<body>
  <canvas id="chartJSContainer" width="600" height="400"></canvas>
  <script src="https://cdn.jsdelivr.net/npm/hammerjs@2.0.8"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.0/chart.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/1.1.1/chartjs-plugin-zoom.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
</body>

编辑:

这不是您想要的,但您也可以使用 streaming plugin 为您处理缩放和更新:

const options = {
  type: 'line',
  data: {
    datasets: [{
      label: '# of Votes',
      data: [],
      borderColor: 'pink'
    }]
  },
  options: {
    scales: {
      x: {
        type: 'realtime',
        realtime: {
          duration: 7500,
          refresh: 1000,
          delay: 2000,
          onRefresh: (chart) => {
            chart.data.datasets[0].data.push({
              x: new Date(),
              y: Math.random()
            })
          }
        }
      }
    },
  }
}

const ctx = document.getElementById('chartJSContainer').getContext('2d');
const chart = new Chart(ctx, options);
<body>
  <canvas id="chartJSContainer" width="600" height="400"></canvas>
  <script src="https://cdn.jsdelivr.net/npm/hammerjs@2.0.8"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.0/chart.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/1.1.1/chartjs-plugin-zoom.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-streaming@2.0.0"></script>
</body>