Skip to content

Instantly share code, notes, and snippets.

@avimoondra
Last active August 29, 2015 14:11
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 avimoondra/32c8635d747a6d7b4650 to your computer and use it in GitHub Desktop.
Save avimoondra/32c8635d747a6d7b4650 to your computer and use it in GitHub Desktop.
Scatter
type price mpgCity driveTrain passengers weight
small 15.9 25 front 5 2705
midsize 33.9 18 front 5 3560
midsize 37.7 19 front 6 3405
midsize 30 22 rear 4 3640
midsize 15.7 22 front 6 2880
large 20.8 19 front 6 3470
large 23.7 16 rear 6 4105
midsize 26.3 19 front 5 3495
large 34.7 16 front 6 3620
midsize 40.1 16 front 5 3935
midsize 15.9 21 front 6 3195
large 18.8 17 rear 6 3910
large 18.4 20 front 6 3515
large 29.5 20 front 6 3570
small 9.2 29 front 5 2270
small 11.3 23 front 5 2670
midsize 15.6 21 front 6 3080
small 12.2 29 front 5 2295
large 19.3 20 front 6 3490
small 7.4 31 front 4 1845
small 10.1 23 front 5 2530
midsize 20.2 21 front 5 3325
large 20.9 18 rear 6 3950
small 8.4 46 front 4 1695
small 12.1 42 front 4 2350
small 8 29 front 5 2345
small 10 22 front 5 2620
midsize 13.9 20 front 5 2885
midsize 47.9 17 rear 5 4000
midsize 28 18 front 5 3510
midsize 35.2 18 rear 4 3515
midsize 34.3 17 front 6 3695
large 36.1 18 rear 6 4055
small 8.3 29 front 4 2325
small 11.6 28 front 5 2440
midsize 61.9 19 rear 5 3525
midsize 14.9 19 rear 5 3610
small 10.3 29 front 5 2295
midsize 26.1 18 front 5 3730
small 11.8 29 front 5 2545
midsize 21.5 21 front 5 3200
midsize 16.3 23 front 5 2890
large 20.7 19 front 6 3470
small 9 31 front 4 2350
midsize 18.5 19 front 5 3450
large 24.4 19 front 6 3495
small 11.1 28 front 5 2495
small 8.4 33 4WD 4 2045
small 10.9 25 4WD 5 2490
small 8.6 39 front 4 1965
small 9.8 32 front 5 2055
midsize 18.2 22 front 5 3030
small 9.1 25 front 4 2240
midsize 26.7 20 front 5 3245
<!DOCTYPE html>
<html lang="en">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="../static/jstat.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8">
</head>
<body>
<style type="text/css">
svg .axis path,
svg .axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
svg .datapoint {
fill: #569BBD;
fill-opacity: 0.5;
stroke: #569BBD;
}
#svgWrapper {
display: inline-block;
}
#panelWrapper {
width: 200px;
border: solid #808080 1px;
padding: 10px;
display: inline-block;
position: fixed;
margin-top: 10px;
}
.separator {
margin-bottom: 10px;
height: 1px;
background-color: #808080;
}
.dropdown-toggle {
width: 180px;
}
</style>
<div>
<div id="svgWrapper">
<svg></svg>
</div>
<div id="panelWrapper">
<div>
<p>
Scatterplot of various numerical attributes of 54 cars. Plot different variables against each other to visualize interesting trends in the data.
</p>
<div class="separator"></div>
<p> X (horizontal axis) </p>
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-expanded="true">
</button>
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
</ul>
</div>
<br/>
<p>Y (vertical axis) </p>
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu2" data-toggle="dropdown" aria-expanded="true">
</button>
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu2">
</ul>
</div>
</div>
</div>
</div>
<script type="text/javascript">
var variables = ["passengers", "weight", "price", "mpgCity"];
var names = {"passengers" : "Passengers",
"weight" : "Weight (pounds)",
"price" : "Price ($1000s)",
"mpgCity" : "Miles Per Gallon"}
menu = $(".dropdown-menu");
variables.forEach(function(element, index, array){
menu.append("<li role='presentation'><a role='menuitem' tabindex='-1' href='#'>"
+ names[element]
+ "</a></li>");
});
var margin = {top: 20, right: 20, bottom: 30, left: 30},
width = 560 - margin.left - margin.right,
height = 350 - margin.top - margin.bottom;
var x = d3.scale.linear()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.ticks(5)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var svg = d3.select("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var scatterplot = function(var1, var2){
d3.csv("../static/data/00/cars.csv", function(error, data) {
d3.selectAll(".graph-component").remove();
data.forEach(function(d) {
d[var1] = +d[var1];
d[var2] = +d[var2];
});
x.domain(d3.extent(data, function(d) { return d[var1]; })).nice();
y.domain(d3.extent(data, function(d) { return d[var2]; })).nice();
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.classed("graph-component", true)
.append("text")
.attr("class", "label graph-component")
.attr("x", width)
.attr("y", -10)
.style("text-anchor", "end")
.text(names[var1]);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.classed("graph-component", true)
.append("text")
.attr("class", "label graph-component")
.attr("transform", "rotate(-90)")
.attr("y", 10)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text(names[var2])
svg.selectAll(".datapoint")
.data(data)
.enter().append("circle")
.attr("class", "datapoint graph-component")
.attr("r", 5)
.attr("cx", function(d) { return x(d[var1]); })
.attr("cy", function(d) { return y(d[var2]); })
svg.selectAll(".datapoint").each(function(d){
insertHTML = "";
variables.forEach(function(variable){
insertHTML = insertHTML + variable + " : " + d[variable] + "<br/>"
});
options = {
container: 'body',
html: true,
placement: "right",
template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
title: insertHTML,
trigger: 'hover focus click'
}
//$(this).tooltip(options)
});
svg.selectAll(".datapoint")
.on("mouseover", function(d){
//$(this).tooltip('show');
tooltip.transition()
.duration(200)
.style("opacity", .9);
tooltip.html((function(){
str = "";
variables.forEach(function(element, index, array){
str = str + element + " : " + d[element] + "<br/>"
});
return str;
})())
.style("left", (d3.event.pageX + 6) + "px")
.style("top", (d3.event.pageY - 65) + "px");
})
.on("mouseout", function(d) {
//$(this).tooltip('hide');
tooltip.transition()
.duration(200)
.style("opacity", 0);
});
});
};
$(".dropdown-menu li a").click(function(){
var selText = $(this).text();
var dropdownButton = $(this).parents("ul").siblings("button");
dropdownButton.html(selText + '<span class="caret"></span>');
dropdownButton.trigger("change");
});
function wrap(text, width) {
displacedHeight = 0;
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
x = text.attr("x"),
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x", x).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan").attr("x", x).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
}
}
text.data([this.getBoundingClientRect()]);
});
return displacedHeight;
}
var displayNote = function(var1, var2){
d3.selectAll(".note").remove();
if(var1 == var2) {
note1 = d3.select('svg').append('text')
.text("Note: You've plotted a variable against itself. That's why the points are in line perfectly!")
.attr("class", "note")
.attr("x",800)
.attr("y",250)
.attr("dy",'0.71em')
.attr("font-family","sans-serif")
.call(wrap, 150);
}
if(var1 == variables[0] || var2 == variables[0]) {
d3.select('svg').append('text')
.text("Note: You've plotted using the passengers variable. This quantity is discrete, and can sensibly only take on values 4, 5, 6!")
.attr("class", "note")
.attr("x",800)
.attr("y", note1.data()[0]['bottom'] + 20)
.attr("dy",'0.71em')
.attr("font-family","sans-serif")
.call(wrap, 150);
}
}
$("button").change(function(){
var1Name = $("#dropdownMenu1").text();
var2Name = $("#dropdownMenu2").text();
var1 = Object.keys(names).filter(function(key) {return names[key] === var1Name})[0];
var2 = Object.keys(names).filter(function(key) {return names[key] === var2Name})[0];
scatterplot(var1, var2);
displayNote(var1, var2);
})
$('#dropdownMenu1').siblings("ul").find("a:contains(" + names[variables[1]] +")").click();
$('#dropdownMenu2').siblings("ul").find("a:contains(" + names[variables[2]] +")").click();
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment