Skip to content

Instantly share code, notes, and snippets.

@jrue
Last active August 29, 2015 14:02
Show Gist options
  • Save jrue/d4dad84fdbab252b6d13 to your computer and use it in GitHub Desktop.
Save jrue/d4dad84fdbab252b6d13 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<title>Taxonomy</title>
<script type="text/javascript" src="js/prefixfree.min.js"></script>
<link href="css/radios-to-slider.min.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="js/d3.v3.min.js"></script>
<script type="text/javascript" src="js/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="js/jquery.radios-to-slider.min.js"></script>
<style type="text/css">
body{
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
#container{
max-width:1000px;
width:100%;
margin:0 auto;
}
#chart{
width: 450px;
height:450px;
position:fixed;
left:50%;
}
#questions{
width:40%;
float:left;
min-width: 400px;
}
h3{
display:block;
margin:5px auto 10px;
text-align: center;
font-size: 18px;
}
fieldset{
border:none;
background:#eee;
text-align: center;
display:block;
margin: 10px 0;
}
.radios{
margin: 10px auto;
}
/* input[type="radio"] {
margin-top: -1px;
vertical-align: middle;
}*/
.morelesslabels{
margin: 0;
padding:0;
}
.less, .more{
color:#777;
display: block;
font-size: 14px;
}
.less{
float:left;
text-align: left;
}
.more{
float: right;
text-align: right;
}
/* .radios{
padding:5px;
height: 22px;
position:relative;
border-radius: 25px;
margin:10px auto;
background-color: #e0e0e0;
display:block;
max-width:250px;
box-sizing:content-box;
text-align: left;
}
.radios input[type="radio"]{
display:none;
}
.radios input[type="radio"] + label{
display:inline-block;
width:22px;
height:22px;
border-radius:22px;
background-color: #fff;
margin-right:25px;
cursor: pointer;
}
.radios input[type="radio"] label:last-of-type{
margin: none;
}
.radios input[type="radio"] + label:before{
}
.radios input[type="radio"]:checked + label{
}*/
</style>
</head>
<body>
<div id="container">
<div id="questions">
</div>
<div id="chart"></div>
</div>
<script type="text/javascript">
(function($, window, d3){
var width = 400,
height = 400,
margin = {top: 50, right: 50, bottom: 50, left:50};
var svg = d3.select("#chart")
.append("svg")
.attr("width", "100%")
.attr("height", "100%")
.attr("viewBox", "0 0 " + width + " " + height);
width = width - margin.left - margin.right;
height = height - margin.top - margin.bottom;
//Equilateral triangle, a2 + b2 = c2.
var thetop = Math.sqrt((width * width) - (width/2 * width/2));
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + ( (-(height - thetop)/2) + margin.top) + ")")
//coordinates of points
var comp = {x: 0, y: height, title: "Comprehensive"},
imer = {x: width, y: height, title: "Immersive"},
strt = {x: width/2, y: height-thetop, title: "Straight"};
svg.selectAll("text")
.data([comp, imer, strt])
.enter()
.append("text")
.attr("x", function(d){ return d.x - (d.title.length * 3);})
.attr("y", function(d){ return d.title == "Straight" ? d.y - 30 : d.y;})
.attr("transform", "translate(" + margin.left + ", "+ margin.top +")")
.text(function(d){ return d.title;})
.style({'font-weight': 'bold', 'fill':'#555', 'font-size': '12px'})
//draw triangle
g.append("path")
.attr("d", "M" + comp.x + "," + comp.y + "L" + imer.x + "," + imer.y + "L" + strt.x + "," + strt.y + "Z")
.style({"fill":"none", "stroke":"black", "stroke-width":"1px"});
g.append("circle")
.attr("cx", width/2)
.attr("cy", strt.y + ((height - strt.y) * 2/3) )
.attr("r", 20)
.style({"fill":"purple"});
//console.log("new coord", stortenLineDistance(strt.x, strt.y, comp.x, comp.y, 10))
/**
* Calculates length of a line on Cartesian grid, then returns point that is X number of pixels down the line.
*
* @param {Number} fromX - starting x point
* @param {Number} fromY - starting y point
* @param {Number} toX - ending x point for vector
* @param {Number} toY - ending y point for vector
* @param {Number} pxDistance - Number of pixels down line toward ending point to return
* @return {Object} - Returns x/y coords of point on line based on number of pixels given
*/
function stortenLineDistance(fromX, fromY, toX, toY, pxDistance){
//if line is vertical
if(fromX === toX)
return {x: toX, y: toY > fromY ? fromY + pxDistance : fromY - pxDistance};
//if line is horizontal
if(fromY === toY)
return {y: toY, x: toX > fromX ? fromX + pxDistance : fromX - pxDistance};
//get each side of original triangle length
var adjacent = toY - fromY;
var opposite = toX - fromX;
var hypotenuse = Math.sqrt(Math.pow(opposite, 2) + Math.pow(adjacent,2));
//find the angle
var angle = Math.acos(adjacent/hypotenuse);
//calculate new opposite and adjacent sides
var newOpposite = Math.sin(angle) * pxDistance;
var newAdjacent = Math.cos(angle) * pxDistance;
//calculate new x/y, see which direction it's going
var y = adjacent > 0 ? fromY + newAdjacent : fromY - newAdjacent,
x = opposite > 0 ? fromX + newOpposite : fromX - newOpposite;
return {y: y, x: x};
}
d3.tsv("questions.tsv", function(error, data){
console.log(data);
var counter = 0;
var questions = d3.select("#questions");
var fieldset = questions.selectAll("fieldset")
.data(data)
.enter()
.append("fieldset");
fieldset.append("h3")
.text(function(d){ return d.title; })
fieldset.append("div")
.attr("class", "radios")
.selectAll("input")
.data(function(d){ return [{n: 0, title: d.id}, {n: 25, title: d.id}, {n: 50, title: d.id}, {n: 75, title: d.id}, {n: 100, title: d.id}];})
.enter()
.append("input")
.attr("id", function(d){ return d.title + Math.floor(Math.random() * 1000000 + 1);})
.attr("type", "radio")
.attr("name", function(d){ return d.title;})
.attr("value", function(d){ return d.n;});
fieldset.append("p")
.attr("class", "morelesslabels")
.append("span")
.attr("class", "more")
.text(function(d){ return d.min + " \u00BB";});
fieldset.select("p")
.append("span")
.attr("class", "less")
.text(function(d){ return "\u00AB " + d.max;});
$(".radios").radiosToSlider();
d3.selectAll(".slider-level")
.on('click', function(d, i){
console.log(d3.select("#" + this.dataset.radio).node().value);
var value = d3.select("#" + this.dataset.radio).node().value,
name = d3.select("#" + this.dataset.radio).node().name,
datum = data.filter(function(d){ return d.id == name});
console.log(datum);
// g.select("circle")
// .transition()
// .attr("cx", datum[0])
})
})
})(jQuery, window, d3)
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment