D3 条形图可在单击按钮时更改数据源,但在按下按钮之前不会显示条形上的鼠标悬停工具提示

问题描述 投票:0回答:1

    var data1 = [
      { group: "A", value: 4 },
      { group: "B", value: 16 },
      { group: "C", value: 8 }
    ];

    var data2 = [
      { group: "A", value: 7 },
      { group: "B", value: 1 },
      { group: "C", value: 20 }
    ];

    var margin = { top: 30, right: 30, bottom: 70, left: 60 },
      width = 460 - margin.left - margin.right,
      height = 400 - margin.top - margin.bottom;

    var svg = d3.select("#viz")
      .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 + ")");

    var x = d3.scaleBand()
      .range([0, width])
      .domain(data1.map(function (d) { return d.group; }))
      .padding(0.2);
    svg.append("g")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.axisBottom(x))

    var y = d3.scaleLinear()
      .domain([0, 20])
      .range([height, 0]);
    svg.append("g")
      .attr("class", "myYaxis")
      .call(d3.axisLeft(y));

    // Initialize the bar chart with the first dataset
    update(data1)

    function update(data) {

      var u = svg.selectAll("rect")
        .data(data)

      u
        .enter()
        .append("rect")
        .merge(u)
        .transition()
        .duration(500)
        .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")

      u
        .on("mouseover", function (d) {
          console.log('d', d)
          var tooltip_str = d.group + ': ' + d.value
          tooltip.html(tooltip_str)
            .style("visibility", "visible");
        })
        .on("mousemove", function (d) {
          tooltip.style("top", event.pageY - (tooltip.node().clientHeight + 5) + "px")
            .style("left", event.pageX - (tooltip.node().clientWidth / 2.0) + "px");
        })
        .on("mouseout", function (d) {
          tooltip.style("visibility", "hidden");
        })

      var tooltip = d3.select("body").append("div")
        .attr("class", "tooltip");

    }
    .tooltip {
      background-color: #fff;
      color: #231F20;
      padding: 15px;
      opacity: .9;
      position: absolute;
      pointer-events: none;
      visibility: hidden;
      font-size: 16px;
      border: 1px solid #BCBDBC;
      font-style: italic;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<button onclick="update(data1)">Variable 1</button>
  <button onclick="update(data2)">Variable 2</button>

  <div id="viz"></div>

我有一个简单的条形图,单击按钮时会更新数据源。 代码来自https://d3-graph-gallery.com/graph/barplot_button_data_simple.html

我想向栏中添加工具提示。加载时,它们不会显示。但单击“变量 2”按钮后,它们确实显示了。当您单击“变量 1”时,它们就会显示。

我不明白为什么他们一开始不出现?我在鼠标悬停功能中添加了控制台日志,但它没有注册。

非常感谢任何帮助。

javascript d3.js
1个回答
0
投票

在您的代码片段中,变量

u
存储初始选择,即 empty(然后在该空选择上执行
.on
)。简单的修复方法是更新
u
以存储输入和合并的矩形。查看更新的片段:

var data1 = [
      { group: "A", value: 4 },
      { group: "B", value: 16 },
      { group: "C", value: 8 }
    ];

    var data2 = [
      { group: "A", value: 7 },
      { group: "B", value: 1 },
      { group: "C", value: 20 }
    ];

    var margin = { top: 30, right: 30, bottom: 70, left: 60 },
      width = 460 - margin.left - margin.right,
      height = 400 - margin.top - margin.bottom;

    var svg = d3.select("#viz")
      .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 + ")");

    var x = d3.scaleBand()
      .range([0, width])
      .domain(data1.map(function (d) { return d.group; }))
      .padding(0.2);
    svg.append("g")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.axisBottom(x))

    var y = d3.scaleLinear()
      .domain([0, 20])
      .range([height, 0]);
    svg.append("g")
      .attr("class", "myYaxis")
      .call(d3.axisLeft(y));

    // Initialize the bar chart with the first dataset
    update(data1)

    function update(data) {

      var u = svg.selectAll("rect")
        .data(data);
        
     u = u
        .enter()
        .append("rect")
        .merge(u);
        
     u.transition()
        .duration(500)
        .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")

      u
        .on("mouseover", function (d) {
          console.log('d', d)
          var tooltip_str = d.group + ': ' + d.value
          tooltip.html(tooltip_str)
            .style("visibility", "visible");
        })
        .on("mousemove", function (d) {
          tooltip.style("top", event.pageY - (tooltip.node().clientHeight + 5) + "px")
            .style("left", event.pageX - (tooltip.node().clientWidth / 2.0) + "px");
        })
        .on("mouseout", function (d) {
          tooltip.style("visibility", "hidden");
        })

      var tooltip = d3.select("body").append("div")
        .attr("class", "tooltip");

    }
.tooltip {
      background-color: #fff;
      color: #231F20;
      padding: 15px;
      opacity: .9;
      position: absolute;
      pointer-events: none;
      visibility: hidden;
      font-size: 16px;
      border: 1px solid #BCBDBC;
      font-style: italic;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<button onclick="update(data1)">Variable 1</button>
  <button onclick="update(data2)">Variable 2</button>

  <div id="viz"></div>

© www.soinside.com 2019 - 2024. All rights reserved.