Skip to content

Instantly share code, notes, and snippets.

@sara-maria
Last active April 10, 2017 21:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sara-maria/efae537119b896181c5fa8e3d4db508e to your computer and use it in GitHub Desktop.
Save sara-maria/efae537119b896181c5fa8e3d4db508e to your computer and use it in GitHub Desktop.
CVCM
index date event_header event_details arrowheight direction category align
0 8/16/80 Born Goirle The Netherlands 50 down life left
1 1/7/98 Graduation Secondary School Koning Willem II college - Gymnasium 75 down education left
2 9/1/99 Study physics Universiteit Utrecht 30 down education left
3 7/1/02 Bachelor Research MRI and X-ray angiography 100 down education left
4 6/1/04 Minor Fundamentals of Business and Economics. Internship at Bain & Company 30 up professional right
5 6/1/05 Master Research MRI blood flow measurements using Arterial Spin Labeling 35 down education left
6 12/1/05 Start PhD Research MR Thermometry for guidance of thermal therapy 35 up education left
7 11/4/10 PhD Defense 30 down education center
8 4/1/11 Postdoctoral research Characterizing trabecular bone using MRI diffusion techniques 40 up professional left
9 6/1/14 Value Based Health Care work International Consortium for Health Outcomes Measurement - ICHOM 40 down professional left
10 9/1/16 Data science & <br> Data vis Data Science specialization @ Coursera. HTML CSS D3.js @ Udacity 40 up education left
11 11/1/19 Entering a Mixed Reality Learning Mixed Reality skills 40 down education left
12 11/7/21 Creating other Realities Creating Mixed Reality environments for creative, educational & therapeutic purposes 55 up professional left
13 3/6/26 Nutrition Studying the impact of nutrition and microbiome on physical and mental health 30 up education left
14 9/1/29 Connecting knowledge Using data visualization to raise cross-discipline and cross-cultural awareness of the connectedness of beings and ideas 45 down professional right
15 8/16/41 Pet Finally getting a guinea pig 40 down life left
16 6/20/54 Dies In my sleep <br> during a pneumonia 40 down life right
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Lato:300,400" rel="stylesheet">
<script src="http://d3js.org/d3.v3.min.js"></script>
<style>
/*
*{
border: 1px solid orange !important;
}
*/
/*
To fix/add:
- hardcoded foh in yc array (because ems --> pix)
- lineheight in foreign object
- font scaling less dramatic
- css separated
- add details on hover?
- make it visible on phones
LAYOUT FEEDBACK:
- instead of arrows pointing to events, maybe a thin line (Robby suggestion)
- arrange categories better
*/
body{
font-family: 'Lato', sans-serif;
font-size:100%; /* flexible baseline - commonly 16px. Then, as example, 1.25em will result in 20px */
font-weight: 300;
margin:0;
height: 100vh; /*30em; /*500px;*/
width: 100vw; /*full width of screen*/ /*width:1500px;*/
overflow-y: hidden;
}
#wrapper {
width:100vw;
height:100vh;
display:block;
}
#CVheader {
height: 10%; /*6em; /*90px;*/
width: 100%;
/* background-color:"red";*/
/* padding-top: .2em; 4px;*/
/* overflow:auto;*/
}
#headerleft {
width:9em; /*300px;*/
height:1.3em;/*40px;*/
float:left;
position:absolute;
color:"black";
background-color:#e0e0d9;
text-align: center;
border-radius: 2em; /*25px;*/
}
#headerright {
width:10em; /*320px;*/
height:1.3em;/*40px;*/
float:right;
text-align: center;
position:absolute;
right: 0;
color:#716c6c;
/* border: 3px solid white;*/
background-color:#444;
border-radius: 2em; /*25px;*/
}
/* #headerright:hover {
animation: shake 0.82s cubic-bezier(.36,.07,.19,.97) both;
transform: translate3d(0, 0, 0);
backface-visibility: hidden;
perspective: 1000px;
}
*/
.hoverclass {
animation: shake 0.7s cubic-bezier(.36,.07,.19,.97) both;
transform: translate3d(0, 0, 0);
backface-visibility: hidden;
/* perspective: 1px;*/
}
@keyframes shake {
10%, 90% {
transform: translate3d(-2px, 1px, 0);
}
20%, 80% {
transform: translate3d(2px, -1px, 0);
}
30%, 50%, 70% {
transform: translate3d(-4px, 3px, 0);
}
40%, 60% {
transform: translate3d(4px, 2px, 0);
}
}
#content {
height:85%;
/* min-height: 80%;*/
}
#lifeline {
width:100vw; /* ensures it stretches the full width of the page */
height:90%;
}
.category_buttons {
height: 2em; /*height of whole section*/
display: -webkit-flex;
display: flex;
-webkit-align-items: top;
align-items: top;
-webkit-justify-content: center;
justify-content: center;
}
div.category_buttons div {
width: 8em;
height:1.1em;
line-height: 1.1em; /*needed for vertical align*/
vertical-align: middle;
text-align: center;
background-color: white;
padding: .3em;
margin-left: 1em;
margin-right: 1em;
border-radius: 2em;
border:1px solid #9d9999;
color:#444;
font-weight: 100
}
div.category_buttons > div:first-of-type { /*select first button "all", to be diff color*/
background-color: rgb(247, 230, 210);
}
#footer {
text-align: center;
font-size: .7em;
width:100vw;
height:5%; /*2.5em;*/
line-height: 2.5sem;
vertical-align: bottom;
bottom:0;
}
#rotatediv {
display:flex;
background-color:#6d6c6c;
display: block;
height: 100%;
width: 100%;
font-size: 4em;
color: "white";
/* float:center;*/
text-align: center;
position:fixed;
color:rgb(247, 230, 210);
vertical-align:middle;
}
h2 {
margin-left: 1em; /*15px;*/
margin-right: 1em; /*15px;*/
margin-bottom: 1em; /*15px;*/
font-size: 2em;
}
h3{
margin-left: 1em;/*15px;*/
margin-top: 0em;
font-weight: 100;
font-size: 1em;
}
h2CV {
margin-bottom: .06em;
font-size: 1em; /*12px;*/
line-height: .6em;
font-weight: 400;
color: "black";
}
h3CV {
margin-top: 0em;
font-weight: 100;
font-size: .8em; /*10px;*/
/* line-height: 10em;*/
color: "black";
}
a {
color:#494949;
text-decoration:none;
}
a:hover {
font-weight: 400;
}
.lefty {text-align: left !important;}
.centry {text-align: center !important;}
.righty {text-align: right !important;}
.lifelinetext{
display:none;
}
/* # info was needed for mouse position testing*/
/*
#info {
position: absolute;
bottom: 10px;
right: 10px;
background-color: black;
color: white;
padding: 25px 50px;
}
*/
/*-------CATCH ROTATED SMART PHONES AND SCREENS -----------*/
/* for non rotated screens: do not show rotation message */
#rotatediv {display: none;}
/* only when orientation is in portrait mode: */
@media screen and (orientation:portrait) {
#content {display: none;}
#rotatediv {display: flex;}
}
/*-------CATCH for iPHONES where body width = "vh" gives problems... -----------*/
/** iPad with landscape orientation. */
@media all and (device-width: 768px) and (device-height: 1024px) and (orientation:landscape){
body {
/* width:2*1024px; always times 2--> visualization is twice width!*/
}
}
/** iPhone 5 */ /*@media screen and (device-aspect-ratio: 40/71) {*/
@media screen and (device-height: 568px) and (device-width: 320px) and (-webkit-min-device-pixel-ratio: 2){
body {
/* width:2*568px; always times 2--> visualization is twice width!*/
}
}
</style>
<script>
// MAIN DRAW CVCM FUNCTION!
function draw(data){
var environment = "CV"; // to ensure colorcodings match the CV or CM page
//Width and height of CV visualization
var w = 2*window.screen.availWidth; //because the visualization is spread over two lengths of the window!
var h = 1/2*window.screen.availHeight;
var margin = {top: 0, right: 0, bottom: 0, left:0};
width = w - margin.left - margin.right;
height = h - margin.top - margin.bottom;
// window.width = w - margin.left - margin.right;
// window.height = h - margin.top - margin.bottom;
//Sizing variables for lifeline visualization
var arrowlinewidth = 5;
var arrowlineheight = 60;
var arrowheadbasewidth = 15;
var arrowheadlength = 15;
var arrowtextdistance = 5;
var lifelineheight = ".7em";
var relypos = 4/9; // where life line will be drawn on y axes
var lifelinemarginL = 40; // margin space at start of life line
var lifelinemarginR = 100; // margin space at end of life line
// Find full domains of input data
var lifeline_extent = d3.extent(data,function(d){
return d['age'];
});
var arrowheight_extent = d3.extent(data,function(d){
return d['arrowheight'];
});
//Setting scales
var xScale = d3.scale.linear()
.domain(lifeline_extent)
.range([lifelinemarginL, width-lifelinemarginR]);
var yScale = d3.scale.linear()
.domain(arrowheight_extent)
.range([0, height]);
//xScale(#years) --> # pixels on time axes
//xScale.invert(#pixels) --> #years
//xScale.invert(lifelinemargin) --> 0 years (born)
//xScale.invert(0) --> -1.3670886075 years (margin on left side, in years)
//Create SVG element that holds the CV
var svg = d3.select("body").select("#content")
.append("svg")
.attr("id","lifeline")
.attr("width", .5*width)
.attr("height", height)
.attr("viewBox", "0 0 "+.52*width+" "+height+"")
//Create one large horizontal life-line
var lifeline = svg.append("rect")
.attr("x", 0)
.attr("y", relypos*height)
.attr("width", width) //line across full length of div!
.attr("height", lifelineheight)
.attr("fill", "#716c6c");
// CREATE ARROW GROUPS at AGE LOCATIONS
var lifearrows = svg.append("g")
.attr("id","lifearrows");
var arrows = lifearrows.selectAll("g")
.data(data) //when I add: function(d){return d.age;},arrows at same age go missing
.enter()
.append("g")
.attr("transform", function(d) { return "translate(" + xScale(d.age) + ",0)" ;} )
.attr("class","arrow")
.attr("id", function(d, i) { return ("arrow" + d.index); })
arrows.append("rect")
.attr("width", arrowlinewidth)
.attr("height", arrowlineheight)
.attr("x", 0)
.attr("y", relypos*height)
.attr("height", function(d) { return d.arrowheight; })
.attr("fill", "#716c6c")
arrows.append("path")
.attr('d', function(d) {
var x = - .5*arrowheadbasewidth + .5*arrowlinewidth;
var y = relypos*height + d.arrowheight; // starting coord. of triangle
var lr = arrowheadbasewidth, ld = arrowheadlength, ll = -.5*arrowheadbasewidth;
return 'M ' + x +' '+ y + ' l ' + lr + ' 0 l ' + ll + ' ' + ld + ' z';
})
.attr("stroke", "#716c6c")
.attr("stroke-width", 2)
.attr("fill", "#716c6c")
// interaction with arrows:
function arrowclick(d3Element){
console.log("you clicked an arrow")
lt = d3.selectAll(".lifelinetext")
var curelement = +d3Element.__data__.index;
};
function arrowmouseover(d3Element){
// d3Element.style.cursor = "pointer";
lt = lifelinetextgroup.selectAll(".lifelinetext")
var curelement = +d3Element.__data__.index;
console.log(curelement)
lt[0][curelement].style.display="flex"
};
function arrowmouseout(d3Element){
// d3Element.style.cursor = "default";
lt = lifelinetextgroup.selectAll(".lifelinetext")
var curelement = +d3Element.__data__.index;
console.log(curelement)
lt[0][curelement].style.display="none"
};
arrows.on("mouseover", function(d) { arrowmouseover(this); })
.on("mouseout", function(d) { arrowmouseout(this); })
.on("click", function() { arrowclick(this); })
// ROTATE ARROWS WHERE INDICATED
for(var i=0; i<data.length ; i++){
if(data[i].direction === "up"){ // NEW: use data on arrow direction: if data.direction == up, flip arrow;
var selection = d3.select("#arrow" + data[i].index +"");
selection.attr("transform", function(d) { return "rotate(-180,0,"+ relypos*height + ") translate(-"+xScale(data[i].age)+",0)";} )
}
};
// Create text labels for all events using FOREIGNOBJECT
var textgroup = svg.append("g")
.attr("id","textgroup");
// Calculate forgeign object box sizes:
var foh = "10em"; // ems - foreign object height can be large, it is the outside box only
var fow = 210; // pixels - foreign object width can be large, it is the outside box only
var bleedoverleft = 1; // years - x-position of text boxes in years, left of the actual event
var fotwmax = 2.8; // years - maximum width of foreign object text label boxes
var fotwmin = fotwmax-.2; // years - minimum width of foreign object text label boxes
// 1. calculate space between the current event's year and the prior and after event
//xScale.invert(#pixels) --> zero point is margin: "prior to born" in #years
var dyears = [Math.abs(xScale.invert(0))];
for(var i=1; i < data.length; i++){
var obj = data[i].age - data[i-1].age;
dyears.push(obj);
}
//xScale.invert(#pix) -> #years after the very last lifeline event
dyears[dyears.length] = xScale.invert(width)-data[data.length-1].age;
// 2. determine x and y-coordinate current event text box in YEARS
var xc = [], yc = [];
for(var i=0; i < dyears.length-1; i++){
// if there is >bleedoverleft years on the left side of the event:
if(dyears[i] > bleedoverleft){
var xct = data[i].age - bleedoverleft; //fixed amount to the left of arrow
var yct = relypos*height + data[i].arrowheight + arrowheadlength + arrowtextdistance;
}
// if there is 1 < X < bleedover years on the left side of the event:
if(dyears[i] <= bleedoverleft & dyears[i] > 0){ // >0 because first entry has negatiev years
var xct = data[i].age - dyears[i];
var yct = relypos*height + data[i].arrowheight + arrowheadlength + arrowtextdistance;
}
xc.push(xct);
yc.push(yct);
}
// Adjust x coodinate list manually:
// change first x coordinate
xc[0]=-.7*bleedoverleft;
// add a last element of xc and yc vector to ensure math goes well: indicates the end of the timeline:
xc[xc.length]=xScale.invert(width)-.9;
yc[yc.length]=yScale.invert(relypos*height);
// 3. foreign object text box width (fotw) --> determine width & position for current event text box in YEARS
var fotw = [];
for(var i=0; i<dyears.length-1; i++){
var obj = (xc[i+1] - xc[i]);
fotw.push(obj);
}
// manually adjust width of label positions:
fotw[fotw.length-2] = fotw[fotw.length-2]-11; // width of one before last one
fotw[fotw.length-1] = fotw[fotw.length-1]-2; // width of last one (death)
xc[xc.length-1]=[fotw.length-1]-1.8;//+xScale.invert(0);
// debugger;
fotw[4]=2.4; // one too small one
fotw[5]=2.6; // one too small one
xc[4]=xc[4]-1.8;//+xScale.invert(0);
// for all fotw > max value, clip to max vaule
for(var i=0; i<=fotw.length-1; i++){
if(fotw[i]>fotwmax){fotw[i]=fotwmax}
};
// 4. Apply these calculated measures for all TEXT boxes
textgroup.selectAll('foreignObject')
.data(data) //, function(d) { return d.event_header, d.event_details, d.direction; })
.enter()
.append('foreignObject')
.attr("id", function(d,i) { return ("textbox" + d.index); })
.attr("x", function(d,i) {
if(d.align === "left"){return xScale(xc[i]); }
if(d.align === "center"){return xScale(xc[i]); }
if(d.align === "right"){return xScale(xc[i]-.8); } // shift these blocks bit to the left
})
.attr("y", function(d,i) {
// debugger;
if(d.direction === "up"){return relypos*height - data[i].arrowheight - arrowheadlength - 125; }
if(d.direction === "down"){return yc[i]; }
})
.attr('width', function(d,i) {return xScale(fotw[i]) })
.attr('height', foh)
.attr("class", function(d) {
if(d.align === "left"){return "lefty";}
if(d.align === "center"){return "centry";}
if(d.align === "right"){return "righty";}
})
.html(function(d,i) { return '<div style="width:' + xScale(fotw[i]) + 'px;"><h2CV>' + d.event_header + '</h2CV></div><div style="width:' + xScale(fotw[i]) + 'px;"><h3CV style="line-height:20%;">' + d.event_details + '</h3CV></div>'} )
//debugger;
d3.selectAll("foreignObject")
.on("mouseover", function(d) { textmouseover(this); })
.on("mouseout", function(d) { textmouseout(this); })
function textmouseover(d3Element){
var curelement = +d3Element.__data__.index;
console.log(curelement)
q = document.getElementsByClassName("lifelinetext")
q[curelement].style.display="flex"
};
function textmouseout(d3Element){
var curelement = +d3Element.__data__.index;
console.log(curelement)
q = document.getElementsByClassName("lifelinetext")
q[curelement].style.display="none"
};
// put date labels inside timeline:
var lifelinetextgroup = svg.append("g")
.attr("id","lifelinetextgroup");
var month = new Array();
month[0] = "January";
month[1] = "February";
month[2] = "March";
month[3] = "April";
month[4] = "May";
month[5] = "June";
month[6] = "July";
month[7] = "August";
month[8] = "September";
month[9] = "October";
month[10] = "November";
month[11] = "December";
lifelinetextgroup.selectAll("text")
.data(data) //, function(d) { return d.date}) <-- causes skip of data again
.enter()
.append("text")
.attr("class", "lifelinetext")
.attr("id", function(d,i) {return "lt"+i+""})
.text(function(d,i) {
if(d.date.getDate() == "1") {return d3.time.format(""+month[d.date.getMonth()]+" "+d.date.getDate()+"st "+d.date.getFullYear()+"");}
if(d.date.getDate() == "2") {return d3.time.format(""+month[d.date.getMonth()]+" "+d.date.getDate()+"nd "+d.date.getFullYear()+"");}
if(d.date.getDate() == "3") {return d3.time.format(""+month[d.date.getMonth()]+" "+d.date.getDate()+"rd "+d.date.getFullYear()+"");}
else {return d3.time.format(""+month[d.date.getMonth()]+" "+d.date.getDate()+"th "+d.date.getFullYear()+"");}
})
.attr("text-anchor", "middle")
.attr("x", function(d,i) {return xScale(d.age); })
.attr("y", function(d,i) {return (relypos*height + 8); })
.attr("font-family", "Garamond")
// .attr("font-size", "9px")
.attr("font-size", ".6em")
.attr("fill", "white");
// create INTERACTIVE CATEGORY buttons!
function key_func(d){
return d.index;
};
function update(cat,duration) { // cat is button category name
console.log("updating")
// GROUP data by category:
var grouped = d3.nest() //grouping. In this case: group data by category
.key(function(d){
return d['category'];
})
.entries(data); //passes data through nest pipeline
debugger;
if(cat.slice(0,4) === "all") {
console.log("show all events")
var data_to_enter = data;
}else{
// filter data for giving category: filter()
var filtered = grouped.filter(function(d) {
if(d.key.slice(0,4) === cat.slice(0,4)) {
return d.key;}
});
var data_to_enter = filtered[0].values;
};
// UPDATE arrow style based on button press
var arrows = d3.select("#lifearrows").selectAll("g")
.data(data_to_enter,key_func) // key func needed to get the correct index of the arrow
// change style of arrow that are not highlighted: the .exit group
arrows.exit().transition()
.duration(duration)
.style("opacity", .1);
// update all other arrows:
arrows.transition().duration(duration)
.style("opacity", 1)
// UPDATE text style based on button press
function fo_styling_exit(d){
if(environment == "CM") { // we are in CM mode
return "#a7a7a7";
} else {
return "#ebebeb";}
};
function fo_styling_enter(d){
if(environment == "CM") { // we are in CM mode
return "#f4f0f0";
} else {
return "black";}
};
var fos = d3.selectAll("foreignObject")
.data(data_to_enter,key_func) // key func needed to get the correct index of the arrow
// change style of arrow that are not highlighted: the .exit group
fos.exit().transition()
.duration(duration)
.attr("fill",fo_styling_exit)
.attr("color",fo_styling_exit)
// update all other arrows:
fos.transition().duration(duration)
.attr("fill",fo_styling_enter)
.attr("color",fo_styling_enter)
}; // end of update function
var categories = ["all","life events","education","professional"];
var buttons = d3.select("#content")
.append("div")
.attr("class","category_buttons")
.selectAll("div")
.data(categories)
.enter()
.append("div")
.text(function(d){return d;});
buttons.on("click",function(d){
// first select all the buttons:
d3.select(".category_buttons")
.selectAll("div")
.transition().duration(500)
.style("background-color", "white")
d3.select(this) //selects current element (which is button)
.transition().duration(500)
.style("background-color", "rgb(247, 230, 210)")
update(d,500);
cg = d;
return cg;
});
buttons.on("mouseover", function(d) {d3.select(this).style("cursor", "pointer")} )
.on("mouseout", function(d) {d3.select(this).style("cursor", "default")} )
// <!-- call functions here that interact with the curriculum -->
// Functions that moves (and recolors) the whole lifeline depending on header click or mouse position -->
var ease = "sin"; //"poly"//"linear" // "cubic", "
var transitiondurationCVCM =2000; // is transition speed of the *moving*
function changeElementColorCM(d3Element){
var curelement = d3.select("body");
var colour = d3.rgb(curelement.attr("style"));
d3Element
.style("background", colour)
.transition().delay(500).duration(1500).ease(ease) // transition speed of background re-coloring
.style("background", "grey")
d3.select("body").select("#content").select("svg")
.transition().duration(transitiondurationCVCM).ease(ease)
.attr("viewBox", ""+.5*width+" 0 "+ .5*width+" "+height+"")
d3.select("body").select("#content").select("svg").select("rect")
.transition().duration(transitiondurationCVCM).ease(ease)
.attr("color","white")
.attr("fill","white")
d3.selectAll("rect")
.transition().duration(transitiondurationCVCM).ease(ease)
.attr("color","white")
.attr("fill", "white")
d3.selectAll("path")
.transition().duration(transitiondurationCVCM).ease(ease)
.attr("stroke", "white")
.attr("fill", "white")
d3.selectAll("foreignObject")
.transition().duration(transitiondurationCVCM).ease(ease)
.attr("fill","white")
.attr("color","white")
d3.selectAll("text")
.transition().duration(transitiondurationCVCM).ease(ease)
.style("fill","gray")
d3.select("body").select("#wrapper").select("#CVheader").select("#headerright")
.transition().duration(transitiondurationCVCM).ease(ease)
.style("color","white");
d3.select("body").select("#wrapper").select("#CVheader").select("#headerleft")
.transition().duration(transitiondurationCVCM).ease(ease)
.style("color","#a5a1a1");
environment = "CM";
console.log(environment)
if (typeof cg !== 'undefined') {
update(cg,2000)
console.log(cg)
}
} // end of changeElementColorCM
function changeElementColorCV(d3Element){
var curelement = d3.select("body");
var colour = d3.rgb(curelement.attr("style"));
d3Element
.style("background", colour)
.transition().delay(500).duration(1500).ease(ease) // transition speed of background re-coloring
.style("background", "white")
d3.select("body").select("#content").select("svg")
.transition().duration(transitiondurationCVCM).ease(ease)
.attr("viewBox", "0 0 "+.52*width+" "+height+"")
d3.select("body").select("#content").select("svg").select("rect")
.transition().duration(transitiondurationCVCM).ease(ease)
.attr("color","#716c6c")
.attr("fill","#716c6c")
d3.selectAll("rect")
.transition().duration(transitiondurationCVCM).ease(ease)
.attr("color","#716c6c")
.attr("fill", "#716c6c")
d3.selectAll("path")
.transition().duration(transitiondurationCVCM).ease(ease)
.attr("stroke", "#716c6c")
.attr("fill", "#716c6c")
d3.selectAll("foreignObject")
.transition().duration(transitiondurationCVCM).ease(ease)
.attr("fill","#716c6c")
.attr("color","#716c6c")
d3.selectAll("text")
.transition().duration(transitiondurationCVCM).ease(ease)
.style("fill","white")
d3.select("body").select("#wrapper").select("#CVheader").select("#headerright")
.transition().duration(transitiondurationCVCM).ease(ease)
.style("color","#716c6c");
d3.select("body").select("#wrapper").select("#CVheader").select("#headerleft")
.transition().duration(transitiondurationCVCM).ease(ease)
.style("color","black");
environment = "CV";
console.log(environment)
if (typeof cg !== 'undefined') {
update(cg,2200)
console.log(cg)
}
} // end of changeElementColorCV
// Function that will give the position of cursor
// and cause interactions with page at certain mouse positions:
function GetcursorPos(p){
// PageX and PageY are position values
// info.innerHTML = 'Position X : ' + p.pageX;
var maxX = screen.width;
var posX = p.pageX/maxX;
// Get current screen (CV or CM), through background color:
var curelement = d3.select("body");
var colour = d3.rgb(curelement.attr("style"));
if(colour.r == 255) { // white, CV environment
if(posX > .85) {
changeElementColorCM(d3.select("body"));
}
if(posX <= .85) {
changeElementColorCV(d3.select("body"));
}
}
if(colour.r == 128) { // dark, CM environment
if(posX < .15) {
changeElementColorCV(d3.select("body"));
}
if(posX >= .15) {
changeElementColorCM(d3.select("body"));
}
}
} //End getcursorpos
addEventListener('mousemove', GetcursorPos, false);
// Set up button functionality of two header texts (CV and CM)
var headerr = d3.select("#headerright");
headerr.on({
"mouseover": function(d) {
d3.select(this).style("cursor", "pointer")
},
"mouseout": function(d) {
d3.select(this).style("cursor", "default")
}
});
var headerl = d3.select("#headerleft")
headerl.on({
"mouseover": function(d) {
d3.select(this).style("cursor", "pointer")
},
"mouseout": function(d) {
d3.select(this).style("cursor", "default")
}
});
//Here, the action after clicking the CV and CM button is defined:
headerr.on("click", function() {
console.log("you clicked the CM header")
var curelement = d3.select("body");
var colour = d3.rgb(curelement.attr("style"));
if(colour.r == 255) {
changeElementColorCM(d3.select("body"));
}
});
headerl.on("click", function() {
console.log("you clicked the CV header")
var curelement = d3.select("body");
var colour = d3.rgb(curelement.attr("style"));
if(colour.r == 128) {
changeElementColorCV(d3.select("body"));
}
});
}; // end draw function
</script>
</head>
<body style="style.background= rgb(255, 255, 255);">
<!-- <div id='info'></div>-->
<div id="rotatediv"><p><br>Rotate device (or widen browser window) for better view</p></div>
<!-- // Wrapper around full visualization -->
<div id="wrapper">
<!-- // Header with CV and CM buttons -->
<div id="CVheader" style="style.background= rgb(0, 0, 255);">
<h2 id="headerleft">Curriculum Vitae</h2>
<h2 id="headerright" >Curriculum Mortem</h2>
</div>
<!-- // Life line with arrows and text -->
<div id="content">
<script type="text/javascript">
// Reading data from CSV
formatdate = d3.time.format("%m/%d/%y")
function formatage(inputdate){
var birthdate = 1980 + 1/12*8;
var age = inputdate.getFullYear() + 1/12*(inputdate.getMonth()+1) - birthdate ;
return age;
}
d3.csv("CVCMdata.csv",function(d){
// transform the data here into needed variables
d['date'] = formatdate.parse(d['date']); // to extract data format
d['age'] = formatage(d['date']);
d['arrowheight']=+d["arrowheight"]; // to make it from strings into numbers
return d;
},draw);
</script>
</div> <!-- #end of content -->
<!-- // Footer with data details and credits -->
<div id="footer">
Source: Data on past events collected throughout the years, future predictions made using <a href="http://fatefulday.eu" target="_blank">fatefulday.eu </a> | <a href="https://sara-maria.github.io/" target="_blank">Sara Maria 2016</a>
</div>
</div> <!-- #end of wrapper -->
<script>
// Javascript media query event handler to window size change
if (matchMedia) {
var mq = window.matchMedia("(min-width: 680px)");
mq.addListener(WidthChange);
WidthChange(mq);
var mqr = window.matchMedia("(orientation: portrait)");
mqr.addListener(RotationChange);
RotationChange(mqr);
};
// Javascript function for header button changes on window resize
function WidthChange(mq) {
if (mq.matches) {
// window width is at least 660px
var hr = document.getElementById("headerright");
hr.textContent = 'Curriculum Mortem'
hr.style.width = "10em";
var hl = document.getElementById("headerleft");
hl.textContent = 'Curriculum Vitae';
hl.style.width = "9em";
} else {
// window width is less than 660px
var hr = document.getElementById("headerright");
hr.textContent = 'CM';
hr.style.width = "3.6em";
var hl = document.getElementById("headerleft");
hl.textContent = 'CV';
hl.style.width = "3.6em";
}
};
// CATCH ROTATED SMART PHONES AND SCREENS //
function RotationChange(mqr) {
// If there are matches, we're in portrait
if(mqr.matches) {
// Portrait orientation
console.log("rotated to portrait");
// document.getElementById("lifeline").style.background="rgb(0,0,255)"
} else {
// Landscape orientation
console.log("rotated back to landscape");
// console.log(document.body.style.width);
// debugger;
// var w = 2*window.screen.availWidth;
// var h = window.screen.availHeight;
//
//// document.body.style.width = "20*560px";
// document.getElementById("lifeline").style.background="rgb(0,255,0)"; //green
//// document.getElementById("lifeline").style.width=w
// document.body.style.width = w;
}
};
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment