function render() {
let margin = 20;
let width = 600 - margin * 2;
let height = 400 - margin * 2;
let svg = d3
.create("svg")
.attr("width", width + margin * 2)
.attr("height", height + margin * 2);
let g = svg.append("g").attr("transform", `translate(${margin},${margin})`);
let xAxis = g
.append("g")
.attr("transform", `translate(${0},${height})`)
.attr("class", "x-axis");
let yAxis = g
.append("g")
.attr("transform", `translate(${0},${0})`)
.attr("class", "y-axis");
function change(newDate) {
let X = newDate.map((d) => d.group);
let Y = newDate.map((d) => d.value);
let colors = d3
.scaleQuantize()
.domain([0, d3.max(Y) || 0])
.range([
"#f0f9ff",
"#e0f2fe",
"#bae6fd",
"#7dd3fc",
"#38bdf8",
"#0ea5e9",
"#0284c7",
"#0369a1",
"#075985",
"#0c4a6e",
]);
let xScale = d3.scaleBand().domain(X).range([0, width]).padding(0.3);
let yScale = d3
.scaleLinear()
.domain([0, d3.max(Y) || 0])
.range([height, 0]);
const timer = 2000;
xAxis.transition().duration(timer).call(d3.axisBottom(xScale));
yAxis.transition().duration(timer).call(d3.axisLeft(yScale));
let rect = g.selectAll("rect").data(newDate);
rect
.join(
(enter) => {
// attributes to transition FROM
return enter
.append("rect")
.attr("width", xScale.bandwidth())
.attr("height", 0)
.attr("x", (d) => xScale(d.group))
.attr("y", yScale(0));
},
(update) => update,
(exit) => {
exit
.transition()
.duration(timer)
.attr("height", 0)
.attr("y", yScale(0))
.remove();
}
)
// enter + update selection
.on("mouseover", mouseover)
.on("mouseout", mouseout)
.on("mousemove", mousemove)
.transition()
.duration(timer)
.attr("height", (d) => yScale(0) - yScale(d.value))
.attr("width", xScale.bandwidth())
// attributes to transition TO
.attr("fill", (d) => colors(d.value))
.attr("x", (d) => xScale(d.group))
.attr("y", (d) => yScale(d.value));
function mouseover() {
focus.style("display", null);
}
function mouseout() {
focus.style("display", "none");
}
function mousemove(event, d) {
const [_xm, ym] = d3.pointer(event);
let t_y = ym + focusHeight / 2 + 10;
if (ym + focusHeight > height) {
t_y = ym - 10;
}
// get xScale center point
let t_x = xScale(d.group) + xScale.bandwidth() / 2;
if (t_x + focusWidth > width) {
focus.attr("transform", `translate(${_xm - focusWidth - 10},${t_y})`);
} else {
focus.attr("transform", `translate(${_xm + 10},${t_y})`);
}
focus.select(".tooltip-title").text(d.group);
focus.select(".tooltip-date").text("value: " + d.value);
}
return svg;
}
var focus = svg.append("g").style("display", "none");
focus
.append("rect")
.attr("class", "tooltip")
.style("pointer-events", "none")
.attr("fill", "white")
.attr("stroke", "#000")
.attr("width", focusWidth)
.attr("height", focusHeight)
.attr("x", focusX)
.attr("y", -22)
.attr("rx", 4)
.attr("ry", 4);
focus
.append("text")
.attr("class", "tooltip-title")
.attr("x", focusX + 8)
.attr("y", -2);
focus
.append("text")
.style("pointer-events", "none")
.attr("class", "tooltip-date")
.attr("x", focusX + 8)
.attr("y", 18);
focus
.append("text")
.style("pointer-events", "none")
.attr("class", "tooltip-likes")
.attr("x", 60)
.attr("y", 18);
return change;
}