|
d3scatterplot = function(svg,data) { |
|
var df=data.df; |
|
var nPix= 420,n=df.length,mar = [40,60,40,40]; |
|
var xv = df.map(function(e) { return e.x;}),xRange=expand(d3.extent(xv)); |
|
var yv = df.map(function(e) { return e.y;}),yRange=expand(d3.extent(yv)); |
|
svg.attr("width", nPix+mar[0]+mar[2]) |
|
.attr("height", nPix+mar[1]+mar[3]); |
|
|
|
var sg = svg.append("g") |
|
.attr("transform", "translate(" |
|
+ mar[0] + "," |
|
+ mar[1] + ")"); |
|
|
|
var xScale = d3.scale.linear() |
|
.range([0, nPix]) |
|
.domain(xRange); |
|
|
|
var yScale = d3.scale.linear() |
|
.range([nPix, 0]) |
|
.domain(yRange); |
|
|
|
|
|
drawdots = function() |
|
{ |
|
sg.selectAll("circle").remove(); |
|
sg.selectAll("circle") |
|
.data(df).enter() |
|
.append("circle") |
|
.attr("cx",function(d) {return xScale(d.x);}) |
|
.attr("cy",function(d) {return yScale(d.y);}) |
|
.attr("fill",function(d,i) { return (i == (n-1))?"red":"black";}) |
|
.attr("id",function(d,i) {return "point" + i}) |
|
.attr("r",5); |
|
} |
|
|
|
|
|
var xAxis = d3.svg.axis().scale(xScale).orient("bottom").ticks(4); |
|
svg.append("g").call(xAxis) |
|
.attr("class", "axis") //Assign "axis" class |
|
.attr("transform","translate(" + mar[0] + "," + (nPix+mar[1]) + ")"); |
|
|
|
var yAxis = d3.svg.axis().scale(yScale).orient("left").ticks(4); |
|
svg.append("g").call(yAxis) |
|
.attr("class", "axis") //Assign "axis" class |
|
.attr("transform","translate(" + mar[0] + "," + (mar[3]) + ")"); |
|
drawdots(); |
|
correlation_meter(df,data.ci); |
|
|
|
svg.on("click",function(el) |
|
{ |
|
//Get mouse position |
|
var mP=d3.mouse(this); |
|
//Mouse position to data coordinates |
|
var nx = xScale.invert(mP[0]-mar[0]),ny = yScale.invert(mP[1]-mar[1]); |
|
//Change datapoint accordingly |
|
df[n-1].x = nx; |
|
df[n-1].y = ny; |
|
correlation_meter(df,data.ci); |
|
drawdots(); |
|
}); |
|
|
|
|
|
} |
|
|
|
correlation_meter = function(df,ci) |
|
{ |
|
var svg = d3.select('svg'),nPix=100; |
|
var xv = df.map(function(e) { return e.x;}); |
|
var yv = df.map(function(e) { return e.y;}); |
|
|
|
d3.select("#meter").remove(); |
|
var sg = svg.append("g") |
|
.attr("id","meter") |
|
.attr("transform", "translate(" |
|
+ 100 + "," |
|
+ 20 + ")"); |
|
var yScale = d3.scale.linear() |
|
.range([nPix, 0]) |
|
.domain([-1,1]); |
|
var yAxis = d3.svg.axis().scale(yScale).orient("left").ticks(4); |
|
sg.append("g").call(yAxis) |
|
.attr("class", "axis") //Assign "axis" class |
|
var cf = corcoef(xv,yv); |
|
// sg.append("circle") |
|
// .attr("cx",10) |
|
// .attr("cy",yScale(cf)) |
|
// .attr("r",4) |
|
// .attr("fill","blue"); |
|
sg.append("line") |
|
.attr("x1",5) |
|
.attr("x2",15) |
|
.attr("y1",yScale(cf)) |
|
.attr("y2",yScale(cf)) |
|
.attr("id","ciline") |
|
.attr("stroke-width","3px") |
|
.attr("stroke", "red") |
|
.attr("fill","black"); |
|
|
|
sg.append("line") |
|
.attr("x1",1) |
|
.attr("x2",1) |
|
.attr("y1",yScale(ci[0])) |
|
.attr("y2",yScale(ci[1])) |
|
.attr("id","ciline") |
|
.attr("stroke-width","5px") |
|
.attr("stroke", "grey") |
|
.attr("fill","black"); |
|
if (cf < ci[0] | cf > ci[1]) |
|
{ |
|
msg ="p < .05" |
|
sg.append("text") |
|
.attr("x",30) |
|
.attr("y",50) |
|
.attr("font-size",28) |
|
.text(msg); |
|
} |
|
} |
|
|
|
|
|
d3.json("data.json", function(data) { |
|
var svg = d3.select("#d3plot").append("svg") |
|
.attr("width","100%") |
|
.attr("height","100%"); |
|
|
|
d3scatterplot(svg,data); |
|
|
|
}); |
|
|
|
variance = function(u) |
|
{ |
|
var n=u.length,alpha = (n/(n-1)); |
|
var r = (d3.mean(u.map(function(v) { return v*v;})) - Math.pow(d3.mean(u),2)); |
|
return alpha*r; |
|
} |
|
|
|
//Subtract mean and divide by sd. |
|
standardise = function(u) |
|
{ |
|
var m = d3.mean(u), s=Math.sqrt(variance(u)); |
|
return u.map(function(v) { return (v-m)/s;}); |
|
} |
|
|
|
//Compute Pearson's correlation between u and v |
|
corcoef = function(u,v) |
|
{ |
|
var us = standardise(u),vs = standardise(v),n=u.length; |
|
return (1/(n-1))*d3.sum(us.mult(vs)); |
|
} |
|
|
|
Array.prototype.enorm = function () { |
|
return Math.sqrt(this.reduce(function(prev,cur) { return prev + cur*cur; },0)); |
|
} |
|
|
|
|
|
Array.prototype.add = function (b) { |
|
var s = Array(this.length); |
|
for (var ind = 0; ind < this.length; ind++) |
|
{ |
|
if (typeof(b)=="number") |
|
{ |
|
s[ind] = this[ind]+ b; |
|
} |
|
else |
|
{ |
|
s[ind] = this[ind]+ b[ind]; |
|
} |
|
} |
|
return s; |
|
}; |
|
|
|
Array.prototype.mult = function (b) { |
|
var s = Array(this.length); |
|
for (var ind = 0; ind < this.length; ind++) |
|
{ |
|
if (typeof(b)=="number") |
|
{ |
|
s[ind] = this[ind]* b; |
|
} |
|
else |
|
{ |
|
s[ind] = this[ind]* b[ind]; |
|
} |
|
} |
|
return s; |
|
}; |
|
|
|
|
|
|
|
Array.prototype.max = function () { |
|
return Math.max.apply(Math, this); |
|
}; |
|
|
|
//Used to expand slightly the plotting window |
|
expand = function(r) |
|
{ |
|
var d = r[1] - r[0],alpha=.8; |
|
return r.add([-alpha*d, alpha*d]); |
|
} |