Control by dragging the handle or by using left/right keys.
Data from CBS statline: "Gezondheid, leefstijl, zorggebruik en -aanbod, doodsoorzaken; kerncijfers - Zorguitgaven, naar type zorg."
Based on this block.
| height: 450 | |
| license: gpl-3.0 | |
| border: no |
Control by dragging the handle or by using left/right keys.
Data from CBS statline: "Gezondheid, leefstijl, zorggebruik en -aanbod, doodsoorzaken; kerncijfers - Zorguitgaven, naar type zorg."
Based on this block.
| Onderwerpen_3 | 2001 | 2002 | 2003 | 2004 | 2005 | 2006 | 2007 | 2008 | 2009 | 2010 | 2011 | 2012 | 2013 | 2014 | 2015 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Ziekenhuizen; specialistenpraktijken | 12.6 | 14.2 | 15.1 | 16.1 | 16.7 | 17.5 | 18.5 | 20.6 | 21.8 | 23.0 | 23.0 | 24.3 | 25.4 | 25.5 | 26.4 | |
| Ouderenzorg | 9.6 | 11.0 | 11.9 | 12.1 | 12.5 | 13.2 | 13.6 | 14.3 | 14.8 | 15.2 | 15.9 | 17.2 | 17.2 | 17.6 | 17.0 | |
| Gehandicaptenzorg | 4.3 | 5.1 | 5.6 | 5.9 | 6.1 | 6.4 | 6.8 | 7.4 | 8.1 | 8.4 | 8.6 | 9.5 | 9.6 | 9.8 | 9.4 | |
| Praktijken eerstelijn | 4.4 | 5.0 | 5.4 | 5.5 | 5.5 | 6.0 | 6.5 | 6.8 | 7.1 | 7.3 | 7.7 | 7.7 | 7.6 | 7.9 | 7.9 | |
| Geestelijke gezondheidszorg | 3.1 | 3.4 | 3.9 | 4.1 | 4.5 | 4.7 | 5.1 | 5.5 | 5.9 | 6.1 | 6.3 | 6.6 | 6.6 | 6.7 | 6.5 | |
| Overige aanbieders zorg | 18.0 | 19.5 | 20.7 | 20.9 | 21.9 | 22.6 | 24.2 | 25.4 | 26.6 | 27.6 | 28.2 | 27.6 | 26.8 | 27.0 | 27.4 |
| <!DOCTYPE html> | |
| <meta charset="utf-8"> | |
| <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet"> | |
| <style> | |
| text { | |
| font-size: 10px; | |
| font-family: "Montserrat", sans-serif; | |
| font-weight: 400; | |
| fill: #777; | |
| } | |
| .axis { | |
| -webkit-user-select: none; | |
| -moz-user-select: none; | |
| user-select: none; | |
| } | |
| .axis--y line { | |
| display: none; | |
| } | |
| .axis--x line { | |
| stroke: #eee; | |
| } | |
| .axis .domain { | |
| fill: none; | |
| stroke: none; | |
| } | |
| .track, | |
| .track-inset, | |
| .track-overlay { | |
| stroke-linecap: round; | |
| } | |
| .track { | |
| stroke: #000; | |
| stroke-opacity: 0.3; | |
| stroke-width: 10px; | |
| } | |
| .track-inset { | |
| stroke: #eee; | |
| stroke-width: 8px; | |
| } | |
| .track-overlay { | |
| pointer-events: stroke; | |
| stroke-width: 50px; | |
| stroke: transparent; | |
| cursor: crosshair; | |
| } | |
| .handle { | |
| fill: #fff; | |
| stroke: #000; | |
| stroke-opacity: 0.5; | |
| stroke-width: 1.25px; | |
| } | |
| rect.bar { | |
| fill: #ABD80A; | |
| shape-rendering: crispEdges; | |
| } | |
| .year, | |
| .total { | |
| text-anchor: end; | |
| } | |
| .title { | |
| font-size: 24px; | |
| } | |
| .total { | |
| font-size: 20px; | |
| fill: #ABD80A; | |
| } | |
| .year { | |
| font-size: 14px; | |
| } | |
| </style> | |
| <body> | |
| <svg width="550" height="450"></svg> | |
| </body> | |
| <script src="https://d3js.org/d3.v4.min.js"></script> | |
| <script> | |
| var svg = d3.select("svg"), | |
| margin = {top: 120, right: 20, bottom: 20, left: 200}, | |
| 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 + ")"); | |
| var x = d3.scaleLinear().range([0, width]), | |
| y = d3.scaleBand().paddingInner(0.4).paddingOuter(0.4).rangeRound([0, height]), | |
| t = d3.scaleLinear().range([0, width - 50]).clamp(true); | |
| var data, | |
| title, | |
| handle, | |
| currentValue; | |
| d3.select(window) | |
| .on("keydown", keydowned); | |
| d3.csv("data.csv", function(error, _data) { | |
| if (error) throw error; | |
| title = _data.columns[0]; | |
| data = d3.entries(_data).slice(0,-1).map(function(d) { return d.value; }); | |
| x.domain([0, Math.round(d3.max(data, function(d) { return +d3.max(d3.values(d).slice(0,-1)); }) / 10) * 10]); | |
| y.domain(data.map(function(d) { return d[title]; })); | |
| t.domain(d3.extent(d3.keys(data[0]).slice(0,-1))); | |
| currentValue = t.domain()[1]; | |
| g.append("text") | |
| .attr("class", "title") | |
| .attr("y", -80) | |
| .attr("dy", "0.35em") | |
| .text("Zorgkosten"); | |
| g.append("text") | |
| .attr("class", "total") | |
| .attr("x", width) | |
| .attr("y", -80) | |
| .attr("dy", "0.35em") | |
| .text(""); | |
| g.append("g") | |
| .attr("class", "axis axis--y") | |
| .call(d3.axisLeft(y)); | |
| g.append("g") | |
| .attr("class", "axis axis--x") | |
| .attr("transform", "translate(0," + height + ")") | |
| .call(d3.axisBottom(x) | |
| .ticks(4, ".0s") | |
| .tickSize(-height)) | |
| .select(".tick:last-of-type text") | |
| .select(function() { return this.parentNode.appendChild(this.cloneNode()); }) | |
| .attr("y", -12) | |
| .attr("text-anchor", "end") | |
| .text("(x € 1 mld)"); | |
| var slider = svg.append("g") | |
| .attr("class", "slider") | |
| .attr("transform", "translate(" + margin.left + "," + margin.top / 1.5 + ")"); | |
| slider.append("line") | |
| .attr("class", "track") | |
| .attr("x1", t.range()[0]) | |
| .attr("x2", t.range()[1]) | |
| .select(function() { return this.parentNode.appendChild(this.cloneNode(true)); }) | |
| .attr("class", "track-inset") | |
| .select(function() { return this.parentNode.appendChild(this.cloneNode(true)); }) | |
| .attr("class", "track-overlay") | |
| .call(d3.drag() | |
| .on("start.interrupt", function() { slider.interrupt(); }) | |
| .on("start drag", function() { | |
| currentValue = Math.round(t.invert(d3.event.x)); | |
| update(); | |
| })); | |
| slider.insert("g", ".track-overlay") | |
| .attr("class", "ticks") | |
| .attr("transform", "translate(0," + 18 + ")") | |
| .selectAll("text") | |
| .data(t.ticks(5)) | |
| .enter().append("text") | |
| .attr("x", t) | |
| .attr("text-anchor", "middle") | |
| .text(function(d) { return d; }); | |
| slider.append("text") | |
| .attr("class", "year") | |
| .attr("x", width) | |
| .attr("dy", "0.35em") | |
| .text("year"); | |
| handle = slider.insert("circle", ".track-overlay") | |
| .attr("class", "handle") | |
| .attr("r", 8); | |
| update(); | |
| }); | |
| function update() { | |
| var bar = g.selectAll(".bar") | |
| .data(data, function(d) { return d[title]; }); | |
| bar.enter().append("rect") | |
| .attr("class", "bar") | |
| .attr("y", function (d) { return y(d[title]); }) | |
| .attr("height", y.bandwidth()) | |
| .attr("width", function(d) { return x(d[currentValue]); }); | |
| bar.append("text").text(function(d) { return d[currentValue]; }); | |
| bar.transition() | |
| .duration(750) | |
| .ease(d3.easeLinear) | |
| .attr("width", function(d) { return x(d[currentValue]); }); | |
| handle.attr("cx", t(currentValue)); | |
| d3.select(".year").text(currentValue); | |
| d3.select(".total").text("€ " + d3.format(".1f")(d3.sum(data, function(d) { return d[currentValue]; })) + " mld"); | |
| } | |
| function keydowned() { | |
| if (d3.event.metaKey || d3.event.altKey) return; | |
| switch (d3.event.keyCode) { | |
| case 37: currentValue = Math.max(t.domain()[0], currentValue - 1); break; | |
| case 39: currentValue = Math.min(t.domain()[1], currentValue + 1); break; | |
| default: return; | |
| } | |
| update(); | |
| d3.event.preventDefault(); | |
| } | |
| </script> |