D3更新的数据未传播到mouseover事件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了D3更新的数据未传播到mouseover事件相关的知识,希望对你有一定的参考价值。

我有一个多系列折线图,我可以选择根据选定的年份显示数据。除了工具提示之外,我的折线图工作得很好,它只是没有更新!

Dashboard

从上面可以看出,工具提示显示1994〜2013而不是2002~2008。

var crimeRate = multiLineChart.selectAll(".crimeRate")
  .data(rateCol);
//console.log("new_data", rateCol);
crimeRate.exit().remove();

var crimeRateEnter = crimeRate.enter().append("g")
  .attr("class", "crimeRate");

crimeRateEnter.append("path")
  .attr("class", "line")
  .attr("d", function(d) {
    return line(d.values);
  })
  .style("stroke", function(d) {
    return z(d.id);
  })
  .on("mouseover", function(d) {
    var xPosition = d3.mouse(this)[0];
    var yPosition = d3.mouse(this)[1] - 30;
    //console.log("Mouse X =", d3.mouse(this)[0], "
Mouse Y =", d3.mouse(this)[1]); 

    //Prevent tooltips from going out of screen		
    if (d3.mouse(this)[0] > (0.9 * svgLine.attr("width"))) {
      xPosition = xPosition - 0.05 * svgLine.attr("width");
    }
    if (d3.mouse(this)[1] < (0.1 * svgLine.attr("height"))) {
      yPosition = yPosition + (0.1 * svgLine.attr("height")) + 50;
    }
    //console.log("is it correct?", rateCol);

    var currentCrimeType = d.id,
      currentMinYear = getCrimeMinYear(currentCrimeType),
      currentMaxYear = getCrimeMaxYear(currentCrimeType),
      diffMinMax = getCrimeRateDiff(currentCrimeType, currentMinYear, currentMaxYear),
      percDiff = diffMinMax[0],
      rateMin = diffMinMax[1],
      rateMax = diffMinMax[2];

    var boxXPos = xPosition - 80;
    var boxYPos = yPosition - 60;
    
    multiLineChart.append("rect")
      .attr("class", "tooltipBox")
      .attr("rx", 10)
      .attr("ry", 10)
      .attr("id", "textBox")
      .attr("x", boxXPos)
      .attr("y", boxYPos)
      .attr("width", 180)
      .attr("height", 75)
      .attr("stroke", "black")
      .style("fill", "white")
      .style("opacity", 0.7);

    multiLineChart.append("text")
      .attr("class", "tooltipText")
      .attr("id", "tooltip")
      .attr("x", boxXPos + 10)
      .attr("y", boxYPos + 10)
      .attr("text-anchor", "middle")
      .attr("font-family", "Open Sans")
      .attr("font-size", "16px")
      .attr("fill", "black")
      .attr("text-anchor", "start")
      .append("tspan")
        .attr("font-weight", "bold")
        .attr("font-style", "italic")
        .attr("font-size", "18px")
        .attr("float", "left")
        .attr("x", boxXPos + 10)
        .attr("y", boxYPos + 20)
        .text(getFullName(d))
      .append("tspan")
        .attr("float", "left")
        .attr("font-weight", "normal")
        .attr("font-style", "normal")
        .attr("font-size", "16px")
        .attr("x", boxXPos + 10)
        .attr("y", boxYPos + 35)
        .text("Dropped by " + percDiff + "%")
      .append("tspan")
        .attr("x", boxXPos + 10)
        .attr("y", boxYPos + 50)
        .text("From " + rateMin + " to " + rateMax)
      .append("tspan")
        .attr("x", boxXPos + 10)
        .attr("y", boxYPos + 65)
        .text("In year " + currentMinYear + " to " + currentMaxYear);

    d3.select(this)
      .style("stroke", "#FFFF00")
      .style("stroke-width", "5px");
  })
  .on("mouseout", function(d) {
    d3.select("#tooltip").remove();
    d3.select("#textBox").remove();

    d3.select(this)
      .style("stroke", function(d) {
        return z(d.id);
      })
      .style("stroke-width", "2px")
  });

crimeRate.select("path")
  .transition()
  .duration(1000)
  .attr("d", function(d) {
    return line(d.values);
  });

上面的代码负责line和mouseover事件。

任何帮助表示赞赏,提前致谢!

答案

经过几个小时的研究,我找到了解决方案。

