Posted at

D3.jsをv3からv4/v5にバージョンアップした際の変更点メモ

More than 1 year has passed since last update.


はじめに

SVGの描画にD3.jsを使っています。

D3.jsの現在のバージョンはv5(2018年7月時点)ですが、v3からv4(2016年7月)で大きな変更があったためそのままでは動かなくなりました。

本記事では、動かなくなった部分の修正ポイントを備忘録的に記載しておきます。


attrとstyleの引数にオブジェクトはNGに

v3では選択したDOMにattrやstyleを使ってオブジェクトで一括して変更を加えることができましたが、v4からはオブジェクトが使えなくなりました。


v3

svg.selectAll('text')

.style({
"font-size": fontSize,
"font-family": fontFamily
});

以下のように書き換える必要があります。


v4/v5

svg.selectAll('text')

.style("font-size", fontSize)
.style("font-family", fontFamily);


d3.scale.linearはd3.scaleLinearに

v4でスケールの名前空間が変更になっています。


v3

scale.x = d3.scale.linear()

.domain([xRangeMin, xRangeMax])
.range([0, width]);

scale.y = d3.scale.linear()
.domain([yRangeMin, yRangeMax])
.range([height, 0]);


以下のように書き換える必要があります。


v4/v5

scale.x = d3.scaleLinear()

.domain([xRangeMin, xRangeMax])
.range([0, width]);

scale.y = d3.scaleLinear()
.domain([yRangeMin, yRangeMax])
.range([height, 0]);


他にも名前空間が変更されていますので、こちらで確認してください。

d3/CHANGES.md at master · d3/d3 · GitHub


Axisの記述変更

v4からはd3.axisTop, d3.axisRight, d3.axisBottom, d3.axisLeftを使います。


v3

var xAxis = svg.append('g')

.attr('class', "x axis")
.attr('transform', translate(margin.left, height + margin.top))
.call(d3.svg.axis().scale(scale.x).orient("bottom").tickSize(6, -height));

var yAxis = svg.append('g')
.attr('class', "y axis")
.attr('transform', translate(margin.left, margin.top))
.call(d3.svg.axis().scale(scale.y).orient("left").tickSize(6, -width));


以下のように書き換える必要があります。


v4/v5

var xAxis = svg.append('g')

.attr('class', "x axis")
.attr('transform', translate(margin.left, height + margin.top))
.call(d3.axisBottom(scale.x).tickSizeInner(6).tickSizeOuter(-height));

var yAxis = svg.append('g')
.attr('class', "y axis")
.attr('transform', translate(margin.left, margin.top))
.call(d3.axisLeft(scale.y).tickSizeInner(6).tickSizeOuter(-width));


また、textで追加した軸タイトルが見えなくなってしまったので、fill属性を追加しました。


v3

xAxis.append("text")

.attr("y", 30)
.attr("x",10)
.style("text-anchor", "start")
.text("X軸タイトル");

 ↓


v4/v5

xAxis.append("text")

.attr("y", 30)
.attr("x",10)
.style("text-anchor", "start")
.style("fill", "#000") // fill属性を追加
.text("X軸タイトル");


d3.layout.forceはd3.forceSimulationに

d3-forceはv4で大きく変わってしまいました。

v4となっても同じようなことは実現できるのですが、ソースは元から書き直した方が早いです。

私はこちらを参考にさせていただきました。

D3.js v4/v5 force simulation 最小構成 – サンプル – データビジュアライゼーション・ラボ

ポイントとなりそうな点だけ記載しておきます。


v3

var force = d3.layout.force()

.charge(-180)
.linkDistance(function(d){ return d.weight); })
.nodes(nodes)
.links(links)
.size([size['width'],size['height']])
.gravity(0.1)
.start();

以下のような感じで書き換えています。


v4/v5

var simulation = d3.forceSimulation()

.force("link", d3.forceLink().distance(function(d) { return d.weight); }))
.force("collide", d3.forceCollide().radius(function(d) { return d.value; }))
.force("charge", d3.forceManyBody().strength(-180))
.force("center", d3.forceCenter(size['width'] / 2, size['height'] / 2))
.force("x", d3.forceX().strength(0.1))
.force("y", d3.forceY().strength(0.1));


参考にしたサイト


おわりに

D3.jsはv4/v5になったことで、さらに使いやすいライブラリへと変化しているようです。

今回はとりあえず今動かしているものが最低限動作するように修正しただけですが、v4/v5に対応した書籍や記事も最近を多くなってきたようですし、D3.jsのポテンシャルを活かすためにも早くキャッチアップして高度なビジュアライズ化に挑戦していきたいですね。