chart = {
const svg = d3.create('svg')
.attr('width', width)
.attr('height', height)
.attr('viewBox', [0, 0, width, height])
.attr('style', `max-width: 100%; height: auto; height:intrinsic;`)
const zx = x.copy()
const zy = y.copy()
const line = d3.line().x(d => zx(d.date)).y(d => zy(d.close))
const gy = svg.append('g')
.call(yAxis, zy)
const gx = svg.append('g')
.call(xAxis, zx)
const path = svg.append('path')
.attr('fill', 'none')
.attr('stroke', 'steelblue')
.attr('stroke-width', 1.5)
.attr('stroke-miterlimit', 1)
.attr('d', line(data))
return Object.assign(svg.node(), {
update(domain) {
const t = d3.transition().duration(1000)
const fdata = data.filter(d => {
const date = new Date(d.date)
return date >= new Date(domain[0]) && date <= new Date(domain[1])
})
const getData = (d) => fdata.includes(d) ? d : new Date(d.date) < new Date(fdata[0].date) ? fdata[0] : fdata[fdata.length - 1];
const line = d3.line().x(d => zx(getData(d).date)).y(d => zy(getData(d).close))
zx.domain(domain)
zy.domain([0, d3.max(fdata, d => d.close)])
gx.transition(t).call(xAxis, zx)
gy.transition(t).call(yAxis, zy)
path.transition(t).attr('d', line(data))
}
})
}