Built with blockbuilder.org
Last active
August 11, 2017 13:31
-
-
Save TommyCoin80/ea47bc62c09c91cbbc604c02b73f4b23 to your computer and use it in GitHub Desktop.
D3.Unconf Badge
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: mit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<head> | |
<link href='https://fonts.googleapis.com/css?family=Play' rel='stylesheet' type='text/css'> | |
<style> | |
body { | |
margin:auto; | |
font-family: 'Play', sans-serif; | |
font-size:100%; | |
} | |
text { | |
font-family: 'Play', sans-serif; | |
} | |
</style> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script> | |
var WeibullPlot = function(opts) { | |
var margin = opts.margin || {top: 320, right: 30, bottom: 260, left: 70}; | |
var height = opts.height || 920; | |
var width = opts.width || 900; | |
var dur = opts.duration || 3000; | |
var del = opts.delay || 250; | |
var ease = opts.ease || d3.easeLinear; | |
var s = {}; | |
//Prep Data | |
var data = {}; | |
data.gridLines = { | |
x: [1].concat(d3.range(3,49,3)), | |
y: d3.range(.01,1,.01) | |
}; | |
data.gridLabels = { | |
x: [3, 12, 24, 36], | |
y: [.01, .05, .10, .25, .50, .75, .99] | |
}; | |
data.points = []; | |
data.points.push({x:1,y:0.0296}); | |
data.points.push({x:2,y:0.0496}); | |
data.points.push({x:3,y:0.089}); | |
data.points.push({x:4,y:0.099}); | |
data.points.push({x:5,y:0.1199}); | |
data.points.push({x:6,y:0.1599}); | |
data.points.push({x:7,y:0.18}); | |
data.points.push({x:8,y:0.1899}); | |
data.points.push({x:9,y:0.215}); | |
data.points.push({x:10,y:0.225}); | |
data.points.push({x:11,y:0.2375}); | |
data.points.push({x:12,y:0.265}); | |
data.regCoeffs = lsReg( | |
data.points.map(function(d) { return xWeib(d.x)}), | |
data.points.map(function(d) { return yWeib(d.y)}) | |
); | |
data.regLine = data.gridLines.x.map(function(d) { | |
return { | |
x: xWeib(d), | |
y: xWeib(d)*data.regCoeffs[0] + data.regCoeffs[1] | |
} | |
}); | |
// Set Scales | |
var scale = {}; | |
scale.x = d3.scaleLinear() | |
.range([0,width]) | |
.domain(d3.extent(data.gridLines.x)); | |
scale.y = d3.scaleLinear() | |
.range([height,0]) | |
.domain(d3.extent(data.gridLines.y)); | |
// Draw | |
s.svg = d3.select("#" + opts.elementId) | |
.append("svg") | |
.attr("height", height + margin.top + margin.bottom) | |
.attr("width", width + margin.left + margin.right) | |
.style("-webkit-user-select","none") | |
.style("cursor","default"); | |
s.chart = s.svg.append("g") | |
.attr("transform","translate(" + margin.left + "," + margin.top + ")"); | |
// Draw Grid | |
s.gridLines = {}; | |
s.gridLabels = {}; | |
s.gridLines.y = s.chart.selectAll(".yLines") | |
.data(data.gridLines.y) | |
.enter() | |
.append("line") | |
.attr("x1",0) | |
.attr("x2",width) | |
.attr("y1", function(d) { return scale.y(d)}) | |
.attr("y2", function(d) { return scale.y(d)}) | |
.style("stroke-opacity", function(d) { return (data.gridLabels.y.indexOf(+d3.format(".2")(d))<0)?.20:.55; }) | |
.style("stroke","black"); | |
s.gridLabels.y = s.chart.selectAll(".yLabels") | |
.data(data.gridLabels.y) | |
.enter() | |
.append("text") | |
.attr("x",0) | |
.attr("y", function(d) { return scale.y(d)}) | |
.attr("text-anchor","end") | |
.attr("dx",-2) | |
.style("font-size",".8em") | |
.text(function(d) { return d3.format('.2p')(d) }); | |
s.gridLines.x = s.chart.selectAll(".xLines") | |
.data(data.gridLines.x) | |
.enter() | |
.append("line") | |
.attr("x1",function(d) { return scale.x(d)}) | |
.attr("x2",function(d) { return scale.x(d)}) | |
.attr("y1", 0) | |
.attr("y2", height) | |
.style("stroke-opacity", function(d) { return (data.gridLabels.x.concat([1,48]).indexOf(d)<0)?.20:.55; }) | |
.style("stroke","black"); | |
s.gridLabels.x = s.chart.selectAll(".xLabels") | |
.data(data.gridLabels.x) | |
.enter() | |
.append("text") | |
.attr("y",height) | |
.attr("x", function(d) { return scale.x(d)}) | |
.attr("text-anchor","start") | |
.attr("dy",16) | |
.style("font-size",".8em") | |
.text(function(d) { return d + ' months'}); | |
// Draw Legend | |
(function() { | |
var km = s.chart.append("g") | |
.attr("transform","translate(" + width*(2/7) + "," + (height + 30) + ")"); | |
km.append("rect") | |
.attr("height",30) | |
.attr("width", width/7) | |
.style("fill","#d11141" ) | |
.attr("rx",4) | |
.style("stroke","gray"); | |
km.append("text") | |
.style("text-anchor","middle") | |
.attr("dy","1.25em") | |
.attr("dx", +km.select("rect").attr("width")/2) | |
.text("Kaplan-Meier") | |
.style("fill","white"); | |
var wf = s.chart.append("g") | |
.attr("transform","translate(" + width*(4/7) + "," + (height + 30) + ")"); | |
wf.append("rect") | |
.attr("height",30) | |
.attr("width", width/7) | |
.style("fill","#00aedb" ) | |
.attr("rx",4) | |
.style("stroke","gray"); | |
wf.append("text") | |
.style("text-anchor","middle") | |
.attr("dy","1.25em") | |
.attr("dx", +wf.select("rect").attr("width")/2) | |
.text("Weibull") | |
.style("fill","white"); | |
})(); | |
drawKM(); | |
// Draw KM Line | |
function drawKM() { | |
var line = d3.line() | |
.x(function(d) { return scale.x(d.x)}) | |
.y(function(d) { return scale.y(d.y)}) | |
.curve(d3.curveStepAfter); | |
s.kmLine = s.chart.selectAll(".dataPoint") | |
.data([data.points]) | |
.enter() | |
.append("path") | |
.attr("d", line) | |
.style("stroke-opacity",1) | |
.style("stroke","#d11141") | |
.style("stroke-width",1.5) | |
.style("fill","none") | |
.each(function(d) { | |
var tl = this.getTotalLength(); | |
var s = d3.select(this); | |
s.attr("stroke-dasharray", tl + " " + tl) | |
.attr("stroke-dashoffset", tl) | |
.transition() | |
.duration(dur) | |
.delay(del) | |
.attr("stroke-dashoffset", 0) | |
.on("end", function() { | |
s.attr("stroke-dasharray","0 0"); | |
weibullSpace(); | |
}) | |
}) | |
} | |
// Transform Spacing | |
function weibullSpace() { | |
scale.x.domain([xWeib(1),xWeib(48)]); | |
scale.y.domain([yWeib(.01),yWeib(.99)]); | |
var line = d3.line() | |
.x(function(d) { return scale.x(xWeib(d.x))}) | |
.y(function(d) { return scale.y(yWeib(d.y))}) | |
.curve(d3.curveStepAfter); | |
s.gridLines.y.transition() | |
.duration(dur) | |
.ease(ease) | |
.delay(del) | |
.attr("y1", function(d) { return scale.y(yWeib(d))}) | |
.attr("y2", function(d) { return scale.y(yWeib(d))}); | |
s.gridLines.x.transition() | |
.duration(dur) | |
.ease(ease) | |
.delay(del) | |
.attr("x1", function(d) { return scale.x(xWeib(d))}) | |
.attr("x2", function(d) { return scale.x(xWeib(d))}); | |
s.gridLabels.y.transition() | |
.duration(dur) | |
.ease(ease) | |
.delay(del) | |
.attr("y", function(d) { return scale.y(yWeib(d));}); | |
s.gridLabels.x.transition() | |
.duration(dur) | |
.ease(ease) | |
.delay(del) | |
.attr("x", function(d) { return scale.x(xWeib(d));}); | |
s.kmLine.transition() | |
.duration(dur) | |
.ease(ease) | |
.delay(del) | |
.attr("d", line) | |
.on("end", drawRegLine); | |
} | |
// Draw straight regression Line | |
function drawRegLine() { | |
var line = d3.line() | |
.x(function(d) { return scale.x(d.x)}) | |
.y(function(d) { return scale.y(d.y)}) | |
.curve(d3.curveBasis) | |
s.regLine = s.chart.selectAll(".regLine") | |
.data([data.regLine]) | |
.enter() | |
.append("path") | |
.attr("d", line) | |
.style("stroke","#00aedb") | |
.style("stroke-width",1.5) | |
.style("fill","none") | |
.each(function(d) { | |
var tl = this.getTotalLength(); | |
var l = d3.select(this) | |
l.attr("stroke-dasharray", tl + " " + tl) | |
.attr("stroke-dashoffset", tl) | |
.transition() | |
.duration(dur) | |
.delay(del) | |
.attr("stroke-dashoffset", 0) | |
.on("end", function() { | |
l.attr("stroke-dasharray","0 0"); | |
normalSpace(); | |
}) | |
}) | |
} | |
// Transform Spacing | |
function normalSpace() { | |
scale.x.domain(d3.extent(data.gridLines.x)); | |
scale.y.domain(d3.extent(data.gridLines.y)); | |
var line = d3.line() | |
.x(function(d) { return scale.x(d.x)}) | |
.y(function(d) { return scale.y(d.y)}) | |
.curve(d3.curveStepAfter); | |
var regLine = d3.line() | |
.x(function(d) { return scale.x(xUnweib(d.x))}) | |
.y(function(d) { return scale.y(yUnweib(d.y))}) | |
.curve(d3.curveBasis); | |
s.gridLines.y.transition() | |
.duration(dur) | |
.ease(ease) | |
.delay(del) | |
.attr("y1", function(d) { return scale.y(d)}) | |
.attr("y2", function(d) { return scale.y(d)}); | |
s.gridLines.x.transition() | |
.duration(dur) | |
.ease(ease) | |
.delay(del) | |
.attr("x1", function(d) { return scale.x(d)}) | |
.attr("x2", function(d) { return scale.x(d)}); | |
s.gridLabels.y.transition() | |
.duration(dur) | |
.ease(ease) | |
.delay(del) | |
.attr("y", function(d) { return scale.y(d);}); | |
s.gridLabels.x.transition() | |
.duration(dur) | |
.ease(ease) | |
.delay(del) | |
.attr("x", function(d) { return scale.x(d);}); | |
s.kmLine.transition() | |
.duration(dur) | |
.ease(ease) | |
.delay(del) | |
.attr("d", line); | |
s.regLine.transition() | |
.duration(dur) | |
.ease(ease) | |
.delay(del) | |
.attr("d", regLine) | |
.on("end", reset) | |
} | |
// Reset the chart and start again | |
function reset() { | |
s.kmLine.transition() | |
.duration(dur) | |
.ease(ease) | |
.delay(del) | |
.style("opacity",0) | |
.transition() | |
.duration(dur) | |
.ease(ease) | |
.remove(); | |
s.regLine.transition() | |
.duration(dur) | |
.ease(ease) | |
.delay(del) | |
.style("opacity",0) | |
.transition() | |
.duration(dur) | |
.ease(ease) | |
.remove() | |
.on("end", drawKM) | |
} | |
function xWeib(x) { | |
return Math.log(x); | |
} | |
function yWeib(y) { | |
return Math.log(Math.log(1/(1 - y))); | |
} | |
function xUnweib(x) { | |
return Math.pow(Math.E,x); | |
} | |
function yUnweib(y) { | |
return 1 -1/Math.pow(Math.E,Math.pow(Math.E,y)); | |
} | |
function lsReg(X,Y) { | |
var meanX = d3.mean(X), | |
meanY = d3.mean(Y); | |
var ssXX = d3.sum(X.map(function(d) { return Math.pow(d - meanX, 2); })), | |
ssYY = d3.sum(Y.map(function(d) { return Math.pow(d - meanY, 2); })); | |
var ssXY = d3.sum(X.map(function(d, i) { return (d - meanX) * (Y[i] - meanY);})) | |
var slope = ssXY / ssXX; | |
var intercept = meanY - (meanX * slope); | |
return [slope, intercept]; | |
} | |
} | |
</script> | |
<div id="chart"></div> | |
<script> | |
WeibullPlot({elementId:"chart"}); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment