将mouseover事件添加到d3.js条形图

时间:2020-11-02 07:23:58

标签: html web d3.js

因此,我有一个带有按钮的条形图,这些按钮将更新预设的输入数据,现在我想包含工具提示,以便在悬停时从y轴显示数据。我尝试遵循一些可以找到但仍然失败的教程。下面是我到目前为止所做的事情,但是为了避免混淆,我取出了大部分数据。

以下代码我的类型未知:鼠标悬停

    var AU = [
   {group: "NSW", value: 871.8},
   {group: "VIC", value: 736.8},
   {group: "QLD", value: 517.9},
   {group: "SA", value: 460.1},
   {group: "WA", value: 498.5},
   {group: "TAS", value: 451.4},
   {group: "NT", value: 410.1},
   {group: "ACT", value: 699.1},
   {group: "Australia", value: 678.5}
];




// set the dimensions and margins of the graph
var margin = {top: 30, right: 30, bottom: 70, left: 60},
    width = 600 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

// append the svg object to the body of the page
var svg = d3.select("#my_dataviz")
  .append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform",
          "translate(" + margin.left + "," + margin.top + ")");

// Initialize the X axis
var x = d3.scaleBand().range([ 0, width ])
  .paddingInner(0.2);
var xAxis = svg.append("g")
  .attr("transform", "translate(0," + height + ")")

// Initialize the Y axis
var y = d3.scaleLinear()
  .range([ height, 0]);
var yAxis = svg.append("g")
  .attr("class", "myYaxis")




// A function that create / update the plot for a given variable:
function update(data) {

  // Update the X axis
  x.domain(data.map(function(d) { return d.group; }))
  xAxis.call(d3.axisBottom(x))


  // text label for the x axis

  // text label for the x axis
  svg.append("text")             
      .attr("transform",
            "translate(" + (width/2) + " ," + 
                           (height + margin.top + 20) + ")")
      .style("text-anchor", "middle")
      .text("Postcode");


  // Update the Y axis
  y.domain([0, d3.max(data, function(d) { return d.value }) ]);
  yAxis.transition().duration(1000).call(d3.axisLeft(y));

    svg.append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 0 - margin.left)
      .attr("x",0 - (height / 2))
      .attr("dy", "1em")
      .style("text-anchor", "middle")
      .text("Price ('000k)");  

  // Create the u variable
  var u = svg.selectAll("rect")
    .data(data)

  u
    .enter()
    .append("rect") // Add a new rect for each new elements
    .merge(u) // get the already existing elements as well
    .transition() // and apply changes to all of them
    .duration(1000)
      .attr("x", function(d) { return x(d.group); })
      .attr("y", function(d) { return y(d.value); })
      .attr("width", x.bandwidth())
      .attr("height", function(d) { return height - y(d.value); })
      .attr("fill", "#69b3a2")
          .on("mouseover", function(d){tooltip.text(d); return tooltip.style("visibility", "visible");})
      .on("mousemove", function(){return tooltip.style("top", (d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10)+"px");})
      .on("mouseout", function(){return tooltip.style("visibility", "hidden");});


  // If less group in the new dataset, I delete the ones not in use anymore
  u
    .exit()
    .remove()
}

// Initialize the plot with the first dataset
update(AU)

1 个答案:

答案 0 :(得分:0)

发生此错误的原因是,通过调用.transition(),所选元素将从d3.select的结果变为当前活动的过渡。尽管transition.on支持事件(“开始”,“结束”,“中断”),但不支持“鼠标悬停”。您可以通过将.on()移到呼叫.transition()之前 来解决此问题。我在下面说明了如何发生此错误。

const svg = d3.select("body")
  .append("svg");

svg
  .append("rect")
  .attr("width", 100)
  .attr("height", 100)
  .attr("fill", "blue")
  .on("mouseover", function() { d3.select(this).attr("fill", "red"); });

svg
  .append("rect")
  .attr("x", 100)
  .attr("width", 100)
  .attr("height", 100)
  .attr("fill", "white")
  .transition()
  .duration(500)
  .attr("fill", "green")
  .on("mouseover", function() { d3.select(this).attr("fill", "red"); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>