对于任何有相同问题并偶然发现的人,我通过分离鼠标悬停功能解决了它,我选择了“path”元素并在此处指定了mouseover事件。

代码片段:

var crimeRate = multiLineChart.selectAll(".crimeRate")
    .data(rateCol);
//console.log("new_data", rateCol);
crimeRate.exit().remove();

var crimeRateEnter = crimeRate.enter().append("g")
                                .attr("class", "crimeRate");

crimeRateEnter.append("path")
    .attr("class", "line")
    .attr("d", function(d) {return line(d.values); })
    .style("stroke", function(d) { return z(d.id); });

crimeRate.select("path")
    .transition()
    .duration(1000)
    .attr("d", function(d) {
        return line(d.values);
    });

crimeRate.select("path")
.on("mouseover", function(d) {
    var xPosition = d3.mouse(this)[0];
    var yPosition = d3.mouse(this)[1] - 30;
    //console.log("Mouse X =", d3.mouse(this)[0], "
Mouse Y =", d3.mouse(this)[1]); 

    //Prevent tooltips from going out of screen     
    if (d3.mouse(this)[0] > (0.9*svgLine.attr("width"))){
        xPosition = xPosition - 0.05 * svgLine.attr("width");
    }       
    if (d3.mouse(this)[1] < (0.1*svgLine.attr("height"))){
        yPosition = yPosition + (0.1*svgLine.attr("height")) + 50;
    }
    //console.log("is it correct?", rateCol);

    var currentCrimeType = d.id,
        currentMinYear = getCrimeMinYear(currentCrimeType), 
        currentMaxYear = getCrimeMaxYear(currentCrimeType), 
        diffMinMax = getCrimeRateDiff(currentCrimeType,currentMinYear,currentMaxYear),
        percDiff = diffMinMax[0],
        rateMin = diffMinMax[1],
        rateMax = diffMinMax[2];

    var boxXPos = xPosition - 80;
    var boxYPos = yPosition - 60;
    multiLineChart.append("rect")
            .attr("class", "tooltipBox")
            .attr("rx", 10)
            .attr("ry", 10)
            .attr("id","textBox")
            .attr("x", boxXPos)
            .attr("y", boxYPos)
            .attr("width", 180)
            .attr("height",75)
            .attr("stroke","black")
            .style("fill","white")
            .style("opacity", 0.7);

    multiLineChart.append("text")
            .attr("class", "tooltipText")
            .attr("id", "tooltip")
            .attr("x", boxXPos + 10)
            .attr("y", boxYPos + 10)
            .attr("text-anchor", "middle")
            .attr("font-family", "Open Sans")
            .attr("font-size", "16px")
            .attr("fill", "black")
            .attr("text-anchor","start")
        .append("tspan")
            .attr("font-weight", "bold")
            .attr("font-style", "italic")
            .attr("font-size", "18px")
            .attr("float","left")
            .attr("x", boxXPos + 10)
            .attr("y", boxYPos + 20)
            .text(getFullName(d))
        .append("tspan")
            .attr("float","left")
            .attr("font-weight", "normal")
            .attr("font-style", "normal")
            .attr("font-size", "16px")
            .attr("x", boxXPos + 10)
            .attr("y", boxYPos + 35)
            .text("Dropped by " + percDiff + "%")
        .append("tspan")
            .attr("x", boxXPos + 10)
            .attr("y", boxYPos + 50)
            .text("From " + rateMin + " to " + rateMax)
        .append("tspan")
            .attr("x", boxXPos + 10)
            .attr("y", boxYPos + 65)
            .text("In year " + currentMinYear + " to " + currentMaxYear);

        d3.select(this)
            .style("stroke", "#FFFF00")
            .style("stroke-width", "5px");
})
.on("mouseout", function(d) {
    d3.select("#tooltip").remove();
    d3.select("#textBox").remove();

    d3.select(this)
    .style("stroke", function(d) { return z(d.id); })
    .style("stroke-width", "2px")
});

以上是关于D3更新的数据未传播到mouseover事件的主要内容,如果未能解决你的问题,请参考以下文章

d3 - 触发鼠标悬停事件

在AngularJS指令中测试mouseover和mouseout事件

d3.js on event + jshint 可能严格违反

为啥Vue会更新父级中的变量-未使用事件

D3.js饼图动态更新转换未按预期工作

mouseover 事件时的鼠标位置