Created
February 15, 2017 07:47
-
-
Save chemok78/0ba768dde9c99a4c21a6785cf951dc14 to your computer and use it in GitHub Desktop.
Kickstarter, Movies and Videogames Sales D3 Treemap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//set dimensions of div container, svg and chart area(g element) | |
var margin = { | |
top: 20, | |
right: 20, | |
bottom: 80, | |
left: 20 | |
}; | |
//width of the chart, within SVG element | |
var w = 1100 - margin.left - margin.right; | |
//height of the chart, within SVG element | |
var h = 1300 - margin.top - margin.bottom; | |
//function to make a given color fade: interpolates color with white with 0.2 on a scale of 0 to 1 | |
var fader = function(color) { | |
return d3.interpolateRgb(color, "#fff")(0.2); | |
} | |
//d3.scaleOrdinal([range]) | |
//ordinal scales of a discrete domain and range | |
//make ordinal scale of 20 colors | |
var color = d3.scaleOrdinal(d3.schemeCategory20.map(fader)); | |
var colorCodes = d3.schemeCategory20.map(fader); | |
//Create treemap function | |
var treemap = d3.treemap() | |
.tile(d3.treemapResquarify) | |
.size([w, h]) | |
.round(true) | |
.paddingInner(1); | |
//tooltip to show cell rectangle data on hover, set to fully transparant/invisible at first | |
var tip = d3.select("#chart").append("div") | |
.attr("id", "tooltip") | |
.style("opacity", 0); | |
//JSON data | |
//var url = "https://cdn.rawgit.com/freeCodeCamp/testable-projects-fcc/a80ce8f9/src/data/tree_map/movie-data.json"; | |
var datasets = { | |
kickstarter: { | |
id: "kickstarter", | |
url: "https://cdn.rawgit.com/freeCodeCamp/testable-projects-fcc/a80ce8f9/src/data/tree_map/kickstarter-funding-data.json", | |
title: "Kickstarter Pledges", | |
description: "Top 100 Most Pledged Kickstarter Campaigns Grouped By Category" | |
}, | |
movies: { | |
id: "movies", | |
url: "https://cdn.rawgit.com/freeCodeCamp/testable-projects-fcc/a80ce8f9/src/data/tree_map/movie-data.json", | |
title: "Movie Sales", | |
description: "Top 100 Highest Grossing Movies Grouped By Genre" | |
}, | |
videogames: { | |
id: "videogames", | |
url: "https://cdn.rawgit.com/freeCodeCamp/testable-projects-fcc/a80ce8f9/src/data/tree_map/video-game-sales-data.json", | |
title: "Video Game Sales", | |
description: "Top 100 Most Sold Video Games Grouped by Platform" | |
} | |
} | |
var loadData = function(dataset) { | |
//on click function to load dataset | |
document.getElementById("title").innerHTML = dataset.title; | |
document.getElementById("description").innerHTML = dataset.description; | |
//reset svg container element | |
d3.select("#chart").select("svg").remove(); | |
//Create SVG element and append to #chart div container | |
//SVG is nested G element | |
var svg = d3.select("#chart") | |
.append("svg") | |
.attr("width", w + margin.left + margin.right) | |
.attr("height", h + margin.top + margin.bottom) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
d3.json(dataset.url, function(error, json) { | |
if (error) throw error; | |
var data = json; | |
//Create a hierarchy of the data | |
var root = d3.hierarchy(data) | |
.sum(sumBySize); | |
//Create treemap layout with root data | |
//treemp is a function that returns a new object woth all the nodes and coordinates x0, x1, y0 and y1 | |
treemap(root); | |
//append a g element for each cell with the given x and y position | |
var cell = svg.selectAll("g") | |
.data(root.leaves()) | |
.enter().append("g") | |
.attr("transform", function(d) { | |
return "translate(" + d.x0 + "," + d.y0 + ")" | |
}); | |
//append a rect element to each g element/cell with coloring | |
cell.append("rect") | |
.attr("class", function(d) { | |
return d.data.category.toLowerCase(); | |
}) | |
.attr("class", "tile") | |
.attr("data-name", function(d) { | |
return d.data.name; | |
}) | |
.attr("data-category", function(d) { | |
return d.data.category; | |
}) | |
.attr("data-value", function(d) { | |
return d.data.value; | |
}) | |
.attr("width", function(d) { | |
return d.x1 - d.x0 | |
}) | |
.attr("height", function(d) { | |
return d.y1 - d.y0 | |
}) | |
.attr("fill", function(d) { | |
return color(d.data.category); | |
}) | |
.on("mouseover", function(d) { | |
tip.transition() | |
.style("opacity", 0.7); | |
tip.html("<p>name: " + d.data.name + "</p><p>category: " + d.data.category + "</p><p data-value=" + d.data.value + ">value: " + d.data.value + "<p>") | |
.style("left", d3.event.pageX - 180 + "px") | |
.style("top", d3.event.pageY - 120 + "px"); | |
}) | |
.on("mouseout", function(d) { | |
tip.transition() | |
.style("opacity", 0); | |
}) | |
cell.append("text") | |
//name of the movie is in d.data.name | |
.selectAll("tspan") | |
//select all tspans on the document | |
.data(function(d) { | |
return d.data.name.split(/(?=[A-Z][^A-Z])/g); | |
}) | |
//split every word into an array of separate words | |
.enter().append("tspan") | |
//for every array of words, append tspans | |
.attr("x", 4) | |
//move every tspan to the right | |
.attr("y", function(d, i) { | |
return 13 + i * 10; | |
}) | |
//move every tspan to the bottom | |
.text(function(d) { | |
return d | |
}) | |
//text of every tspan is d | |
//dimensions of the blocks in the legen | |
var blockWidth = 30; | |
var blockHeight = 20; | |
//extract the leaves data from the root object | |
var leaves = root.leaves(); | |
//extract all the categories in an array | |
var categories = []; | |
leaves.forEach(function(item) { | |
if (categories.indexOf(item.data.category) == -1) { | |
categories.push(item.data.category); | |
} | |
}); | |
//put all the categories and belonging color codes in a separate array | |
var legendData = []; | |
categories.forEach(function(item, index) { | |
var object = { | |
category: item, | |
colorCode: colorCodes[index] | |
} | |
legendData.push(object); | |
}); | |
//add legend group for holding the rects and text elements | |
//every g element holds a rect and text element and is translated x pixels to the right | |
var legend = svg.selectAll(".legend") | |
.data(legendData) | |
.enter() | |
.append("g") | |
.attr("class", "legend-item") | |
.attr("font-size", "12px") | |
.attr("font-style", "PT Sans") | |
.attr("transform", function(d, i) { | |
return ("translate(" + i * 90 + ", 0)"); | |
}); | |
legend.append("rect") | |
.attr("x", 20) | |
.attr("y", h + (margin.bottom / 2.7)) | |
.attr("width", blockWidth) | |
.attr("height", blockHeight) | |
.style("fill", function(d) { | |
return d.colorCode; | |
}); | |
legend.append("text") | |
.attr("x", 20 + blockWidth + 3) | |
.attr("y", h + (margin.bottom / 2.7) + (blockHeight / 1.5)) | |
.style("text-anchor", "start") | |
.text(function(d) { | |
return d.category | |
}); | |
}); //d3.json | |
} //load dataset | |
function sumBySize(d) { | |
return d.value; | |
} | |
//window load data with movies set | |
loadData(datasets.movies); | |
//event listeneers for each button to load data set | |
document.getElementById("movies").addEventListener("click", function() { | |
loadData(datasets.movies); | |
}); | |
document.getElementById("kickstarter").addEventListener("click", function() { | |
loadData(datasets.kickstarter); | |
}); | |
document.getElementById("videogames").addEventListener("click", function() { | |
loadData(datasets.videogames); | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<head> | |
<meta charset="utf-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<link href="https://fonts.googleapis.com/css?family=PT+Sans" rel="stylesheet"> | |
<head> | |
<body> | |
<div class="container text-center"> | |
<button type="button" class="btn btn-secondary" id="videogames">Video Games Data Set</button> | |
<button type="button" class="btn btn-secondary" id="movies">Movies Data Set</button> | |
<button type="button" class="btn btn-secondary" id="kickstarter">Kickstarter Data Set</button> | |
<h1 id="title"></h1> | |
<h5 id="description"></h5> | |
<div id="chart"></div> | |
</div> | |
</body> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
margin-top: 20px; | |
font-family: 'PT Sans', sans-serif; | |
} | |
svg { | |
font: 10px sans-serif; | |
} | |
#tooltip { | |
position: absolute; | |
text-align: center; | |
vertical-algin: middle; | |
width: 180px; | |
height: 120px; | |
padding-top: 10px; | |
padding-bottom: 10px; | |
padding-left: 5px; | |
padding-right: 5px; | |
font: 12px PT Sans; | |
background: #2c3e50; | |
border: 0px; | |
border-radius: 8px; | |
color: white; | |
} | |
.container { | |
padding-top: 20px; | |
} | |
#title { | |
padding-top: 20px; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment