chart = {
const columnIndex = parseInt(category);
const height = 320
const margin = { top: 20, right: 30, bottom: 30, left: 50 }
const svg = d3.create('svg')
.attr('viewBox', [0, 0, width, height])
const x = d3.scaleTime()
.domain(d3.extent(data, d => d.date))
.range([margin.left + 12, width - margin.right])
const xAxis = (g, x) => {
g
.attr('transform', `translate(0, ${height - margin.bottom})`)
.call(d3.axisBottom(x).ticks(width / 120).tickSizeOuter(0));
}
const y = d3.scaleLinear()
.domain([d3.min(data, d => d.column[columnIndex]), d3.max(data, d => d.column[columnIndex])]).nice()
.range([height - margin.bottom, margin.top])
const yAxis = g => g
.attr('transform', `translate(${margin.left}, 0)`)
.call(d3.axisLeft(y).tickFormat(v => `${v.toFixed(1)}%`));
const gx = svg.append('g')
.call(xAxis, x)
.attr('font-size', 14)
.attr('font-family', 'var(--sans-serif)');
svg.append('g')
.call(yAxis)
.selectAll('text')
.attr('font-size', 12)
.attr('font-family', 'var(--sans-serif)');
const line = x => d3.line()
.x(d => x(d.date))
.y(d => y(d.column[columnIndex]))
const linePath = svg.append('path')
.datum(data)
.attr('fill', 'none')
.attr('stroke', '#ddd')
.attr('stroke-width', 1)
.attr('stroke-linejoin', 'round')
.attr('stroke-linecap', 'round')
.attr('d', line(x))
const bar = svg.append('g')
.selectAll('rect')
.data(data)
.join('rect')
.attr('fill', d => d.column[columnIndex] > 0 ? '#22577A' : '#f9564f')
.attr('x', d => x(d.date))
.attr('width', 2)
.attr('y', d => {
const value = d.column[columnIndex]
if (value < 0) {
return y(0)
} else {
return y(value)
}
})
.attr('height', d=> {
const value = d.column[columnIndex]
if (value < 0) {
return y(value) - y(0);
} else {
return y(0) - y(value)
}
})
const zoom = d3.zoom()
.scaleExtent([1, 16])
.extent([[margin.left, 0], [width - margin.right, height]])
.translateExtent([[margin.left, -Infinity], [width - margin.right, Infinity]])
.on('zoom', zoomed)
svg.call(zoom)
function zoomed(event) {
const xz = event.transform.rescaleX(x);
gx.call(xAxis, xz);
bar.attr('x', d => xz(d.date))
linePath.attr('d', line(xz))
}
return svg.node();
}