简体   繁体   English

我如何遍历 d3.select(this)

[英]How Do I iterate through d3.select(this)

I'm afraid I still don't understand d3-object.恐怕我还是不明白 d3-object。
I created d3-elements and assigned select.on("mouseover", onGraphicMouseOver) events to them.我创建了 d3-elements 并为它们分配了select.on("mouseover", onGraphicMouseOver)事件。
Now I'm in my function and have this .现在我在我的职能中并拥有this .

If I log this I get my straight svg-string:如果我记录this我会得到我的直接 svg-string:

<g id="a29" style="touch-action: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
  <line class="hotwater graphic" x1="270" y1="110" x2="540" y2="110" id="g29"></line>
  <line class="hotwater graphic" x1="270" y1="120" x2="540" y2="120"></line>
</g>

So far, so fine.到目前为止,一切都很好。

Now I want to wark with the lines, like assigning classes to them and for this, I want to iterate through them.现在我想解决这些问题,比如为它们分配类,为此,我想遍历它们。
What is the best way to do?最好的方法是什么?

My first idea:我的第一个想法:

for (var i = 0; i < this.childNodes.length; i++) {
    this.childNodes[i].classList.add("graphicmouseover");
}

But isn't there a simpler way, using d3.js.但是没有更简单的方法,使用 d3.js。
And if so, how can I find such informations by myself.如果是这样,我如何自己找到此类信息。 I now played around with d3 since many weeks but don't have a really complete idea of the concept.几个星期以来,我现在一直在玩 d3,但对这个概念还没有一个真正完整的概念。 Perhaps someone knows a more informative documentation than the original, for a dumb like me :(对于像我这样的笨蛋,也许有人知道比原版内容更丰富的文档:(
I really appreciate a helpful hint, so I don't have to annoy you with these noob-questions.我真的很感谢一个有用的提示,所以我不必用这些菜鸟问题来惹恼你。

Thanks Carsten谢谢卡斯滕

Update because of request: I load the svg-string of the inner element (here both lines) as text out of a database.由于请求而更新:我将内部元素(此处为两行)的 svg-string 作为文本从数据库中加载。 Then:然后:

function loadGraphicIntoEditor(svgGraphics, editor) {
//svgGraphics are the json-recordsets, editor is the d3.selected svg-area

  for (var i = 0; i < svgGraphics.length; i++) {
    var graphic = svgGraphics[i];

    const graph = editor.append("g")             //appending the g-tag to the svg-area
        .attr("id", "a" + graphic.Id.toString())
        .html(graphic.SvgString)                 //the string <line...></line>
        .on("mouseenter", onGraphicMouseEnter)
        .on("mouseover", onGraphicMouseOver)
        .on("mouseout", onGraphicMouseOut)
        .on("mousedown", onGraphicMouseDown)
        .on("dblclick", onGraphicDblClick)
        .on("contextmenu", onGraphicContext)
        .call(d3.drag()
            .on("start", graphicDragStart)
            .on("drag", graphicDragging)
            .on("end", graphicDragEnd));
    d3.select(graph.node().childNodes[0]).attr("id", "g" + graphic.Id.toString());
  }
}

FINAL UPDATE:最终更新:

This is my solution now:这是我现在的解决方案:

function onGraphicMouseOver(d, i) {
    d3.select(this).selectAll('.graphic').classed("graphicmouseover", true);
}

...life could be so easy :) ...生活可以如此简单:)

thank you guys谢谢你们

Try something like:尝试类似:

 var lines = d3.selectAll('line.hotwater'); //console.log(lines); lines.each(function(d,i) { //console.log(i, d, this); //console.log(this); d3.select(this) .attr("stroke", "black") .attr("stroke-width", "5px") })
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> <svg width="1000" height="1000" style="background:#ff0000"> <g id="a29" style="touch-action: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"> <line class="hotwater graphic" x1="270" y1="110" x2="540" y2="110" id="g29"></line> <line class="hotwater graphic" x1="270" y1="120" x2="540" y2="120"></line> </g> </svg>

Output:输出:

在此处输入图片说明

