Skip to content

Instantly share code, notes, and snippets.

@timelyportfolio
Last active October 21, 2017 12:21
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 timelyportfolio/c7ae4661d58b78b50fe662dd02d32b7d to your computer and use it in GitHub Desktop.
Save timelyportfolio/c7ae4661d58b78b50fe662dd02d32b7d to your computer and use it in GitHub Desktop.
d3.tree() on Titanic
license: mit

This example courtesy of Displayr who have generously offered to sponsor a series of independently authored posts about interactive visualization with R and JavaScript. Thank you so much Displayr for this opportunity.


Code in R

Below is the R source code for creating this visualization. You might notice that much of this is actually JavaScript. To see the JavaScript, please inspect index.html.

library(d3r)
library(dplyr)
library(htmltools)
titan_nest <- as.data.frame(Titanic) %>%
  select(-Age) %>%
  group_by(Class, Sex, Survived) %>%
  summarise(Freq = sum(Freq)) %>%
  d3_nest(value_cols="Freq", root="Titanic")

browsable(
  tagList(
    d3_dep_v4(offline=FALSE),
    tag("svg", list(id="tree", height=600, width=800)),
    tags$script(HTML(
sprintf("
  var titanic = %s;
  var tree = d3.tree()
    .size([400, 750])(d3.hierarchy(titanic));

  var tree_g = d3.select('#tree')
    .append('g')
    .attr('transform', 'translate(20,20)');

  var nodes = tree_g.selectAll('.node')
    .data(tree.descendants())

  nodes = nodes.merge(
    nodes
      .enter()
      .append('g')
      .classed('node', true)
  )

  var color = d3.scaleOrdinal(d3.schemeCategory10);
  nodes
    .attr('transform', function(d) {
      return 'translate(' + d.y + ',' + d.x + ')';
    });

  nodes
    .append('rect')
    .attr('height', 10)
    .attr('width', 5)
    .attr('y', -5)
    .style('fill', function(d) {
      return color(d.data.name);
    })

  nodes
    .append('text')
    .text(function(d){
      return d.data.name
    })
    .attr('dy', function(d) {
      if(d.height===0) {return 5}
      return -5
    })
    .attr('dx', function(d) {
      if(d.height===0) {return 5}
      return -2
    })
    .attr('text-anchor', 'beginning')
    .style('font-size', '10px')
    .style('fill', function(d) {
      return color(d.data.name);
    })

  var links = tree_g.selectAll('.link')
    .data(tree.links());

  links = links.merge(
    links.enter()
      .append('path')
      .classed('link', true)
  )

  links
    .attr(
      'd',
      d3.linkHorizontal()
        .x(function(d) { return d.y; })
        .y(function(d) { return d.x; })
    )
    .style('fill', 'none')
    .style('stroke', function(d) {
      return color(d.target.data.name);
    })
",
titan_nest
)
    ))
  )
)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<script src="https://unpkg.com/d3@4.9.1"></script>
</head>
<body style="background-color:white;">
<svg id="tree" height="600" width="800"></svg>
<script>
var titanic = {"children":[{"name":"1st","children":[{"name":"Male","children":[{"name":"No","Freq":118,"colname":"Survived"},{"name":"Yes","Freq":62,"colname":"Survived"}],"colname":"Sex"},{"name":"Female","children":[{"name":"No","Freq":4,"colname":"Survived"},{"name":"Yes","Freq":141,"colname":"Survived"}],"colname":"Sex"}],"colname":"Class"},{"name":"2nd","children":[{"name":"Male","children":[{"name":"No","Freq":154,"colname":"Survived"},{"name":"Yes","Freq":25,"colname":"Survived"}],"colname":"Sex"},{"name":"Female","children":[{"name":"No","Freq":13,"colname":"Survived"},{"name":"Yes","Freq":93,"colname":"Survived"}],"colname":"Sex"}],"colname":"Class"},{"name":"3rd","children":[{"name":"Male","children":[{"name":"No","Freq":422,"colname":"Survived"},{"name":"Yes","Freq":88,"colname":"Survived"}],"colname":"Sex"},{"name":"Female","children":[{"name":"No","Freq":106,"colname":"Survived"},{"name":"Yes","Freq":90,"colname":"Survived"}],"colname":"Sex"}],"colname":"Class"},{"name":"Crew","children":[{"name":"Male","children":[{"name":"No","Freq":670,"colname":"Survived"},{"name":"Yes","Freq":192,"colname":"Survived"}],"colname":"Sex"},{"name":"Female","children":[{"name":"No","Freq":3,"colname":"Survived"},{"name":"Yes","Freq":20,"colname":"Survived"}],"colname":"Sex"}],"colname":"Class"}],"name":"Titanic"};
var tree = d3.tree()
.size([400, 750])(d3.hierarchy(titanic));
var tree_g = d3.select('#tree')
.append('g')
.attr('transform', 'translate(20,20)');
var nodes = tree_g.selectAll('.node')
.data(tree.descendants())
nodes = nodes.merge(
nodes
.enter()
.append('g')
.classed('node', true)
)
var color = d3.scaleOrdinal(d3.schemeCategory10);
nodes
.attr('transform', function(d) {
return 'translate(' + d.y + ',' + d.x + ')';
});
nodes
.append('rect')
.attr('height', 10)
.attr('width', 5)
.attr('y', -5)
.style('fill', function(d) {
return color(d.data.name);
})
nodes
.append('text')
.text(function(d){
return d.data.name
})
.attr('dy', function(d) {
if(d.height===0) {return 5}
return -5
})
.attr('dx', function(d) {
if(d.height===0) {return 5}
return -2
})
.attr('text-anchor', 'beginning')
.style('font-size', '10px')
.style('fill', function(d) {
return color(d.data.name);
})
var links = tree_g.selectAll('.link')
.data(tree.links());
links = links.merge(
links.enter()
.append('path')
.classed('link', true)
)
links
.attr(
'd',
d3.linkHorizontal()
.x(function(d) { return d.y; })
.y(function(d) { return d.x; })
)
.style('fill', 'none')
.style('stroke', function(d) {
return color(d.target.data.name);
})
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment