xxxxxxxxxx
<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