d3.js で散布図でマウスオーバーでメッセージを表示する方法のメモ。
on("mouseover", function (e) { ... }) でマウスオーバー時のイベントを処理します。
メッセージは div タグで作成しておき、マウスオーバー時に内部の html を変更して表示するようにします。
以下のようなイメージです。
const tooltip = d3.select("#scatter")
.append("div")
.style("position", "absolute")
.style("text-align", "left")
.style("background", "#ffffff")
.style("border", "1px solid #000000")
.style("padding", "10px")
.style("opacity", 0)
;
svg.append("g")
.selectAll("circle")
.data(dataset)
.enter()
....
.on("mouseover", function (e) {
const d = e.target.__data__;
tooltip
.style("left", e.x + 30 + 'px')
.style("top", e.y + 'px')
.html(
"id: " + d[3] + ""
+ "[" + d[0] + ", " + d[1] + "]" + ""
+ "value: " + d[2]
)
.style("opacity", 1)
;
})
.on("mouseout", function (d) {
tooltip
.style("opacity", 0)
;
})
;
HTML 全体は以下の通りです。
<html>
<head>
<title>d3.js test</title>
</head>
<body>
d3.js test
<script src="../d3.min.js"></script>
<script type="text/javascript">
const dataset = [
[0.0, 0.0, 0.0, "p00"],
[1.0, 2.0, 0.1, "p01"],
[1.5, 4.0, 0.2, "p02"],
[2.0, 1.5, 0.3, "p03"],
[1.5, 4.0, 0.4, "p04"],
[2.5, 3.5, 0.5, "p05"],
[1.0, 4.0, 0.6, "p06"],
[1.5, 3.5, 0.7, "p07"],
[0.5, 2.0, 0.8, "p08"],
[1.0, 2.5, 0.9, "p09"],
[1.5, 1.0, 1.0, "p10"],
];
const width = 800;
const height = 600;
const margin = {"top": 30, "bottom": 30, "right": 30, "left": 30};
const svg =
d3.select("#scatter")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
;
const xScale =
d3.scaleLinear()
.domain([0, d3.max(dataset, function (d) { return d[0]; })])
.range([margin.left, margin.left + width])
;
const yScale =
d3.scaleLinear()
.domain([d3.max(dataset, function (d) { return d[1]; }), 0])
.range([margin.bottom, margin.bottom + height])
;
svg.append("g")
.attr("class", "x_axis")
.attr("transform",
"translate(" +
[0, height + margin.top].join(",")
+ ")"
)
.call(d3.axisBottom(xScale).ticks(0.5)
);
svg.append("g")
.attr("class", "y_axis")
.attr("transform",
"translate(" +
[margin.left, 0].join(",")
+ ")"
)
.call(d3.axisLeft(yScale).ticks(0.5)
);
const colorMax = 255;
const colorMin = 80;
const colorScale = d3.scaleLinear()
.domain([d3.min(dataset, function (d) { return d[2]; })
, d3.max(dataset, function (d) { return d[2]; })])
.range([colorMin, colorMax])
;
const tooltip = d3.select("#scatter")
.append("div")
.style("position", "absolute")
.style("text-align", "left")
.style("background", "#ffffff")
.style("border", "1px solid #000000")
.style("padding", "10px")
.style("opacity", 0)
;
svg.append("g")
.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx", function (d) { return xScale(d[0]); })
.attr("cy", function (d) { return yScale(d[1]); })
.attr("r", 10)
.attr("fill", function (d) {
return "rgba(0, 0, " + Math.round(colorScale(d[2])) + ", 0.8)";
})
.on("mouseover", function (e) {
const d = e.target.__data__;
console.log(e);
tooltip
.style("left", e.x + 30 + 'px')
.style("top", e.y + 'px')
.html(
"id: " + d[3] + ""
+ "[" + d[0] + ", " + d[1] + "]" + ""
+ "value: " + d[2]
)
.style("opacity", 1)
;
})
.on("mouseout", function (d) {
tooltip
.style("opacity", 0)
;
})
;
</script>
</body>
</html>