D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
sandravizz
Full window
Github gist
6.11 histogram | small multiple
Built with
blockbuilder.org
<!DOCTYPE html> <meta charset="utf-8"> <html> <head> <!-- Google fonts reference --> <link href="https://fonts.googleapis.com/css2?family=Montserrat+Alternates:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Montserrat:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Roboto:ital,wght@0,100;0,300;1,100;1,300&display=swap" rel="stylesheet"> <!-- Connecting with D3 library--> <script src="https://d3js.org/d3.v4.min.js"></script> <!-- Creating the headlines --> <p id="h1">SMALL MULTIPLE | HISTOGRAM </p> <div id="link">by <a href="https://slides.com/sandravizmad">SANDRA</a></div> <style> /*Defining text stylings*/ #h1 { font-size:30px; margin:30px 0px 0px 20px; color:#f5fa91; font-family:'Montserrat Alternates', sans-serif; font-weight:300; } #link { font-family:'Montserrat Alternates', sans-serif; font-weight:200; font-size:10px; margin:5px 0px 0px 22px; color:white; } a:link, a:visited, a:active { text-decoration: none; color:white; border-bottom:1.5px dotted white; } body { background-color:#011227; } /*Defining axis stylings*/ .y-axis text, .x-axis text { font-family:'Montserrat Alternates', sans-serif; font-weight:400; font-size:8px; opacity:1; fill:white; } .y-axis path { fill:none; stroke-width:0; stroke-opacity:1; stroke:white; } .x-axis path { fill:none; stroke-width:0; stroke-opacity:1; stroke:white; } .y-axis line, .x-axis line { fill:none; stroke-width:0.1; stroke-opacity:0.5; stroke:white; stroke-dasharray:2; } /*Defining chart stylings*/ #region { fill:black; font-family:'Montserrat Alternates', sans-serif; font-family:'Poiret One', cursive; font-size:12px; } .bar { fill:#8ff798; } #label { fill:#f5fa91; font-family:'Montserrat Alternates', sans-serif; font-size:11px; } </style> </head> <body> <script> //Margin conventions var m = {top:0, right:0, bottom:0, left:0} w = 0 - m.left - m.right, h = 0 - m.top - m.bottom; //Container var svg = d3.select("body") .append("svg") .attr("width", w + m.left + m.right) .attr("height", h + m.top + m.bottom) .append("g") .attr("transform", `translate(${m.left}, ${m.top})`); //Margin conventions for the small multiple container var m_s = {top:20, right:50, bottom:50, left:30} w_s = 400 - m_s.left - m_s.right, h_s = 400 - m_s.top - m_s.bottom; //Define the format var parseDate = d3.timeParse("%d/%m/%Y"); var formatDate = d3.timeFormat("%Y"); //Data loading d3.csv( "https://gist.githubusercontent.com/sandravizz/221448a76bf10751d522a3a892825eb0/raw/fe62c91476647525aeca0cbac86475b1bc629d93/data", prepare, data => { //X scale var x = d3.scaleTime() .domain(d3.extent(data, d => d.date)) .range([0, w_s]) .clamp(false); //Nesting data by region var nest = d3.nest() .key(d => d.region) .entries(data); //Histogram generator var histo = d3.histogram() .value(d => d.date) .domain(x.domain()) .thresholds(x.ticks(d3.timeYear)); //Applying the histogram generator to the data var regions = nest.map(d => {return { key: d.key, values: histo(d.values) }}); //Calculating the max by region var localMax = regions.map(d => {return { region: d.key, max: d3.max(d.values, s => s.length) }}) //Find the global max as the domain for the y scale //Y scale var y = d3.scaleLinear() .domain([0, d3.max(localMax, d => d.max)]) .range([h_s, 40]); //Small multiple container var svg_s = d3.select("body") .selectAll("svg") .data(regions) .enter() .append("svg") .attr("width", w_s + m_s.left + m_s.right) .attr("height", h_s + m_s.top + m_s.bottom) .append("g") .attr("transform",`translate(${m_s.left}, ${m_s.top})`); //For each region add a label svg_s.append("text") .attr("id", "region") .attr("x", m_s.left) .attr("y", m_s.top) .text(d => d.key) //Draw histogram var hist = svg_s.append("g") .attr("class","hist") .attr("transform",`translate(${m_s.left}, ${m_s.top})`); //X axis hist.append("g") .attr("class", "x-axis") .attr("transform", `translate(0, ${h_s})`) .call(d3.axisBottom(x) .tickValues(x.domain()) .tickPadding(5) .tickFormat(formatDate)); //Data binding var bar = hist.selectAll(".bar") .data(d => d.values) .enter() .append("g") .attr("class","bar") .attr("transform",s =>`translate(${x(s.x0)}, ${y(s.length)})`); //Adding labels to the bars bar.append("text") .attr("id", "label") .attr("dy", ".75em") .attr("y", -12) .attr("x",s =>(x(s.x1) - x(s.x0))-15) .text(s => {if(s.length > 1) {return s.length;}}); //Draw the bars bar.append("rect") .attr("class"," bar") .attr("x", 1) .attr("width", s => x(s.x1) - x(s.x0)) .attr("height", s => h_s - y(s.length)); }); //Data format function prepare(d) { d.date = parseDate(d.date); return d; } </script> </body> </html>
https://d3js.org/d3.v4.min.js