// 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('

Taller

'); 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('

Shorter

'); // 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");