D3.jsで要素を活用するという記事内で使用したデモページです。
<g>
要素でグループ化していないシンプルな横棒グラフです。
license: gpl-3.0 |
D3.jsで要素を活用するという記事内で使用したデモページです。
<g>
要素でグループ化していないシンプルな横棒グラフです。
<!DOCTYPE html> | |
<html lang="ja"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | |
<link rel="stylesheet" href="playground.css"> | |
<style> | |
.bars { | |
fill: skyblue; | |
} | |
.texts { | |
fill: white; | |
font-size: 12px; | |
font-weight: bold; | |
font-family: Arial, sans-serif; | |
} | |
</style> | |
<title>Document</title> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
</head> | |
<body> | |
<svg id="chart"></svg> | |
</body> | |
<script> | |
const nameFormat = d3.format('02d'); | |
const data = d3.shuffle(d3.range(0, 20)).map((d, i) => { | |
return { | |
name: `name-${nameFormat(d)}`, | |
value: Math.round(Math.random() * 100), | |
}; | |
}); | |
const size = { | |
width: window.innerWidth, | |
height: window.innerHeight | |
}; | |
const margin = {top: 10, right: 10, bottom: 10, left: 60}; | |
const svg = d3.select('#chart') | |
.attr('width', size.width) | |
.attr('height', size.height); | |
const xScale = d3.scaleLinear() | |
.domain([0, 100]) | |
.range([margin.left, size.width - margin.right]); | |
const yScale = d3.scaleBand() | |
.domain(data.map(d => d.name)) | |
.range([margin.top, size.height - margin.bottom]) | |
.padding(0.2); | |
const fillScale = d3.scaleLinear() | |
.domain([0, 100]) | |
.range(['yellow', 'green']); | |
const yAxis = d3.axisLeft(yScale); | |
const bars = svg.selectAll('.bars') | |
.data(data) | |
.enter() | |
.append('rect') | |
.attr('class', 'bars') | |
.attr('x', xScale(0)) | |
.attr('y', d => yScale(d.name)) | |
.attr('width', d => xScale(d.value) - xScale(0)) | |
.attr('height', yScale.bandwidth()); | |
const texts = svg.selectAll('.texts') | |
.data(data) | |
.enter() | |
.append('text') | |
.attr('class', 'texts') | |
.attr('x', xScale(0)) | |
.attr('y', d => yScale(d.name) + yScale.bandwidth() / 2) | |
.attr('dx', '.5em') | |
.attr('dy', 1) | |
.attr('text-anchor', 'start') | |
.attr('dominant-baseline', 'middle') | |
.text(d => d.value); | |
const guide = svg.append('text') | |
.attr('class', 'guide') | |
.attr('x', size.width - margin.right) | |
.attr('y', 0) | |
.attr('dx', '-1em') | |
.attr('dy', '.5em') | |
.attr('text-anchor', 'end') | |
.attr('dominant-baseline', 'text-before-edge'); | |
svg.append('g') | |
.attr('class', 'axis-y') | |
.attr('transform', `translate(${xScale(0)}, 0)`) | |
.call(yAxis); | |
bars.on('click', () => { | |
yScale.domain(d3.shuffle(yScale.domain())); | |
d3.select('.axis-y') | |
.transition().duration(500) | |
.call(yAxis); | |
bars.transition() | |
.duration(500) | |
.attr('y', d => yScale(d.name)); | |
texts.transition() | |
.duration(500) | |
.attr('y', d => yScale(d.name) + yScale.bandwidth() / 2); | |
}).on('mouseover', (d, i, nodes) => { | |
d3.select(nodes[i]) | |
.transition().duration(500) | |
.style('fill', d => fillScale(d.value)); | |
guide.style('display', 'inline') | |
.text(d.name); | |
}).on('mouseout', (d, i, nodes) => { | |
d3.select(nodes[i]) | |
.transition().duration(500) | |
.style('fill', 'skyblue'); | |
guide.style('display', 'none'); | |
}); | |
</script> | |
</html> |
@font-face { | |
font-family: Original Yu Gothic; | |
src: local("Yu Gothic"); | |
font-weight: 300 | |
} | |
@font-face { | |
font-family: Original Yu Gothic; | |
src: local("Yu Gothic"); | |
font-weight: 500 | |
} | |
@font-face { | |
font-family: Original Yu Gothic; | |
src: local("Yu Gothic"); | |
font-weight: 700 | |
} | |
@font-face { | |
font-family: Helvetica Neue; | |
src: local("Helvetica Neue Regular"); | |
font-weight: 100 | |
} | |
@font-face { | |
font-family: Helvetica Neue; | |
src: local("Helvetica Neue Regular"); | |
font-weight: 200 | |
} | |
html { | |
width: 100%; | |
height: 100%; | |
padding: 0; | |
margin: 0; | |
font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, Original Yu Gothic, Yu Gothic, YuGothic, Verdana, Meiryo, sans-serif; | |
font-weight: 400; | |
-webkit-font-smoothing: antialiased; | |
-moz-osx-font-smoothing: grayscale; | |
} | |
body { | |
width: 100%; | |
height: 100%; | |
padding: 0; | |
margin: 0; | |
color: #34495e; | |
background: #fefefe; | |
} | |
#chart { | |
width: 100%; | |
height: 100%; | |
margin: 0; | |
} |