Commit 28f8a218 authored by Kjetil Thuen's avatar Kjetil Thuen
Browse files

Added some error handling

parent f6d459fc
......@@ -6,9 +6,18 @@ currentFrame = 0
window.nesstartimebars = {}
window.nesstartimebars.main = (containerId, dataDesc) ->
timebars.displayPoster containerId,
"fa fa-cog fa-spin",
"Fetching data",
"Please wait"
nesstarloader.reloadNesstarData( (data) ->
timebars.setupChart containerId, data, dataDesc.display
currentFrame = timebars.nextFrame containerId, currentFrame
, (errorStatus) ->
timebars.displayPoster containerId,
"fa fa-exclamation-triangle"
"Problems fetching data",
errorStatus
, dataDesc)
window.nesstartimebars.toggleAnimation = (containerId) ->
......
......@@ -34,8 +34,9 @@ requestDescription = () ->
}
}
fetchData = (url, callback) ->
fetchData = (url, callback, errFunc) ->
request = new XMLHttpRequest()
request.onerror = errFunc
request.onload = callback
request.open 'GET', url, true
request.send()
......@@ -59,39 +60,43 @@ flattenNesstarData = (cellValue) ->
# Runs a Nesstar cube REST response through flattenNesstarData and then sorts
# the resulting collection of objects by year and birthyear
prepareFuncFactory = (callback) ->
prepareFuncFactory = (successCallback, errorCallback) ->
prepareDataForTimeBar = ->
values = JSON.parse(@response).payload.values
saneValueStore = lodash.map(values, flattenNesstarData)
if @status is 200
values = JSON.parse(@response).payload.values
saneValueStore = lodash.map(values, flattenNesstarData)
valuesByYear = lodash.groupBy saneValueStore, (cell) ->
parseInt(cell.tid)
valuesByYear = lodash.groupBy saneValueStore, (cell) ->
parseInt(cell.tid)
valuesByYearAndBirthYear = lodash.mapValues valuesByYear, (years) ->
lodash.groupBy years, (cell) ->
parseInt(cell.tid) - parseInt(cell.alder)
valuesByYearAndBirthYear = lodash.mapValues valuesByYear, (years) ->
lodash.groupBy years, (cell) ->
parseInt(cell.tid) - parseInt(cell.alder)
flattenedValuesByYearAndBirthYear =
lodash.mapValues valuesByYearAndBirthYear, (years) ->
lodash.filter lodash.map(years, (birthYear) ->
{
birthyear: parseInt(birthYear[0].tid) - parseInt(birthYear[0].alder)
year: parseInt birthYear[0].tid
age: parseInt birthYear[0].alder
label: parseInt birthYear[0].alder
rvalue: birthYear[0].value
lvalue: birthYear[1].value
}
), (cell) ->
#Ages < 100 are really age groups. Eeeeewww!
cell.age < 100
flattenedValuesByYearAndBirthYear =
lodash.mapValues valuesByYearAndBirthYear, (years) ->
lodash.filter lodash.map(years, (birthYear) ->
{
birthyear: parseInt(birthYear[0].tid) -
parseInt(birthYear[0].alder)
year: parseInt birthYear[0].tid
age: parseInt birthYear[0].alder
label: parseInt birthYear[0].alder
rvalue: birthYear[0].value
lvalue: birthYear[1].value
}
), (cell) ->
#Ages < 100 are really age groups. Eeeeewww!
cell.age < 100
callback flattenedValuesByYearAndBirthYear
successCallback flattenedValuesByYearAndBirthYear
else
errorCallback @status + ": " + @statusText
prepareDataForTimeBar
reloadData = (consumerFunc, dataDesc) ->
prep = prepareFuncFactory consumerFunc
fetchData assembleDataRequest(dataDesc), prep
reloadData = (consumerFunc, errFunc, dataDesc) ->
prep = prepareFuncFactory consumerFunc, errFunc
fetchData assembleDataRequest(dataDesc), prep, errFunc
exports.reloadNesstarData = reloadData
......@@ -120,6 +120,14 @@ addBar = (newBar, chartId) ->
.classed "selected", (d) ->
d.birthyear is completeData[chartId].selectedYear
barGroup.append('rect')
.attr 'class', 'click-capture'
.style 'visibility', 'hidden'
.attr 'x', 0
.attr 'y', 0
.attr 'width', "100%"
.attr 'height', barThickness(chartId) + 2
barGroup.append "rect"
.attr "class", "right"
.attr "x", chartWidth(chartId) / 2 + margin(chartId)
......@@ -149,19 +157,21 @@ updateChart = (chartId, frameNum) ->
yAxesGroup = chart.select "yAxesGroup"
label = d3.select chartId + " span.yearLabel"
.html completeData[chartId].displayDetails.name + " " +
lodash.keys(completeData[chartId].yearData)[frameNum]
.html completeData[chartId].displayDetails.name +
" <span class='year'>" +
lodash.keys(completeData[chartId].yearData)[frameNum] +
"</span>"
valuepoints = chart.selectAll "g.valuepoint"
.data data, (d) -> d.birthyear
valuepoints.classed "selected", (d) ->
d.birthyear is completeData[chartId].selectedYear
valuepoints.transition()
.attr "transform", (d, i) ->
"translate(0, " + (y_scale(chartId)(i) + 1) + ")"
valuepoints.classed "selected", (d) ->
d.birthyear is completeData[chartId].selectedYear
valuepoints.select "rect.left"
.transition()
.attr "x", (d) -> (chartWidth(chartId) / 2) -
......@@ -186,12 +196,14 @@ updateChart = (chartId, frameNum) ->
undefined
nextFrame = (chartId, frameNum) ->
num = frameNum or 0
num++
if num >= lodash.keys(completeData[chartId].yearData).length
num = 0
updateChart chartId, num
num
dataLength = lodash.keys(completeData[chartId].yearData).length
if dataLength > 0
num = frameNum or 0
num++
if num >= dataLength
num = 0
updateChart chartId, num
num
#Constructor.
#
......@@ -220,58 +232,87 @@ setupChart = (chartId, data, displayDetails) ->
birthyearlabel: "Birthyear"
}
completeData[chartId].selectedYear =
valuesFromFrame(chartId, 0)[0].birthyear
lodash.forEach (lodash.keys completeData), (id) ->
d3.select id
.html ""
svg = d3.select id
.insert "svg"
.attr "class", "chart"
.attr "shape-rendering", "geometricPrecision"
.attr "width", chartWidth(id)
.attr "height", chartHeight(id)
nextFrame id, 0
axesGroup = svg.append "g"
.attr "class", "yAxesGroup"
.attr "transform",
"translate("+ chartWidth(id) / 2 + "," + margin(id) + ")"
if lodash.keys(completeData).length < 1 or
lodash.keys(completeData[chartId].yearData).length < 2
displayPoster(chartId,
"fa fa-exclamation-triangle",
"Problems rendering chart",
"Could not understand data")
else
lodash.forEach (lodash.keys completeData), (id) ->
d3.select id
.html ""
svg = d3.select id
.insert "svg"
.attr "class", "chart"
.attr "shape-rendering", "geometricPrecision"
.attr "width", chartWidth id
.attr "height", chartHeight id
nextFrame id, 0
axesGroup = svg.append "g"
.attr "class", "yAxesGroup"
.attr "transform",
"translate("+ chartWidth(id) / 2 + "," + margin(id) + ")"
metadata = d3.select chartId
.append "div"
.attr "class", "metaData"
metadata.append "span"
.attr "class", "yearLabel"
metadata.append "div"
.attr "class", "dataDetails"
d3.select chartId
.append "div"
.attr "class", "leftLabel"
.html "<i class='" +
completeData[chartId].displayDetails.leftsymbol +
"'></i> " +
completeData[chartId].displayDetails.leftlabel
d3.select chartId
.append "div"
.attr "class", "rightLabel"
.html completeData[chartId].displayDetails.rightlabel +
" <i class='" +
completeData[chartId].displayDetails.rightsymbol +
"'></i>"
window.onresize = setupChart
displayPoster = (chartId, icon, header, message) ->
d3.select chartId
.html ""
metadata = d3.select chartId
poster = d3.select chartId
.append "div"
.attr "class", "metaData"
metadata.append "span"
.attr "class", "yearLabel"
.data data
.attr "class", "poster"
.style "min-height", -> chartHeight(chartId) / 2 + "px"
.style "margin-top", -> chartHeight(chartId) / 4 + "px"
metadata.append "div"
.attr "class", "dataDetails"
d3.select chartId
.append "div"
.attr "class", "leftLabel"
.html "<i class='" +
completeData[chartId].displayDetails.leftsymbol +
"'></i> " +
completeData[chartId].displayDetails.leftlabel
d3.select chartId
.append "div"
.attr "class", "rightLabel"
.html completeData[chartId].displayDetails.rightlabel +
" <i class='" +
completeData[chartId].displayDetails.rightsymbol +
"'></i>"
if icon
poster.append "div"
.attr "class", "icon"
.append "i"
.attr "class", icon
if header
poster.append "h3"
.attr "class", "header"
.html header
window.onresize = setupChart
if message
poster.append "div"
.attr "class", "message"
.html message
exports.displayPoster = displayPoster
exports.setupChart = setupChart
exports.speed = speed
exports.nextFrame = nextFrame
......@@ -23,9 +23,42 @@ div.chartContainer {
position: relative;
}
.chart {
pointer-events: all;
.poster {
@include rounded();
position: relative;
margin: 5em;
background: rgba(0.2, 0.2, 0.2, 0.6);
padding: 2em;
color: #fff;
.icon {
position: absolute;
font-size: 50px;
top: 25px;
left: 30px;
clear: both;
}
.message {
position: absolute;
top: 60px;
left: 90px;
font-size: 14px;
clear: both;
}
.header {
position: absolute;
top: 20px;
left: 90px;
font-size: 20px;
clear: both;
}
}
.chart {
.valuepoint {
pointer-events: all;
}
.valuepoint text {
visibility: hidden;
text-anchor: middle;
......@@ -57,6 +90,11 @@ div.metaData {
display: inline;
span.yearLabel {
font-size: 150%;
span.year {
font-weight: bold;
color: #f44;
text-shadow: 0 0 0.2em white, 0 0 0.2em white;
}
}
dl {
dt {
......
......@@ -47,7 +47,7 @@
]
},
display: {
name: "Befolkningsframskrivning for Hordaland, fordelt på kjønn",
name: "Befolkningsframskrivning for Bergen, fordelt på kjønn",
leftsymbol: "fa fa-female",
rightsymbol: "fa fa-male",
leftlabel: "Kvinner",
......
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