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