artus9033 / chartjs-plugin-dragdata

Draggable data points plugin for Chart.js
MIT License
261 stars 55 forks source link

d3-drag causing dragData to break in Android Chrome #34

Closed gspeach closed 3 years ago

gspeach commented 5 years ago

So after some extensive testing I found that d3-drag is using preventDefault() without passive: true causes dragData to break chart.js chart. Ill try my best to explain, and hope we can find a solution.

Error Message

image

Here where it calls .on 'eventType' it should be able to pass a third option passive: true

const ChartJSdragDataPlugin = { id: 'dragdata', afterInit: function(chartInstance) { if (chartInstance.options.dragData) { select(chartInstance.chart.canvas).call( drag().container(chartInstance.chart.canvas) .on('start', getElement(chartInstance, chartInstance.options.onDragStart)) .on('drag', updateData(chartInstance, chartInstance.options.onDrag)) .on('end', dragEndCallback(chartInstance,chartInstance.options.onDragEnd)) ) } } }

This is the offending code in d3-drag in noevent.js. Where it calls event.preventDefault();

import {event} from "d3-selection"; export function nopropagation() { event.stopImmediatePropagation(); } export default function() { event.preventDefault(); event.stopImmediatePropagation(); }

Here are some threads I found in github that might have solutions, but I havent been able to get anything to work.

https://github.com/d3/d3-selection/issues/113 https://github.com/d3/d3-drag/issues/35

gspeach commented 5 years ago

I think I found a solution... seems to be working for me. Please let me know if you get this same issue, and if this fixes it for you.

Thanks, gspeach

Where you set the ChartJSdragDataPlugin and you set this line.

.on('drag', updateData(chartInstance, chartInstance.options.onDrag))

Instead try this:

.on('drag.touchable', updateData(chartInstance, chartInstance.options.onDrag))

When adding touchable to the drag event it seems to be allowing me to drag without errors on android chrome.

Also here is a custom event listener I made that I added to the canvas that stops the browser scrolling which prevents dragging smoothly. Its for angular, but it can easily be converted for regular JS. Also keep in mind the this.dragging variable is set dynamically using the drag events used by the chart. So its false when not dragging and true when dragging.

this.elementRef.nativeElement.querySelector('#canvas').addEventListener('touchmove', function(e) { e.returnValue = true; if (_this.dragging) { e.preventDefault(); } }, { passive: _this.dragging } );

chrispahm commented 5 years ago

Thanks @gspeach for already inspecting this! Did you get to check if the drag.touchable event works for desktop browsers as well? I will try and check your solution by the end of the week!

Best Christoph

gspeach commented 5 years ago

yeah it works for me in firefox, chrome, edge, safari desktop and android chrome and ios safari.

chrispahm commented 3 years ago

Just updated to d3-drag v2, which seems to alleviate this issue. Please re-open if it still persists!