Skip to content

Instantly share code, notes, and snippets.

@radbrt
Last active February 27, 2019 22:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save radbrt/99e2726dd98a306d312c to your computer and use it in GitHub Desktop.
Save radbrt/99e2726dd98a306d312c to your computer and use it in GitHub Desktop.
Innbyggerantall

#Innbyggerantall Kartet kan dras og zoomes. Grafen nederst viser innbyggertall i kommunen, og kommunnen du holder pekeren over markeres i denne grafen. Zoomer du lang nok inn på kartet, vises kommunenavn.

Data fra SSB og Kartverket, mye av koden inspirert/kopiert fra @alignedleft.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Innbyggerantall</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script>
<script type="text/javascript" src="json-stat.js" ></script>
<style type="text/css">
body {
background-color: #fff;
}
svg {
background-color: #fff;
margin: 0;
padding: 0;
}
path.kommune {
stroke: #4499aa;
stroke-width: 0.5px;
}
svg path:hover {
fill: yellow;
}
svg rect.highlight {
fill: #ff0000;
}
#tooltip {
position: absolute;
top: 0;
left: 0;
z-index: 10;
margin: 10;
padding: 10px 5px 10px 5px;
width: 950px;
height: 12px;
color: #CC5D0E;
font-family: sans-serif;
font-size: 12px;
font-weight: bold;
text-align: center;
background-color: rgba(0, 0, 0, 0.75);
opacity: 0;
pointer-events: none;
}
.axis path,
.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.axis text {
font-family: "Helvetica Neue", "sans-serif";
font-size: 11px;
}
</style>
</head>
<body>
<div id="tooltip"></div>
<script>
JSONstat("https://data.ssb.no/api/v0/dataset/85432.json?lang=no", function() {
var utd=this.Dataset(0).toTable( { type : "arrobj", content : "id" } ).filter(function(d) { return d.Nivaa>='03a' && d.Kjonn=='0' && d.Tid=='2014'; });
var utdata = d3.nest()
.key(function(d) { return d.Region;})
.rollup(function(d) {
return d3.sum(d, function(g) {return g.value; });
})
.entries(utd);
JSONstat( "https://data.ssb.no/api/v0/dataset/1078.json?lang=no", function(){
var nl=this.Dataset(0).toTable( { type : "arrobj", content : "id" } );
var w = 960;
var h = 500;
var map;
var text;
var maxZoomIn = w*40;
var maxZoomOut = h;
d3.json("kommuner_2.5pct.json", function(json) {
var nFormat = d3.format(",");
var zero = d3.format("04d");
var data = d3.nest()
.key(function(d) { return d.Region;})
.rollup(function(d) {
return d3.sum(d, function(g) {return g.value; });
})
.entries(nl);
var color = d3.scale.quantize()
.domain([0, Math.sqrt(d3.max(data, function(d) { return d.values; })) ])
.range(["#d4b9da", "#c994c7", "#df65b0", "#e7298a", "#ce1256", "#91003f"])
;
var textsize = d3.scale.linear()
.domain([maxZoomOut, maxZoomIn])
.range([6, 14]);
var offset = d3.scale.linear()
.domain([maxZoomOut, maxZoomIn])
.range([0, -30]);
var xScale = d3.scale.ordinal()
.domain([428])
.rangeRoundBands([ 10, w - 10 ], 0.05);
var yScale = d3.scale.linear()
.domain([0, 700000])
.range([h-10,10]);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("right")
;
data.sort(function(a, b) {
return d3.ascending(a.values, b.values);
});
for (u=0; u<utdata.length; u++) {
for (i=0; i<data.length; i++) {
if (utdata[u].key == data[i].key) {
data[i].utd = utdata[u].values;
}
}
}
//console.log(data);
for (i=0; i<data.length; i++) {
for(j=0; j<json.features.length; j++) {
if (zero(json.features[j].properties.komm) == data[i].key) {
json.features[j].properties.antall = data[i].values;
json.features[j].properties.utd = data[i].utd;
json.features[j].properties.rank = 428-i;
//data[i].included='1';
}
}
}
json.features.sort(function(a, b) {
return d3.descending(a.properties.antall, b.properties.antall);
});
//Define map projection
var projection = d3.geo.mercator()
.center([16, 61])
.translate([ w/2, h/2 ])
.scale([ w*2.2 ])
;
//Define path generator
var path = d3.geo.path()
.projection(projection);
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
var tooltip = d3.select("#tooltip");
var zoom = d3.behavior.zoom()
.translate( projection.translate() )
.scale( projection.scale() )
.scaleExtent([ maxZoomOut, maxZoomIn ])
.on("zoom", function(d) {
//Get the translate and scale values from this event
var t = d3.event.translate;
var s = d3.event.scale;
//Update the zoom and projection objects with these
zoom.translate(t);
projection.translate(t).scale(s);
//Recalculate paths (given new t and s values)
map.attr("d", path);
text
.attr("x", function(d) {
return path.centroid(d)[0] + offset(s);
})
.attr("y", function(d) {
return path.centroid(d)[1];
})
.attr("font-size", textsize(s))
.text(function(d) {
if(s>w*7) {
return d.properties.navn;
} else {
return "";
}
})
;
});
groups = svg.selectAll("g")
.data(json.features)
.enter()
.append("g")
.attr("class", "gr");
map = groups.append("path")
.attr("d", path)
.style("fill", function(d) {
if (d.properties.antall) {
return color( Math.sqrt(d.properties.antall) );
} else {
return "#999";
}
})
.attr("class", "kommune")
.on("mouseover", function(d, i) {
d3.select(this).style("fill", "#fefe33");
//console.log(d);
var p=i+1;
tooltip.text(d.properties.navn + " er norges " + (p==1? "" : (d.properties.rank) + ".") + " største kommune med " + nFormat(d.properties.antall) + " innbyggere, " + Math.round(d.properties.utd, -1) + "% har høyere utdanning"
).style("opacity", 1);
current = d.properties.komm;
d3.selectAll("rect.bar")
.filter(function(d) {
if(zero(current)==d.key) { return true; }
}).classed("highlight", true);
d3.selectAll("circle")
.filter(function(d) {
if(zero(current)==d.key) { return true; }
})
.classed("highlight", true)
.style("opacity", 1)
;
})
.on("mouseout", function(d) {
d3.selectAll("rect.bar").classed("highlight", false);
tooltip.style("opacity", 0).text("");
d3.select(this).style("fill", function(d) {
if (d.properties.antall) {
return color( Math.sqrt(d.properties.antall) );
} else {
return "#999";
}
})
.style("stroke", "#4499aa");
d3.selectAll("circle").style("opacity", 0);
})
.call(zoom);
text = groups
.append("text")
.text(function(d) {
return "";
})
.attr("x", function(d) {
return path.centroid(d)[0];
})
.attr("y", function(d) {
return path.centroid(d)[1];
})
.attr("font-size", textsize(w*2))
.attr("fill", "#444")
.call(zoom);
gthing = svg.selectAll("#g1")
.attr("class", "theBar")
.data(data)
.enter()
.append("g");
thing = gthing
.append("rect")
.attr("height", function(d) {
return h - 10 - yScale(d.values);
})
.attr("width", "1.5px")
.attr("x", function(d, i) {
return 5 + 2*i;
})
.attr("y", function(d) {
return yScale(d.values);
})
.attr("class", "bar");
points = gthing
.append("circle")
.attr("cy", h-5)
.attr("cx", function(d, i) { return 5 + 2*i; })
.attr("r", 2)
.attr("opacity", 0);
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + (w-80) + ",0)")
.call(yAxis);
});
});
});
</script>
</body>
</html>
/*
JSON-stat Javascript Toolkit v. 0.8.3
http://json-stat.org
https://github.com/badosa/JSON-stat
Copyright 2015 Xavier Badosa (http://xavierbadosa.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the License for the specific language governing
permissions and limitations under the License.
*/
function JSONstat(t,e){return window===this?new JSONstat.jsonstat(t,e):void 0}var JSONstat=JSONstat||{}
JSONstat.version="0.8.3",function(){"use strict"
function t(t){return"[object Array]"===Object.prototype.toString.call(t)}function e(e,n){var i,s,r,l,a=function(t,e){var n,i,s=e!==!1
if(window.XDomainRequest&&/^(http(s)?:)?\/\//.test(t)){if(!s)return
i=new XDomainRequest,i.onload=function(){n=JSON.parse(i.responseText),e.call(JSONstat(n))},i.open("GET",t),i.send()}else if(i=new XMLHttpRequest,i.onreadystatechange=function(){if(4===i.readyState){var t=i.status
n=t&&i.responseText&&(t>=200&&300>t||304===t)?JSON.parse(i.responseText):null,s&&e.call(JSONstat(n))}},i.open("GET",t,s),i.send(null),!s)return n},o=function(e,n){var i,s=[]
if("string"==typeof e&&(e=[e]),t(e)){if(e.length===n)return e
if(1===e.length){for(i=0;n>i;i++)s.push(e[0])
return s}}for(i=0;n>i;i++){var r=void 0===e[i]?null:e[i]
s.push(r)}return s}
if(this.length=0,this.id=[],null!==e&&void 0!==e)switch(this["class"]=e["class"]||"bundle",this["class"]){case"bundle":var u=[],h=0
if(this.error=null,this.length=0,"string"==typeof e&&e.length>0&&(e=a(e,"function"==typeof n?n:!1)),null===e||"object"!=typeof e)return this["class"]=null,void(void 0===e&&(delete this.id,delete this["class"],delete this.error,delete this.length))
if(e.hasOwnProperty("error"))return void(this.error=e.error)
if("dataset"===e["class"]||"collection"===e["class"])return JSONstat(e)
for(s in e)h++,u.push(s)
this.__tree__=e,this.length=h,this.id=u
break
case"dataset":e.hasOwnProperty("__tree__")||(delete e["class"],e={__tree__:e}),this.__tree__=i=e.__tree__,this.label=i.label||null,this.note=i.note||null,this.link=i.link||null,this.href=i.href||null,this.updated=i.updated||null,this.source=i.source||null,this.extension=i.extension||null
var f,c=0
if(i.hasOwnProperty("value")&&t(i.value))c=i.value.length
else if(i.hasOwnProperty("status")&&t(i.status))c=i.status.length
else if(i.hasOwnProperty("dimension")){var d=i.dimension.size,p=1
for(f=d.length;f--;)p*=d[f]
c=p}if(this.value=o(i.value,c),this.status=i.hasOwnProperty("status")?o(i.status,c):null,i.hasOwnProperty("dimension")){if(!t(i.dimension.id)||!t(i.dimension.size)||i.dimension.id.length!=i.dimension.size.length)return
var v=i.dimension,g=v.role||null,y=v.id,_=v.size.length,b=function(t){g.hasOwnProperty(t)||(g[t]=null)}
if(this.length=_,this.id=y,g&&(b("time"),b("geo"),b("metric"),b("classification")),g&&null===g.classification){var m=[],w=["time","geo","metric"],O=function(t,e){for(var n=e.length;n--;)if(t===e[n])return!0
return!1}
for(f=0;3>f;f++){var x=g[w[f]]
null!==x&&(m=m.concat(x))}for(g.classification=[],f=0;_>f;f++)O(y[f],m)||g.classification.push(y[f])
0===g.classification.length&&(g.classification=null)}this.role=g,this.n=c
for(var S=0,k=this.length;k>S;S++)if(v[v.id[S]].category.hasOwnProperty("index")){if(t(v[v.id[S]].category.index)){var P={},D=v[v.id[S]].category.index
for(r=D.length,l=0;r>l;l++)P[D[l]]=l
v[v.id[S]].category.index=P}}else{var j=0
v[v.id[S]].category.index={}
for(s in v[v.id[S]].category.label)v[v.id[S]].category.index[s]=j++}}else this.length=0
break
case"dimension":i=e.__tree__
var J=[],N=i.category
if(!e.hasOwnProperty("__tree__")||!i.hasOwnProperty("category"))return
if(!N.hasOwnProperty("label")){N.label={}
for(s in N.index)N.label[s]=s}for(s in N.index)J[N.index[s]]=s
this.__tree__=i,this.label=i.label||null,this.note=i.note||null,this.link=i.link||null,this.href=i.href||null,this.id=J,this.length=J.length,this.role=e.role,this.hierarchy=N.hasOwnProperty("child"),this.extension=i.extension||null
break
case"category":var T=e.child
this.id=T,this.length=null===T?0:T.length,this.index=e.index,this.label=e.label,this.note=e.note||null,this.unit=e.unit,this.coordinates=e.coord
break
case"collection":if(this.length=0,this.label=e.label||null,this.note=e.note||null,this.link=e.link||null,this.href=e.href||null,this.updated=e.updated||null,this.source=e.source||null,this.extension=e.extension||null,null!==this.link&&e.link.item){var z=e.link.item
if(this.length=t(z)?z.length:0,this.length)for(l=0;l<this.length;l++)this.id[l]=z[l].href}}}e.prototype.Item=function(t){if(null===this||"collection"!==this["class"]||!this.length)return null
if("number"==typeof t)return t>this.length||0>t?null:this.link.item[t]
var e,n=[]
if("object"==typeof t){if(!t["class"]&&!t.follow)return null
t["class"]?e=function(t,e,i){i["class"]===t.link.item[e]["class"]&&n.push(t.link.item[e])}:t.follow&&(e=function(t,e){n.push(JSONstat(t.id[e]))})}else e=function(t,e){n.push(t.link.item[e])}
for(var i=0;i<this.length;i++)e(this,i,t)
return n},e.prototype.Dataset=function(t){if(null===this)return null
if("dataset"===this["class"])return void 0!==t?this:[this]
if("bundle"!==this["class"])return null
if(void 0===t){for(var n=[],i=0,s=this.id.length;s>i;i++)n.push(this.Dataset(this.id[i]))
return n}if("number"==typeof t){var r=this.id[t]
return void 0!==r?this.Dataset(r):null}var l=this.__tree__[t]
return void 0===l?null:new e({"class":"dataset",__tree__:l})},e.prototype.Dimension=function(t){var n,i=[],s=this.id.length,r=function(t,e){var n=t.role
if(null!==n)for(var i in n)for(var s=null!==n[i]?n[i].length:0;s--;)if(n[i][s]===e)return i
return null}
if(null===this||"dataset"!==this["class"])return null
if(void 0===t){for(n=0;s>n;n++)i.push(this.Dimension(this.id[n]))
return i}if("number"==typeof t){var l=this.id[t]
return void 0!==l?this.Dimension(l):null}var a=this.__tree__.dimension
if(void 0===a)return null
if("object"==typeof t){if(t.hasOwnProperty("role")){for(n=0;s>n;n++){var o=this.id[n]
r(a,o)===t.role&&i.push(this.Dimension(o))}return void 0===i[0]?null:i}return null}var u=a[t]
return void 0===u?null:new e({"class":"dimension",__tree__:u,role:r(a,t)})},e.prototype.Category=function(t){if(null===this||"dimension"!==this["class"])return null
if(void 0===t){for(var n=[],i=0,s=this.id.length;s>i;i++)n.push(this.Category(this.id[i]))
return n}if("number"==typeof t){var r=this.id[t]
return void 0!==r?this.Category(r):null}var l=this.__tree__.category
if(void 0===l)return null
var a=l.index[t]
if(void 0===a)return null
var o=l.unit&&l.unit[t]||null,u=l.coordinates&&l.coordinates[t]||null,h=l.child&&l.child[t]||null,f=l.note&&l.note[t]||null
return new e({"class":"category",index:a,label:l.label[t],note:f,child:h,unit:o,coord:u})},e.prototype.Data=function(e){var n,i,s=[],r=function(t){for(var e in t)if(t.hasOwnProperty(e))return e},l=function(t,e){for(var n=[],i=t.dimension,s=i.id,l=0,a=s.length;a>l;l++){var o=s[l],u=e[o]
n.push("string"==typeof u?u:1===i.size[l]?r(i[o].category.index):null)}return n}
if(null===this||"dataset"!==this["class"])return null
if(void 0===e){for(i=this.value.length,n=0;i>n;n++)s.push(this.Data(n))
return s}if("number"==typeof e){var a=this.value[e]
return void 0!==a?{value:a,status:this.status?this.status[e]:null}:null}var o=this.__tree__,u=o.dimension.size,h=u.length
if(t(e)){if(this.length!==e.length)return null
var f=1,c=0,d=[],p=[]
for(n=0;h>n;n++)if(void 0!==e[n]){if("number"!=typeof e[n]||e[n]>=u[n])return null
f*=n>0?u[h-n]:1,c+=f*e[h-n-1]}else d.push(n),p.push(u[n])
if(d.length>1)return null
if(1===d.length){for(var v=0,g=p[0];g>v;v++){var y=[]
for(n=0;h>n;n++)y.push(n!==d[0]?e[n]:v)
s.push(this.Data(y))}return s}return{value:this.value[c],status:this.status?this.status[c]:null}}var _=l(o,e),b=[],m=o.dimension
for(i=_.length,n=0;i>n;n++)b.push(m[m.id[n]].category.index[_[n]])
return this.Data(b)},e.prototype.toTable=function(t,e){if(null===this||"dataset"!==this["class"])return null
1==arguments.length&&"function"==typeof t&&(e=t,t=null)
var n,i,s,r,l,a=this.__tree__
if(t=t||{field:"label",content:"label",vlabel:"Value",slabel:"Status",type:"array",status:!1},"function"==typeof e){n=this.toTable(t)
var o=[],u="array"!==t.type?0:1,h="object"!==t.type?n.slice(u):n.rows.slice(0)
for(l=h.length,i=0;l>i;i++){var f=e.call(this,h[i],i)
void 0!==f&&o.push(f)}return"object"===t.type?{cols:n.cols,rows:o}:("array"===t.type&&o.unshift(n[0]),o)}if("arrobj"===t.type){n=this.toTable({field:"id",content:t.content,status:t.status})
var c=[],d=n.shift()
for(l=n.length,i=0;l>i;i++){var p={}
for(s=n[i].length;s--;)p[d[s]]=n[i][s]
c.push(p)}return c}var v,g,y,_,b="id"===t.field
if("object"===t.type){var m="number"==typeof this.value[0]||null===this.value[0]?"number":"string"
v=function(t,e){var n=b&&t||e||t
z.push({id:t,label:n,type:"string"})},g=function(t,e,n){var i=b&&"value"||t||"Value",s=b&&"status"||e||"Status"
n&&z.push({id:"status",label:s,type:"string"}),z.push({id:"value",label:i,type:m})},y=function(t){B.push({v:t})},_=function(t){B.push({v:t}),V.push({c:B})}}else v=function(t,e){var n=b&&t||e||t
z.push(n)},g=function(t,e,n){var i=b&&"value"||t||"Value",s=b&&"status"||e||"Status"
n&&z.push(s),z.push(i),T.push(z)},y=function(t){B.push(t)},_=function(t){B.push(t),T.push(B)}
var w=a.dimension,O=w.id,x=O.length,S=w.size
if(x!=S.length)return!1
var k=[],P=1,D=1,j=[],J=[],N=[],T=[],z=[],V=[]
for(i=0;x>i;i++){var q=O[i],C=w[q].label
v(q,C),P*=S[i],D*=S[i]
var R=[]
for(s=0;s<S[i];s++)for(var X in w[O[i]].category.index)if(w[O[i]].category.index[X]===s){var E="id"!==t.content&&w[O[i]].category.label?w[O[i]].category.label[X]:X
R.push(E)}k.push(R),j.push(D)}for(g(t.vlabel,t.slabel,t.status),l=k.length,i=0;l>i;i++){for(var G=[],A=0,H=k[i].length;H>A;A++)for(var I=0;I<P/j[i];I++)G.push(k[i][A])
J.push(G)}for(l=J.length,i=0;l>i;i++){var L=[],M=0
for(r=0;P>r;r++)L.push(J[i][M]),M++,M===J[i].length&&(M=0)
N.push(L)}for(r=0;P>r;r++){var B=[]
l=J.length
for(var F=0;l>F;F++)y(N[F][r])
t.status&&y(this.status?this.status[r]:null),_(this.value[r])}return"object"===t.type?{cols:z,rows:V}:T},e.prototype.node=function(){return this.__tree__},e.prototype.toString=function(){return this["class"]},e.prototype.toValue=function(){return this.length},JSONstat.jsonstat=e}()
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment