HorizontalBarChart = (data, props) => {
const [width, height] = props.size;
const [xKey, yKey] = props.axisKeys;
const animate = props.animate;
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.attr("font-size", "0.625rem")
.attr("font-family", "sans-serif")
.attr("font-weight", "bold");
let topContainer = svg
.selectAll(".top-container")
.data([0])
.enter()
.append("g")
.attr("class", "top-container")
.attr("transform", "translate(30,20)")
const margin = {bottom: 25, right: 50}
const xDomain = props.domain || [0, d3.max(data, d => d[xKey])];
const xScale = d3.scaleLinear()
.domain(xDomain)
.range([0, width - margin.right]);
const zx = xScale.copy();
const yScale = d3.scaleBand()
.domain(data.map(d => d[yKey]))
.range([0, height - margin.bottom])
.padding(0.1);
const xAxis = (g, scale) => {
console.log('in xAxis ' + scale.domain() + ' and range ' + scale.range());
g
.attr("class", "xAxis")
.call(d3.axisTop(scale).tickSizeOuter(0))
.call(g => g.select(".domain").remove());
};
const yAxis = (g, scale) => {
g
.attr("class", "yAxis")
.call(d3.axisLeft(scale))
.call(g => g.select(".domain").remove());
};
const gx = topContainer
.append("g")
.call(xAxis, zx);
const gy = topContainer
.append("g")
.call(yAxis, yScale);
const renderChart = (data) => {
topContainer
.selectAll("rect")
.data(data, d => d.key)
.enter()
.append("rect")
.attr("fill", "steelblue")
.attr("x", d => zx(0))
.attr("y", d => yScale(d[yKey]))
.attr("height", yScale.bandwidth());
const allRect = topContainer
.selectAll("rect");
if (animate) {
allRect
.transition()
.duration(1500)
.attr("width", d => zx(d[xKey]))
} else {
allRect
.attr("width", d => zx(d[xKey]));
}
topContainer
.selectAll(".barText")
.data(data, d => d.key)
.enter()
.append("text")
.attr("class", "barText")
.attr("y", d => yScale(d[yKey]) + (yScale.bandwidth()/2) + 4)
.attr("fill", "white")
.style("text-anchor", "end")
.each(function(d) {
const deepCopy = JSON.parse(JSON.stringify(d));
deepCopy[xKey] = 0;
this._current = deepCopy;
});
const allText = topContainer
.selectAll(".barText");
if (animate) {
allText
.transition()
.duration(1500)
.attr("x", d => zx(d[xKey])-5)
.textTween(function(d) {
const interpolateToD = d3.interpolate(this._current, d);
return (t) => {
this._current = interpolateToD(t);
return this._current[xKey].toFixed(0);
};
});
} else {
allText
.attr("x", d => zx(d[xKey]) - 5)
.text(d => d[xKey]);
}
}
renderChart(data);
return Object.assign(svg.node(), {
update(data) {
const t = svg.transition().duration(1000);
const newXDomain = [0, d3.max(data, d => d[xKey])];
zx.domain(newXDomain);
gx.transition(t).call(xAxis, zx);
renderChart(data);
}
});
}