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.

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

1,570 views

Published on

Inside Frontend #1にて発表したないようです。

HTML版
http://shimz.me/slide/inside-frontend_1/#/

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

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

  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

×