D3 Grouped Bar Chart
by falsy
HTML
<!doctype html>
<html lang="ko">
<head>
<title>D3.js Grouped bar chart</title>
</head>
<body>
<div id="svg-area"></div>
</body>
</html>
JavaScript
const data = [{
group: '행1',
sentiment: '열1',
value: 1
}, {
group: '행1',
sentiment: '열2',
value: 3
}, {
group: '행1',
sentiment: '열3',
value: 2
}, {
group: '행1',
sentiment: '열4',
value: 4
}, {
group: '행1',
sentiment: '열5',
value: 1
}, {
group: '행2',
sentiment: '열1',
value: 3
}, {
group: '행2',
sentiment: '열2',
value: 1
}, {
group: '행2',
sentiment: '열3',
value: 4
}, {
group: '행2',
sentiment: '열4',
value: 3
}, {
group: '행2',
sentiment: '열5',
value: 2
}]
const width = 350
const height = 350
const margin = {top: 20, left: 40, bottom: 20, right: 40}
const colors = [
'#63a1af',
'#7ab8aa',
'#93caa8',
'#add7a8',
'#c6e3a7'
]
const subgroups = [...new Set(data.map(({ sentiment }) => sentiment))]
const groups = [...new Set(data.map(({ group }) => group))].reverse()
const values = data.map(({ value }) => value)
let chartData = []
data.forEach(({ group, sentiment, value }) => {
const leftData = chartData.filter((d) => d.group !== group)
let groupData = chartData.find((d) => d.group === group)
if (groupData) {
groupData[sentiment] = value
} else {
groupData = {}
groupData.group = group
groupData[sentiment] = value
}
chartData = [...leftData, groupData]
})
const svg = d3
.select('#svg-area')
.append('svg')
.attr('width', width)
.attr('height', height + 20)
.append('g')
const x = d3
.scaleLinear()
.domain([0, d3.max(values)])
.range([50, width - 10])
svg
.append('g')
.attr('transform', `translate(-24, ${height})`)
.call(d3.axisBottom(x).tickSizeInner(0).tickSizeOuter(0).tickPadding(15).tickValues([0, ...values]))
.call((g) => g.select('.domain').attr('stroke', '#ebebeb'))
.call((g) =>
g.selectAll('text')
.attr('fill', '#888')
.attr('font-size', 13)
.attr('text-anchor', 'middle')
.attr('dx', 0)
.attr('dy', 0)
)
const y = d3.scaleBand().domain(groups).range([height, 0]).padding(0)
const columnHeight = 26
const columnLen =...