D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
marous91
Full window
Github gist
Wachttijden kaart
Built with
blockbuilder.org
<!DOCTYPE html> <head> <meta charset="utf-8"> <script src="https://d3js.org/d3.v3.min.js"></script> <script src="https://d3js.org/d3.v4.min.js"></script> <style> * { font-family: arial; } body { width: 100%; /*overflow: auto;*/ overflow-x: hidden; } h1,h5,ul,svg { margin-top: 2px; margin-bottom: 2px; /*margin-left: 20px; margin-right: 20px;*/ margin-left: 1%; margin-right: 1%; } .container { width: 100%; /*overflow: hidden;*/ } svg { float: left; width: 39%; } .table-container { width: 59%; overflow-x: scroll; font-size: 12px; } circle.bubble, path.gemeente_withData { cursor: pointer; } circle.bubble { fill-opacity: 0.3; } table { width: 100%; /*height: 580px;*/ overflow-y: scroll; overflow-x: scroll; border-collapse: collapse; } th { background: #333; color: white; font-weight: bold; /*cursor: s-resize;*/ background-position: 3% center; } td, th { padding: 6px; border: 1px solid #ccc; text-align: left; } /*th.des:after { content: "\21E9"; } th.aes:after { content: "\21E7"; }*/ .button-container { height: 50px; } /* Max width before this PARTICULAR table gets nasty This query will take effect for any screen smaller than 760px and also iPads specifically. */ @media only screen and (max-width: 760px), (min-device-width: 768px) and (max-device-width: 1024px) { /* Force table to not be like tables anymore */ table, thead, tbody, th, td, tr { display: block; } .table-container { overflow-x: auto; } /* Hide table headers (but not display: none;, for accessibility) */ thead tr { position: absolute; top: -9999px; left: -9999px; } tr { border: 1px solid #ccc; } td { /* Behave like a "row" */ border: none; border-bottom: 1px solid #eee; position: relative; padding-left: 50%; } td:before { /* Now like a table header */ position: absolute; /* Top/left values mimic padding */ top: 6px; left: 6px; width: 45%; padding-right: 10px; white-space: nowrap; } /* Label the data */ td:before { content: attr(data-th) ": "; font-weight: bold; width: 6.5em; display: inline-block; } svg { width: 100%; } .table-container { width: 100%; } } /* Smartphones (portrait and landscape) ----------- */ @media only screen and (min-device-width : 320px) and (max-device-width : 480px) { body { padding: 0; margin: 0; width: 320px; } } /* iPads (portrait and landscape) ----------- */ @media only screen and (min-device-width: 768px) and (max-device-width: 1024px) { body { width: 495px; } } </style> </head> <body> <h1>Landelijke spreiding wachttijden</h1> <h5>Legenda</h5> <ul> <li>ingevulde gemeentes: blauw: korte aanmeldwachttijd, rood: lange aanmeldwachttijd</li> <li>cirkels: kleine cirkel: korte behandelwachttijd, grote cirkel: lange behandelwachttijd</li> </ul> <div class="button-container"></div> <div class="container"> <!-- <button class="reset"></button> --> </div> <script> d3.text("verrijkt_wachttijden_bestand_mediquest_2016_compleet.csv", (error,rawData) => { if (error) console.log(error) // console.log(rawData); var data = d3.dsvFormat(";").parse(rawData); // console.log("data",data) // load provincies map d3.json("NLprovincies.geojson", function(error, mapData_provinces) { console.log("mapData_provinces",mapData_provinces); d3.json("nl-townships.geojson", (error,mapData_gemeentes) => { if (error) console.log(error) console.log("mapData_gemeentes", mapData_gemeentes, mapData_gemeentes.features[0]) data = dataTransform(data, mapData_gemeentes); console.log("data",data) AllDataLength = data.length; // width and height of svg var width = 500, height = 580; // var svg = d3.select("body") // svg will be in body element var svg = d3.select(".container") .append("svg") // .attr("width", width) .attr("height", height); // Create a unit projection. var projection = d3.geo.mercator() .scale(1) .translate([0, 0]); var geoPath = d3.geo.path().projection(projection); var colorScale_Aanmeldtijd = d3.scaleLinear() .domain(d3.extent(data.filter(d=>d.Aanmeldtijd), function(d) { return parseInt(d.Aanmeldtijd); })) .range(["#99c5dc","red"]) var colorScale_Behandeltijd = d3.scaleLinear() .domain(d3.extent(data.filter(d=>d.Behandeltijd), function(d) { return parseInt(d.Behandeltijd); })) .range(["#99c5dc","red"]) // roep functies aan drawMap(mapData_gemeentes); drawDataOnMap(); drawChart(data); function dataTransform(data, map) { console.log("dataTransform",data,map) var newData = []; data.map(d => { d.Naam_zorgaanbieder = d["Naam.zorgaanbieder"]; d.Plaats_zorgaanbieder = d["Plaats.zorgaanbieder"]; // d.Nadere_typering = d["Nadere.typering"]; // d.Type_GGZ = d["Type.GGZ"]; }) // console.log("data",data) data.forEach( (d,i) => { map.features.forEach( (map,j) => { if (d.gm_code === "GM"+map.properties.code) { map.wachttijden = d; d.map = map; } }) }) data = data.filter(d => d.map && d.Aanmeldtijd) data.forEach(d => { newData.push({ // AGBCODE_INDIENER: d.AGBCODE_INDIENER, Naam_zorgaanbieder: d.Naam_zorgaanbieder, gm_naam: d.gm_naam, Plaats: d.Plaats_zorgaanbieder, // PLAATS: d.PLAATS, // AGBCODE_INDIENER // Type_GGZ: Type_GGZ, // Type_vestiging: d.Type_vestiging, Circuit: d.Circuit, // Nadere_typering: Nadere_typering, Aanmeldtijd: d.Aanmeldtijd, Behandeltijd: d.Behandeltijd, lat: d.lat, lon: d.lon }) }) console.log("newData",newData); return newData; } function getTop(data,n,key) { data.forEach(d => {delete d.lon; delete d.lat; }) data = data.filter((d,i)=> d.Aanmeldtijd !== "NA" && d.Behandeltijd !== "NA"); sortData(data, key) data = data.filter((d,i)=> i<n); return data; } function sortData(data, key) { return data.sort(function(a, b) { return b[key] > a[key]; }); } function drawChart(data) { var key = "Behandeltijd"; if (data.length === AllDataLength) { data = getTop(data,100,key); } else { data = sortData(data, key); } console.log("drawChart()",data) d3.select("h3").remove(); var sortAscending = true; if (data.length === 100) { var titel = "100 kortste "+key+"en"; } else if (data.length === 1) { var titel = "data van "+data[0].Naam_zorgaanbieder; } else { var titel = "data van gemeente "+data[0].gm_naam; } // var tableContainer = d3.select("body") var tableContainer = d3.select(".container") .append("div") .attr("class","table-container") tableContainer.append("h3").text(titel) var table = tableContainer.append('table'); var titles = d3.keys(data[0]); var headers = table.append('thead').append('tr') .selectAll('th') .data(titles).enter() .append('th') .text(function (d) { return d; }) // .on('click', function (d) { // headers.attr('class', 'header'); // if (sortAscending) { // rows.sort(function(a, b) { return b[d] < a[d]; }); // sortAscending = false; // this.className = 'aes'; // } else { // rows.sort(function(a, b) { return b[d] > a[d]; }); // sortAscending = true; // this.className = 'des'; // } // }); var rows = table.append('tbody').selectAll('tr') .data(data).enter() .append('tr'); rows.selectAll('td') .data(function (d) { return titles.map(function (k) { return { 'value': d[k], 'name': k}; }); }).enter() .append('td') .attr('data-th', function (d) { return d.name; }) .text(function (d) { return d.value; }) .style("background", d => { if (d.name === "Aanmeldtijd" || d.name === "Behandeltijd") { if (d.value === "NA") { return "white"; } else { if (d.name === "Aanmeldtijd") { return colorScale_Aanmeldtijd(parseInt(d.value)); } else if (d.name === "Behandeltijd") { return colorScale_Behandeltijd(parseInt(d.value)); } } } else { return "white"; } }) } function showResetBtn() { d3.select("button.reset").remove(); d3.select(".button-container") .insert("button",":first-child") .attr("class", "reset") .text("reset") .on("click", () => { // console.log("reset"); d3.select(".table-container").remove(); drawChart(data); d3.select("button.reset").remove(); }) } function drawMap(mapData_gemeentes) { console.log("drawMap()",mapData_gemeentes); var colorScale = d3.scaleLinear() .domain(d3.extent(data.filter(d=>d.Aanmeldtijd), function(d) { return parseInt(d.Aanmeldtijd); })) .range(["#99c5dc","rgb(178,0,0)"]) // grijs tot rood /* projection */ // Compute the bounds of a feature of interest, then derive scale & translate. // var bounds = geoPath.bounds(mapData_provinces), var bounds = geoPath.bounds(mapData_gemeentes), scale = .95 / Math.max((bounds[1][0] - bounds[0][0]) / width, (bounds[1][1] - bounds[0][1]) / height), translate = [(width - scale * (bounds[1][0] + bounds[0][0])) / 2, (height - scale * (bounds[1][1] + bounds[0][1])) / 2]; // Update the projection to use computed scale & translate. projection .scale(scale) .translate(translate); /* provincies */ // make group element for provincie paths var g_provinces = svg.append("g") .attr("class", "provinces"); // draw provincie paths g_provinces.selectAll("path") .data(mapData_provinces.features).enter() // load data .append("path") .attr("class", function(d) { return d.properties.name; }) .style("fill", "transparent") .style("stroke", "black") .style("stroke-width", 0.2) .attr("d", geoPath); /* gemeentes */ // make group element for gemeente paths var g_gemeentes = svg.append("g") .attr("class", "gemeentes"); // draw gemeente paths g_gemeentes.selectAll("path") .data(mapData_gemeentes.features).enter() // load data .append("path") .attr("class", function(d) { if (d.wachttijden) { if (d.wachttijden.Aanmeldtijd !== "NA") { return "gemeente_withData "+d.properties.name; } else { return d.properties.name; } } else { return d.properties.name; } }) .style("fill", d => { if (!d.wachttijden || d.wachttijden.Aanmeldtijd === "NA") { return "transparent"; } else { return colorScale(parseInt(d.wachttijden.Aanmeldtijd)) } }) .style("fill-opacity",0.9) .style("stroke", "#99e600") .style("stroke-width", 0.1) .attr("d", geoPath) .filter(d => { if (d.wachttijden) { return d.wachttijden.Aanmeldtijd !== "NA"; }}) .on("click", (d) => { // console.log("click", d); d3.select(".table-container").remove(); drawChart(data.filter(d2 => { return d.properties.name === d2.gm_naam})); showResetBtn(); }) } function drawDataOnMap() { console.log("drawDataOnMap",data); drawBubbles(data); function drawBubbles(data) { console.log("drawBubbles",data) // schaal: circle size aan de hand van magnitude var rScale = d3.scaleLinear() .domain(d3.extent(data.filter(d=>d.Behandeltijd), function(d) { return parseInt(d.Behandeltijd); })) .range([1,20]); // circle radius // make group element for bubbles var bubbles = svg.append("g") .attr("class","bubbles"); // add bubbles to map bubbles.selectAll("circle.bubble") .data(data).enter() .append("circle") .attr("class","bubble") .attr("cx", function(d) { if (d.lon !== "#N/A") { return projection([d.lon,d.lat])[0]; } }) .attr("cy", function(d) { if (d.lon !== "#N/A") { return projection([d.lon,d.lat])[1]; } }) .attr("r", function(d) { if (d.Behandeltijd !== "NA") { return rScale(parseInt(d.Behandeltijd)); } }) .style("fill", function(d) { if (d.lon !== "#N/A") { return "red"; } else { return "transparent"; } }) .style("fill-opacity", 0.3) .on("click", (d) => { // console.log("click", d) d3.select(".table-container").remove(); drawChart([d]); // drawChart(data.filter(d2 => { return d.gm_naam === d2.gm_naam})); showResetBtn(); }) } } }) }) }) </script> </body>
https://d3js.org/d3.v3.min.js
https://d3js.org/d3.v4.min.js