简体   繁体   中英

Adding expandable bars using d3.js

I am trying to get something as shown below:

在此处输入图片说明

This is the data I am using

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'
            ]
        }];

I want to add more such bars as one below another with some text beside it but I am failing. Bars like below.

在此处输入图片说明

Code of the same is here:

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

The width of the block should be the number of students under the category. and when hover on the bar it should display like this:

在此处输入图片说明

What I have tried so far is this

which is not desirable.

Any help is much appreciated.

Edit 2: I need this:

在此处输入图片说明

which is nothing but one bar showing the 5 categories each. Categories are: Struggling, Level one, Level Two, Level Three, and Mastered. Each category should represent unique color. And the number of students appearing under that category should appear as number. Rest of the animation part when hovered is already done.

Your question is very vague so I'll just shot into the dark. Is this what you're looking for? https://fiddle.jshell.net/70864r68/17/

Changed 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;
                });
          });
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM