使用d3.js添加可扩展条

时间:2016-01-05 12:31:43

标签: javascript html css d3.js

我想获得如下所示的内容:

enter image description here

这是我正在使用的数据

var student_data = [{
            category: 'Struggling',
            students: [
              'Ben',
              'Elizabeth'
            ]
        }, {
            category: 'Level One',
            students: [
              'Jessica',
              'Matt'
            ]
        },
        {
            category: 'Level Two',
            students: [
              'Luke',
              'Leia',
              'Han',
              'Chewbaca'
            ]
        },
        {
            category: 'Level Three',
            students: [
              'Obi-one',
              'Qui-Gon'
            ]
        }, {
            category: 'Mastered',
            students: [
              'John',
              'Katie'
            ]
        }];

我想在它旁边添加更多这样的条形图,旁边有一些文字,但我失败了。酒吧如下。

enter image description here

相同的代码在这里:

http://plnkr.co/edit/uG1OGO57g4Nad5d0m3Lm?p=preview

街区的宽度应该是该类别下的学生人数。当悬停在栏上时,它应显示如下:

enter image description here

到目前为止,我所尝试的是this

这是不可取的。

非常感谢任何帮助。

编辑2:我需要这个:

enter image description here

这只是一个显示每个5个类别的栏。类别包括:苦苦挣扎,第一级,第二级,第三级和掌握。每个类别应代表独特的颜色。出现在该类别下的学生人数应显示为数字。悬停时剩余的动画部分已经完成。

1 个答案:

答案 0 :(得分:2)

你的问题很模糊,所以我只是陷入黑暗中。这是你在找什么? https://fiddle.jshell.net/70864r68/17/

改变了JS:

var student_data = [{
        classes:'class1',
        category: 'Struggling',
        students: [
          'Ben',
        ]
    }, 
    {
        classes:'class1',
        category: 'Struggling',
        students: []
    },
    {
        classes:'class1',
        category: 'Struggling',
        students: [
          'Ben',
          'Elizabeth'
        ]
    },{
        classes: 'class1',
        category: 'Level One',
        students: [
          'Jessica',
          'Matt'
        ]
    },
    {
        classes: 'class1',
        category: 'Level Two',
        students: [
          'Luke',
          'Leia',
          'Han',
          'Chewbaca'
        ]
    },
    {
        classes: 'class1',
        category: 'Level Three',
        students: [
          'Obi-one',
          'Qui-Gon'
        ]
    }, {
        classes: 'class1',
        category: 'Mastered',
        students: [
          'John',
          'Katie'
        ]
    }, {
        classes: 'class2',
        category: 'Struggling',
    students: [
      'Benten',
      'Elizabeth Hurly',
      'Obi wan Kenobi'
    ]
    }, {
        classes: 'class2',
        category: 'Level One',
        students: [
          'Jessica simpson',
          'Matt Demon'
        ]
    },
    {
    classes: 'class2',
        category: 'Level Two',
    students: [
      'Liam',
      'Leisa',
      'Huston',
      'Chan'
    ]
    },
    {
        classes: 'class2',
        category: 'Level Three',
        students: [
          'Orlando',
          'Quintoon Terento'
        ]
    }, {
    classes: 'class2',
        category: 'Mastered',
    students: [
      'Johny',
      'Kate'
    ]
    }];

    // 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, 5])
          .range(['red', 'grey', 'lightblue', 'darkblue', 'pink', 'green']);

    for (var i = 0; i < student_data.length; i++) {
        // 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(d.students.length);
          })
          .style('padding-right', function(d, i) {
            return 1 + d.students.length + "rem";
          })
          // 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;
                });
          });
    }