D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
rebih
Full window
Github gist
Life in Weeks - Rebecca Herzog
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Simple Template</title> <style> body { font: 10px sans-serif; } h2 { margin-top: 0; color: grey; } svg { //background-color: #888; background-color: transparent; padding: 35px; } .content { fill: lightsteelblue; } .label { fill: white; font-size: x-large; font-weight: bolder; } div.tooltip { position: absolute; text-align: left; width: auto; height: auto; padding: 2px; font: 12px sans-serif; background: lightsteelblue; border: 0px; border-radius: 8px; pointer-events: none; } </style> </head> <body> <h2>Life in Weeks - Rebecca Herzog</h2> <svg class="draw-area" width="780" height="1400"></svg> <script src="https://d3js.org/d3.v4.js"></script> <!-- IMPORT DATA --> <script> let jsonLifeEvents = [ { "edescription": "My first day on earth", "startyear": 0, "startweek": 1, "endyear": null, "endweek": null }, { "edescription": "Kindergarten", "startyear": 5, "startweek": 2, "endyear": 6, "endweek": 52 }, { "edescription": "Primary School", "startyear": 7, "startweek": 1, "endyear": 11, "endweek": 52 }, { "edescription": "Secondary School", "startyear": 12, "startweek": 1, "endyear": 15, "endweek": 51 }, { "edescription": "Apprenticeship at Coop Basel", "startyear": 16, "startweek": 1, "endyear": 19, "endweek": 52 }, { "edescription": "FHNW iCompetence", "startyear": 22, "startweek": 7, "endyear": 26, "endweek": 47 }]; </script> <!-- GENERATOR-SCRIPT --> <script> const margin = {top: 50, right: 50, bottom: 50, left: 50}; const svg = d3.select("svg"); const width = +svg.attr("width") - margin.left - margin.right; const height = +svg.attr("height") - margin.top - margin.bottom; // content area of your visualization (note: g elements do NOT have dimensions) const vis = svg.append("g"); // Everything below is for illustration purposes // delete it and replace it with your own visualization (by appending to `vis`) const years = 91; const weeks = 52; //extend event objs by duration jsonLifeEvents = jsonLifeEvents.map(e=>{ const firstWeek = e.startyear * weeks + e.startweek; const lastWeek = e.endyear * weeks + e.endweek; e.duration = lastWeek - firstWeek; return e; }); const maxEventLen = () => Math.max(...jsonLifeEvents.filter(e => e.duration > 0).map(e => e.duration)); const minEventLen = () => Math.min(...jsonLifeEvents.filter(e => e.duration > 0).map(e => e.duration)); const color = d3.scaleOrdinal() .domain([minEventLen(), maxEventLen()]) .range(['#FFEB3B', '#FF9800', '#E65100', '#FF3D00', '#D81B60', '#673AB7']); // Assign data-variables, process + merge jsonLifeEvents data let gridData = generateGridData(jsonLifeEvents); // I like to log the data to the console for quick debugging console.log(gridData); // Add Events to grid // addEvents(jsonLifeEvents); // let row = svg.selectAll(".row") .data(gridData) .enter().append("g") .attr("class", "row"); let column = row.selectAll(".square") .data(function(d) { return d; }) .enter().append("rect") .attr("class","square") .attr("id", d => "cube-" + d.idR + "-" + d.idC) .attr("x", d => d.x) .attr("y", d => d.y) .attr("width", d => d.width) .attr("height", d => d.height) .style("fill", d => d.color || '#ECEFF1') .style("stroke", "transparent") // add Tooltip .on('mouseenter', function(d) { div.transition() .duration(200) .style("opacity", .9); if (d.event_description != null) { div.html( d.event_description + "<br>Jahr: " + d.idR + "<br>Woche: " + d.idC) .style("left", (d3.event.pageX) + "px") .style("top", (d3.event.pageY - 28) + "px"); } else { div.html( "Jahr: " + d.idR + "<br>Woche: " + d.idC) .style("left", (d3.event.pageX) + "px") .style("top", (d3.event.pageY - 28) + "px"); } }) .on('mouseout', function(d) { div.transition() .duration(500) .style("opacity", 0); }); // Define the div for the tooltip let div = d3.select("body").append("div") .attr("class", "tooltip") .style("opacity", 0); // // Generate the Array with the cubes // function generateGridData(jsonLifeEvents) { let data = []; let xpos = 1; //starting xpos and ypos at 1 so the stroke will show when we make the grid below let ypos = 1; const width = 10; const height = 10; let idR = 0; // Jahr let idC = 0; // Woche let description; let start; let end; // iterate for rows for (let row = 0; row < years; row++) { data.push( [] ); // iterate for cells/columns inside rows for (let column = 1; column <= weeks; column++) { //show event only once //show even for whole duration const event = jsonLifeEvents.find(e => { if(!e.endyear) return e.startyear === row && e.startweek === column; const currentWeek = row * weeks + column; const firstWeek = e.startyear * weeks + e.startweek; const lastWeek = e.endyear * weeks + e.endweek; return currentWeek >= firstWeek && currentWeek <= lastWeek }); if(event){ //color by event length const firstWeek = event.startyear * weeks + event.startweek; const lastWeek = event.endyear * weeks + event.endweek; console.log('duration', lastWeek - firstWeek); event.color = color(lastWeek - firstWeek); } data[row].push({ x: xpos, y: ypos, width: width, height: height, idR: row, idC: column, dataid: row + "-" + column, color: event ? event.color : null, event_description: event ? event.edescription : null }); // increment the x position. I.e. move it over by 50 (width variable) xpos += width+5; } // reset the x position after a row is complete xpos = 1; // increment the y position for the next row. Move it down 50 (height variable) ypos += height+5; } return data; } function addEvents(param){ console.log(param); for (let i = 0; i < param.length; i++) { let sweek = param[i].startweek - 1; gridData[param[i].startyear][sweek].event_description = param[i].edescription; let cubeID = "cube-" + param[i].startyear + "-" + param[i].startweek; console.log("addEvent: " + cubeID); } } /* * V4 Scale */ // set the ranges const xWeeks = d3.scaleLinear().domain([1, weeks]).range([5, 770]); const yYears = d3.scaleLinear().domain([0, years-1]).range([5, 1355]); // Add the x Axis svg.append("g") .call(d3.axisTop(xWeeks) .ticks(5)); // text label for the x axis svg.append("text") .attr("transform", "translate(" + (width / 2) + " ," + (height + margin.top + 20) + ")") .style("text-anchor", "middle") .text("Weeks"); // Add the y Axis svg.append("g") .call(d3.axisLeft(yYears) .ticks(9)); // text label for the y axis svg.append("text") .attr("transform", "rotate(-90)") .attr("y", 0 - margin.left) .attr("x",0 - (height / 2)) .attr("dy", "1em") .style("text-anchor", "middle") .text("Year"); </script> </body> </html>
https://d3js.org/d3.v4.js