barAndDotChart = (dataset1, dataset2) => {
const width = 900;
const height = 200;
const svg = d3
.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [0, 0, width, height]);
const barPadding = 1;
const rects = svg.selectAll("rect").data(dataset1).join("rect");
rects
.attr("x", (d, i) => i * (width / dataset1.length))
.attr("y", (d) => height - (d / d3.max(dataset1)) * height)
.attr("width", width / dataset1.length - barPadding)
.attr("height", (d) => d)
.attr("fill", "steelblue");
svg
.selectAll("circle")
.data(dataset2)
.join("circle")
.attr(
"cx",
(d, i) =>
i * (width / dataset2.length) +
(width / dataset2.length - barPadding) / 2
)
.attr("cy", (d) => height - (d / d3.max(dataset2)) * height)
.attr("r", 3)
.attr("fill", (d) => (d === 0 ? "transparent" : "red"));
svg
.selectAll("text.label")
.data(dataset1)
.join("text")
.attr("class", "label")
.attr("font-family", "sans-serif")
.attr("font-size", 9)
.attr("fill", "white")
.attr(
"x",
(d, i) =>
i * (width / dataset1.length) +
(width / dataset1.length - barPadding) / 2
)
.attr("y", height - 8) // 一定の高さに調整
.attr("text-anchor", "middle")
.text((d, i) => dannzyodataset[i]);
svg
.selectAll("text.value")
.data(dataset1)
.join("text")
.attr("class", "value")
.attr("font-family", "sans-serif")
.attr("font-size", 9)
.attr("fill", "steelblue")
.attr(
"x",
(d, i) =>
i * (width / dataset1.length) +
(width / dataset1.length - barPadding) / 2
)
.attr("y", 12) // 一定の高さに調整
.attr("text-anchor", "middle")
.text((d, i) => {
if (i % 3 === 0) {
// 3つごとに繰り返す
return "1\n";
} else if (i < dataset1.length - 1) {
const prevValue =
parseFloat(dataset1[i - 1]) !== 0 &&
isFinite(parseFloat(dataset1[i - 1]) / parseFloat(d))
? (parseFloat(d) / parseFloat(dataset1[i - 1]))
.toFixed(4)
.slice(0, -1)
: "";
return `${prevValue}\n`;
} else {
return "";
}
});
svg
.selectAll("text.value2")
.data(dataset2)
.join("text")
.attr("class", "value2")
.attr("font-family", "sans-serif")
.attr("font-size", 9)
.attr("fill", "red")
.attr(
"x",
(d, i) =>
i * (width / dataset2.length) +
(width / dataset2.length - barPadding) / 2
)
.attr("y", 20) // 一定の高さに調整
.attr("text-anchor", "middle")
.text((d, i) => {
if (i % 3 === 0) {
// 3つごとに繰り返す
return "1\n";
} else if (i < dataset1.length - 1) {
const prevValue =
parseFloat(dataset2[i - 1]) !== 0 &&
isFinite(parseFloat(dataset2[i - 1]) / parseFloat(d))
? (parseFloat(d) / parseFloat(dataset2[i - 1]))
.toFixed(4)
.slice(0, -1)
: "";
return `${prevValue}\n`;
} else {
return "";
}
});
return svg.node();
}