Successfully reported this slideshow.
Your SlideShare is downloading. ×

データビジュアライゼーションの作り方

Ad

Inside Frontend #1
データビジュアライゼーション
の作り方
Created by /Masayuki Shimizu @_shimizu

Ad

1

Ad

群馬県高崎市在住2015年11月に転職日本経済新聞社メディア戦略部DataViz/GIS エンジニア
自己紹介
清水正行
2

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Check these out next

1 of 62 Ad
1 of 62 Ad

More Related Content

データビジュアライゼーションの作り方

  1. 1. Inside Frontend #1 データビジュアライゼーション の作り方 Created by /Masayuki Shimizu @_shimizu
  2. 2. 1
  3. 3. 群馬県高崎市在住2015年11月に転職日本経済新聞社メディア戦略部DataViz/GIS エンジニア 自己紹介 清水正行 2
  4. 4. 主なお仕事 3
  5. 5. 日経:Visual Data日経:Visual Data 4
  6. 6. 5
  7. 7. 6
  8. 8. 7
  9. 9. 8
  10. 10. 9
  11. 11. 本日の目録 VDataコンテンツの作り方D3.js バッドノウハウ集Z-indexが効かない問題Pathのトランジション折り返さない問題svgをpngに変換(つらい) 10
  12. 12. VDataコンテンツの作り方 11 . 1
  13. 13. 制作フロー 1. 企画発案(記者より) 2. データ収集・分析・整形 3. デザイン案やモックを作って打ち合わせ 4. デザイン決定 5. 実装 6. 宣伝用の素材等作成 (SNSに流す用のグラフィックスや動画など) 11 . 2
  14. 14. 作成チーム PM1人 デザイナー3人 エンジニア2人 2ライン(デザイナー1、エンジニア1) 作成期間(2週間~4週間)、速報(6時間) 一点物が多い 11 . 3
  15. 15. これらの条件を踏まえ、日経ビジュアルデータで はD3.jsというライブラリを採用しています。 11 . 4
  16. 16. D3.js データビジュアライゼーションライブラリ 12 . 1
  17. 17. 特徴 Data-Driven Document デファクトスタンダード チャートライブラリではない 学習コストが高いと言われている(誤解?) 12 . 2
  18. 18. D3 GalleryD3 Gallery 12 . 3
  19. 19. D3.jsを使っても公式サイトのGalleryに掲載されて いるような複雑なデータビジュアライゼーション が簡単に作れるわけではありません。 12 . 4
  20. 20. 忘れましょう。 12 . 5
  21. 21. データビジュアライゼーションで必要になる作業 12 . 6
  22. 22. データを図表で表現する 12 . 7
  23. 23. Data -> Document 12 . 8
  24. 24. データの内容をエレメントの属性やスタイルに 反映する処理を繰り返す 12 . 9
  25. 25. 面倒なこと エレメントとデータのリレーション管理 トランジション 値の正規化や座標計算 12 . 10
  26. 26. D3は、データビジュアライゼーション作成の上で 面倒な処理を肩代わりしてくれる。 12 . 11
  27. 27. Data-Driven Document var data = [{id:0, value:100}, {id:1, value:200}, {id:2, value:300}] //選択した要素にデータを束縛する const div = d3.selectAll("div").data(data, (d) => d.id) //要素が足りない時は追加 const appendDiv = selector.enter().append("div") //要素が多すぎる時は削除 const removeDiv = selector.exit().remove() //アトリビュートの内容をアップデートする div.merge(appendDiv).attr("width", d=> d.value ) 12 . 12
  28. 28. 複雑なデータになっても 市区町村境界データ GeoJSON 6MB 1755 Features 15795 Properties 12 . 13
  29. 29. 操作は変わらない const projection = d3.geoMercator() .fitExtent([[0, 0], [1240, 800]], geojson) const desc = d3.geoPath().projection(projection) //path要素にデータを束縛する const path = svg.selectAll("path").data(geojson.features) //path要素が足りなければ追加する const appendPath = path.enter().append("path") //path要素が多すぎるなら削除する const removePath = path.exit().remove() 12 . 14
  30. 30. 12 . 15
  31. 31. 可視化 //人口が2万人以上・以下で塗り分ける maps.attr("fill", d => (d.properties.pop > 20000) ? "green" : "blue" //群馬県に所属する市区町村だけ赤く塗る maps.filter(d => d.properties.pref === "群馬県").attr("fill", "red" 12 . 16
  32. 32. 12 . 17
  33. 33. D3.jsはデータを基にエレメントを操作する機能 と、トランジションや計算処理など最低限の機能 のみを提供する。自由度は高いが作り手側でやら なくてはならないことも多い。 また、ブラウザ間の差異を埋めるような機能はな い。 12 . 18
  34. 34. BAD KNOWHOWBAD KNOWHOW 13 . 1
  35. 35. z-indexが効かない 13 . 2
  36. 36. 13 . 3
  37. 37. 重なり合う要素が多い場合 13 . 4
  38. 38. 対応策 最初にレイヤーを作っておき、手前に出したいエ レメントをコピーして表示する <svg> <g class="axisLayer"></g> <g class="plotLayer"> <circle class="orgin"> </g> <g class="overlay"> </g> </svg> <svg> <g class="axisLayer"></g> <g class="plotLayer"> <circle class="orgin"> </g> <g class="overlay"> <circle class="copy"> // <!-- 他の </g> </svg> 13 . 5
  39. 39. copy tips 束縛されたデータもコピーしておく var plotLayer = d3.select(".plotLayer") var ovarlay = d3.select(".overlay") plotLayer .selectAll("rect") .on("mouseover", copy(overlay)) function copy(layer){ return function(){ var node = d3.select(this).node() var nodeName = node.nodeName var nodeAttr = node.attributes var data = d3.select(this).data() 13 . 6
  40. 40. ポイント はじめにレイヤーの構成をしっかり決めておく 要素を並べ替えるより、コピーしてしまう方が 管理がしやすい オリジナルの要素にバインドされているデータ も一緒にコピーしておくと便利 13 . 7
  41. 41. pathトランジション 13 . 8
  42. 42. 例えば地形を変形する場合 13 . 9
  43. 43. 問題点 13 . 10
  44. 44. SAMPLE 13 . 11
  45. 45. 対応策 頂点の数を揃える function geo2square(coordinates, width, height) { var centroid = d3.polygonCentroid(coordinates) width = (width) ? width : 0 ; height = (height) ? height : 0 ; var p = [] var i = 0 var length = coordinates.length var qtr = ~~(length/4) var nScale = d3.scaleLinear().domain([0, qtr]).range([0, width var sScale = d3.scaleLinear().domain([0, qtr]).range([width, 13 . 12
  46. 46. ポイント 頂点数の多いpathに合わせて、調整する 行政区ポリゴンが複数のパスで作られている場 合は、面積を計算して一番大きなポリゴンを変 形させる 13 . 13
  47. 47. 折り返さない問題 13 . 14
  48. 48. 問題点 SVGには折り返すという機能がないため、レスポ ンシブに対応するためにはリサイズのたびにすべ ての座標を再計算して更新する必要がある。 text要素も折り返しが効かないので、地味に困る。 13 . 15
  49. 49. 対応策 tspanで括る var textArray = ["1行目、あ","2行目", "3行目あああああ" d3.select("svg").append("text") .datum(textArray) .attr("transform", "translate(100, 100)" .each(leftLinebreak) function leftLinebreak(array){ d3.select(this).selectAll("tspan" .data(array) .enter() .append("tspan") .attr("x", "0em") .attr("y", function(d,i) <text> <tspan x="0em" y="0em">1行目、あ</tspan <tspan x="0em" y="1em">2行目</tspan> <tspan x="0em" y="2em">3行目あああああ< <tspan x="0em" y="3em">4行目あ</tspan> </text> 13 . 16
  50. 50. SAMPLE 13 . 17
  51. 51. foreignObject SVGの中にHTMLを埋め込める。折り返しも効く。 ※ IE11未対応 <svg> <foreignObject width="200" height="200"> <html> <div style="width:100px">あああああああああああああああああああああああああああ </html> </foreignObject> </svg> 13 . 18
  52. 52. aout wrap 13 . 19
  53. 53. ポイント SVG要素のレスポンシブ対応は割と大変 scale()やviewBoxで対応できる場合もある 13 . 20
  54. 54. SVGをPNGに変換する 13 . 21
  55. 55. SNS投稿用素材ダウンロードページ   13 . 22
  56. 56. SVGをラスタライズする方法 1. SVG要素をdata URIスキームに変換してimageオ ブジェクトにする 2. imageオブジェクトをcanvasにdrawImageする 3. canvasから取得したデータをdata URI化する 13 . 23
  57. 57. 問題点 ブラウザによって動かない(IE) SVGに適用されているCSSが反映されない 画像、webフォントが反映されない 13 . 24
  58. 58. 対応策 ブラウザ縛り 要素を辿ってスタイルを属性に変換する 素材は全てdata URIスキームに変換してSVGに 埋め込む 13 . 25
  59. 59. SAMPLE 13 . 26
  60. 60. ポイント なんでもかんでもフロントでやろうとしない 13 . 27
  61. 61. まとめ データの収集・整形なども含め、データビジュア ライゼーションを作成するには地味で泥臭い作業 がとても重要です。 14 . 1
  62. 62. 資料 Visual Data ~データや映像で体感:日本経済新 聞 D3.js - Data-Driven Documents bl.ocks.org/shimizu - 今回使ったサンプルコード 14 . 2

×