【问题标题】:Adding expandable bars using d3.js使用 d3.js 添加可扩展条
【发布时间】:2016-01-05 12:31:43
【问题描述】:

我正在尝试得到如下所示的东西:

这是我正在使用的数据

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

我想在另一个下方添加更多这样的条,旁边有一些文字,但我失败了。如下图所示。

相同的代码在这里:

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

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

到目前为止我尝试过的是this

这是不可取的。

非常感谢任何帮助。

编辑 2:我需要这个:

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

【问题讨论】:

  • 您介意勾勒出您要归档的内容吗?
  • 我正在尝试实现多个 bar 的 figure1 类型。
  • 抱歉,这并没有多大帮助。你的意思是你想要多个看起来相同的条堆叠在一起?
  • 是的,外观相同,但数据不同,旁边还有一些文字;说如果有两个条,那么它们的文本就是“bar1”和“bar2”。我不知道如何修改代码和相应代码中使用的数据。
  • 请在此处绘制图形草图并张贴图片

标签: javascript html css d3.js


【解决方案1】:

您的问题非常模糊,所以我将直接进入黑暗。这是你要找的吗? 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;
                });
          });
    }

【讨论】:

  • 非常感谢您的回复。我需要相同的解决方案,但 5 个块代表一个 bar 。你能把整个 var 分成 2 个小节吗?
  • 5 块代表一根柱?怎么样?请尽可能详细地描述您想要的最终结果,否则我们将一直在黑暗中拍摄。
  • 抱歉让休伯特感到困惑,我将尝试勾勒出我想要的结果并相应地编辑我的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-29
  • 2012-10-25
  • 2012-08-07
  • 1970-01-01
  • 2014-05-02
  • 2012-10-04
相关资源
最近更新 更多