Skip to content

Instantly share code, notes, and snippets.

@matsuby
Last active October 24, 2018 03:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matsuby/9ff32e1ba54dfbc16ab69247c77149bc to your computer and use it in GitHub Desktop.
Save matsuby/9ff32e1ba54dfbc16ab69247c77149bc to your computer and use it in GitHub Desktop.
d3を使って円から円を直線で結ぶサンプル
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>d3を使って円から円を直線で結ぶサンプル</title>
</head>
<body>
<div id="container"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script>
// 参考: https://qiita.com/daxanya1/items/734e65a7ca58bbe2a98c
// v3とv4でAPIが結構変わっているので注意。サンプルはv5。
// => https://github.com/d3/d3/blob/master/API.md
const svg = d3.select("#container")
.append("svg")
.attr("width", 600)
.attr("height", 600)
.style("border", "solid 1px red");
const mainData = [100, "お昼ご飯といえば?"]; // 真ん中(4)のデータ
const data = [
[45, "ラーメン"],
[65, "カップ焼きそば"],
[55, "おにぎり"],
[40, "そば"],
[85, "ビッグマック"],
[25, "ガム"],
[35, "弁当"],
[30, "その他"],
];
data.splice(4, 0, mainData);
const color = d3.scaleOrdinal(d3.schemeCategory10);
// 600*600のSVGエリアを200*200のboxに9等分した際の中心座標をindexから求める
const getX = i => [100, 300, 500][i % 3];
const getY = i => [100, 300, 500][Math.floor(i / 3)];
const g = svg.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", (d, i) => `translate(${getX(i)},${getY(i)})`);
g.append("circle")
.attr("r", d => d[0])
.attr("fill", (d, i) => color(++i));
g.append("text")
.text(d => d[1])
.attr("text-anchor", "middle")
.attr("dy", ".35em")
.attr("fill", "white");
const line = d3.line()
.x(i => getX(i))
.y(i => getY(i));
// 常に真ん中の丸から円を引くため、繰り返しの中のlineに部分的な配列を渡す
data.forEach((v, i) => {
if (i === 4) return;
setTimeout(() => {
const path = svg.append("path")
.attr("d", line([4, i]))
.attr("fill", "none")
.attr("stroke", "lightgreen")
.transition()
.duration(1000)
.attr("stroke", "black");
const length = path.node().getTotalLength() - data[4][0] - v[0];
path.attr("stroke-dasharray", `0 ${data[4][0]} ${length} ${v[0]}`);
}, i <= 3 ? i * 150 : (i - 1) * 150)
});
</script>
<script src="https://gist.github.com/matsuby/9ff32e1ba54dfbc16ab69247c77149bc.js"></script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment