D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
TommyCoin80
Full window
Github gist
D3.Unconf Badge
Built with
blockbuilder.org
<!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>
https://d3js.org/d3.v4.min.js