Skip to content

Instantly share code, notes, and snippets.

@wboykinm
Last active August 29, 2015 14:05
Show Gist options
  • Save wboykinm/1a2806d828cb3fa64c4d to your computer and use it in GitHub Desktop.
Save wboykinm/1a2806d828cb3fa64c4d to your computer and use it in GitHub Desktop.
One-handled #d3js brush, as magnitude selector on a data distribution
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<link href="roc.css" rel="stylesheet"/>
<link href='http://fonts.googleapis.com/css?family=Rajdhani' rel='stylesheet' type='text/css'>
</head>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="roc.js"></script>
</body>
</html>
body {
font-family: 'Rajdhani', sans-serif;
}
.rocChart {
position: relative;
font-size: 1.1rem;
width: 100%;
}
.rocChart .roc {
fill: #87CEFF;
stroke-width: 0px;
fill-opacity: 1;
}
.rocChart .baseline {
fill: none;
stroke: #333;
stroke-width: 0;
}
.rocChart .brush .extent {
fill-opacity: 1;
fill: #49ada6;
shape-rendering: crispEdges;
}
.rocChart .brush .resize {
stroke: transparent;
stroke-width: 20;
fill: #666;
}
// Default roc curve
var rocData = {"roc":[[0,0,0],[0.011360850020433183,0.1520501138952164,14344],[0.029015120555782592,0.2667995444191344,28413],[0.04675112382509195,0.3604783599088838,42773],[0.07592970984879444,0.45074031890660593,57789],[0.12071924805884757,0.5472665148063781,73212],[0.18422558234572947,0.6463553530751709,88373],[0.2804250102165917,0.7428815489749431,103470],[0.43261136085002044,0.8288724373576309,118368],[0.639967306906416,0.9245444191343963,133392],[1.0,1.0,148430]],"campaign_id":null};
// Dimensions
var margin = {top: 20, right: 10, bottom: 10, left: 10},
width = 380,
chartRatio = 1,
height = width * chartRatio;
// Normalize x and y scales as 0-1
var x = d3.scale.linear()
.domain([0, d3.max(rocData.roc, function(d){
return d[1] - d[0];
})])
.range([0, width/3]);
var y = d3.scale.linear()
.domain([0, 1])
.range([0, height - margin.top - margin.bottom]);
// Define dimensions and place svg
var svg = d3.select("body").append("svg")
.attr("class","rocChart")
.attr("width", width)
.attr("height", height + margin.top + margin.bottom);
// Define the area
var area = d3.svg.area()
.y(function(d) { return y(d[0]); })
.x1(function(d) { return x(d[1] - d[0]); })
.interpolate("basis");
// Add the area to the chart, populated with the data
svg.append("path")
.datum(rocData.roc)
.attr("class", "roc")
.attr("d", area)
.attr("transform", "translate(" + (width/3 + margin.left) + "," + margin.top + ")");
// Add the brush to the Y axis, set to 10% of the extent
var brush = d3.svg.brush()
.y(y)
.extent([0,0.1])
.on("brushend", function(){
brushg.selectAll(".resize.s")
.style("display","inline")
});
// Tack the brush onto a group element
var brushg = svg.append("g")
.attr('class', 'brush')
.attr('height', height)
.attr("transform", "translate(" + (width/3) + "," + margin.top + ")")
.call(brush);
// Set the brush to non-clickable
brushg.selectAll("rect")
.style("pointer-events","none");
// Disable the top brush handle
brushg.selectAll(".resize.n")
.style("pointer-events","none");
// Add a circle to the bottom of the brush
brushg.selectAll(".resize.s")
.append('circle')
.attr("cx", -19)
.attr("cy", 0)
.attr("r", 4);
// Move everything over 20 pixels from the ROC curve area
brushg.selectAll("rect")
.attr("width", 2)
.attr({transform: 'translate(-20,0)'});
// Add a "sliding track" line to the brush
var yLine = brushg.append("line")
.attr("y1", 0)
.attr("y2", height - margin.top - margin.bottom)
.attr("stroke-width", 0.5)
.attr("stroke", "#666")
.attr("transform", "translate(-19,0)");
// Add a horizonal line to the lower brush end to show curve intersection
brushg.selectAll(".resize.s")
.append("line")
.attr("x1", -width/3)
.attr("x2", width/3*2)
.attr("stroke-width", 0.5)
.attr("stroke", "#999");
// Add guidance text to right side of chart
svg.append('foreignObject')
.attr("x", width - 100)
.attr("y", margin.top/2)
.attr('width', 100 - margin.right)
.attr('height', 100)
.append("xhtml:div")
.attr('class', 'labelContainer')
.html('<p class="rocLabel right">Taller</p>');
svg.append('foreignObject')
.attr("x", width - 100)
.attr("y", height - margin.bottom)
.attr('width', 100 - margin.right)
.attr('height', 100)
.append("xhtml:div")
.attr('class', 'labelContainer')
.html('<p class="rocLabel right">Shorter</p>');
// Add range text to left side of chart
svg.append('text')
.attr("x", margin.left)
.attr("y", margin.top)
.style("text-anchor", "left")
.attr('class', 'rocLabel')
.text("0 Buildings");
svg.append('text')
.attr("x", margin.left)
.attr("y", height + margin.bottom)
.style("text-anchor", "left")
.attr('class', 'rocLabel maxTargets')
.text("1000 Buildings");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment