LoginSignup
0
3

More than 5 years have passed since last update.

csvからDataを読んでるd3を変数から読むように変更する

Posted at

背景

d3.jsの例は大体CSVからデータを読む様になっているが、諸事情により、JS内の変数から処理したい

とりあえずD3を見る

Grouped Bar Chart のJSを js2.coffeeで変更した。リンクを開けば、どんなグラフになるか見れる。

  svg = d3.select('svg')
  margin = 
    top: 20
    right: 20
    bottom: 30
    left: 40
  width = +svg.attr('width') - (margin.left) - (margin.right)
  height = +svg.attr('height') - (margin.top) - (margin.bottom)
  g = svg.append('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')
  x0 = d3.scaleBand().rangeRound([
    0
    width
  ]).paddingInner(0.1)
  x1 = d3.scaleBand().padding(0.05)
  y = d3.scaleLinear().rangeRound([
    height
    0
  ])
  z = d3.scaleOrdinal().range([
    '#98abc5'
    '#8a89a6'
    '#7b6888'
    '#6b486b'
    '#a05d56'
    '#d0743c'
    '#ff8c00'
  ])
  d3.csv 'data.csv', ((d, i, columns) ->
    `var i`
    i = 1
    n = columns.length
    while i < n
      d[columns[i]] = +d[columns[i]]
      ++i
    d
  ), (error, data) ->
    if error
      throw error
    keys = data.columns.slice(1)
    x0.domain data.map((d) ->
      d.State
    )
    x1.domain(keys).rangeRound [
      0
      x0.bandwidth()
    ]
    y.domain([
      0
      d3.max(data, (d) ->
        d3.max keys, (key) ->
          d[key]
      )
    ]).nice()
    g.append('g').selectAll('g').data(data).enter().append('g').attr('transform', (d) ->
      'translate(' + x0(d.State) + ',0)'
    ).selectAll('rect').data((d) ->
      keys.map (key) ->
        {
          key: key
          value: d[key]
        }
    ).enter().append('rect').attr('x', (d) ->
      x1 d.key
    ).attr('y', (d) ->
      y d.value
    ).attr('width', x1.bandwidth()).attr('height', (d) ->
      height - y(d.value)
    ).attr 'fill', (d) ->
      z d.key
    g.append('g').attr('class', 'axis').attr('transform', 'translate(0,' + height + ')').call d3.axisBottom(x0)
    g.append('g').attr('class', 'axis').call(d3.axisLeft(y).ticks(null, 's')).append('text').attr('x', 2).attr('y', y(y.ticks().pop()) + 0.5).attr('dy', '0.32em').attr('fill', '#000').attr('font-weight', 'bold').attr('text-anchor', 'start').text 'Population'
    legend = g.append('g').attr('font-family', 'sans-serif').attr('font-size', 10).attr('text-anchor', 'end').selectAll('g').data(keys.slice().reverse()).enter().append('g').attr('transform', (d, i) ->
      'translate(0,' + i * 20 + ')'
    )
    legend.append('rect').attr('x', width - 19).attr('width', 19).attr('height', 19).attr 'fill', z
    legend.append('text').attr('x', width - 24).attr('y', 9.5).attr('dy', '0.32em').text (d) ->
      d
    return

csvの読まれたデータを見る

データを読んでいるところはここなので、読んだあとのdataがどうなっているかを見れば良いので、console.logなどして中身を確認してみる

  d3.csv 'data.csv', ((d, i, columns) ->
    `var i`
    i = 1
    n = columns.length
    while i < n
      d[columns[i]] = +d[columns[i]]
      ++i
    d
  ), (error, data) ->
    if error
      throw error
dataの中身
[Object, Object, Object, Object, Object, Object, columns: Array[8]]

は6個のハッシュのようなObjectと何故かcolumnsがKeyのHash型みたいなものが入っている。あとでdata.columnsのところで呼ばれるのが、この部分であることがわかる。前半6個のHash(Object)は、以下のような感じ。

5 to 13 Years:4499890
14 to 17 Years:2159981
18 to 24 Years:3853788
25 to 44 Years:10604510
45 to 64 Years:8819342
65 Years and Over:4114496
State:"CA"
Under 5 Years:2704659

つまり、1行ずつのデータがColumn名:値Key-Valueの形になったデータであることがわかる。
最後のColumnsは ["State","Under 5 Years","5 to 13 Years","14 to 17 Years","18 to 24 Years","25 to 44 Years","45 to 64 Years","65 Years and Over"]である。

自分で変数にしてみる

上でdataを解体したので残りは簡単。

簡略化のため簡単なデータを作る。改行も面倒だったので、関数にして動かす。

変更
# d3.csv 'data.csv', ((d, i, columns) ->
#   `var i`
#   i = 1
#   n = columns.length
#   while i < n
#     d[columns[i]] = +d[columns[i]]
#     ++i
#   d
# ), (error, data) ->
#   if error
#     throw error
test = () ->
  data = [{ 'State': 'Beijing', 'a': 10, 'b': 20, 'c': 30}, {'State': 'Tokyo', 'a': 12, 'b': 10, 'c': 10}]
  data['columns'] = ['State', 'a', 'b', 'c']

# (以下は全部同じ)

test() #これで実行

これで、以下のグラフが出来た。

Screen Shot 2017-03-24 at 12.42.28 AM.png

これで、自由自在に自分のデータを描画できるようになった。

0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3