Skip to content

Instantly share code, notes, and snippets.

@palewire
Last active October 5, 2018 07:56
Show Gist options
  • Select an option

  • Save palewire/359f60d94de3a65bbd678837fa4cc9c0 to your computer and use it in GitHub Desktop.

Select an option

Save palewire/359f60d94de3a65bbd678837fa4cc9c0 to your computer and use it in GitHub Desktop.
Responsive d3 treemap
license: MIT
height: 600
border: no
,ben,stumbo,14.12.2017 17:50,file:///home/ben/.config/libreoffice/4;

This treemap shows the salaries of the Opening Day rosters of the 2017 Houston Astros and Los Angeles Dodgers baseball teams, according to Cot's Baseball Contracts.

The code uses d3 version 3. Open the preview above in a new window to test responsiveness. This code was developed by Ben Welsh and Ryan Menezes of the Los Angeles Times for the Dec. 14, 2017 story "Why Wall Street gets a cut of your power bill.".

<!DOCTYPE html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.container {
max-width: 1270px;
margin: 0 auto;
}
.graphic {
max-width: 1000px;
display: block;
margin: 25px auto;
}
.infobox {
display: none;
}
</style>
<body>
<article class="container">
<section class="graphic">
<section class="treemap"></section>
<section class="infobox"></section>
</section>
</article>
</body>
<script src="//d1qqc1e9kvmdh8.cloudfront.net/js/jquery-1.12.4/jquery.min.js"></script>
<script src="//d1qqc1e9kvmdh8.cloudfront.net/js/underscore-1.8.3-min.js"></script>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/queue.v1.min.js"></script>
<script>
var app = {};
app.selector = "section.graphic";
app.$el = $(app.selector);
app.$infobox = $(".infobox", app.selector);
d3.selection.prototype.moveToFront = function() {
return this.each(function(){
this.parentNode.appendChild(this);
});
};
app.prep_csv_row = function (row) {
return {
name: row.name,
last_name: row.last_name,
salary: +row.salary,
team: row.team
}
};
app.intcomma = function(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
};
app.draw = function () {
console.log("draw");
// Calculate the height and width
app.width = app.$el.width();
// ... once we're below a mobile cutoff width, the treemap becomes a square
if (app.width < 580) {
app.isMobile = true;
app.scaledHeight = app.width * 1;
// otherwise it's more of a rectangle
} else {
app.isMobile = false;
app.scaledHeight = app.width * 0.45;
}
// Create the d3 layout
app.chart = d3.layout.treemap()
.size([app.width, app.scaledHeight])
.sticky(true)
.sort(function(x, y){
return d3.ascending(x.salary, y.salary);
})
.value(function(d) { return d.salary; });
// Create the svg
app.svg = d3.select("section.treemap")
.append("svg")
.attr("width", app.width)
.attr("height", app.scaledHeight);
// Create g elements to group all the squares with their labels
app.nodes = app.svg.datum(app.clustered_data).selectAll("g")
.data(app.chart.nodes)
.enter()
.append("g")
.attr("data-name", function(d) { return d.name; })
.attr("data-last-name", function(d) { return d.last_name; })
.attr("data-team", function (d) { return d.team; })
.attr("data-salary", function(d) { return d.salary; });
// Create the squares inside those
app.nodes.append("rect")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("width", function(d) { return d.dx; })
.attr("height", function(d) { return d.dy; })
.attr("stroke", "white")
.attr("stroke-width", 0.5)
.attr("fill", function (d) {
return d.team == 'Dodgers' ? '#005A9C': '#EB6E1F';
});
// Add the labels as well
app.nodes.append('text')
.attr("x", function(d) { return d.x + 5; })
.attr("y", function(d) { return d.y + 20; })
.text(function (d) {
// Only if there are more than 5 million, to avoid labels on very small boxes
if ((!app.isMobile) & d.salary > 5000000) {
return d.last_name;
} else if (d.salary > 10000000) {
return d.last_name
}
})
.attr("font-family", "Courier")
.attr("font-size", function (d) { return app.isMobile == true ? '13px': '16px'; })
.attr("text-anchor", "left");
app.nodes.on("mouseover", app.mouseover);
app.nodes.on("mouseout", app.mouseout);
};
app.resize = function () {
console.log("resize");
$("section.treemap").empty();
app.draw();
};
app.mouseover = function() {
d3.select(this)
.select("rect")
.attr("stroke-width", 2);
d3.select(this).moveToFront();
var that = $(this);
var html = "<b>" + that.attr("data-name") + "</b> $" + app.intcomma(that.attr("data-salary"));
app.$infobox.html(html).show();
};
app.mouseout = function () {
d3.select(this)
.select("rect")
.attr("stroke-width", 0.3);
app.$infobox.html("").hide();
}
app.boot = function (error, data) {
console.log("boot");
app.data = _.map(data, app.prep_csv_row);
app.clustered_data = {
"name": "cluster",
"children": [
{
"name": "dodgers",
"children":_.where(app.data, {"team": "Dodgers"})
},
{
"name": "astros",
"children":_.where(app.data, {"team": "Astros"})
},
]
};
app.draw();
d3.select(window).on("resize", app.resize);
};
queue()
.defer(d3.csv, 'players.csv')
.await(app.boot);
</script>
name last_name salary team
McCann, Brian McCann 17000000 Astros
Beltran, Carlos Beltran 16000000 Astros
Gurriel, Yulieski Gurriel 14400000 Astros
Reddick, Josh Reddick 13000000 Astros
Keuchel, Dallas Keuchel 9150000 Astros
Morton, Charlie Morton 7000000 Astros
Gregerson, Luke Gregerson 6250000 Astros
Sipp, Tony Sipp 6000000 Astros
Aoki, Nori Aoki 5500000 Astros
Gattis, Evan Gattis 5200000 Astros
Altuve, Jose Altuve 4687500 Astros
Springer, George Springer 3900000 Astros
McHugh, Collin McHugh 3850000 Astros
Gonzalez, Marwin Gonzalez 3725000 Astros
Fiers, Michael Fiers 3450000 Astros
Harris, Will Harris 2200000 Astros
Marisnick, Jake Marisnick 1100000 Astros
Devenski, Chris Devenski 554500 Astros
Giles, Ken Giles 550100 Astros
McCullers Jr., Lance McCullers Jr. 548000 Astros
Feliz, Michael Feliz 546200 Astros
Musgrove, Joe Musgrove 543400 Astros
Peacock, Brad Peacock 541500 Astros
Bregman, Alex Bregman 539400 Astros
Gustave, Jandel Gustave 537200 Astros
Paulino, David Paulino 536100 Astros
Correa, Carlos Correa 535000 Astros
Singleton, Jonathan Singleton 2000000 Astros
Kershaw, Clayton Kershaw 35571429 Dodgers
Gonzalez, Adrian Gonzalez 22357143 Dodgers
Kazmir, Scott Kazmir 17666667 Dodgers
Ethier, Andre Ethier 17500000 Dodgers
Turner, Justin Turner 13000000 Dodgers
Hill, Rich Hill 12666667 Dodgers
McCarthy, Brandon McCarthy 11500000 Dodgers
Jansen, Kenley Jansen 11333333 Dodgers
Puig, Yasiel Puig 8214286 Dodgers
Ryu, Hyun-Jin Ryu 7833333 Dodgers
Forsythe, Logan Forsythe 7000000 Dodgers
Grandal, Yasmani Grandal 5500000 Dodgers
Maeda, Kenta Maeda 3125000 Dodgers
Romo, Sergio Romo 3000000 Dodgers
Wood, Alex Wood 2800000 Dodgers
Gutierrez, Franklin Gutierrez 2600000 Dodgers
Utley, Chase Utley 2000000 Dodgers
Avilan, Luis Avilan 1500000 Dodgers
Van Slyke, Scott Van Slyke 1325000 Dodgers
Hatcher, Chris Hatcher 1250000 Dodgers
Seager, Corey Seager 575000 Dodgers
Hernandez, Enrique Hernandez 555000 Dodgers
Pederson, Joc Pederson 555000 Dodgers
Garcia, Yimi Garcia 555000 Dodgers
Baez, Pedro Baez 550000 Dodgers
Ravin, Josh Ravin 545000 Dodgers
Barnes, Austin Barnes 540000 Dodgers
Dayton, Grant Dayton 540000 Dodgers
Stripling, Ross Stripling 540000 Dodgers
Toles, Andrew Toles 540000 Dodgers
Stewart, Brock Stewart 537500 Dodgers
Toscano, Dian Toscano 1600000 Dodgers
Crawford, Carl Crawford 21857143 Dodgers
Guerrero, Alexander Guerrero 7500000 Dodgers
Olivera, Hector Olivera 4666666 Dodgers
Sierra, Yaisel Sierra 3500000 Dodgers
Arruebarruena, Erisbel Arruebarruena 5500000 Dodgers
Kemp, Matt Kemp 2750000 Dodgers
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment