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

# はじめに
SVGの描画にD3.jsを使っています。
D3.jsの現在のバージョンはv5（2018年7月時点）ですが、v3からv4（2016年7月）で大きな変更があったためそのままでは動かなくなりました。
本記事では、動かなくなった部分の修正ポイントを備忘録的に記載しておきます。
# attrとstyleの引数にオブジェクトはNGに
v3では選択したDOMにattrやstyleを使ってオブジェクトで一括して変更を加えることができましたが、v4からはオブジェクトが使えなくなりました。

```javascript:v3
svg.selectAll('text')
    .style({
        "font-size": fontSize,
        "font-family": fontFamily
    });
```

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

```javascript:v4/v5
svg.selectAll('text')
    .style("font-size", fontSize)
    .style("font-family", fontFamily);
```

# d3.scale.linearはd3.scaleLinearに
v4でスケールの名前空間が変更になっています。

```javascript:v3
scale.x = d3.scale.linear()
    .domain([xRangeMin, xRangeMax])
    .range([0, width]);

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

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

```javascript: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](https://github.com/d3/d3/blob/master/CHANGES.md#scales-d3-scale)

# Axisの記述変更
v4からはd3.axisTop, d3.axisRight, d3.axisBottom, d3.axisLeftを使います。

```javascript: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));
```

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

```javascript: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属性を追加しました。

```javascript:v3
xAxis.append("text")
    .attr("y", 30)
    .attr("x",10)
    .style("text-anchor", "start")
    .text("X軸タイトル");
```

　↓

```javascript: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 最小構成 &#8211; サンプル &#8211; データビジュアライゼーション・ラボ](https://wizardace.com/d3-forcesimulation-simple/)

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

```javascript: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();
```

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

```javascript: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/CHANGES.md at master · d3/d3 · GitHub](https://github.com/d3/d3/blob/master/CHANGES.md)
- [細かすぎて伝わらないD3 ver.4の話](https://www.slideshare.net/xxshimizuxx/d3-ver4)
- [D3.js v4/5 使い方 徹底攻略 &#8211; データビジュアライゼーション・ラボ](https://wizardace.com/)

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