NOTE: I set the svg background to red in the HTML注意:我在 HTML 中将 svg 背景设置为红色

But then I used d3.selectAll('line.hotwater');但后来我使用了d3.selectAll('line.hotwater'); to select both of our lines.选择我们的两条线。 And then used lines.each() to loop over them.然后使用lines.each()循环它们。 And used d3.select(this) to turn that into a d3 selection which we can then modify like usual:并使用d3.select(this)将其转换为 d3 选择,然后我们可以像往常一样修改它:

d3.select(this)
    .attr("stroke", "black")
    .attr("stroke-width", "5px")

This adds the black stoke and the 5px stroke width to the lines so that we see them on the svg.这将向线条添加黑色笔触和 5px 笔触宽度,以便我们在 svg 上看到它们。

I am using d3.js V5.x here but I think the API has been like this for a few versions.我在这里使用 d3.js V5.x,但我认为 API 已经有几个版本是这样的。

Update: as OP clarified更新:正如 OP 所澄清的

Easiest method is just to use d3's selectAll:最简单的方法就是使用 d3 的 selectAll:

select(this).selectAll('.graphic').classed("graphicmouseover", true);

This is essentially doing a descendent querySelectorAll of “this” (from the event) and then looping over and setting the class for each of those selected.这本质上是执行“this”(来自事件)的后代 querySelectorAll,然后循环并为每个选定的对象设置类。 D3 manages this for us with its select all. D3 用它的全选为我们管理这个。

Update after understanding the OP's problem more fully.在更全面地了解 OP 的问题后更新。

Problem is that the events are attached to the group and not the lines.问题是事件附加到组而不是行。

But I think there is a way to achieve this with a pattern like:但我认为有一种方法可以通过以下模式实现这一目标:

const graph = editor.append("g")             //appending the g-tag to the svg-area
        .attr("id", "a" + graphic.Id.toString())
        .html(graphic.SvgString);                 //the string <line...></line>

    console.log(graph.selectAll('line.graphic').size()); //gives the size of the selection

    graph.selectAll('line.graphic')
        // .attr('stroke', 'blue')
        .on('click', onClick);

I tried to make a minimal reproducible example from the OP's code here: https://codepen.io/Alexander9111/pen/MWwmVLr我试图从这里的 OP 代码中制作一个最小的可重现示例: https : //codepen.io/Alexander9111/pen/MWwmVLr

Also here:也在这里:

 const svgGraphics = [ { Id: '29', SvgString: `<line class="hotwater graphic" x1="270" y1="110" x2="540" y2="110" id="g29"></line> <line class="hotwater graphic" x1="270" y1="120" x2="540" y2="120"></line>` } ] const editor = d3.select('svg'); loadGraphicIntoEditor(svgGraphics, editor); function onClick(d,i){ console.log('clicked'); //console.log(this); //or console.log(event.target); } function loadGraphicIntoEditor(svgGraphics, editor) { //svgGraphics are the json-recordsets, editor is the d3.selected svg-area for (var i = 0; i < svgGraphics.length; i++) { var graphic = svgGraphics[i]; const graph = editor.append("g") //appending the g-tag to the svg-area .attr("id", "a" + graphic.Id.toString()) .html(graphic.SvgString); //the string <line...></line> console.log(graph.selectAll('line.graphic').size()); graph.selectAll('line.graphic') // .attr('stroke', 'blue') .on('click', onClick); // .on("mouseenter", onGraphicMouseEnter) // .on("mouseover", onGraphicMouseOver) // .on("mouseout", onGraphicMouseOut) // .on("mousedown", onGraphicMouseDown) // .on("dblclick", onGraphicDblClick) // .on("contextmenu", onGraphicContext) // .call(d3.drag() // .on("start", graphicDragStart) // .on("drag", graphicDragging) // .on("end", graphicDragEnd)); d3.select(graph.node().childNodes[0]).attr("id", "g" + graphic.Id.toString()); } }
 line { stroke: black; stroke-width: 5px; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> <svg width="1000" height="1000" style="background:#ff0000"> </svg>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM