d3js 堆叠柱状图

  这一章节介绍堆叠柱状图的画法,下面直接上图和数据。

 

 

 

  1、准备数据

const stackBarData = [
            { year: 2015, HW: 3740, XM: 920, MAC: 980, www: 490 },
            { year: 2016, HW: 1400, XM: 1840, MAC: 960, www: 1400 },
            { year: 2017, HW: 640, XM: 930, MAC: 620, www: 400 },
            { year: 2018, HW: 920, XM: 480, MAC: 1600, www: 400 }
        ];
const stackBarKeys = Object.keys(stackBarData[0]).splice(1, 5);
 // 1、处理数据
  const data = d3.stack()
                 .keys(stackBarKeys)
                 .order(d3.stackOrderNone)(stackBarData);
 

  为了方便起见,这边在知道长度的情况下获取了每个柱子区间对应的label。

  2、create dimensions

const dms = {
      width: 1400,
      height: 600,
      margin: {
        top: 50,
        right: 150,
        left: 30,
        bottom: 50
        }
      }
dms.innerWidth = dms.width - dms.margin.left - dms.margin.right;
dms.innerHeight = dms.height - dms.margin.top - dms.margin.bottom;

  3、draw canvas

const mainsvg = d3.select('#stack-bar')
         .append('svg')
         .attr('width', dms.width)
         .attr('height', dms.height)
const maingroup = mainsvg.append('g')
          .attr('transform', `translate(${dms.margn.left}, ${dms.margin.top)`)
const stackBarArea = maingroup.append('g')
                            .attr('id', 'stack-bar-area')

  4、create scale and color

const xScale = d3.scaleBand()
        .domain(stackBarData.map(d=>d.year))
        .range([0, dms.innerWidth])
        .padding(0.2) // 柱子之间的距离

const yScale = d3.scaleLinear()
        .domain([0, d3.max(data, d=>d3.max(d, subd =>subd[1]))])
        .range([dms.innerHeight, 0])
        .nice()

const colors = d3.scaleOrdinal()
        .domain(stackBarKeys)
        .range(d3.schemeCategory10)   // 10种颜色

  5、draw data

const dataGroup = stackBarArea.selectAll('g')
                    .data(data)
                    .join('g')
                    .attr('class', 'dataGroup')
                    .attr('fill', d=>colors(d.key))
                    .attr('opacity', 0.8)

 dataGroup.selectAll('rect')
                    .data(d=>d)
                    .join('rect')
                    .attr('class', 'datarect')
                    .attr('x', d=>xScale(d.data.year))
                    .attr('y', d=>yScale(d[1]))
                    .attr('width', xScale.bandwidth())
                    .attr('height', d=>yScale(d[0]) - yScale(d[1]))

  6、create axes

const xAxis = d3.axisBottom(xScale)
        
const xAxisGroup = maingroup.append('g')
                            .call(xAxis)
                            .attr('transform',`translate(0, ${dms.innerHeight})`)

const yAxis = d3.axisLeft(yScale)
                    
const yAxisGroup = maingroup.append('g')
                            .call(yAxis)

  7、create legend

const legendArea = maingroup.append('g')
                            .selectAll('g')
                            .data(stackBarKeys)
                            .join('g')
                            .attr('class', 'legend')
                            .attr('transform', (d, i) =>`translate(0, ${i * 22})`)

legendArea.append('rect')
                    .attr('x', dms.innerWidth + 5)
                    .attr('width', 19)
                    .attr('height', 16)
                    .attr('fill', d=>colors(d))
                    .attr('opacity', 0.8)

        
legendArea.append('text')
                    .attr('x', dms.innerWidth + 28)
                    .attr('y', 8)
                    .attr('dy', '0.32em')
                    .text(d=>d)

   结束。

posted @ 2022-08-04 22:23  先起这个昵称  阅读(475)  评论(0编辑  收藏  举报