使用 Hammer + 图表 + 图表插件缩放在移动设备上不起作用

问题描述 投票:0回答:1

我在使用 Chartjs-plugin-zoom 和 Hammer.js 的 Chart.js 图表中遇到移动设备上的拖动功能问题。该图表在桌面浏览器上按预期工作,但在移动设备上查看时,拖动似乎无法按预期工作。

重现步骤:

Open the chart on a mobile device.
Attempt to drag to pan the chart horizontally.
Observe that the drag functionality is not responsive.

预期行为: 我希望能够在移动设备上水平拖动和平移图表,就像在桌面浏览器上一样。

<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/1.1.1/chartjs-plugin-zoom.min.js"></script>
<div class="container">
   <h3>Chart Example</h3>
  <div class="chart">
    <canvas id="cumulativeChart"></canvas>
  </div>
</div>
<script>const ctx = document.getElementById('cumulativeChart');
  const labels = [
  'Jul 13', 'Jul 14', 'Jul 15', 'Jul 16', 'Jul 17', 'Jul 18',
  'Jul 19', 'Jul 20', 'Jul 21', 'Jul 22', 'Jul 23', 'Jul 24',
  'Jul 25', 'Jul 26', 'Jul 27', 'Jul 28', 'Jul 29', 'Jul 30',
  'Jul 31', 'Aug 01', 'Aug 02', 'Aug 03', 'Aug 04', 'Aug 05',
  'Aug 06', 'Aug 07', 'Aug 08', 'Aug 09', 'Aug 10', 'Aug 11',
  ];
  
  const data = {
  labels: labels,
  datasets: [{
      label: 'Cumulative Data',
      borderColor: '#3a96fd',
      borderWidth: 2,
      data: [
          0.13299527, 0.16131551, 0.18795605, 0.20597476, 0.22560615, 0.23797296,
          0.25541133, 0.28006363, 0.30473082, 0.32418763, 0.33880094, 0.35331442,
          0.36290294, 0.38035896, 0.40230393, 0.42181523, 0.43855241, 0.4481249,
          0.4696107, 0.48147319, 0.4958352, 0.52931651, 0.55098815, 0.56771866,
          0.58238203, 0.60083731, 0.61222939, 0.6262777, 0.64303029, 0.65866165,
      ],
      pointRadius: 4,
      pointBackgroundColor: '#3a96fd',
      fill: true
  }]};
  
  const config = {
  type: 'line',
  data: data,
  options: {
      responsive: true,
      scales: {
          y: {
              grid: {
                  color: 'rgba(128,151,177, 0.3)',
                  borderDash: [3, 3],
                  drawTicks: false,
                  borderColor: '#424b5f',
              },
              ticks: {
                  align: "center",
                  padding: 10,
              },
          },
          x: {
              grid: {
                  color: 'rgba(128,151,177, 0.3)',
                  borderDash: [3, 5],
                  drawTicks: false,
                  borderColor: '#424b5f'
              },
              ticks: {
                  align: "center",
                  padding: 10,
              }
          }
      },
      plugins: {
          legend: {
              display: false
          },
          tooltip: {
              usePointStyle: true,
          },
          zoom: {
              zoom: {
                  wheel: {
                      enabled: true,
                  },
                  pinch: {
                      enabled: true
                  },
                  drag: {
                      enabled: true
                  },
                  mode: 'x',
              },
              pan: {
                  enabled: true,
                  mode: 'x',
              },
              limits: {
                  x: {
                      minRange: 3
                  },
              },
          }
      }
  }
  };
  
  const myChart = new Chart(
  ctx,
  config
  );</script>

在桌面上完美工作,但在移动设备上只能使用捏缩放,拖动缩放不起作用,有什么解决方案吗?,谢谢

我已经查看了Chart.js和chartjs-plugin-zoom官方文档,但找不到解决方案。任何有关如何在移动设备上启用拖动功能的见解或建议将不胜感激。

mobile chart.js drag hammer.js chartjs-plugin-zoom
1个回答
0
投票

移动设备未实现拖动缩放;我认为它被认为是 移动用户通常不使用的东西,因为它们都是关于 捏:)。它也可能会干扰其他常用手势,例如滚动。

如果你想在移动设备上测试拖动缩放,映射似乎相当简单 移动事件

