気が付くと、下記のサンプルがChromeで動かなくなっていた。ちなみにFirefoxやEdgeでは問題なく動作したのだが。
https://bl.ocks.org/sfpgmr/cee0c48acb0854e2055c
paths.each(function(){
// 馬セルの取り出しと座標補正
var path = d3.select(this);
console.log(path.node().pathSegList.getItem(0).x);
convertToRelative(path.node());
var m = path.node().createSVGPathSegMovetoRel
(path.node().pathSegList.getItem(0).x - boundingBox.x.baseVal.value - boundingBox.width.baseVal.value / 2.0,
path.node().pathSegList.getItem(0).y - boundingBox.y.baseVal.value - boundingBox.height.baseVal.value / 2.0
);
エラーは上記コードあたりで発生。pathSegListがundefinedとなってしまっていた。ああ、これは何か規格が変わったのかなと思ってググるとSVGPathSegListが規格から削除されたのでそれに合わせてChrome48バージョンより削除されたらしい。
これに相当する新しいインターフェースはSVGPathDataインターフェースだそうである。
ただ、今使っているChrome49でもこの新しいインターフェースはサポートされていない。
path.node().getPathData()
VM1585:1 Uncaught TypeError: path.node(...).getPathData is not a function(…)
そのために新バージョンおよび旧バージョン用のPolyfillがあるそうだ。
新バージョン
https://github.com/jarek-foksa/path-data-polyfill.js
旧バージョン
https://github.com/progers/pathseg
SVGPathSegListを削除するにあたってはそれなりの議論があったようだ。
https://bugs.chromium.org/p/chromium/issues/detail?id=539385
SVGPathSegListインターフェースというのはpathの中身をコマンド・リストのような形で保持し、操作できるインターフェースである。
pathのデータはm 223.44064,240.57693ような文字列をdアトリビュートに設定するのであるが、d中のコマンド文字列を解析し、コマンドをオブジェクトのリストとして保持し、スクリプトから操作しやすいインターフェースとして提供するためにSVGPathSegListが用意されたのである。リストであるから、新たなコマンドを生成して挿入したり、削除したりすることも可能である。
SVGPathSegListが便利なのは、pathの解析が簡単にできることである。もしコマンド文字列からだとパーサーから自前で実装する必要がある。
ChromeでこのSVGPathSegListが削除されたのは、
- 仕様から削除されたこと
- もともと使いづらい仕様で、実際ほとんど使われていない
- 実装に不具合があった
という理由らしい。しかしいきなりばっさり削除するのはどうかな。代替インターフェースであるSVGPathDataインターフェースが実装された後にすればよいのにと思うが。