javascript - 使用 d3.js 的可扩展堆叠条形图

标签 javascript d3.js charts

我正在尝试创建堆叠条形图,这样当您单击它们时,它会为您提供有关该堆叠的更多详细信息。

考虑每个条形代表一个主题,条形中的每个部分代表学生在六个不同级别学习该主题的掌握程度:比如说 1 级到 6 级; 1 级 - 学生的表现很差,6 级表示学生已经掌握了这门学科

假设最初堆叠的条形图如下所示:

enter image description here

如果您选择一个主题,可以说是实体几何。

然后我点击其中一个栏:

enter image description here

如上所示,可以看到有 4 名学生在这门课上苦苦挣扎,而 4 名学生需要练习这门课......等等......

然后堆叠条将以这种方式扩展,为我提供有关 enter image description here 的更多信息

我们如何在 D3 中做到这一点?

感谢任何帮助。

最佳答案

我没有看到任何关于学习或使用 D3 的研究或尝试。虽然 D3 最初可能令人望而生畏,但文档使它变得相当平易近人,如果您的问题稍微具体一点,您可能会在这里获得更多关注。

也就是说,请看下面的示例。您将看到 D3 是将数据映射到元素和编排 DOM 操作的助手。另请注意,普通的旧 CSS 可以完成大部分交互性要求。最后,了解您可以通过多种不同的方式完成这些;这只是一个快速的技巧。

var student_data = [{
  category: 'Struggling',
  students: [
    'Ben',
    'Elizabeth'
  ]
}, {
  category: 'Level One',
  students: [
    'Jessica',
    'Matt'
  ]
}, {
  category: 'Mastered',
  students: [
    'John',
    'Katie'
  ]
}];

// the quantile scale maps an input domain of
// values to an output range of values by 'spreading'
// the domain across the range.
var colors = d3.scale.quantile()
  .domain([0, student_data.length])
  .range(['red', 'grey', 'lightblue', 'darkblue']);

// the base element
var root = d3.select('.panel');

// selectAll ~= querySelectorAll
// says, find all elements with class 'category'
// if none exist, prepare a selection of
// student_data.length elements
var display = root.selectAll('.category')
  .data(student_data);

// take the prepared selection and
// for each
display.enter()
  // create an element
  .append('div')
  // assign the 'category' class to the element
  .attr('class', 'category')
  // set the background color
  .style('background-color', function(d, i) {
    // d is the current array element of student_data
    // i is the index of the current array element of student_data
    // so, pass i to the colors scale/map to get back a color
    return colors(i);
  })
  // add a mouse enter handler to set the text of a
  // yet to be added label.
  .on('mouseenter', function(d) {
    // this is the current element
    d3.select(this)
      // so, select the first element
      // with class label
      .select('.label')
      // and set it's text to the category property
      // of current array element of student_data
      .text(d.category);
  })
  // add a mouse leave handler to reset the text of the still
  // yet to be added label.
  .on('mouseleave', function(d) {
    d3.select(this).select('.label').text(d.students.length);
  })
  // for each created element
  .each(function(d) {
    // select the current element
    var selection = d3.select(this);
    // create the label referenced above
    var label = selection.append('div')
      // assign it a class of 'label'
      .attr('class', 'label')
      // and set it's text to count of
      // the students property
      .text(function(d) {
        // d = student_data[i]
        return d.students.length;
      });
    // also, prepare a new selection of
    // elements for each of the student names
    var names = selection
      .selectAll('.student')
      .data(d.students);
    // take the prepared selection and
    // for each
    names.enter()
      // create an element
      .append('div')
      // assign the 'student' class
      .attr('class', 'student')
      // and set the text to that
      // of the current element
      .text(function(dd) {
        // dd = student_data[i].students[j]
        return dd;
      });
  });
div {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  font-family: arial;
}
.panel {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-box-align: start;
  -webkit-align-items: flex-start;
  -ms-flex-align: start;
  align-items: flex-start;
  width: 100%;
  font-size: 0.8rem;
}
.category {
  display: inline-block;
  padding: 0.5rem;
  min-width: 2rem;
  min-height: 2rem;
  color: white;
  background-color: black;
  transition: all 250ms ease;
}
.category:hover {
  min-width: 10rem;
  width: auto;
  height: auto;
  transition: all 250ms ease;
}
.label {
  transition: all 250ms ease;
}
.student {
  display: none;
  padding: 0.25rem;
  width: 100%;
  color: black;
  background-color: white;
  cursor: pointer;
  transition: all 250ms ease;
}
.student:hover {
  background-color: lightblue;
}
.category:hover .label {
  padding-bottom: 0.5rem;
}
.category:hover .student {
  display: inline-block;
}
<div class='panel'></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

关于javascript - 使用 d3.js 的可扩展堆叠条形图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34409750/

相关文章:

c# - Winforms图表: how to enable background color gauge

php - 如何在 php 中划分系列以创建用于 google 图表的 json 表

android - 安卓雷达图

javascript - IE8 将缓存中的动态 iframe 内容重新加载到错误的 iframe 中

Javascript DOM 操作,每次点击创建一个新的 li 元素

javascript - 有没有办法自动逐个节点打开 D3 折叠树(对于有子节点的节点)?

javascript - D3.js更改时间格式并将数据导出为csv

javascript - Angular ng-repeat with condition

javascript - 使用 JavaScript 中对象的值获取键?

javascript - 将数据值存储在 JSON 文件中