LoginSignup
4
3

More than 3 years have passed since last update.

D3.jsのプラグイン「venn.js」を使ってベン図を描く

Posted at

はじめに

ユーザーのサイト利用に関する併用状況をWebで可視化する必要があり、
(3つまでであれば)ベン図が直感的でわかりやすいと思ったのですが
意外と簡単にベン図を作成するJavaScriptライブラリが見つからなかった中
D3.jsのプラグイン「venn.js」が使いやすかったので備忘録的に残します。

venn.jsのGitHubこちら
venn.js

ベン図

examplesフォルダにサンプルが豊富にありますので、
そこを見ればだいたいやりたいことは載っています。
いくつか実際に使ってみたサンプルについて書いていきます。

基本

examples/simple.htmlを少し手直ししています。
・日本語でも動きます。
・D3.jsのバージョンをv4→v5に上げても動きます。

<!doctype html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>venn.js sample</title>
<style>
body {
    font-family: "Hiragino Kaku Gothic Pro W3","Hiragino Kaku Gothic ProN",Meiryo,sans-serif;
    font-size: 14px;
}
</style>
</head>

<body>
    <div id="venn"></div>
</body>

<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="../venn.js"></script>
<script>
// データセットの用意
var sets = [ {sets: ['サイトA'], size: 12},
             {sets: ['サイトB'], size: 12},
             {sets: ['サイトA','サイトB'], size: 2}];

// #vennに描画
var chart = venn.VennDiagram();
d3.select("#venn").datum(sets).call(chart);
</script>
</html>

chart1.png

色の変更

examples/styled.htmlを参考にしています。
以降はscript内のみ書きます。
・色を指定することができます。
・丸の色及びテキストの色両方変更することもできます(もちろん片方だけも可能)

// データセットの用意
var sets = [ {sets: ['サイトA'], size: 12},
             {sets: ['サイトB'], size: 12},
             {sets: ['サイトA','サイトB'], size: 2}];

// #vennに描画
var chart = venn.VennDiagram();
d3.select("#venn").datum(sets).call(chart);

// 色の変更
var colors = ['red', 'blue']; // 1つ目を赤、2つ目を青に
d3.selectAll("#venn .venn-circle path")
    .style("fill", function(d,i) { return colors[i]})
d3.selectAll("#venn .venn-circle text")
    .style("fill", function(d,i) { return colors[i]})

chart2.png

順番の変更

examples/orientation_order.htmlを参考にしています。
・描画の順番を変えることができます。

// データセットの用意
var sets = [ {sets: ['サイトA'], size: 12},
             {sets: ['サイトB'], size: 12},
             {sets: ['サイトA','サイトB'], size: 2}];

// #vennに描画
var chart = venn.VennDiagram();

// 順番の変更
var customOrdering = {'サイトB': 1, 'サイトA': 2}; // 1つ目サイトBに、2つ目をサイトAに
chart.orientationOrder(function (a, b) { return customOrdering[a.setid] - customOrdering[b.setid]});

d3.select("#venn").datum(sets).call(chart);

chart3.png

ツールチップの表示

examples/intersection_tooltip.htmlを参考にしています。
ツールチップのstyleを定義する必要があるため、ここはHTMLすべて書きます。
・ツールチップで数値(ここではユーザー数)を表示することができます。
・マウス操作に合わせて色の透明度などを変化させることができます。

<!doctype html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>venn.js sample</title>
<style>
body {
    font-family: "Hiragino Kaku Gothic Pro W3","Hiragino Kaku Gothic ProN",Meiryo,sans-serif;
    font-size: 14px;
}
</style>
</head>

<body>
    <div id="venn"></div>
</body>

<style>
.venntooltip {
  position: absolute;
  text-align: center;
  width: 128px;
  height: 22px;
  background: #333;
  color: #ddd;
  padding: 2px;
  border: 0px;
  border-radius: 8px;
  opacity: 0;
}
</style>

<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="../venn.js"></script>
<script>
// データセットの用意
var sets = [ {sets: ['サイトA'], size: 12},
             {sets: ['サイトB'], size: 12},
             {sets: ['サイトA','サイトB'], size: 2}];

// #vennに描画
var chart = venn.VennDiagram();
var div = d3.select("#venn")
div.datum(sets).call(chart);

var tooltip = d3.select("body").append("div")
    .attr("class", "venntooltip");

div.selectAll("path")
    .style("stroke-opacity", 0)
    .style("stroke", "#fff")
    .style("stroke-width", 3)

div.selectAll("g")
    .on("mouseover", function(d, i) {
        // sort all the areas relative to the current item
        venn.sortAreas(div, d);

        // Display a tooltip with the current size
        tooltip.transition().duration(400).style("opacity", .9);
        tooltip.text(d.size + " ユーザー");

        // highlight the current path
        var selection = d3.select(this).transition("tooltip").duration(400);
        selection.select("path")
            .style("fill-opacity", d.sets.length == 1 ? .4 : .1)
            .style("stroke-opacity", 1);
    })

    .on("mousemove", function() {
        tooltip.style("left", (d3.event.pageX) + "px")
               .style("top", (d3.event.pageY - 28) + "px");
    })

    .on("mouseout", function(d, i) {
        tooltip.transition().duration(400).style("opacity", 0);
        var selection = d3.select(this).transition("tooltip").duration(400);
        selection.select("path")
            .style("fill-opacity", d.sets.length == 1 ? .25 : .0)
            .style("stroke-opacity", 0);
    });
</script>
</html>

chart4.png

おわりに

venn.jsの説明というより、ほとんどD3.jsの説明になってしまいましたが。。。
見方を変えればvenn.jsでSVGに描画してしまえば、あとはD3.jsの世界なので
スタイルの変更などは比較的自由に行えます。
難易度は上がりますが、レイアウトを動的に変えることなどもできるので、
ビジュアライズの世界が広がりますね。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3