javascript - 将包含特定数据的鼠标悬停添加到 d3.js 树形图

标签 javascript d3.js

我使用 d3.js 组合了以下树状图。就选民投票率而言,它是前 20 名的州。 Link

我不确定如何将“值”添加到悬停中。理想情况下,它应该显示每个状态的唯一值。我可以为一个人(例如加利福尼亚州)做这件事,但我不确定如何使其灵活,以便它为不同的州生成其他值。

let margin = {
    top: 0,
    right: 0,
    bottom: 0,
    left: 0
  },
  width = 1100 - margin.left - margin.right,
  height = 900 - margin.top - margin.bottom;

// append the svg object to the body of the page
let svg = d3
  .select('#treemap')
  .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 + ')');
// Read data
d3.csv('https://raw.githubusercontent.com/oihamza/Interactive-Data-Vis-Fall2020/master/Project%201/stateVoterTurnout.csv', function(data) {
  // stratify the data: reformatting for d3.js
  var root = d3
    .stratify()
    .id(function(d) {
      return d.name;
    }) // Name of the entity (column name is name in csv)
    .parentId(function(d) {
      return d.parent;
    })(
      // Name of the parent (column name is parent in csv)
      data
    );

  // data is an object
  console.log(data);

  let values = data[1].value;

  let tooltip = d3
    .select('body')
    .append('div')
    .style('position', 'absolute')
    .style('z-index', '10')
    .style('visibility', 'hidden')
    .style('background-color', 'white')
    .style('border', 'solid')
    .style('border-width', '2px')
    .style('border-radius', '5px')
    .style('padding', '5px')
    .text(`${values} voters`);

  root.sum(function(d) {
    return +d.value;
  }); // Compute the numeric value for each entity

  // Then d3.treemap computes the position of each element of the hierarchy
  // The coordinates are added to the root object above
  d3.treemap().size([width, height]).padding(3)(root);

  console.log(root.leaves());
  // use this information to add rectangles:

  svg
    .selectAll('rect')
    .data(root.leaves())
    .enter()
    .append('rect')
    .attr('x', function(d) {
      return d.x0;
    })
    .attr('y', function(d) {
      return d.y0;
    })
    .attr('width', function(d) {
      return d.x1 - d.x0;
    })
    .attr('height', function(d) {
      return d.y1 - d.y0;
    })
    .style('stroke', 'black')
    .style('fill', '#945f04')
    .on('mouseover', function() {
      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');
    });

  // and to add the text labels

  svg
    .selectAll('text')
    .data(root.leaves())
    .enter()
    .append('text')
    .attr('x', function(d) {
      return d.x0 + 10;
    }) // +10 to adjust position (more right)
    .attr('y', function(d) {
      return d.y0 + 20;
    }) // +20 to adjust position (lower)
    .text(function(d) {
      return d.data.name;
    })
    .attr('font-size', '15px')
    .attr('fill', 'white');
});
body,
h1,
h2,
h3,
h4,
h5,
h6 {
  font-family: "Montserrat", sans-serif
}

.styling {
  transform-origin: center center;
  align-content: center;
  position: relative;
}

.tooltip {
  position: relative;
  display: inline-block;
  /* border-bottom: 1px dotted black; */
}

.tooltip .tooltiptext {
  visibility: hidden;
  width: 180px;
  background-color: black;
  color: #fff;
  text-align: center;
  border-radius: 6px;
  padding: 5px 0;
  /* Position the tooltip */
  position: absolute;
  z-index: 1;
}

.tooltip:hover .tooltiptext {
  visibility: visible;
}
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Montserrat">
<span class="styling"><div id="treemap"></div></span>

<!-- Loading this version of d3 -->
<script src="https://d3js.org/d3.v4.js"></script>

最佳答案

当您mouseovermousemove 矩形时,您会发现它被分配了带有第一个参数的数据(通常称为d)——就像当您使用 .attr() 设置属性或使用 .style() 设置样式时,您会这样做。

您可以使用此 d 动态设置工具提示的 .text():

let margin = {
    top: 0,
    right: 0,
    bottom: 0,
    left: 0
  },
  width = 1100 - margin.left - margin.right,
  height = 900 - margin.top - margin.bottom;

