気が付くと、下記のサンプルが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
インターフェースが実装された後にすればよいのにと思うが。