【问题标题】:drag event not fired on mobile devices移动设备上未触发拖动事件
【发布时间】:2019-05-20 18:00:09
【问题描述】:

我正在制作一个基于 d3 force layout v5 的应用程序,需要与鼠标和触摸事件进行交互。我如何在其中链接触摸事件?

这是我的问题示例代码,它只出现在整页上:https://codepen.io/bragamonte/full/QRqvEd


  var svg = d3.select("svg"), width = svg.property('clientWidth'),
  height = svg.attr("height");
  // height = 500;


  var simulation = d3.forceSimulation()
    .force("link", d3.forceLink().id(function(d) { return d.id; }).distance(d => (10 - d.source.order) * 9 ))
    .force('charge', d3.forceManyBody().strength(-400).theta(1))
    .force('collide', d3.forceCollide().radius(d => 40).iterations(2))
    .force("center", d3.forceCenter(width / 2, height / 2))
  ;


  const graph = 
    {
      "nodes": [
        {"id": 1, "name": "SIGMA", "order": 1, "icon": "https://github.com/favicon.ico"},
        // 
        {"id": 2, "name": "PLAN", "order": 2, "icon": "https://github.com/favicon.ico"},
        {"id": 3, "name": "DO", "order": 2, "icon": "https://github.com/favicon.ico"},
        {"id": 4, "name": "CHECK", "order": 2, "icon": "https://github.com/favicon.ico"},
        {"id": 5, "name": "ACTION", "order": 2, "icon": "https://github.com/favicon.ico"},
        {"id": 6, "name": "Dashboard", "href": "/dashboard", "order": 3, "icon": "https://github.com/favicon.ico"},
        {"id": 7, "name": "SS", "href": "/ss", "order": 3, "icon": "https://github.com/favicon.ico"},
        {"id": 8, "name": "OS", "href": "/os", "order": 3, "icon": "https://github.com/favicon.ico"},
        {"id": 9, "name": "Preventiva", "href": "/preventiva", "order": 3, "icon": "https://github.com/favicon.ico"},
        {"id": 10, "name": "Estrutura", "href": "/cadastros/departamentos", "order": 3, "icon": "https://github.com/favicon.ico"},
        {"id": 11, "name": "Relatórios", "href": "/relatorios", "order": 3, "icon": "https://github.com/favicon.ico"},
        {"id": 12, "name": "Telemetria", "href": "/telemetria", "order": 3, "icon": "https://github.com/favicon.ico"}
      ],
      "links": [
        // main
        {"source": "2", "target": 1, "distance": 130},
        {"source": "3", "target": 1, "distance": 130},
        {"source": "4", "target": 1, "distance": 130},
        {"source": "5", "target": 1, "distance": 130},
        // 
        {"source": "6", "target": 4, "distance": 50},
        {"source": "7", "target": 3, "distance": 50},
        {"source": "8", "target": 3, "distance": 50},
        {"source": "9", "target": 3, "distance": 50},
        {"source": "10", "target": 2, "distance": 50},
        {"source": "11", "target": 4, "distance": 50},
        {"source": "12", "target": 2, "distance": 50},
      ]
  };


  // var node, link, label;

  function dragstarted(d) {
    console.log(' >> drag started');
    if (!d3.event.active) simulation.alphaTarget(0.3).restart()
    d.fx = d.x
    d.fy = d.y
  }

  function dragged(d) {
    console.log(' >> dragged');
    d.fx = d3.event.x
    d.fy = d3.event.y
  }

  function dragended(d, a, b) {
    console.log(' >> drag ended');
    d.fx = d3.event.x
    d.fy = d3.event.y
    if (!d3.event.active) simulation.alphaTarget(0);
  }

  function dragsubject() {
    return simulation.find(d3.event.x, d3.event.y);
  }


    var link =
      svg.append("g")
        .style("stroke", "#aaa")
        .selectAll("line")
        .data(graph.links)
        .enter()
        .append("line");

    var node =
      svg.selectAll("circle")
        .data(graph.nodes)
        .enter()
        .append("g")
        .attr("class", "nodes")
        .attr("class", function (d) { return !!d.href ? 'node-link' : ''; })
        .call(d3.drag()
          .subject(dragsubject)
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended)
        );


      node.append("image")
          .attr("xlink:href", function (d) { return d.icon || "resources/img/icon-sigma.png"; })
          .attr("x", -25)
          .attr("y", -25)
          .attr("width", d => (10 - d.order) * 8)
          .attr("height", d => (10 - d.order) * 8);

  var label =
    svg.append("g")
      .attr("class", "labels")
      .selectAll("text")
      .data(graph.nodes)
      .enter()
      .append("text")
      .attr("dx", d => (9 - d.order) * 6)
      .attr("dy", d => (9 - d.order))
      .text(function(d) { return d.name });

  simulation.nodes(graph.nodes).on("tick", () => {
    node.attr("transform", d => `translate(${d.x},${d.y})`)

    link
      .attr("x1", function(d) { return d.source.x; })
      .attr("y1", function(d) { return d.source.y; })
      .attr("x2", function(d) { return d.target.x; })
      .attr("y2", function(d) { return d.target.y; });

    label
      .attr("x", function(d) { return d.x; })
      .attr("y", function (d) { return d.y; })
  });

  simulation.force("link").links(graph.links);

当在移动设备上使用时,例如 chrome 开发工具,事件 drag 不会被触发,但像 startend 这样的事件会触发。

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    您应该在移动设备上使用触摸事件。

    d3.select("svg").on("touchstart", yourFunction);
    d3.select("svg").on("touchmove", yourFunction);
    

    【讨论】:

    • 我刚刚添加了这个事件,里面只有一个日志并且可以工作,这是一个错误吗?
    • 这不是错误,它应该是这样的。触摸事件和鼠标事件是不同的!例如,鼠标事件将同时保持一个位置,而触摸事件可能同时保持多个触摸位置(多点触摸)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-14
    • 2023-01-20
    • 2021-11-20
    • 1970-01-01
    • 2020-12-09
    相关资源
    最近更新 更多