// append the svg object to the body of the page
let svg = d3
  .select('#treemap')
  .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 + ')');
// Read data
d3.csv('https://raw.githubusercontent.com/oihamza/Interactive-Data-Vis-Fall2020/master/Project%201/stateVoterTurnout.csv', function(data) {
  // stratify the data: reformatting for d3.js
  var root = d3
    .stratify()
    .id(function(d) {
      return d.name;
    }) // Name of the entity (column name is name in csv)
    .parentId(function(d) {
      return d.parent;
    })(
      // Name of the parent (column name is parent in csv)
      data
    );

  let tooltip = d3
    .select('body')
    .append('div')
    .style('position', 'absolute')
    .style('z-index', '10')
    .style('visibility', 'hidden')
    .style('background-color', 'white')
    .style('border', 'solid')
    .style('border-width', '2px')
    .style('border-radius', '5px')
    .style('padding', '5px');

  root.sum(function(d) {
    return +d.value;
  }); // Compute the numeric value for each entity

  // Then d3.treemap computes the position of each element of the hierarchy
  // The coordinates are added to the root object above
  d3.treemap().size([width, height]).padding(3)(root);
  // use this information to add rectangles:

  svg
    .selectAll('rect')
    .data(root.leaves())
    .enter()
    .append('rect')
    .attr('x', function(d) {
      return d.x0;
    })
    .attr('y', function(d) {
      return d.y0;
    })
    .attr('width', function(d) {
      return d.x1 - d.x0;
    })
    .attr('height', function(d) {
      return d.y1 - d.y0;
    })
    .style('stroke', 'black')
    .style('fill', '#945f04')
    .on('mouseover', function() {
      tooltip.style('visibility', 'visible');
    })
    .on('mousemove', function(d) {
      tooltip
        .style('top', d3.event.pageY - 10 + 'px')
        .style('left', d3.event.pageX + 10 + 'px')
        .text(`${d.data.value} voters`);
    })
    .on('mouseout', function() {
      tooltip.style('visibility', 'hidden');
    });

  // and to add the text labels

  svg
    .selectAll('text')
    .data(root.leaves())
    .enter()
    .append('text')
    .attr('x', function(d) {
      return d.x0 + 10;
    }) // +10 to adjust position (more right)
    .attr('y', function(d) {
      return d.y0 + 20;
    }) // +20 to adjust position (lower)
    .text(function(d) {
      return d.data.name;
    })
    .attr('font-size', '15px')
    .attr('fill', 'white');
});
body,
h1,
h2,
h3,
h4,
h5,
h6 {
  font-family: "Montserrat", sans-serif
}

.styling {
  transform-origin: center center;
  align-content: center;
  position: relative;
}

.tooltip {
  position: relative;
  display: inline-block;
  /* border-bottom: 1px dotted black; */
}

.tooltip .tooltiptext {
  visibility: hidden;
  width: 180px;
  background-color: black;
  color: #fff;
  text-align: center;
  border-radius: 6px;
  padding: 5px 0;
  /* Position the tooltip */
  position: absolute;
  z-index: 1;
}

.tooltip:hover .tooltiptext {
  visibility: visible;
}
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Montserrat">
<span class="styling"><div id="treemap"></div></span>

<!-- Loading this version of d3 -->
<script src="https://d3js.org/d3.v4.js"></script>

在这些 .on() 函数中没有必要返回任何东西。

关于javascript - 将包含特定数据的鼠标悬停添加到 d3.js 树形图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64851125/

相关文章:

javascript - React,列表中的每个 child 都应该有一个唯一的 key prop

javascript - 长文本的省略号

javascript - d3 转换后调用函数

javascript - d3 处理多个数组中的数据

JavaScript将纯文本转换为链接&&表情符号

javascript - 避免检测到 "whether Chrome DevTools(console) is open"

javascript - 将动态内容设置为 iframe

javascript - 条形图中的 rangeRoundBands outerPadding 太大了

javascript - PubNub Twitter 数据流设置不返回数据

javascript - 如何将模板变量传递给 Vue js 中的事件处理方法