Я создаю карту с использованием библиотеки d3js и указываю кружок в определенных местах и пытаюсь создать событие щелчка на этом круге, но эти круги не доступны для кликов. Вот код.
<!DOCTYPE html>
<head>
<title>A D3 Map, points plotted with canvas instead of SVG</title>
<style>
body {
margin: 0;
}
#container {
position: relative;
overflow: hidden;
z-index: 0;
}
#points{
width:100%;
height:100%;
position:relative;
z-index:100;
}
.layer{
position:absolute;
z-index:-10;
}
.tile {
pointer-events: none;
position: absolute;
width: 256px;
height: 256px;
}
.info {
position: absolute;
bottom: 0px;
left: 0px;
padding: 20px;
background: #000;
color: #fff;
width: 100%;
height: 18px;
z-index: 1000;
font-family:Helvetica, Arial, sans-serif;
font-size:16px;
}
.credit{
position:absolute;
bottom: 0px;
right: 0px;
padding: 9px 20px;
color:#fff;
font-family:Helvetica, Arial, sans-serif;
font-size:13px;
z-index: 1000;
}
.credit a{
text-decoration:none;
color:#ddd;
}
</style>
<script src = "http://d3js.org/d3.v3.min.js"></script>
<script src = "http://d3js.org/d3.geo.tile.v0.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.2/d3.min.js"></script>
</head>
<body>
<div id = "container">
<div class = "layer"></div>
<div id = "map">
<canvas>
<div id = "points" ></div>
</canvas>
</div>
<div class = "credit"><p>Data © <a href = "http://www.openstreetmap.org/copyright">OpenStreetMap</a> Tiles © <a href = "http://cartodb.com/attributions">CartoDB</a></p></div>
</div>
<script type='text/javascript'>
/* global variables and initial canvas space set up*/
var width = window.innerWidth;
var height = window.innerHeight;
var prefix = prefixMatch(["webkit", "ms", "Moz", "O"]);
console.info(width,height)
var dataSet = "";
d3.csv("/../map2/karriereTutor.csv", function(error, dataset) {
dataSet = dataset;
createMap(dataset)
});
var tile = d3.geo.tile()
.size([width, height]);
var projection = d3.geo.mercator()
.scale((1 << 24) / 2 / Math.PI)
.translate([width / 2, height / 2]); // just temporary
$('.arc').on('click',function(){
console.info('asdfd')
})
var zoom = d3.behavior.zoom()
.scale(4.5 << 12)
.scaleExtent([1 << 9, 12 << 23])
.translate([width / 3 ,3000])
.on("zoom", zoomed);
var container = d3.select("#container")
.style("width", width + "px")
.style("height", height + "px")
.call(zoom)
.on("mousemove", mousemoved)
var base = d3.select('#map');
var chart = d3.select('canvas')
.attr("class", "layer")
.attr('width', width)
.attr('height', height);
var context = chart.node().getContext('2d');
var locations = d3.select('#points');
var layer = d3.select('.layer');
var info = base.append("div")
.attr("class", "info");
zoomed();
function createMap(dataset) {
var dataBinding = locations.selectAll("points.arc")
.data(dataset)
.enter()
.append("div")
.classed("arc", true)
.attr('id',function(d){ return d.city })
.attr("x", function(d) { return projection([d.y,d.x])[0]})
.attr("y", function(d) {return projection([d.y,d.x])[1]})
.attr("radius", 5)
.attr("fillStyle", "#ff0000")
drawCanvas();
}
function drawCanvas() {
var elements = locations.selectAll("div.arc");
elements.each(function(d) {
var node = d3.select(this);
context.beginPath();
context.arc(node.attr("x"), node.attr("y"), node.attr("radius"), 0, 2 * Math.PI);
context.fillStyle = node.attr("fillStyle");
context.fill();
context.closePath();
})
}
function reDraw() {
context.clearRect(0, 0, width, height);
drawCanvas();
}
function zoomed() {
var tiles = tile
.scale(zoom.scale())
.translate(zoom.translate())
();
projection
.scale(zoom.scale() / 2 / Math.PI)
.translate(zoom.translate());
d3.selectAll("div.arc")
.attr("x", function(d) {return projection([d.y,d.x])[0]})
.attr("y", function(d) {return projection([d.y,d.x])[1]})
reDraw();
var image = layer
.style(prefix + "transform", matrix3d(tiles.scale, tiles.translate))
.selectAll(".tile")
.data(tiles, function(d) { return d; })
image.exit()
.remove();
image.enter().append("img")
.attr("class", "tile")
.attr("src", function(d) { return "http://" + ["a", "b", "c"][Math.random() * 3 | 0] + ".tile.openstreetmap.org/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; })
.style("left", function(d) { return (d[0] << 8) + "px"; })
.style("top", function(d) { return (d[1] << 8) + "px"; })
}
function mousemoved() {
// for(var i = 0; i < dataSet.length; i++){
// var projectionPoints = projection.invert(d3.mouse(this));
// // console.info(dataSet[i].x, projectionPoints[1])
// if (Math.round(projectionPoints[1]) == Math.round(dataSet[i].x)){
// console.info(dataSet[i].city)
// }
// }
info.text(formatLocation(projection.invert(d3.mouse(this)), zoom.scale()));
}
function matrix3d(scale, translate) {
var k = scale / 256, r = scale % 1 ? Number : Math.round;
return "matrix3d(" + [k, 0, 0, 0, 0, k, 0, 0, 0, 0, k, 0, r(translate[0] * scale), r(translate[1] * scale), 0, 1 ] + ")";
}
function prefixMatch(p) {
var i = -1, n = p.length, s = document.body.style;
while (++i < n) if (p[i] + "Transform" in s) return "-" + p[i].toLowerCase() + "-";
return "";
}
function formatLocation(p, k) {
var format = d3.format("." + Math.floor(Math.log(k) / 2 - 2) + "f");
return (p[1] < 0 ? format(-p[1]) + " S" : format(p[1]) + " N") + " "
+ (p[0] < 0 ? format(-p[0]) + " W" : format(p[0]) + " E");
}
</script>
</body>
</html>
x,y,name,city
48.0851267,11.198654,karriere tutor,Wörthsee
52.2815691,7.443409099999999,karriere tutor,Rheine
48.2629984,11.4339022,karriere tutor,Dachau
49.7019294,9.2559214,karriere tutor,Miltenberg
47.697371,9.5629717,karriere tutor,Meckenbeuren
48.5667364,13.4319466,karriere tutor,Passau
52.4357364,8.6159777,karriere tutor,Rahden
49.6743636,12.1489337,karriere tutor,Weiden in der Oberpfalz
47.7782704,9.612130299999999,karriere tutor,Ravensburg
48.3705449,10.89779,karriere tutor,Augsburg Bayern
51.9032375,8.385753500000002,karriere tutor,Gütersloh
53.6764136,10.2378854,karriere tutor,Ahrensburg
51.3876468,10.7465696,karriere tutor,Straussberg
49.749992,6.6371433,karriere tutor,Trier
52.52000659999999,13.404954,karriere tutor,Berlin
54.3232927,10.1227651,karriere tutor,Kiel
51.4969802,11.9688029,karriere tutor,Halle (Saale)
51.6659316,8.7276375,karriere tutor,Borchen
52.3472237,14.5505672,karriere tutor,Frankfurt (Oder)
54.0729431,9.9840158,karriere tutor,Neumünster Holstein
53.9317752,9.5051475,karriere tutor,Itzehoe
53.5395845,8.580942499999999,karriere tutor,Bremerhaven
54.19517639999999,9.1019015,karriere tutor,Heide Holstein
51.8368113,10.7844266,karriere tutor,Wernigerode
52.9154545,12.7990783,karriere tutor,Neuruppin
52.21697469999999,13.453792,karriere tutor,Zossen
53.2464214,10.4115179,karriere tutor,Lüneburg
50.8021728,8.7667933,karriere tutor,Marburg
53.8654673,10.6865593,karriere tutor,Lübeck
51.8205718,9.8683087,karriere tutor,Einbeck
50.0522076,8.6952638,karriere tutor,Neu-Isenburg
51.2964148,6.8401844,karriere tutor,Ratingen
51.2041968,6.6879511,karriere tutor,Neuss
50.0294877,8.6949231,karriere tutor,Dreieich
51.3387609,6.5853417,karriere tutor,Krefeld
49.4874592,8.466039499999999,karriere tutor,Mannheim
54.0924406,12.0991466,karriere tutor,Rostock
54.08654629999999,13.3923414,karriere tutor,Greifswald
47.84199820000001,12.9728226,karriere tutor,Freilassing
50.4358385,7.825795299999999,karriere tutor,Montabaur
53.2778837,9.7240138,karriere tutor,Tostedt
49.8028671,8.603536199999999,karriere tutor,Pfungstadt
48.8914741,9.034192899999999,karriere tutor,Hardthof bei Markgröningen
48.6471033,9.4519635,karriere tutor,Kirchheim unter Teck
48.6893963,10.1610948,karriere tutor,Heidenheim an der Brenz
47.6779496,9.173238399999999,karriere tutor,Konstanz
50.5558095,9.6808449,karriere tutor,Fulda
53.6355022,11.4012499,karriere tutor,Schwerin Mecklenburg
51.3127114,9.4797461,karriere tutor,Kassel Hessen
50.0782184,8.239760799999999,karriere tutor,Wiesbaden
48.4010822,9.987607599999999,karriere tutor,Ulm Donau
48.5950369,8.8671577,karriere tutor,Herrenberg
50.1109221,8.6821267,karriere tutor,Frankfurt am Main
52.3758916,9.732010400000002,karriere tutor,Hannover
48.1351253,11.5819805,karriere tutor,München
51.3396955,12.3730747,karriere tutor,Leipzig
50.937531,6.9602786,karriere tutor,Köln
51.5135872,7.465298100000001,karriere tutor,Dortmund
51.4556432,7.0115552,karriere tutor,Essen Ruhr
53.07929619999999,8.8016936,karriere tutor,Bremen
53.5510846,9.9936819,karriere tutor,Hamburg
50.14720579999999,8.824969099999999,karriere tutor,Maintal
48.8940624,9.195464,karriere tutor,Ludwigsburg Württemberg
49.9456399,11.5713346,karriere tutor,Bayreuth
52.2688736,10.5267696,karriere tutor,Braunschweig
50.2612094,10.962695,karriere tutor,Coburg
50.3569429,7.5889959,karriere tutor,Koblenz am Rhein
47.9837999,10.1801883,karriere tutor,Memmingen
51.3670777,7.4632841,karriere tutor,Hagen Westfalen
51.1652199,7.0671161,karriere tutor,Solingen
53.1434501,8.214552099999999,karriere tutor,Oldenburg (Oldb)
51.1804572,6.4428041,karriere tutor,Mönchengladbach
51.4185682,6.884522599999999,karriere tutor,Mülheim an der Ruhr
49.0134297,12.1016236,karriere tutor,Regensburg
49.47741,8.445179999999999,karriere tutor,Ludwigshafen am Rhein
49.4771169,10.988667,karriere tutor,Fürth Bayern
51.0504088,13.7372621,karriere tutor,Dresden
50.8216502,6.1320672,karriere tutor,Würselen
51.2562128,7.150763599999999,karriere tutor,Wuppertal
50.73743,7.0982068,karriere tutor,Bonn
48.7781001,8.0875217,karriere tutor,Karlsruhe Baden
48.7758459,9.1829321,karriere tutor,Stuttgart
51.2277411,6.7734556,karriere tutor,Düsseldorf
48.1916623,11.6460441,karriere tutor,Unterföhring
50.22683079999999,8.6181618,karriere tutor,Bad Homburg vor der Höhe
50.09563620000001,8.776084299999999,karriere tutor,Offenbach am Main
50.17874,8.47191,karriere tutor,Königstein im Taunus
49.3063689,8.6427693,karriere tutor,Walldorf Baden
50.98476789999999,11.02988,karriere tutor,Erfurt
49.24015720000001,6.996932699999999,karriere tutor,Saarbrücken
52.3905689,13.0644729,karriere tutor,Potsdam
49.4521018,11.0766654,karriere tutor,Nürnberg Mittelfranken
51.9606649,7.6261347,karriere tutor,Münster Westfalen
49.9928617,8.2472526,karriere tutor,Mainz am Rhein
52.1205333,11.6276237,karriere tutor,Magdeburg
47.9990077,7.842104299999999,karriere tutor,Freiburg im Breisgau
50.1467469,8.561455500000001,karriere tutor,Eschborn Taunus
49.8728253,8.6511929,karriere tutor,Darmstadt
48.6813312,9.0088299,karriere tutor,Böblingen
52.0302285,8.532470800000002,karriere tutor,Bielefeld
52.844198,8.053015799999999,karriere tutor,Cloppenburg
53.7513549,9.6632521,karriere tutor,Elmshorn
48.5788725,7.8160821,karriere tutor,Kehl Rhein



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы реализовали цикл ввода / обновления / выхода с холстом с использованием узлов DOM (в данном случае без рендеринга), но эти узлы DOM вообще не взаимодействуют с холстом - холст представляет собой набор пикселей без состояния. В результате любое взаимодействие мыши с холстом может взаимодействовать только с холстом в целом - пиксель не может иметь собственное событие щелчка мыши.
К счастью, существует ряд методов, с помощью которых можно отслеживать курсор мыши на холсте и связывать его с нарисованными фигурами.
Самый простой способ прямо из коробки - это, вероятно, использовать d3.forceSimulation без реальной симуляции. Он поставляется с удобным методом, который использует дерево квадратов для поиска узла, ближайшего к действию мыши (он также позволяет указать радиус поиска). Это дает преимущество в том, что его можно быстро кодировать и быстро выполнять, не беспокоясь о попытках узнать о четырехугольных деревьях. Если бы у вас были формы, отличные от кругов, это могло бы быть не идеально.
force.find (x, y, r) `есть только в d3v4 и далее, но похоже, что вы используете и d3v3, и d3v4, поэтому d3.forceSimulation будет работать в этом примере без изменений
Вот пример, который отслеживает, какой город находится ближе всего к указателю мыши при наведении курсора на холст:
Сначала мы устанавливаем узлы:
var simulation = d3.forceSimulation().nodes(dataset);
Затем находим положение мыши и находим ближайший узел:
var xy = d3.mouse(this); // get xy position of mouse
var longlat = projection.invert(xy); // convert it to a lat long
var nearest = simulation.find(longlat[1],longlat[0]); // see what point is closest.
Несколько примечаний здесь:
y в вашем CSV и ваши широты как x, это противоречит обычному соглашению, но чтобы избежать изменений в другом месте кода, я его сохранил. Вот почему near.find () использует здесь широту и долготу (y, x).x и y для отслеживания положения узла, поэтому я не указал никаких функций доступа, поскольку у вас уже есть свойства x, y в вашем наборе данных.Приведенные выше четыре или пять строк кода с небольшой модификацией функции наведения указателя мыши для отображения ближайшего к мыши города могут выглядеть как это
Я не указал радиус поиска, но помните, что он будет в градусах, поскольку симуляция работает с географическими координатами (d.x, d.y).
Элементы
divне являются частью HTML DOM, поэтому они не получают событий мыши. Подобно тому, как вы обновляете местоположение на карте, опустите мышь вниз, просмотрите список div и определите, какая точка нажата.