Advertisement
Guest User

Untitled

a guest
Jan 25th, 2015
187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.16 KB | None | 0 0
  1. 'use strict'
  2.  
  3. ###
  4. * 色を変換する関数を定義する
  5. ###
  6. hex2rgb = (hexcode) ->
  7. # rgbに変換する
  8. result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hexcode);
  9. if result is null
  10. console.log "error!"
  11. return
  12.  
  13. [r,g,b] = [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)]
  14. return [r,g,b]
  15.  
  16. rgb2hsv = (r,g,b) ->
  17. # rgb to hsv
  18. r = r / 255
  19. g = g / 255
  20. b = b / 255
  21.  
  22. max_v = Math.max(Math.max(r,g), b)
  23. min_v = Math.min(Math.min(r,g), b)
  24. v = max_v
  25. s = max_v - min_v
  26. if min_v == max_v
  27. h = 0
  28. else if min_v == b
  29. h = 60 * (g-r)/s + 60
  30. else if min_v == r
  31. h = 60 * (b-g)/s + 180
  32. else
  33. h = 60 * (r-b)/s + 300
  34. return [h,s,v]
  35.  
  36. hsv2rgb = (h,s,v) ->
  37. console.log [h,s,v]
  38. if h is null
  39. r = 0
  40. g = 0
  41. b = 0
  42. else
  43. h_dash = h / 60
  44. x = s * (1 - Math.abs(h_dash % 2 - 1))
  45. if h_dash < 1
  46. [r,g,b] = [s,x,0]
  47. else if h_dash < 2
  48. [r,g,b] = [x,s,0]
  49. else if h_dash < 3
  50. [r,g,b] = [0,s,x]
  51. else if h_dash < 4
  52. [r,g,b] = [0,x,s]
  53. else if h_dash < 5
  54. [r,g,b] = [x,0,s]
  55. else if h_dash < 6
  56. [r,g,b] = [s,0,x]
  57. else
  58. console.log '変換エラー'
  59. return
  60. r += (v-s)
  61. g += (v-s)
  62. b += (v-s)
  63. r *= 255
  64. g *= 255
  65. b *= 255
  66. return [Math.round(r),Math.round(g),Math.round(b)]
  67.  
  68. readTopoFileDone = false
  69. readAttrFileDone = false
  70.  
  71. # fileから読み込んだdataの格納変数
  72. topo_data = null
  73. attr_data = null
  74. map_width = 500
  75. map_height = 650
  76. svg = null
  77.  
  78.  
  79. ###
  80. * JSONファイルを読み込み、地図描画関数mainを呼び出す
  81. ###
  82. readTopoFile = (json) ->
  83. topo_data = json
  84. readTopoFileDone = true
  85.  
  86. readAttrFile = (json) ->
  87. attr_data = json
  88. readAttrFileDone = true
  89.  
  90. d3.json("yokohama_topo_out.json", (error, json) ->
  91. if error
  92. return console.warn error
  93. readTopoFile(json)
  94. if readTopoFileDone and readAttrFileDone
  95. main(topo_data, attr_data))
  96.  
  97. d3.json("yokohama_codes_and_stat.json", (error, json) ->
  98. if error
  99. return console.warn(error)
  100. readAttrFile(json)
  101. if readTopoFileDone and readAttrFileDone
  102. main(topo_data, attr_data))
  103.  
  104.  
  105. ###
  106. * 地図を描画する
  107. ###
  108. main = (topo, attr) ->
  109. labelLineHeight = 16
  110. # 属性情報を入れ直すためのHash Table
  111. attrHash = []
  112.  
  113. # attr情報を、IDをkeyとするhash-tableに変換する
  114. # idをKeyとしたhashテーブル&property毎のhashテーブルを作成する
  115. for e in attr
  116. attrHash[e.cityid]=e
  117.  
  118. # 人口の最大値と最小値を求めておく
  119. # --全年齢人口データのみを入れた配列を作成する
  120. elements = []
  121. target_key = "ttl"
  122. for e in attr
  123. elements.push(e[target_key])
  124.  
  125. # -- maxとminをとる
  126. target_max = Math.max.apply(null, elements)
  127. target_min = Math.min.apply(null, elements)
  128.  
  129. # svgを追加
  130. svg = d3.select("body #map").append("svg").attr("width", map_width).attr("height", map_height)
  131.  
  132. # 横浜市のmapを描画する
  133. yokohama = topojson.object(topo, topo.objects.yokohama)
  134.  
  135. # 横浜市を中心に指定したメルカトル図法で10万分の1で描画する
  136. projection = d3.geo.mercator().center([139.59,35.45]).scale(100000).translate([map_width / 2, map_height / 2])
  137.  
  138. # pathを作成する
  139. path = d3.geo.path().projection(projection)
  140. svg.append("path").datum(yokohama).attr("d", path)
  141.  
  142. # classを指定する
  143. svg.selectAll(".yokohama").data(yokohama.geometries).enter().append("path").attr("class", (d) ->
  144. return "yokohama " + d.properties.name).attr("d", path)
  145.  
  146.  
  147. # 色を塗る
  148. ###
  149. areaGrad = d3.scale.linear().domain([target_min, target_max]).range(["#bee59e", "#349946"])
  150. svg.selectAll("path").attr("fill", "#bee59e")
  151. for k, v of attrHash
  152. console.log areaGrad(attrHash[k][target_key])
  153. svg.selectAll("."+k).attr("fill", areaGrad(attrHash[k][target_key]))
  154. ###
  155.  
  156. # 色を塗る
  157. hexcode_min = "ee0000"
  158. hexcode_max = "#00ee00"
  159.  
  160. # 念のためあらかじめ塗っておく
  161. svg.selectAll("path").attr("fill", "#bee59e")
  162.  
  163. # HEXカラーコードからRGBに変換
  164. [r_min,g_min,b_min] = hex2rgb(hexcode_min)
  165. [r_max,g_max,b_max] = hex2rgb(hexcode_max)
  166. # RGB(0-255)からHSVに変換
  167. [h_min,s_min,v_min] = rgb2hsv(r_min,g_min,b_min)
  168. [h_max,s_max,v_max] = rgb2hsv(r_max,g_max,b_max)
  169. areaGrad = d3.scale.linear().domain([target_min, target_max]).range([[h_max,s_max,v_max], [h_min,s_min,v_min]])
  170.  
  171. for k, v of attrHash
  172. [h,s,v] = areaGrad(attrHash[k][target_key])
  173. [r,g,b] = hsv2rgb(h,s,v)
  174. svg.selectAll("."+k).attr("fill", "rgba(#{r},#{g},#{b},1)")
  175.  
  176. # 内部境界に線を引く
  177. svg.append("path")
  178. .datum(topojson.mesh(topo, topo.objects.yokohama, (a, b) ->
  179. return a isnt b))
  180. .attr("d", path)
  181. .attr("class", "subunit-boundary")
  182.  
  183. # 区コードのラベル貼り
  184. city_labels = new Array()
  185. svg.selectAll(".cityname-label")
  186. .data(yokohama.geometries)
  187. .enter()
  188. .append("text")
  189. .attr("class", (d) ->
  190. if not (city_labels.indexOf(d.properties.name) > -1)
  191. city_labels.push(d.properties.name)
  192. return "cityname-label "+d.properties.name)
  193. .attr("transform", (d) ->
  194. # 文字をpath中央から、文字高さ1/2分高い位置に貼る
  195. pos = path.centroid(d)
  196. pos[1] -= labelLineHeight / 2
  197. return "translate(" + pos + ")")
  198. .attr("dy", ".35em")
  199. .text((d) ->
  200. return attrHash[d.properties.name].name)
  201.  
  202. # 値ラベル貼り
  203. svg.selectAll(".stat-label")
  204. .data(yokohama.geometries)
  205. .enter()
  206. .append("text")
  207. .attr("class", (d) ->
  208. if not (city_labels.indexOf(d.properties.name) > -1)
  209. city_labels.push(d.properties.name)
  210. return "stat-label "+d.properties.name)
  211. .attr("transform", (d) ->
  212. # 文字をpath中央から、文字高さ1/2分高い位置に貼る
  213. pos = path.centroid(d)
  214. pos[1] += labelLineHeight / 2
  215. return "translate(" + pos + ")")
  216. .attr("dy", ".35em")
  217. .text((d) ->
  218. return attrHash[d.properties.name][target_key])
  219.  
  220. # 各最初のエリアのみラベルを表示する
  221. for id in city_labels
  222. svg.select(".cityname-label."+id).style("display", "block")
  223. svg.select(".stat-label."+id).style("display", "block")
  224.  
  225. return true
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement