ROIPlot

by Simon Raper

CSS

.labels {
    font: 10px sans-serif;
    fill: black;
}

text {
    font: 10px sans-serif;
}
.spoke {
    fill: none;
    stroke: #999;
    shape-rendering: crispEdges;
    stroke-width: 1;
    stroke-dasharray: 4, 2;
}
.axis path, .arc, .line {
    fill: none;
    stroke: #999;
    shape-rendering: crispEdges;
    stroke-width: 1;
}
.axis text {
    font-family: sans-serif;
    font-size: 11px;
}

JavaScript

//Add data

var dataset = [
    [100, 235, "Microtech"],
    [345, 120, "Datalab"],
    [65, 420, "Nanomesh"],
    [110, 112, "Squilch"],
    [701, 77, "Red Mango"],
    [203, 303, "Blue Gerbil"]
];


//Set constants

var w = 500,
    padding = 50;

//Create adaptable scales

var maxDist = d3.max(dataset, function (d) {
    return Math.sqrt(Math.pow(d[0], 2) + Math.pow(d[1], 2));
})

var xScale = d3.scale.linear()
    .domain([0, maxDist + 50])
    .range([padding, w - padding]);

var yScale = d3.scale.linear()
    .domain([0, maxDist + 50])
    .range([w - padding, padding]);

//Set up the svg
var svg = d3.select("body")
    .append("svg")
    .attr("width", w)
    .attr("height", w);

//Set up dragging
var drag = d3.behavior.drag().on("drag", dragmove);

function dragmove(d) {
    d3.select(this)
        .attr("x", d.x = d3.event.x)
        .attr("y", d.y = d3.event.y)
        .attr("dx", 0).attr("dy", 0);
}


//Draw an arc

var radius = w - 2 * padding,
    radians = Math.PI / 2
    m = w - padding;

var points = 50;

var angle = d3.scale.linear()
    .domain([0, points - 1])
    .range([0, radians]);

var arc = d3.svg.line.radial()
    .interpolate("basis")
    .tension(0)
    .radius(radius)
    .angle(function (d, i) {
    return angle(i);
});


svg.append("path").datum(d3.range(points)).attr("class", "arc").attr("d", arc).attr("transform", "translate(" + padding + "," + m + ")");

//Calculate the angles for each ROI

roi = [0.1, 0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4, 5, 10, 50];

thetas = roi.map(function (x) {
    return 180 / Math.PI * Math.atan(x)
});

console.log(thetas);

//Add in the spokes
var ga = svg.selectAll(".spokegroup")
    .data(thetas)
    .enter().append("g")
    .attr('class', 'spokegroup')
    .attr("transform", function (d) {
    return "translate(" + padding + "," + m + ") rotate(" + -d + ")";
});
ga.append("line")
    .attr("class", "spoke")
    .attr("x2", radius);

//Add in the labels
ga.append("text")
    .attr("x", radius + 6)
   ...