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

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)
结束。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/278959.html