Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

細かすぎて伝わらないD3 ver.4の話

8,579 views

Published on

※ なぜか、スライド内の画像が天地逆転して表示されています。

D3.js ver.4の新機能などについて。

Published in: Data & Analytics
  • Be the first to comment

細かすぎて伝わらないD3 ver.4の話

  1. 1. 細かすぎて伝わらないD3 v4の話 Created by Shimizu Masayuki
  2. 2. プロフィール 清水正行FB TW 群馬県高崎市在住 GUNMA GIS GEEK - Blog 2015/11 - 転職 毎日D3.jsを書いています コンプライアンスにより社名は秘匿。(申請書めんどい)
  3. 3. ご注意 文字とコードを読むプレゼンです。 重要なのは初めの10分くらいです。 質問があれば逐次受けつます。 トイレとかにいってもOKです。 気楽にやりましょう。
  4. 4. では、はじめます。
  5. 5. 6月28日、データビジュアライゼーショ ンライブラリとして有名な「D3.js」がメ ジャーバージョンアップしました。
  6. 6. Releases v3 2012年12月22日- 3.0.0 2016年5月5日- 3.5.17 v4 2016年1月5日- 4.0.0 α 2016年6月24日- 4.0.0 rc 2016年6月28日- 4.0.0 2016年10月27日- 4.3.0
  7. 7. メジャーバージョンアップによって、ど のような変化があったのか。
  8. 8. 阿鼻叫喚
  9. 9. 結構、大きな変更がありました。
  10. 10. v4になって変わったところ。
  11. 11. モジュール化 D3 v3は一つの巨大なライブラリでしたが、v4では機能ごとのモジ ュールに変更されました。モジュールはそれ単体でインストール して利用することができます。 npm install d3‐array <script src="https://d3js.org/d3‐array.v1.min.js"></script> webpackやrollup.jsを使って、必要なモジュールだけを選んでカス タムビルドすることもできるようになりました。
  12. 12. でも、モジュールが別モジュールに依存 している場合がある。
  13. 13. 依存関係
  14. 14. 名前空間 モジュルー化に伴い名前空間の見直しが行われています。 スケール d3.scale.linear   ‐>  d3.ScaleLinear d3.scale.sqrt    ‐>  d3.scaleSqrt レイアウト d3.layout.cluster  ‐>  d3.cluster d3.layout.hierarchy  ‐>  d3.hierarchy d3.layout.pack   ‐>  d3.pack
  15. 15. つまり?
  16. 16. 全滅
  17. 17. 全滅
  18. 18. でっでも、ドットが抜けただけでしょ?
  19. 19. まったく別名になったものもあるよ!
  20. 20. スケール d3.scale.ordinal().rangePoints()  ‐> d3.scalePoint()  d3.scale.ordinal().rangeBand()    ‐> d3.scaleBand()  レイアウト d3.layout.force()   ‐> d3.forceSimulation() Axis d3.svg.axis().orient('left')    ‐>  d3.axisLeft()
  21. 21. 細かい仕様の変更もある オブジェクトリテラルを渡してのアップデートはできなくなった v3 enable d3.select("cicle")   .attr({     "cx": 10,     "cy": 20,     "r":10   }) v4 only d3.select("cicle")   .attr("cx", 10)   .attr("cy", 20)   .attr("r", 10)
  22. 22. v3 -> v4 細かい変更をあげたらきりがないほどに 変わりました。
  23. 23. 今のところv4に対応した参考書は、日本 で出版されたものはもとより、海外でも ほとんどありません。
  24. 24. じゃあ、どうやって学べばいいのさ!
  25. 25. D3 v4を学ぶには? チェンジログ読め。 CHANGES.md (長い) リファレンス読め。 D3 API Reference (膨大) 下記スライドを読め。 D3 V4 - What's new? (103枚)
  26. 26. つらい。
  27. 27. しかし、喜びの声もある。
  28. 28. 細かすぎてつたわらない、 ver.4の素晴らしい進化。
  29. 29. d3-selection より柔軟なセレクター操作が可能に。
  30. 30. セレクター基本操作 //セレクト var selected = d3.select("circle") //データバインド selected.data([1, 10, 100, 100]) //足りない要素を追加 var appented = selected.enter().append("circle") //多すぎる要素を削除 var deleted = selected.exit().remove() //アップデート selected.attr("fill", "red") appentede.attr("fill", "red")
  31. 31. セレクタの戻り値が変わりました v3 > var svg = d3.select("svg") > svg [Array[1]] v4 > var svg = d3.select("svg") > svg {_groups: Array[1], _parents: Array[1]}
  32. 32. セレクターオブジェクトTIPS > var g = d3.select("svg").selectAll("g") > g.data([100, 200, 300]).enter().append("g") > g {   _groups: Array[1],   _parents: Array[1] } > g.data([1000, 2000, 3000, 4000]) > g {   _groups: Array[1],   _parents: Array[1],    _enter: Array[1],   _exit: Array[1] }
  33. 33. セレクションマージ セレクタとセレクタをマージして、両方を含む新たなセレクタを 生成できます。 var selected = d3.select("circle")   .data([1, 100, 1000]) var appented = selected.enter().append("circle") //マージして一括アップデート selected.merge(appented)   .attr("fill", "red")
  34. 34. セレクションフィルター 選択済みのセレクターをフィルタリングしてアップデートを適用 することができます。 var circles = d3.selectAll("circle") circles.filter(function(d, i) { return i%2 })   .transition()   .attr("cx", 0) 疑似クラスでの指定もできます。 circle.filter(":nth‐child(even)").attr("cx", 0)
  35. 35. d3-queue 非同期通信ユーティリティ
  36. 36. 非同期通信をまとめて処理 d3.queue()   .defer(d3.tsv, 'data1.tsv')   .defer(d3.json, 'japan.geojson')   .await(function(error, tsv, geojson) {         console.log(tsv)     console.log(geojson)   }) d3.queue()   .defer(d3.tsv, 'data1.tsv')   .defer(d3.json, 'japan.geojson')   .awaitAll(function(error, results) {     console.log(results)   })
  37. 37. d3-array 便利な配列操作
  38. 38. v3 - d3.nest > var data = [     {name:"a", value:10},      {name:"b", value:20},      {name:"a", value:30} ] > var nested = d3.nest()     .key(function(d){ return d.name })     .map(data)      > nested {a: Array[2], b: Array[1]}
  39. 39. v4 - d3.nest 戻り値が、d3コレクションオブジェクトになりました。 > var data = [     {name:"a", value:10},      {name:"b", value:20},      {name:"a", value:30} ] > var nested = d3.nest()     .key(function(d){ return d.name })     .map(data) > nested {$a: Array[2], $b: Array[1]} // <‐ d3‐collection Object
  40. 40. d3-collection 便利な構造化データ形式
  41. 41. > var map = d3.map({foo:1}) > map.set("bar", 2)     .set("hoge", "aaaa")     > map.get("hoge") aaaa > map.keys() ["foo", "bar", "hoge"] > map.values() [1, 2, "aaaa"] > map.entries() [   {"key":"foo","value":1},   {"key":"bar","value":2},   {"key":"hoge","value":"aaaa"} ]
  42. 42. d3-stratify 階層データジェネレーター
  43. 43. D3では階層構造のデータを必要とすることが多い {   "name": "Eve",   "children": [     {       "name": "Cain"     },     {       "name": "Seth",       "children": [         {           "name": "Enos"         },         {           "name": "Noam"         }       ]     },     ・・・ }
  44. 44. フラットなオブジェクトを階層構造へ変換する var data = [   {"name": "Eve",   "parent": ""},   {"name": "Cain",  "parent": "Eve"},   {"name": "Seth",  "parent": "Eve"},   {"name": "Enos",  "parent": "Seth"}] var stratifyData = d3.stratify()   .id(function(d){ return d.name })   .parentId(function(d){ return d.parent })   (data)
  45. 45. csv -> 構造化データ id,value1,value2 日本, 日本.群馬県, 日本.群馬県.高崎市,100,2000 日本.群馬県.前橋市,200,1000 日本.群馬県.桐生市,130,3000 日本.埼玉県, 日本.埼玉県.さいたま市,140,3200 日本.埼玉県.所沢市,210,2400 日本.東京都, 日本.東京都.千代田区, 日本.東京都.千代田区.大手町,220,1000 var stratify = d3.stratify()   .parentId(function(d) {     return d.id.substring(0, d.id.lastIndexOf("."))   })   var root = stratify(tsv)   .sum(function(d) { return d.value1 })
  46. 46. d3-transition より自在なアニメーションを実現。
  47. 47. イベントリスナー トランジションの終了時にイベントが発行されるようになりまし た。 var circle = d3.select("circle") circle   .transition()   .duration(2000)   .attr("cx", 500)   .on("start", function(){     console.log("start!")   })   .on("end", function(){     console.log("end!")   })   
  48. 48. トランジションチェイン AからBへ移動して、さらにCへと移動するなど複雑なアニメーシ ョンが可能に。 var circle = d3.select("circle") circle   .transition()   .duration(1000)   .attr("cx", 500) <‐‐x軸を移動   .transition()   .duration(1000)   .attr("cy", 500) <‐‐ y軸を移動
  49. 49. 共通オブジェクト メソッドチェインの数を減らし、複数のオブジェクトを同期して アニメーションするなどが簡単にできるようになりました。 var t = d3.transition()   .duration(2000)      circle.transition(t)   .attr("cx", 1000)      rect.transition(t)   .attr("x", 1000)
  50. 50. イベントも共通のリスナーを設定できる。 var t = d3.transition()   .duration(2000)   .on("end", function(){       alert("トランジション終了")   })      circle.transition(t)   .attr("cx", 1000)      rect.transition(t)   .attr("x", 1000)
  51. 51. d3-geo 地図表示
  52. 52. Fit Extentd v3 & v4 var projection = d3.geoMercator()   .scale(2000)   .center([139.5, 34]) v4.3.0 var projection = d3.geoMercator()   .fitExtent([[0, 0], [width, height]], geojson) 幅と高さを指定してgeojsonを渡すと、いい感じに表示するための プロジェクションを返す。 レスポンシブな地図を描画しやすくなった。
  53. 53. canvas レンタリング もうSVG専用だなんていわせない。
  54. 54. var line = d3.line()     .x(function(d) { return x(d.date); })     .y(function(d) { return y(d.value); }) SVGレンダリング path.datum(data).attr("d", line) canvasレンダリング var context = d3.select("canvas").node().getContext("2d") line.context(context)(data)
  55. 55. 地図もcanvasにレンタリグングできます var context = d3.select("canvas").node().getContext("2d") var projection = d3.geoMercator()     .fitExtent([[0, 0], [chartWidth, chartHeight]], geojson) var geoPath = d3.geoPath().projection(projection)   .context(context) geoPath(geojson) <‐ canvas Draw Maps
  56. 56. d3-force 力学モデルでグラフを描画
  57. 57. v3 Force Layout おなじみのコード。 var force = d3.layout.force()   .nodes(nodes)   .links(links)   .size([width, height])   .gravity(0.1)   .charge(‐30)   .friction(0.95)   .linkDistance(220)   .linkStrength(1)
  58. 58. v4 Force Simulation 全然違う。 var simulation = d3.forceSimulation()     .force("link", d3.forceLink()       .id(function(d){ return d.index })         .distance(220))     .force("charge", d3.forceManyBody())     .force("center", d3.forceCenter(width / 2, height / 2))     .force("y", d3.forceY(0))     .force("x", d3.forceX(0))
  59. 59. サイズ指定ではなくセンター指定になった V3 var force = d3.layout.force()   .size([width, height]) V4 var simulation = d3.forceSimulation()     .force("center", d3.forceCenter(width / 2, height / 2))
  60. 60. ノードの衝突判定 新たにノード同士の衝突判定を行う機能が追加 var simulation = d3.forceSimulation()     .force("collide",d3.forceCollide(function(d){        return d.r + 8 //半径に対して8pxのマージンを指定       }).iterations(16) )
  61. 61. 座標に最も近いノードを見つける var simulation = d3.forceSimulation() simulation.find(x, y, r) マウスイベントと連動させる svg.on("mousemove", function(){     var findNode = simulation.find(d3.event.x, d3.event.y)     console.log(findNode) })     
  62. 62. ところで。
  63. 63. 疲れていませんか?
  64. 64. まとめ
  65. 65. v4になったことで、v3で不便であったことや一部 統合性のとれていなかった設計などが修正され、 非常に使いやすいライブラリになっています。座標 計算等のアルゴリズムも最適化され処理速度も向 上しているので、ぜひ使ってみてください。

×