Built with blockbuilder.org
Last active
December 12, 2019 01:34
-
-
Save da1fujimoto/2dae0d6abe3711de022920bffc54543a to your computer and use it in GitHub Desktop.
D3 Line Chart Demo v5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: mit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[[{"date":"2019/1/1","value":70},{"date":"2019/2/1","value":65.1},{"date":"2019/3/1","value":81.6},{"date":"2019/4/1","value":55.3},{"date":"2019/5/1","value":30.6},{"date":"2019/6/1","value":55.4},{"date":"2019/7/1","value":72.9},{"date":"2019/8/1","value":82.2},{"date":"2019/9/1","value":66.4},{"date":"2019/10/1","value":73.3},{"date":"2019/11/1","value":25.4},{"date":"2019/12/1","value":57.4}],[{"date":"2019/1/1","value":55.8},{"date":"2019/1/15","value":80},{"date":"2019/2/1","value":33.4},{"date":"2019/2/15","value":65.3},{"date":"2019/3/1","value":45.2},{"date":"2019/3/15","value":70.9},{"date":"2019/4/1","value":82.1},{"date":"2019/4/15","value":66.6},{"date":"2019/5/1","value":45.3},{"date":"2019/5/15","value":33.2},{"date":"2019/6/1","value":90.2},{"date":"2019/6/15","value":34.5},{"date":"2019/7/1","value":45.3},{"date":"2019/7/15","value":33.2},{"date":"2019/8/1","value":90.2},{"date":"2019/8/15","value":34.5}]] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="description" content=""> | |
<title></title> | |
<!-- Custom CSS --> | |
<link rel="stylesheet" href="style.css"> | |
</head> | |
<body> | |
<div> | |
<select name="" id="select-data" class="form-control"> | |
<option value="0">Data 1</option> | |
<option value="1">Data 2</option> | |
</select> | |
</div> | |
<div class="canvas"></div> | |
<script src="https://d3js.org/d3.v5.min.js"></script> | |
<script src="https://unpkg.com/d3-interpolate-path/build/d3-interpolate-path.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.9.1/d3-tip.min.js"></script> | |
<script src="main.js"></script> | |
</body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const svg = d3.select('.canvas').append('svg') | |
.attr('width', 800) | |
.attr('height', 450); | |
const margin = {top: 50, right: 30, bottom: 50, left: 30}; | |
const width = svg.attr('width') - margin.left - margin.right; | |
const height = svg.attr('height') - margin.top - margin.bottom; | |
const g = svg.append('g') | |
.attr('transform', `translate(${margin.left}, ${margin.top})`) | |
const timeparser = d3.timeParse('%Y/%m/%d'); | |
const format = d3.timeFormat('%Y/%m'); | |
const selector = document.querySelector('#select-data'); | |
const color = d3.color('#85a7cc'); | |
const bisect = d3.bisector(d => d.date); | |
// data read | |
d3.json('dataset.json').then(data => { | |
// event listener | |
selector.addEventListener('change', () => { | |
update(data[selector.value]); | |
}); | |
create(data[selector.value]); | |
}); | |
// scaler | |
const x = d3.scaleTime().range([0, width]); | |
const y = d3.scaleLinear().range([height, 0]); | |
// line path generator | |
const line = d3.line() | |
.x(d => x(d.date)) | |
.y(d => y(d.value)) | |
.curve(d3.curveCatmullRom.alpha(0.4)); | |
const path = g.append('path') | |
.attr('fill', 'none') | |
.attr('stroke', color) | |
.attr('stroke-width', 2); | |
// line area | |
const lineArea = g.append('path'); | |
const linearGradient = g.append('defs') | |
.append('linearGradient') | |
.attr('id', 'linear-gradient') | |
.attr('gradientTransform', 'rotate(90)'); | |
linearGradient.append('stop') | |
.attr('offset', '0%') | |
.attr('stop-color', color.brighter(1.5)); | |
linearGradient.append('stop') | |
.attr('offset', '100%') | |
.attr('stop-color', '#fff'); | |
const area = d3.area() | |
.x(d => x(d.date)) | |
.y0(y(0)) | |
.y1(d => y(d.value)) | |
.curve(d3.curveCatmullRom.alpha(0.4)); | |
// axis settings | |
const xAxisCall = d3.axisBottom(x) | |
.tickFormat(format); | |
const yAxisCall = d3.axisLeft(y); | |
const xAxis = g.append('g') | |
.attr('class', 'axis axis-x') | |
.attr('transform', `translate(0, ${height})`); | |
const yAxis = g.append('g') | |
.attr('class', 'axis axis-y') | |
.call(yAxisCall); | |
// tooltip | |
const tip = d3.tip() | |
.attr('class', 'd3-tip') | |
.offset([-10, 0]) | |
.html(d => `<p>${format(d.date)}</p><p>${d.value}%</p>`) | |
g.call(tip); | |
const dashline = g.append('line'); | |
const dashline2 = g.append('line'); | |
const circle = g.append('circle') | |
.attr('class', 'point-circle'); | |
const showTip = (data, i) => { | |
circle.attr('cx', x(data[i].date)) | |
.attr('cy', y(data[i].value)) | |
.attr('r', 4) | |
.attr('fill', '#fff') | |
.attr('stroke', color) | |
.attr('stroke-width', 2) | |
.style('display', 'block') | |
dashline.attr('x1', x(data[i].date)) | |
.attr('x2', x(data[i].date)) | |
.attr('y1', 0) | |
.attr('y2', height) | |
.attr('stroke', '#ccc') | |
.attr('stroke-width', '1px') | |
.attr('stroke-dasharray', '2') | |
.style('display', 'block'); | |
dashline2.attr('x1', 0) | |
.attr('x2', width) | |
.attr('y1', y(data[i].value)) | |
.attr('y2', y(data[i].value)) | |
.attr('stroke', '#ccc') | |
.attr('stroke-width', '1px') | |
.attr('stroke-dasharray', '2') | |
.style('display', 'block'); | |
tip.show(data[i], circle.node()); | |
} | |
// create graph | |
const create = data => { | |
data = data.map(d => { | |
return {date: timeparser(d.date), value: d.value} | |
}); | |
x.domain([d3.min(data, d => d.date), d3.max(data, d => d.date)]); | |
y.domain([0, d3.max(data, d => d.value)]); | |
xAxis.call(xAxisCall); | |
yAxis.call(yAxisCall); | |
path.data([data]).attr('d', line); | |
lineArea.data([data]).attr('d', area).style("fill", "url(#linear-gradient)"); | |
g.on('mousemove', () => { | |
const xcord = x.invert(d3.mouse(g.node())[0]); | |
showTip(data, bisect.left(data, xcord)); | |
}); | |
g.on('mouseleave', () => { | |
circle.style('display', 'none'); | |
dashline.style('display', 'none'); | |
dashline2.style('display', 'none'); | |
tip.hide(); | |
}); | |
}; | |
// updage graph | |
const update = data => { | |
data = data.map(d => { | |
return {date: timeparser(d.date), value: d.value} | |
}); | |
x.domain([d3.min(data, d => d.date), d3.max(data, d => d.date)]); | |
y.domain([0, d3.max(data, d => d.value)]); | |
xAxis.transition().duration(1000) | |
.ease(d3.easeCircleInOut) | |
.call(xAxisCall); | |
yAxis.transition().duration(1000) | |
.ease(d3.easeCircleInOut) | |
.call(yAxisCall); | |
const dBeforeLine = path.attr('d'); | |
const dBeforeArea = lineArea.attr('d'); | |
path.data([data]) | |
.transition().duration(1000) | |
.ease(d3.easeCircleInOut) | |
.attrTween('d', (d, i, n) => { | |
const previous = d3.select(n[i]).attr('d'); | |
const current = line(d); | |
return d3.interpolatePath(previous, current); | |
}); | |
lineArea.data([data]) | |
.transition().duration(1000) | |
.ease(d3.easeCircleInOut) | |
.style("fill", "url(#linear-gradient)") | |
.attrTween('d', (d, i, n) => { | |
const previous = d3.select(n[i]).attr('d'); | |
const current = area(d); | |
return d3.interpolatePath(previous, current); | |
}); | |
g.on('mousemove', () => { | |
const xcord = x.invert(d3.mouse(g.node())[0]); | |
showTip(data, bisect.left(data, xcord)); | |
}); | |
g.on('mouseleave', () => { | |
circle.style('display', 'none'); | |
dashline.style('display', 'none'); | |
dashline2.style('display', 'none'); | |
tip.hide(); | |
}); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
svg { | |
margin-left: auto; | |
margin-right: auto; | |
display: block; | |
} | |
.chart-tip { | |
position: absolute; | |
width: auto; | |
height: auto; | |
padding: 10px 15px; | |
border-radius: 4px; | |
background: rgba(255,255,255,.95); | |
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1); | |
visibility: hidden; | |
font-size: 12px; | |
font-weight: bold; | |
max-width: 160px; | |
} | |
.d3-tip { | |
line-height: 1; | |
font-weight: bold; | |
padding: 10px; | |
background: rgba(0, 0, 0, 0.8); | |
color: #fff; | |
border-radius: 2px; | |
font-size: 10px; | |
} | |
.d3-tip:after { | |
box-sizing: border-box; | |
display: inline; | |
font-size: 10px; | |
width: 100%; | |
line-height: 1; | |
color: rgba(0, 0, 0, 0.8); | |
content: "\25BC"; | |
position: absolute; | |
text-align: center; | |
} | |
.d3-tip.n:after { | |
margin: -1px 0 0 0; | |
top: 100%; | |
left: 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment