Commit a940a0a5 authored by Kjetil Thuen's avatar Kjetil Thuen

Feed graph from actual rest data.

Still need some pre-display data manipulation to work properly
parent df2dd1b0
timebars = require './timebars.coffee'
nesstarloader = require './nesstarloader.coffee'
completeData = {}
timeBarAnim = undefined
currentFrame = 0
window.nesstartimebars = {}
window.nesstartimebars.main = (containerId) ->
nesstarloader.reloadNesstarData( (foo) ->
completeData = foo
timebars.setupChart containerId, completeData
timebars.setupChart containerId, foo
currentFrame = timebars.nextFrame containerId, currentFrame
)
window.nesstartimebars.toggleAnimation = (containerId) ->
if timeBarAnim?
clearInterval window.timeBarAnim
clearInterval timeBarAnim
timeBarAnim = undefined
document.getElementById("playBtn")
.innerHTML = "<i class='fa fa-play'></i>"
else
timeBarAnim = setInterval ->
timebars.setFrame containerId
timebars.nextFrame containerId
, timebars.speed()
document.getElementById("playBtn")
.innerHTML = "<i class='fa fa-pause'></i>"
timebars.setupChart containerId, window.data
undefined
lodash = require 'lodash'
getDataDescription = () ->
requestDescription = () ->
{
host: "http://nesstar-dev.nsd.uib.no"
port: 80
......@@ -38,13 +38,15 @@ fetchData = (url, callback) ->
request.send()
assembleDataRequest = () ->
datadesc = getDataDescription()
datadesc = requestDescription()
datadesc.host + ":" +
datadesc.port + "/" +
datadesc.service + "/cube/" +
datadesc.cube + "/query?q=" +
JSON.stringify(datadesc.filter)
# Turns the over-verbose and rigid cell descriptions from the Nesstar REST cube
# JSON format into something more manageble
flattenNesstarData = (cellValue) ->
flattenedCell = lodash.object lodash.map cellValue.coordinate, (x) ->
[ x.category, x.member ]
......@@ -52,27 +54,21 @@ flattenNesstarData = (cellValue) ->
flattenedCell.value = cellValue.value[0].value
flattenedCell
# Runs a Nesstar cube REST response through flattenNesstarData and then sorts
# the resulting collection of objects by year and gender
prepareFuncFactory = (callback) ->
prepareDataForTimeBar = ->
values = JSON.parse(@response).payload.values
saneValueStore = lodash.map(values, flattenNesstarData)
men = lodash.filter saneValueStore, (cell) ->
parseInt(cell.Kjnn) is 1
women = lodash.filter saneValueStore, (cell) ->
parseInt(cell.Kjnn) is 2
menByYear = lodash.groupBy men, (cell) ->
valuesByYear = lodash.groupBy saneValueStore, (cell) ->
parseInt(cell.tid)
womenByYear = lodash.groupBy women, (cell) ->
parseInt(cell.tid)
restructuredData = {
men: menByYear
women: womenByYear
}
valuesByYearAndGender = lodash.mapValues valuesByYear, (cells) ->
lodash.groupBy cells, (cell) ->
parseInt(cell.Kjnn)
callback restructuredData
callback valuesByYearAndGender
prepareDataForTimeBar
......@@ -80,4 +76,4 @@ reloadData = (consumerFunc) ->
prep = prepareFuncFactory consumerFunc
fetchData assembleDataRequest(), prep
window.reloadNesstarData = reloadData
exports.reloadNesstarData = reloadData
d3 = require 'd3-browserify'
lodash = require 'lodash'
completeData = {}
chartWidth = -> 900
chartHeight = -> 500
numBars = -> 100
speed = -> 100
margin = -> 10
next = (prev) ->
prv = (if prev?rvalue then prev.rvalue else 25)
plv = (if prev?lvalue then prev.lvalue else 25)
{
rvalue: Math.max(1, Math.min(100, prv + 10 * (Math.random() - .5)))
lvalue: Math.max(1, Math.min(100, plv + 10 * (Math.random() - .5)))
}
barThickness = ->
chartHeight() / numBars()
......@@ -44,7 +38,12 @@ addBar = (newBar) ->
.attr "width", (d) -> x d.lvalue
.attr "height", barThickness()
updateChart = (containerId, data) ->
valuesFromFrame = (containerId, frameNum) ->
frameIndexes = lodash.keys(completeData[containerId])
completeData[containerId]['' + frameIndexes[frameNum] + '']
updateChart = (containerId, frameNum) ->
data = valuesFromFrame containerId, frameNum
chart = d3.select containerId + " svg.chart"
valuepoints = chart.selectAll "g.valuepoint"
.data data, (d) -> d.lvalue + "," + d.rvalue
......@@ -55,46 +54,40 @@ updateChart = (containerId, data) ->
.attr "transform", (d, i) ->
"translate(0, " + (y(i) + .5) + ")"
newBar = valuepoints.enter()
addBar newBar
addBar valuepoints.enter()
valuepoints.exit()
.transition()
.duration speed() / 2
.attr "height", 0
.remove()
undefined
nextFrame = (containerId, frameNum) ->
num = frameNum or 0
num++
if num > lodash.keys(completeData[containerId]).length
num = 0
updateChart containerId, num
num
#Constructor.
#
#The data parameter should be an object with named years. Each year member
#should be an array with at least two members (male and female, further members
#are ignored), each element in these arrays should contain an object that has
#the value property.
#
#The conteinerId is just a string identfying a div within wich the graph should
#be built
setupChart = (containerId, data) ->
completeData[containerId] = data
chart = d3.select containerId
.append "svg"
.insert "svg"
.attr "class", "chart"
.attr "width", chartWidth()
.attr "height", chartHeight()
updateData = (data) ->
lodash.rest(lodash.clone(data).concat(next(lodash.last(data))))
# State (data and intervals) stored in the window object
window.initTimeBars = (containerId) ->
window.data = d3.range numBars()
.map ->
next lodash.last(window.data)
setupChart(containerId, window.data)
updateChart(containerId, data)
window.animateBarChart = (containerId) ->
if window.timeBarAnim?
console.log("stopp")
clearInterval(window.timeBarAnim)
window.timeBarAnim = undefined
document.getElementById("playBtn").innerHTML = "<i class='fa fa-play'></i>"
else
console.log("start")
window.timeBarAnim = setInterval ->
data = updateData window.data
updateChart(containerId, data)
window.data = data
, speed()
document.getElementById("playBtn").innerHTML = "<i class='fa fa-pause'></i>"
undefined
exports.setupChart = setupChart
exports.speed = speed
exports.nextFrame = nextFrame
#main {
margin-top: 5em;
}
#main button {
margin: 1em;
}
.chart rect.right {
fill: maroon;
}
......
......@@ -11,12 +11,12 @@
<body>
<section id="main">
<div id="content"></div>
<button id="playBtn" class="btn btn-primary" onclick="window.animateBarChart('#content')">
<button id="playBtn" class="btn btn-primary" onclick="window.nesstartimebars.toggleAnimation('#content')">
<i class="fa fa-play"></i>
</button>
</section>
<script>
window.initTimeBars("#content");
window.nesstartimebars.main("#content");
</script>
</body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment