【问题标题】:Changing color for each stacked bar in D3.js更改 D3.js 中每个堆叠条的颜色
【发布时间】:2021-03-06 10:07:47
【问题描述】:

有人可以帮我更改 d3 中堆叠条的颜色吗?如果尝试了一些方法,但它不起作用。谢谢。

示例:

  1. admit_male - 浅蓝色
  2. admit_female - 深蓝色
  3. reject_male - 淡红色
  4. reject_female - 深红色

var 数据 = [ { 类别:“巴斯大学”, 承认_男性:512, 承认女:89, 拒绝男性:313, 拒绝女:19

  },
  {
    Category: "University Of Bristol",
    admit_male: 22,
    admit_female: 24,
    reject_male: 351,
    reject_female: 317
  },
  {
    Category: "University Of Greenwish",
    admit_male: 138,
    admit_female: 131,
    reject_male: 279,
    reject_female: 244
  },

];

var w=500,h=600,padding=40;
var svg=d3.select('body').append('svg')
            .attr('width', w)
            .attr('height', h);
var stack=d3.stack()
            .keys(['admit_male','admit_female','reject_male','reject_female']);

var datasets=[d3.stack().keys(['admit_male','admit_female'])(data),
              d3.stack().keys(['reject_male','reject_female'])(data)];

var num_groups=datasets.length;

var xlabels=data.map(function(d){return d['Category']});

var xscale=d3.scaleBand()
                .domain(xlabels)
                .range([padding,w-padding])
                .paddingInner(0.5);

var ydomain_min=d3.min(datasets.flat().map(function(row) {
                        return d3.min(row.map(function(d){return d[1];}));
                    }));
var ydomain_max=d3.max(datasets.flat().map(function(row) {
                        return d3.max(row.map(function(d){return d[1];}));
                    }));

var yscale=d3.scaleLinear()
                .domain([0,ydomain_max])
                .range([h-padding,padding]);

var accent = d3.scaleOrdinal(d3.schemeBlues[6]);
var xaxis=d3.axisBottom(xscale);
var yaxis=d3.axisLeft(yscale);

d3.range(num_groups).forEach(function(gnum) {
    svg.selectAll('g.group'+gnum)
        .data(datasets[gnum])
        .enter()
        .append('g')
            .attr('fill',accent)
            .attr('class', 'group'+gnum)
        .selectAll('rect')
        .data(d=>d)
        .enter()
        .append('rect')
            .attr('x',(d,i)=>xscale(xlabels[i])+(xscale.bandwidth()/num_groups)*gnum)
            .attr('y',d=>yscale(d[1]))
            .attr('width',xscale.bandwidth()/num_groups)
            .attr('height',d=>yscale(d[0])-yscale(d[1]));
        });

svg.append('g')
        .attr('class','axis x')
        .attr('transform','translate(0,'+(h-padding)+")")
    .call(xaxis);
svg.append('g')
        .attr('class','axis y')
        .attr('transform','translate('+padding+",0)")
        
    .call(yaxis);

【问题讨论】:

    标签: javascript html d3.js


    【解决方案1】:

    为颜色创建一个序数比例:

    const colorScale = d3.scaleOrdinal()
        .domain(['admit_male', 'admit_female', 'reject_male', 'reject_female'])
        .range(['#a4c5fd', '#4472b4', '#f36e92', '#b02d51']);
    

    并使用key 属性调用它:

    .attr('fill', d=>colorScale(d.key))
    

    这里是演示:

    var data = [{
        Category: "University Of Bath",
        admit_male: 512,
        admit_female: 89,
        reject_male: 313,
        reject_female: 19
    
      },
      {
        Category: "University Of Bristol",
        admit_male: 22,
        admit_female: 24,
        reject_male: 351,
        reject_female: 317
      },
      {
        Category: "University Of Greenwish",
        admit_male: 138,
        admit_female: 131,
        reject_male: 279,
        reject_female: 244
      },
    
    ];
    
    var w = 500,
      h = 600,
      padding = 40;
    var svg = d3.select('body').append('svg')
      .attr('width', w)
      .attr('height', h);
    var stack = d3.stack()
      .keys(['admit_male', 'admit_female', 'reject_male', 'reject_female']);
      
      const colorScale = d3.scaleOrdinal()
        .domain(['admit_male', 'admit_female', 'reject_male', 'reject_female'])
        .range(['#a4c5fd', '#4472b4', '#f36e92', '#b02d51']);
    
    var datasets = [d3.stack().keys(['admit_male', 'admit_female'])(data),
      d3.stack().keys(['reject_male', 'reject_female'])(data)
    ];
    
    var num_groups = datasets.length;
    
    var xlabels = data.map(function(d) {
      return d['Category']
    });
    
    var xscale = d3.scaleBand()
      .domain(xlabels)
      .range([padding, w - padding])
      .paddingInner(0.5);
    
    var ydomain_min = d3.min(datasets.flat().map(function(row) {
      return d3.min(row.map(function(d) {
        return d[1];
      }));
    }));
    var ydomain_max = d3.max(datasets.flat().map(function(row) {
      return d3.max(row.map(function(d) {
        return d[1];
      }));
    }));
    
    var yscale = d3.scaleLinear()
      .domain([0, ydomain_max])
      .range([h - padding, padding]);
    
    var accent = d3.scaleOrdinal(d3.schemeBlues[6]);
    var xaxis = d3.axisBottom(xscale);
    var yaxis = d3.axisLeft(yscale);
    
    d3.range(num_groups).forEach(function(gnum) {
      svg.selectAll('g.group' + gnum)
        .data(datasets[gnum])
        .enter()
        .append('g')
        .attr('fill', d=>colorScale(d.key))
        .attr('class', 'group' + gnum)
        .selectAll('rect')
        .data(d => d)
        .enter()
        .append('rect')
        .attr('x', (d, i) => xscale(xlabels[i]) + (xscale.bandwidth() / num_groups) * gnum)
        .attr('y', d => yscale(d[1]))
        .attr('width', xscale.bandwidth() / num_groups)
        .attr('height', d => yscale(d[0]) - yscale(d[1]));
    });
    
    svg.append('g')
      .attr('class', 'axis x')
      .attr('transform', 'translate(0,' + (h - padding) + ")")
      .call(xaxis);
    svg.append('g')
      .attr('class', 'axis y')
      .attr('transform', 'translate(' + padding + ",0)")
    
      .call(yaxis);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

    【讨论】:

    • 感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 2021-11-04
    • 2021-03-06
    • 2023-03-28
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    相关资源
    最近更新 更多