简体   繁体   English

如何遍历数组以将HTML分配给工具提示

[英]How can I Loop through array to assign html to tooltip

I have a line chart and am trying to add html to a mouseover/tooltip on my legend. 我有一个折线图,正尝试将HTML添加到图例上的mouseover / tooltip。 I want to loop through the array (full_names) so that 'full_names[0]' is displayed in the tooltip on the first legend line, 'full_names[1]' one the second, etc. Currently, they all display 'full_names[0]'. 我想遍历数组(full_names),以便在第一条图例行的工具提示中显示“ full_names [0]”,在第二条图例行的工具提示中显示“ full_names [1]”,等等。目前,它们都显示“ full_names [0]” ]”。 Why do my full_names not loop through correctly? 为什么我的full_names无法正确循环?

id_list is also an array that I loop through in order to sequentially assign id's. id_list也是我循环遍历的数组,以便顺序分配id。

my legend: 我的传说:

var lineLegend = svg.selectAll(".lineLegend").data(id_list)
        .enter().append("g")
        .attr("class", "lineLegend")
        .attr("id", function (d, i) { return id_list[i % id_list.length] 
        })
        .attr("transform", function (d, i) {
            return "translate(" + width + "," + (i * 20) + ")";
        })

        .on("click", function (id) {
            var this_chart = d3.select("#temperature_graph")
            var liney = this_chart.select("#" + id)
            var alldots = this_chart.selectAll("." + id)
            var isActive = liney.classed("active");
            var dotsActive = alldots.classed("active")
            console.log(liney)
            liney.classed("active", !isActive);
            alldots.classed("active", !dotsActive)
        })
        .on("mouseover", function (i) {
            div.transition()
                .duration(100)
                .style("opacity", .9);

I want to loop through the array (full_names) here: 我想在这里遍历数组(full_names):

 div.html( function (d, i) { return full_names[i % full_names.length]})
                .style('color', '#404040')
                .style("left", (d3.event.pageX) + "px")
                .style("top", (d3.event.pageY - 28) + "px");
        })

the rest: 其余的部分:

        .on("mouseout", function (d) {
            div.transition()
                .duration(500)
                .style("opacity", 0);
        });
 lineLegend.append("text").text(function (d) {
            return d;}).attr("transform", 
       "translate(-94,15)").style("font-family", "Sans- 
       Serif").style('fill', '#5a5a5a'); //align texts with boxes
 lineLegend.append("rect")
            .attr("fill", function (d, i) { return colors[i % 
       colors.length] })
            .attr("width", 12).attr("height", 10).attr("transform", 
       "translate(-32,4)").attr("rx", "3");

I think that I may have a scoping issue with my array? 我认为我的阵列可能存在范围问题? As in, I can correctly loop through id_list, just not full_names. 如图所示,我可以正确遍历id_list,而不是full_names。 Both variables were created in the same place. 这两个变量都在同一位置创建。 Is that because id_list is included in my var linelegend? 那是因为id_list包含在我的var linelegend中吗?

Thanks so much!! 非常感谢!!

The problem here is this: i in your html() anonymous function refers to the index of the div , and that will be always 0. Instead of that, you want to get the index of the lineLegend you hover over. 这里的问题是这样的: i在您的html()匿名函数中引用div的索引,并且该索引始终为0。取而代之的是,您希望获得将鼠标悬停在lineLegend的索引。

Here are some brief examples. 这里有一些简短的例子。 Right now you're doing this: 现在,您正在执行此操作:

lineLegend.on("mouseover", function(d,i){
    tooltip.html(function(d,i){
        //here, 'i' is the index of the 'tooltip', always 0.
    });
});

As you can see, the index in the outer anonymous function is not the same of the index in the inner anonymous function. 正如你所看到的,在外部匿名函数的指数是一样的内部匿名函数的索引。

It should be: 它应该是:

lineLegend.on("mouseover", function(d,i){
    tooltip.html(function(){
        //here, 'i' is the index of the 'lineLegend'.
    });
});

Or, if you want to use parameters in the html() anonymous function, give them other names: 或者,如果要在html()匿名函数中使用参数,请给它们其他名称:

It should be: 它应该是:

lineLegend.on("mouseover", function(d,i){
    tooltip.html(function(e,j){//no 'i' here
        //here, 'i' is the 'lineLegend' index and 'j' the tooltip index
    });
});

And here are some demos. 这是一些演示。 First, using the incorrect i , you can see that the "tooltip" always shows name1 : 首先,使用不正确的i ,您可以看到“ tooltip”始终显示name1

 var fullNames = ["name1", "name2", "name3"]; var tooltip = d3.select("#tooltip"); var p = d3.select("body") .selectAll(null) .data(["foo", "bar", "baz"]) .enter() .append("p") .text(String); p.on("mouseover", function(d, i) { tooltip.html(function(d, i) { return fullNames[i] }) }) 
 #tooltip { width: 100%; background-color: wheat; } 
 <script src="https://d3js.org/d3.v5.min.js"></script> <div id="tooltip">Tooltip</div> 

Now the same code, referencing the correct i : 现在相同的代码,引用正确的i

 var fullNames = ["name1", "name2", "name3"]; var tooltip = d3.select("#tooltip"); var p = d3.select("body") .selectAll(null) .data(["foo", "bar", "baz"]) .enter() .append("p") .text(String); p.on("mouseover", function(d, i) { tooltip.html(function() { return fullNames[i] }) }) 
 #tooltip { width: 100%; background-color: wheat; } 
 <script src="https://d3js.org/d3.v5.min.js"></script> <div id="tooltip">Tooltip</div> 

Finally, an advice: don't do what you're trying to do (using the element's indices to get values in another array), that's not the idiomatic D3. 最后,一个建议:不要做您想做的事情(使用元素的索引来获取另一个数组中的值),这不是惯用的D3。 Just bind the data. 只需绑定数据。 That way, things are clear and won't break unexpectedly. 这样一来,事情就很清楚了,不会意外中断。

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

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