d3 circle .on("click")事件未触发 [英] d3 circle .on("click") event not firing

查看:492
本文介绍了d3 circle .on("click")事件未触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道它应该很简单,只需选择所需的元素并对其应用调用,但就我而言,这样做没有任何反应.

I understand it should be as simple as selecting the element you need and applying the call to it, but in my case, nothing is happening when I do so.

就我而言,我需要根据地图的缩放级别重新绘制圆圈.

In my case, I need to re draw circles based on a zoom level of a map.

如果缩放级别为<一定数量的圆圈,请使用数据集A. 如果缩放级别为>数字,则使用数据集B绘制圆圈.

If the zoom level is < a certain number, use dataset A for the circles. If the zoom level is > the number use dataset B to draw the circles.

我可以很好地绘制圆,并且它们会随着缩放级别的改变而改变,但是当我向其中添加.on("click")事件时,什么也没有发生.

I can draw the circles fine, and they do change on changing of the zoom level, but when I add an .on("click") event to these though, nothing happens.

这是一个Codepen链接,显示缺少点击事件,该链接不起作用 CODEPEN链接

Here is a Codepen link showing the lack of click event working CODEPEN LINK

这是我正在使用的代码,感觉在update()函数中以及我在使用.remove()函数的方式上做错了事情:

Here is the code I am using, I have a feeling I am doing something wrong in the update() function, and the way I am using the .remove() function:

L.mapbox.accessToken = 'pk.eyJ1Ijoic3RlbmluamEiLCJhIjoiSjg5eTMtcyJ9.g_O2emQF6X9RV69ibEsaIw';
var map = L.mapbox.map('map', 'mapbox.streets')
  .setView([53.4072, -2.9821], 14);

var data = {
  "largeRadius": [{
    "coords": [53.3942, -2.9785],
    "name": "Jamaica Street"
  }, {
    "coords": [53.4073, -2.9824],
    "name": "Hood Street"
  }],
  "smallRadius": [{
    "coords": [53.4075, -2.9936],
    "name": "Chapel Street"
  }, {
    "coords": [53.4073, -2.9824],
    "name": "Hood Street"
  }]
};

// Sort data for leaflet LatLng conversion
data.largeRadius.forEach(function(d) {
  d.LatLng = new L.LatLng(d.coords[0], d.coords[1]);
});
data.smallRadius.forEach(function(d) {
  d.LatLng = new L.LatLng(d.coords[0], d.coords[1]);
});

var svg = d3.select(map.getPanes().overlayPane).append("svg");

var g = svg.append("g").attr("class", "leaflet-zoom-hide");

var circles = g.selectAll("circle")
  .data(data.smallRadius)
  .enter().append("circle");

function update() {
  circles.remove();
  translateSVG();

  var dataInstance;
  var radius;

  if (map.getZoom() < 17) {
    dataInstance = data.largeRadius;
    radius = 0.008;
  } else {
    dataInstance = data.smallRadius;
    radius = 0.001;
  }

  dataInstance.forEach(function(d) {
    d.LatLng = new L.LatLng(d.coords[0], d.coords[1]);
  });

  circles = g.selectAll("circle")
    .data(dataInstance)
    .enter().append("circle")
    .attr("id", function(d) {
      return d.name
    })
    .attr("cx", function(d) {
      return map.latLngToLayerPoint(d.LatLng).x
    })
    .attr("cy", function(d) {
      return map.latLngToLayerPoint(d.LatLng).y
    })
    .attr("r", function() {
      return radius * Math.pow(2, map.getZoom())
    });
}

function translateSVG() {
  var width = window.innerWidth;
  var height = window.innerHeight;

  var regExp = /\(([^)]+)\)/;
  var translateString = regExp.exec(document.querySelector(".leaflet-map-pane").attributes[1].nodeValue);
  var translateX = parseInt(translateString[1].split(" ")[0]);
  var translateY = parseInt(translateString[1].split(" ")[1]);

  if (translateX < 0) {
    translateX = Math.abs(translateX);
  } else {
    translateX = -translateX;
  }
  if (translateY < 0) {
    translateY = Math.abs(translateY);
  } else {
    translateY = -translateY;
  }

  svg.attr("width", width);
  svg.attr("height", height);
  svg.attr("viewBox", function() {
    return translateX + " " + translateY + " " + width + " " + height;
  });
  svg.attr("style", function() {
    return "transform: translate3d(" + translateX + "px, " + translateY + "px, 0px);";
  });
}

// THIS IS THE CLICK EVENT THAT DOES NOT WORK
circles.on("click", function () {
  alert("clicked");
})

map.on("moveend", update);
update();

推荐答案

我不确定这是否可以完全解决您的问题,主要是因为我不确定我是否完全了解您要实现的目标,但是如果您移动点击"代码:

I'm not sure if this fixes your issue completely, mostly because I'm not sure I fully understand what you're trying to achieve, but if you move the 'click' code:

circles.on("click", function () {
  alert("clicked");
});

在更新中,完成销毁并重新创建后,您将对其进行重新绑定,因此更新功能将变为:

Inside your update, then you'll rebind that after you've done the destroy and re-create, so your update function becomes this:

function update() {
  circles.remove();
  translateSVG();

  var dataInstance;
  var radius;

  if (map.getZoom() < 17) {
    dataInstance = data.largeRadius;
    radius = 0.008;
  } else {
    dataInstance = data.smallRadius;
    radius = 0.001;
  }

  dataInstance.forEach(function(d) {
    d.LatLng = new L.LatLng(d.coords[0], d.coords[1]);
  });

  circles = g.selectAll("circle")
    .data(dataInstance)
    .enter().append("circle")
    .attr("id", function(d) {
      return d.name
    })
    .attr("cx", function(d) {
      return map.latLngToLayerPoint(d.LatLng).x
    })
    .attr("cy", function(d) {
      return map.latLngToLayerPoint(d.LatLng).y
    })
    .attr("r", function() {
      return radius * Math.pow(2, map.getZoom())
    });

    circles.on("click", function () {
      alert("clicked");
    });
}

,然后从底部删除circle.on("click")部分.确保每次释放绑定都值得,我不确定是要覆盖内存还是在每次更新时添加绑定.

and you then remove the circles.on("click") part from the bottom. It may also be worth making sure you're releasing that bind each time, i'm unsure if it'll be overwriting the memory or adding to it each update.

这就像我想像的那样,属于您的分支: http://codepen.io/anon/pen/waqJqB?editors=101

Here's a fork of yours where it seems to be working as I imagine it: http://codepen.io/anon/pen/waqJqB?editors=101

这篇关于d3 circle .on("click")事件未触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