Built with blockbuilder.org
forked from tomshanley's block: Makeover Monday - YouTube ratings
forked from tomshanley's block: Makeover Monday - YouTube ratings
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; font-family: sans-serif; }
.domain { display: none; }
.tick text { fill: #808080 }
.tick line { stroke: #808080; shape-rendering: crispEdges; }
</style>
</head>
<body>
<select id="user"></select>
<div class="A-plus"></div>
<div class="A"></div>
<div class="A-minus"></div>
<div class="B-plus"></div>
<div class="B"></div>
<div class="B-minus"></div>
<div class="C-and-D"></div>
<script>
var maxVideoViews;
var maxSubscribers;
var radius = 2;
function formatBillions(d) {
var roundedNumber = Math.round(d/1000000000);
return roundedNumber + "bn";
};
function formatMillions(d) {
var roundedNumber = Math.round(d/1000000);
return roundedNumber + "m";
};
d3.csv("data.csv", convertTextToNumbers, function(error, data) {
if(error) { throw error; };
var dropDown = d3.select("#user").on("change", highlightUser);
dropDown.selectAll("option")
.data(data)
.enter()
.append("option")
.attr("value", function(d) { return d.User; })
.text(function(d) { return d.User; });
maxVideoViews = d3.max(data, function(d){ return d.VideoViews; });
maxSubscribers = d3.max(data, function(d){ return d.Subscribers; });
var nestedData = d3.nest()
.key(function(d){ return d.Rating; })
.entries(data);
nestedData.forEach(function(d) {
drawChart(d.key, d.values);
});
});
function highlightUser() {
var sel = document.getElementById('user');
var selectedUser = sel.options[sel.selectedIndex].value;
d3.selectAll("circle")
.style("opacity", function(d) { return d.User==selectedUser ? 1 : 0.2; })
.attr("r", function(d) { return d.User==selectedUser ? 5 : radius; });
};
function drawChart(key, data) {
var width = 600;
var height = 95;
var margin = {"top": 20, "left": 150, "right": 100, "bottom": 0,}
var className = "." + key;
var maxVideoViewsRating = d3.max(data, function(d){ return d.VideoViews; });
var maxSubscribersRating = d3.max(data, function(d){ return d.Subscribers; });
var div = d3.select(className).append("div")
var svg = div.append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom);
svg.append("text")
.text(key)
.attr("x", 0)
.attr("y", margin.top + height/2)
.style("fill", "black")
svg.append("text")
.text("(n=" +data.length+")")
.attr("x", 0)
.attr("y", margin.top + height/2 + 16)
.style("fill", "black")
var scaleVideoViews = d3.scaleLinear()
.range([0,width/2])
.domain([0,maxVideoViews]);
var xAxisVideoViews = d3.axisTop(scaleVideoViews).tickFormat(formatBillions);
var gXAxisVideoViews = svg.append("g")
.attr("transform", "translate(" + (margin.left/2) + "," + margin.top + ")")
.call(xAxisVideoViews);
var gVideoViews = svg.append("g")
.attr("transform", "translate(" + (margin.left/2) + "," + margin.top + ")");
var simulationVideoViews = d3.forceSimulation(data)
.force("x", d3.forceX(function(d) { return scaleVideoViews(d.VideoViews); }).strength(1))
.force("y", d3.forceY(height/2))
.force("collide", d3.forceCollide(radius + 0.5))
.stop();
for (var i = 0; i < 120; ++i) simulationVideoViews.tick();
var circlesVideoViews = gVideoViews.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("class", "user-circle")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y +")"; });
circlesVideoViews.append("circle")
.attr("r", radius)
.attr("cx", 0)
.attr("cy", 0)
.style("fill", "DarkSlateBlue")
.style("fill-opacity", 0.7 );
circlesVideoViews.append("text")
.text(function(d){ return d.User; })
.attr("class", "user-label")
.attr("x", 0)
.attr("y", function(d) {
if (d.VideoViews == maxVideoViewsRating) {
return -10;
} else {
return 20;
};
})
.attr("text-anchor", function(d) {
if (d.VideoViews == maxVideoViewsRating) {
return "start";
} else {
return "end";
};
})
.style("visibility", function(d){
if (d.Rating == "A-plus" || d.VideoViews == maxVideoViewsRating ) {
return "inherit";
} else {
return "hidden";
};
});
var scaleSubscribers = d3.scaleLinear()
.range([0,width/2])
.domain([0,maxSubscribers]);
var gSubscribers = svg.append("g")
.attr("transform", "translate(" + (margin.left + width/2) + "," + margin.top + ")");
var xAxisSubscribers = d3.axisTop(scaleSubscribers).tickFormat(formatMillions);
var gXAxisSubscribers = svg.append("g")
.attr("transform", "translate(" + (margin.left + (width/2)) + "," + margin.top + ")")
.call(xAxisSubscribers);
var simulationSubscribers = d3.forceSimulation(data)
.force("x", d3.forceX(function(d) { return scaleSubscribers(d.Subscribers); }).strength(1))
.force("y", d3.forceY(height/2))
.force("collide", d3.forceCollide(radius + 0.5))
.stop();
for (var i = 0; i < 120; ++i) simulationSubscribers.tick();
var circlesSubscribers = gSubscribers.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("class", "user-circle")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y +")"; });
circlesSubscribers.append("circle")
.attr("r", radius)
.attr("cx", 0)
.attr("cy", 0)
.style("fill", "Tomato")
.style("fill-opacity", 0.7 );
circlesSubscribers.append("text")
.text(function(d){ return d.User; })
.attr("class", "user-label")
.attr("x", 0)
.attr("y", function(d) {
if (d.Subscribers == maxSubscribersRating) {
return -10;
} else {
return 20;
};
})
.style("text-anchor", function(d) {
if (d.Subscribers == maxSubscribersRating) {
return "start";
} else {
return "end";
};
})
.style("visibility", function(d){
if (d.Rating == "A-plus" || d.Subscribers == maxSubscribersRating ) {
return "inherit";
} else {
return "hidden";
};
});
d3.selectAll("circle")
.on("mouseover", function(d){
d3.select("#user").property('value', d.User);
highlightUser();
})
.on("mouseout", function(d){
d3.selectAll("circle").style("opacity", 0.7).attr("r", radius);
})
}
function convertTextToNumbers(d) {
d.Rank = +d.Rank;
d.Subscribers = +d.Subscribers;
d.VideoViews = +d.VideoViews;
return d;
};
</script>
</body>
https://d3js.org/d3.v4.min.js