touchstart
->
mousedown
touchmove
->
mousemove
touchend 鼠标事件 鼠标按下 -> 鼠标移动 -> 鼠标向上。我用过这篇文章 寻求灵感。请检查其中的注释以了解可能的陷阱(一个重要的区别是我仅映射画布元素的事件,而不是整个文档。

const ctx = document.getElementById('cumulativeChart');
const labels = [
    'Jul 13', 'Jul 14', 'Jul 15', 'Jul 16', 'Jul 17', 'Jul 18',
    'Jul 19', 'Jul 20', 'Jul 21', 'Jul 22', 'Jul 23', 'Jul 24',
    'Jul 25', 'Jul 26', 'Jul 27', 'Jul 28', 'Jul 29', 'Jul 30',
    'Jul 31', 'Aug 01', 'Aug 02', 'Aug 03', 'Aug 04', 'Aug 05',
    'Aug 06', 'Aug 07', 'Aug 08', 'Aug 09', 'Aug 10', 'Aug 11',
];

const data = {
    labels: labels,
    datasets: [{
        label: 'Cumulative Data',
        borderColor: '#3a96fd',
        borderWidth: 2,
        data: [
            0.13299527, 0.16131551, 0.18795605, 0.20597476, 0.22560615, 0.23797296,
            0.25541133, 0.28006363, 0.30473082, 0.32418763, 0.33880094, 0.35331442,
            0.36290294, 0.38035896, 0.40230393, 0.42181523, 0.43855241, 0.4481249,
            0.4696107, 0.48147319, 0.4958352, 0.52931651, 0.55098815, 0.56771866,
            0.58238203, 0.60083731, 0.61222939, 0.6262777, 0.64303029, 0.65866165,
        ],
        pointRadius: 4,
        pointBackgroundColor: '#3a96fd',
        fill: true
    }]
};

const config = {
    type: 'line',
    data: data,
    options: {
        responsive: true,
        scales: {
            y: {
                grid: {
                    color: 'rgba(128,151,177, 0.3)',
                    borderDash: [3, 3],
                    drawTicks: false,
                    borderColor: '#424b5f',
                },
                ticks: {
                    align: "center",
                    padding: 10,
                },
            },
            x: {
                grid: {
                    color: 'rgba(128,151,177, 0.3)',
                    borderDash: [3, 5],
                    drawTicks: false,
                    borderColor: '#424b5f'
                },
                ticks: {
                    align: "center",
                    padding: 10,
                }
            }
        },
        plugins: {
            legend: {
                display: false
            },
            tooltip: {
                usePointStyle: true,
            },
            zoom: {
                zoom: {
                    wheel: {
                        enabled: true,
                    },
                    pinch: {
                        enabled: true
                    },
                    drag: {
                        enabled: true
                    },
                    mode: 'x',
                },
                pan: {
                    enabled: true,
                    mode: 'x',
                },
                limits: {
                    x: {
                        minRange: 3
                    },
                },
            }
        }
    }
};

const myChart = new Chart(
    ctx,
    config
);

function touchHandler(event){
    const touches = event.changedTouches,
        first = touches[0],
        type = event.type.replace(/^touch/, "mouse").replace(/start$/, "down").replace(/end$/, "up");
        // touchstart -> mousedown; touchmove -> mousemove; touchend -> mouseup

    const simulatedEvent = new Event(type, {
        bubbles: true, cancelable: true
    })
    simulatedEvent.screenX = first.screenX;
    simulatedEvent.screenY = first.screenY;
    simulatedEvent.clientX = first.clientX;
    simulatedEvent.clientY = first.clientY;

    first.target.dispatchEvent(simulatedEvent);
    //event.preventDefault();
}

myChart.canvas.addEventListener("touchstart", touchHandler, true);
myChart.canvas.addEventListener("touchmove", touchHandler, true);
myChart.canvas.addEventListener("touchend", touchHandler, true);
myChart.canvas.addEventListener("touchcancel", touchHandler, true);
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/1.1.1/chartjs-plugin-zoom.min.js"></script>
<div class="container">
    <h3>Chart Example</h3>
    <div class="chart">
        <canvas id="cumulativeChart"></canvas>
    </div>
</div>

© www.soinside.com 2019 - 2024. All rights reserved.