dak ブログ

python、rubyなどのプログラミング、MySQL、サーバーの設定などの備忘録。レゴの写真も。

d3.js の散布図でマウスオーバーでメッセージを表示

2021-12-03 19:41:38 | javascript
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>


d3.js でシンプルな散布図を描画

2021-12-03 17:24:26 | javascript
d3.js でシンプルな散布図を描画する方法のメモ。
d3.js では左上が [0, 0] となるため、yScale では range を[margin.top, margin.top + height] にしています。
<html>
<head>

<title>d3.js test</title>
</head>
<body>
d3.js test
<script src="../d3.min.js"></script> <script type="text/javascript"> const dataset = [ // x, y, 値, ID [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": 60, "bottom": 30, "right": 30, "left": 60}; 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.top, margin.top + height]) ; const svg = d3.select("#scatter") .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) ; svg.append("g") .attr("class", "x_axis") .attr("transform", "translate(" + [0, margin.top + height].join(",") + ")" ) .call(d3.axisBottom(xScale)) ; svg.append("g") .attr("class", "y_axis") .attr("transform", "translate(" + [margin.left, 0].join(",") + ")" ) .call(d3.axisLeft(yScale)) ; 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]) ; 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", 7) .attr("fill", function (d) { return "rgba(" + Math.round(colorScale(d[2])) + ", 0, 0, 0.8)"; }) ; </script> </body> </html>