3

Looks like Google Chrome v70 completely screwed up the usage of D3 under touch screen laptops.

We are working with a Panasonic FZ-M1 tablet where we run some webserver stuff which is creating a topology view with force directed graph. since yesterday the graph is completely unresponsive to gesture, you can't move, you can't zoom, nothing. We installed Chrome v69 and then it works perfectly. Unfortunately Chrome is auto updating. Tested with D3 v5.7.0, still the same.

You can try by using a touchscreen laptop or tablet with the D3 force directed graph example in the gallery or by enabling touch screen simulation in developer tools.

altocumulus
  • 21,179
  • 13
  • 61
  • 84
Lorenzo
  • 41
  • 2

2 Answers2

3

D3 relies on the ontouchstart property for feature detection, i.e. touch event listeners are only attached if this property is present. Due to changes in Chrome v70 this detection mechanism seems to be broken in D3.

ontouch* APIs default to disabled on desktop

To avoid confusion on touch feature detection, ontouch* members on window, document, and element are disabled by default on desktop (Mac, Windows, Linux, ChromeOS). Note that this is not disabling touches, and usage such as addEventListener("touchstart", ...) is not affected.

Related: Disable legacy touch event APIs on desktop

Your laptops running Windows are most likely detected as being desktop devices instead of mobile devices. Hence, they are affected by those changes to Chrome v70 resulting in the touch event listeners not being registered any more.

This issue has been previously reported as an issue on the d3-drag module: #47 Upcoming touch detection changes in desktop Chrome. Once I had commented on that issue providing a reference to this question, fortunately, Mike Bostock replied within an hour. Better still, there is an easy solution to problem: You can use drag.touchable(detector) to control when to apply touch event listeners overriding the default behavior:

Touch event listeners are only registered if the detector returns truthy for the corresponding element when the drag behavior is applied.

As suggested by Mike drag.touchable(navigator.maxTouchPoints) seems to be a good candidate. The nuclear option drag.touchable(true) would ensure the touch event listeners be applied in any case.

Community
  • 1
  • 1
altocumulus
  • 21,179
  • 13
  • 61
  • 84
  • I attempted this solution. My app works perfectly on Chrome via a touch display on Mac, but d3.drag failed when I switched to the Windows production machine running Chrome 74. I applied the solution `d3.drag().touchable(navigator.maxTouchPoints)` as well as `d3.drag().touchable(true)` , which did allow me to drag the element on a touch screen, but am now getting `UncaughtTypeError: Failed to execute 'elementFromPoint' on 'Document': The provided double value is non-finite` so my drag events aren't firing. – interwebjill May 01 '19 at 17:22
  • I posted the question here: https://stackoverflow.com/questions/55940323/d3-drag-issue-on-windows-chrome-when-applying-document-elementfrompoint – interwebjill May 01 '19 at 18:15
3

Open following in chrome browser

chrome://flags

and find Touch Events API

set Touch Events API to Enabled (the default is now “Disabled”)

Hopefully this works.

Prashant
  • 276
  • 3
  • 13