block by rickdg 4a19a87b216c6a26b0d05448b049b044

d3 | how old will we be

Full Screen

My youngest is always asking me, ‘how old will you be when I’m x years? and by brother/sister is x years

So this sketch is for him! but it was weird doing it, actually made me pause.

Used moment.js to calculate the dates; no real need though, as they were just subtractions—but handy if I do anything more detailed with the sketch.

The nav/options are an array (caled dates in the code) that can just be added to and changed, and the rest get’s worked out and displayed.

forked from eesur‘s block: d3 | how old will we be

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>d3 | family ages</title> 
  <meta name="author" content="Sundar Singh | eesur.com">
  
  <link rel="stylesheet" href="main.css">
  <script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script> 
  <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.3/moment.min.js" charset="utf-8"></script> 
</head>
<body>

<header>
  <h1>How old will I be?</h1>
  <p>Our family ages, at different points</p>
  <nav></nav>
</header>
<section id="vis"></section>

<script src="d3_code_ages.js" charset="utf-8"></script>

</body>
</html>

d3_code_ages.js

(function() {
    'use strict';


var data = [
    {
        name: 'S',
        born: 1977,
        colour: '#FDBB30'
    },
    {
        name: 'H',
        born: 1978,
        colour: '#7AC143'
    },
    {
        name: 'M',
        born: 2001,
        colour: '#EC008C'
    },
    {
        name: 'A',
        born: 2004,
        colour: '#00B0DD'
    },
    {
        name: 'K',
        born: 2007,
        colour: '#EE3124'
    },
    {
        name: 'Z',
        born: 2014,
        colour: '#F47521'
    },
];

var dates = [1988, 1998, 2001, 2004, 2007, 2015, 2018, 2021, 2023, 2026, 2029, 2050];

var w = 900,
    h = 300;

// // svg container
var svg = d3.select('#vis').append('svg')
    .attr({
        width: w,
        height: h
    });

var scale = d3.scale.linear()
            .domain([0, 100])
            .range([40, w - 40]);

console.log(scale(28));
// reference for date selection    
var selectedDate = 2015;

// create navigation
function buttons() {
    var nav = d3.select('nav').append('ul');

    var li = nav.selectAll('li')
        .data(dates)
        .enter()
        .append('li');
    li
        .text(function (d) { return d; })
        .style('pointer-event', 'none');

    li 
        .on('click', function (d) {
            selectedDate = d;
            render();
        });

}

// create chart
function bar() {
    // group 
    var g = svg.selectAll('g') 
        .data(data)
        .enter()
        .append('g')
        .classed('gBar', true);

    // name
    g.append('text')
        .attr({
            class: 'name',
            x: 20,
            y: function (d,i) { return ySpacing(i); },
        })
        .text(function (d) { return d.name; });

    // bar
    g.append('rect')
        .attr({
            x: 40,
            y: function (d,i) { return ySpacing(i) -5; },
            width: 0,
            height: 8
        })
        .style({
            stroke: 'none',
            fill: function (d) { return d.colour; }
        })
        .transition() // a little motion
        .attr({
            width: function (d) { 
                if (age(d.born, selectedDate) < 0) {
                    return 0;
                } else {
                    return scale(age(d.born, selectedDate)); 
                }    
            }
        });

    // age
    g.append('text')
        .attr({
            class: 'age',
            x: function (d) { 
                if (age(d.born, selectedDate) < 0) {
                    return 40;
                } else {
                    return scale(age(d.born, selectedDate)) + 60; 
                }    
            },
            y: function (d,i) { return ySpacing(i); },
        })
        .text(function (d) { 
            if (age(d.born, selectedDate) < 0) {
                return 'not born';
            } else {
                return age(d.born, selectedDate); 
            }    
        });
}

// calculate age
function age(_birth, _date) {
    // use moment.js to calc age
    var a = moment([_birth, 0]);
    var b = moment([_date, 0]);

    return b.diff(a, 'years');
}
// calculate spacing (so I can change in one place)
function ySpacing(_i) {
   return  _i*40 + 40; 
}
// update on selection
function render() {
    d3.selectAll('.gBar').remove();
    bar();
}

// render navigation options
buttons();
// render initial chart
render();


})();

main.css

@import url(http://fonts.googleapis.com/css?family=Source+Code+Pro:400,600);
    
body {
  font-family: "Source Code Pro", Consolas, monaco, monospace;
  line-height: 1.5;
  font-weight: 400;
  background-color: #130C0E;
  padding: 0;
  /*margin: 0;*/
  margin: 0 auto;
  width: 960px;
  height: 100px;
}
h1 {
  font-size: 48px;
  color: #7AC143;
  font-weight: 400;
  margin: 0;
  padding: 0;
  line-height: 100%;
}
p {
  font-size: 18px;
  color: #7AC143;
  font-weight: 400;
  margin: 0;
  padding: 0;
  letter-spacing: 6px;
  text-transform: uppercase;
}
p span {
  letter-spacing: 1px;
  color: #EE3124;
  font-size: 14px;
}
text {
  font-size: 18px;
  fill: #7AC143;
  alignment-baseline: middle;
}
#vis {

}
header {
  height: 150px;
  padding: 20px;
}
button {
  font-family: "Source Code Pro", Consolas, monaco, monospace;
  font-size: 14px;
  background: #130C0E;
  color: #7AC143;
  border: none;
  outline:none;
  padding: 4px 8px;
  letter-spacing: 1px;
  pointer-events: all;
}
button:hover {
  background: #7AC143;
  color: #130C0E;
}

nav {
}

ul {
  overflow: auto;
  list-style-type: none;
  padding-left: 0;
  margin-left: 0;
}

li {
  cursor: pointer;
  background: #7AC143;
  color: #130C0E;
  height: 30px;
  display: inline-block;
  margin-right: 5px;
  padding: 2px 8px 0 8px;
  letter-spacing: 2px;

  -webkit-transition: all 0.5s ease;
  -moz-transition: all 0.5s ease;
  -o-transition: all 0.5s ease;
  -ms-transition: all 0.5s ease;
  transition: all 0.5s ease;
}

/*li:last-child {

}*/


li:hover {
  background: #130C0E;
  color: #7AC143;
}