功能mousemove代码在d3.js堆栈式条形图中不起作用

时间:2019-05-01 10:07:13

标签: d3.js

我尝试结合多个鼠标事件,这些事件是我从https://www.d3-graph-gallery.com/graph/barplot_stacked_hover.htmlhttps://www.d3-graph-gallery.com/graph/barplot_stacked_highlight.html中摘取的。

不幸的是,mousemove功能不起作用。如第一个示例所示,我想在鼠标后面显示“工具提示”。

// set the dimensions and margins of the graph
var margin = {
    top: 10,
    right: 30,
    bottom: 20,
    left: 50
  },
  width = 460 - margin.left - margin.right,
  height = 400 - 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 + ")");

// Parse the Data
d3.csv("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/data_stackedXL.csv").then(function(data) {

  // List of subgroups = header of the csv files = soil condition here
  var subgroups = data.columns.slice(1)

  // List of groups = species here = value of the first column called group -> I show them on the X axis
  var groups = d3.map(data, function(d) {
    return (d.group)
  }).keys()

  // Add X axis
  var x = d3.scaleBand()
    .domain(groups)
    .range([0, width])
    .padding([0.2])
  svg.append("g")
    .attr("transform", "translate(0," + height + ")")
    .call(d3.axisBottom(x).tickSizeOuter(0));

  // Add Y axis
  var y = d3.scaleLinear()
    .domain([0, 120])
    .range([height, 0]);
  svg.append("g")
    .call(d3.axisLeft(y));

  // color palette = one color per subgroup
  var color = d3.scaleOrdinal()
    .domain(subgroups)
    .range(d3.schemeSet2);

  //stack the data? --> stack per subgroup
  var stackedData = d3.stack()
    .keys(subgroups)
    (data)

  // ----------------
  // Highlight a specific subgroup when hovered
  // ----------------

  // ----------------
  // Create a tooltip
  // ----------------
  var tooltip = d3.select("#my_dataviz")
    .append("div")
    .style("opacity", 0)
    .attr("class", "tooltip")
    .style("background-color", "white")
    .style("border", "solid")
    .style("border-width", "1px")
    .style("border-radius", "5px")
    .style("padding", "1px")




  // What happens when user hover a bar
  var mouseover = function(d) {
    // what subgroup are we hovering?
    var subgroupName = d3.select(this.parentNode).datum().key; // This was the tricky part
    var subgroupValue = d.data[subgroupName];

    // Reduce opacity of all rect to 0.2
    d3.selectAll(".myRect").style("opacity", 0.2)
    // Highlight all rects of this subgroup with opacity 0.8. It is possible to select them since they have a specific class = their name.
    d3.selectAll("." + subgroupName)
      .style("opacity", 1)

    tooltip
      .html("subgroup: " + subgroupName + "<br>" + "Value: " + subgroupValue)
      .style("opacity", 1)
  }

  var mousemove = function(d) {
    tooltip
      .style("left", (d3.mouse(this)[0] + 90) + "px") // It is important to put the +90: other wise the tooltip is exactly where the point is an it     creates a weird effect
      .style("top", (d3.mouse(this)[1]) + "px")
  }

  // When user do not hover anymore
  var mouseleave = function(d) {
    // Back to normal opacity: 0.8
    d3.selectAll(".myRect")
      .style("opacity", 0.8)
    tooltip
      .style("opacity", 0)

  }

  // Show the bars
  svg.append("g")
    .selectAll("g")
    // Enter in the stack data = loop key per key = group per group
    .data(stackedData)
    .enter().append("g")
    .attr("fill", function(d) {
      return color(d.key);
    })
    .attr("class", function(d) {
      return "myRect " + d.key
    }) // Add a     class to each subgroup: their name
    .selectAll("rect")
    // enter a second time = loop subgroup per subgroup to add all rectangles
    .data(function(d) {
      return d;
    })
    .enter().append("rect")
    .attr("x", function(d) {
      return x(d.data.group);
    })
    .attr("y", function(d) {
      return y(d[1]);
    })
    .attr("height", function(d) {
      return y(d[0]) - y(d[1]);
    })
    .attr("width", x.bandwidth())
    .attr("stroke", "grey")
    .on("mouseover", mouseover)
    .on("mousemove", mousemove)
    .on("mouseleave", mouseleave)

})
<head>
  <script src="https://d3js.org/d3.v5.min.js"></script>
  <script src="https://d3js.org/d3-scale-chromatic.v1.min.js "></script>
</head>

<body>
  <div id="my_dataviz"></div>
</body>

0 个答案:

没有答案