分组类别条形图与不同的组在d3? [英] grouped category bar chart with different groups in d3?

查看:109
本文介绍了分组类别条形图与不同的组在d3?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的要求是绘制一个类别分组的条形图,其中每个类别具有不同数量的组,使用纯d3。我不知道如何使用域和范围来满足我的要求。



我尝试了在


My requirement is to draw a category-grouped bar chart in which each category has a different number of groups, using pure d3. I have no idea how to take domain and range to meet my requirement.

I tried in the way given in the answer to d3 nested grouped bar chart, but it did not work in my case.

Here my graph structure is like:

解决方案

The issue with the plunker of the answer that you mention is that it will just work for values that have the same children. In order to handle the dynamic children values I took this approach

Lets create the color mapping for our groups:

var color = {
  Mechanical: '#4A7B9D',
  Electrical: '#54577C',
  Hydraulic: '#ED6A5A'
};

We also need a structure with nested values that will be the inner groups:

// Simulated data structure
var data = [{
  key: 'Mechanical',
  values: [{
    key: 'Gear',
    value: 11
  }, {
    key: 'Bearing',
    value: 8
  }, {
    key: 'Motor',
    value: 3
  }]
}];

I created a barPadding value which will dictate the separation between bars:

var barPadding = 120;

We are going to need a dummy scale to get the rangeBand of the bars, lets do that:

// dummy array
var rangeBands = [];
// cummulative value to position our bars
var cummulative = 0;
data.forEach(function(val, i) {
  val.cummulative = cummulative;
  cummulative += val.values.length;
  val.values.forEach(function(values) {
    rangeBands.push(i);
  })
});
// set scale to cover whole svg 
var x_category = d3.scale.linear()
  .range([0, width]);

// create dummy scale to get rangeBands (width/childrenValues)
var x_defect = d3.scale.ordinal().domain(rangeBands)
.rangeRoundBands([0, width], .1);
var x_category_domain = x_defect.rangeBand() * rangeBands.length;
x_category.domain([0, x_category_domain]);

Then lets add all our category groups g elements:

var category_g = svg.selectAll(".category")
  .data(data)
  .enter().append("g")
  .attr("class", function(d) {
    return 'category category-' + d.key;
  })
  .attr("transform", function(d) { // offset by inner group size
    var x_group = x_category((d.cummulative * x_defect.rangeBand()));
    return "translate(" + x_group + ",0)";
  })
  .attr("fill", function(d) { // make child elements of group "inherit" this fill
    return color[d.key];
  });

Adding our inner groups g elements:

var defect_g = category_g.selectAll(".defect")
  .data(function(d) {
    return d.values;
  })
  .enter().append("g")
  .attr("class", function(d) {
    return 'defect defect-' + d.key;
  })
  .attr("transform", function(d, i) { // offset by index
    return "translate(" + x_category((i * x_defect.rangeBand())) + ",0)";
  });

Having our g elements lets add the labels:

var category_label = category_g.selectAll(".category-label")
  .data(function(d) {
    return [d];
  })
  .enter().append("text")
  .attr("class", function(d) {
    console.log(d)
    return 'category-label category-label-' + d.key;
  })
  .attr("transform", function(d) {
    var x_label = x_category((d.values.length * x_defect.rangeBand() + barPadding) / 2);
    var y_label = height + 30;
    return "translate(" + x_label + "," + y_label + ")";
  })
  .text(function(d) {
    return d.key;
  })
  .attr('text-anchor', 'middle');

var defect_label = defect_g.selectAll(".defect-label")
  .data(function(d) {
    return [d];
  })
  .enter().append("text")
  .attr("class", function(d) {
    console.log(d)
    return 'defect-label defect-label-' + d.key;
  })
  .attr("transform", function(d) {
    var x_label = x_category((x_defect.rangeBand() + barPadding) / 2);
    var y_label = height + 10;
    return "translate(" + x_label + "," + y_label + ")";
  })
  .text(function(d) {
    return d.key;
  })
  .attr('text-anchor', 'middle');

And finally our rects:

var rects = defect_g.selectAll('.rect')
  .data(function(d) {
    return [d];
  })
  .enter().append("rect")
  .attr("class", "rect")
  .attr("width", x_category(x_defect.rangeBand() - barPadding))
  .attr("x", function(d) {
    return x_category(barPadding);
  })
  .attr("y", function(d) {
    return y(d.value);
  })
  .attr("height", function(d) {
    return height - y(d.value);
  });

Here's the above code in plnkr: https://plnkr.co/edit/L0eQwtEMQ413CpoS5nvo?p=preview

这篇关于分组类别条形图与不同的组在d3?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