d3 считает перекрывающиеся фигуры в точке - PullRequest
0 голосов
/ 25 августа 2018

У меня есть этот базовый рисунок эллипсов: https://codepen.io/almn22/pen/zJrWrd

Я пытаюсь сделать так, чтобы при наведении указателя мыши на область под текстовым выводом отображалось количество фигур в этой точке. Таким образом, в приведенном ниже примере, когда вы наводите курсор мыши на самую темную серую область, должен появиться текст «3».

Для моего реального случая использования формы являются случайными без предсказуемой формы, поэтому я не могу рассчитывать на то, что они являются эллипсами или кругами. Я строю их как полигоны SVG, используя d3js. У меня есть данные для полигонов, это просто атрибут "points".

Любая помощь будет принята с благодарностью!

<!DOCTYPE html>
<head>
  <meta charset="utf-8">
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <style>
    body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
    ellipse {
  stroke: white;
  fill: lightgray;
  mix-blend-mode: multiply;
}
  </style>
</head>

<body>
  <script>
    const svgContainer = d3.select("body")
  		.append("svg")
  		.attr("width","560")
  		.attr("height","900").attr("translate", "45, 45");

    const ellipses = [
  		{"cx":  145, "cy":  125, "rx": 88, "ry": 20},
  		{"cx":  175, "cy":  175, "rx": 88, "ry": 77},
  		{"cx": 225, "cy": 125, "rx": 88, "ry": 55},
  		{"cx": 275, "cy": 275, "rx": 88, "ry": 77}
		];

    const svgEllipses = svgContainer
  		.selectAll("ellipse")
  		.data(ellipses)
  		.enter()
  		.append("ellipse");

    svgEllipses
    	.attr("cx", (d,i) => { return d.cx; })
    	.attr("cy", (d,i) => { return d.cy; })
    	.attr("rx", (d,i) => { return d.rx; })
    	.attr("ry", (d,i) => { return d.ry; });
    

  </script>
</body>

1 Ответ

0 голосов
/ 06 января 2019

Это моё решение этого вопроса.

Основная идея заключается в том, что при нажатии все фигуры нечувствительны к мыши.Также счетчик n запускается с 0. Затем одна за другой каждая фигура становится чувствительной к мыши.Если мышь находится внутри фигуры, то счетчик n увеличивается на единицу: n++.

Надеюсь, это поможет.

let m = {};// mouse
let shapes = Array.from(document.querySelectorAll(".shape"));

svg.addEventListener("click", e => {  
  let n = 0;// a counter
  m = oMousePos(e);// thr mouse position on click
  shapes.map(s=>{
  // all the shapes are insensitive to the mouse
  shapes.map(_s=>{_s.style.pointerEvents = "none";})
  // this shape is the only one sensitive to the mouse in this moment
  s.style.pointerEvents = "all";
  // detecting if the mouse is inside the shape
  let elmt = document.elementFromPoint(m.x, m.y);
  // if it is and the element has className.baseVal == "shape"
  if(elmt.className.baseVal == "shape"){
    //increase tho counter
    n++
  };
});
  //use the counter
  console.log(n);
});

function oMousePos(evt) {
  return {
    x: evt.clientX,
    y: evt.clientY
  };
}
svg {
  border: 1px solid;
  display: block;
  margin: 0 auto;
}

.shape {
  mix-blend-mode: multiply;
}
<svg id="svg" width="500" height="400" translate="45, 45">
  <ellipse class="shape" cx="145" cy="125" rx="88" ry="20" fill="#aaa"></ellipse>
  <circle class="shape" cx="175" cy="175" r="88" fill="#bbb"></circle>
  <ellipse class="shape" cx="225" cy="125" rx="88" ry="55" fill="#ccc"></ellipse>
  <circle class="shape" cx="275" cy="275" r="77" fill="#ddd"></circle>
</svg>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...