Skip to content

Instantly share code, notes, and snippets.

@mforando
Created April 18, 2019 14:47
Show Gist options
  • Save mforando/b63615044ca0fc61258588afeeb41ea3 to your computer and use it in GitHub Desktop.
Save mforando/b63615044ca0fc61258588afeeb41ea3 to your computer and use it in GitHub Desktop.
Variation in Nursing Time by DRG
license: mit
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://cdn.jsdelivr.net/jstat/latest/jstat.min.js"></script>
<style>
body { margin:15px;position:fixed;top:0;right:0;bottom:0;left:0; }
.waffle {
display: flex;
flex-wrap: wrap;
width: 120px;
}
.block {
width: 10px;
height: 10px;
margin: 1px;
}
</style>
</head>
<br>
<div>
Source: <a href="https://link.springer.com/article/10.1186/1472-6955-12-26">
https://link.springer.com/article/10.1186/1472-6955-12-26
</a>
</div>
<br>
<br>
<div id="bellcurve">
</div>
<body>
<script>
var distdata = [{"DRG":"760_1","Desc":"OTHER MENTAL DISORDERS","Mean":63.48,"SD":78.47,"Number of patients":64}
,{"DRG":"144_1","Desc":"RESPIRATORY SYSTEM SIGNS. SYMPTOMS & OTHER DIAGNOSES","Mean":165.2,"SD":181.75,"Number of patients":52}
,{"DRG":"058_2","Desc":"OTHER DISORDERS OF NERVOUS SYSTEM","Mean":93.85,"SD":92.75,"Number of patients":148}
,{"DRG":"058_1","Desc":"OTHER DISORDERS OF NERVOUS SYSTEM","Mean":39.23,"SD":35.9,"Number of patients":176}
,{"DRG":"053_2","Desc":"SEIZURE","Mean":230.66,"SD":207.78,"Number of patients":31}
,{"DRG":"566_1","Desc":"OTHER ANTEPARTUM DIAGNOSES","Mean":243.02,"SD":201.5,"Number of patients":57}
,{"DRG":"173_2","Desc":"OTHER VASCULAR PROCEDURES","Mean":276.51,"SD":228.65,"Number of patients":43}
,{"DRG":"342_1","Desc":"FRACTURE OR DISLOCATION EXCEPT FEMUR & PELVIS","Mean":243.67,"SD":201.17,"Number of patients":42}
,{"DRG":"190_2","Desc":"CIRCULATORY DISORDERS W AMI","Mean":451.02,"SD":372.33,"Number of patients":33}
,{"DRG":"463_1","Desc":"KIDNEY & URINARY TRACT INFECTIONS","Mean":371.22,"SD":294.31,"Number of patients":57}
]
function toTitleCase(str) {
return str.replace(
/\w\S*/g,
function(txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
}
);
}
var margin = {top: 30, right: 10, bottom: 10, left: 10},
width = 250 - margin.left - margin.right,
height = 80 - margin.top - margin.bottom;
var x = d3.scaleLinear().rangeRound([0, width]);
var y = d3.scaleLinear()
var svg = d3.select("#bellcurve").selectAll(".densSVGs").data(distdata)
svg.enter()
.append("svg")
.style("display","block")
.style("overflow","visible")
.attr("class","densSVGs")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
var gX = d3.selectAll(".densSVGs").append("g")
.attr("class", "xaxis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
// .selectAll(".tick")
// .remove();
var line = d3.line()
.x(function (d) { return x(d.q); })
.y(function (d) { return y(d.p); });
d3.selectAll(".densSVGs").each(function(d){
var array = []
for (var i = d.Mean - 4 * d.SD; i < d.Mean + 4 * d.SD; i += 1) {
q = i
p = jStat.normal.pdf(i, d.Mean, d.SD);
arr = {
"q": q,
"p": p
}
array.push(arr);
};
var min_d = d3.min(array, function (d) {return d.q;});
var max_d = d3.max(array, function (d) {return d.q;});
var max_p = d3.max(array, function (d) {return d.p;});
x.domain([-0, 900]);
y.range([height, 0]).domain([0, max_p]);
d3.select(this).select(".xaxis").transition().call(d3.axisBottom(x))
d3.select(this).append("clipPath")
.attr("id", "rect-clip")
.append("rect")
.attr("class", "rect")
.attr("x",150)
.attr("y",0)
.attr("width",width)
.attr("height",height)
.style("fill", "#FE4A49")
//no clip path
d3.select(this).append("path")
.datum(array)
.attr("class", "line")
.attr("d", line)
.style("fill", "rgb(204, 204, 204)")
//no clip path
d3.select(this).append("path")
.datum(array)
.attr("class", "line")
.attr("d", line)
.style("fill", "#FE4A49")
// .attr("clip-path","url(#rect-clip)")
d3.select(this).append("text")
.attr("id", "cutofftxt")
.attr("x", x(d.Mean))
.attr("dx",5)
.attr("y", -10)
.style("font-size","12px")
.style("fill","black")
.text(d.Mean + " minutes")
d3.select(this).append("text")
.attr("id", "dgtxt")
.attr("x", width)
.attr("dx",25)
.attr("y", -10)
.style("font-size","12px")
.style("fill","black")
.text("DRG " + d.DRG)
d3.select(this).append("text")
.attr("id", "dgtxt")
.attr("x", width)
.attr("dx",25)
.attr("y", 10)
.style("font-size","12px")
.style("fill","black")
.text( toTitleCase(d.Desc))
d3.select(this).append("line")
.attr("id", "cutoffline")
.attr("x1", x(d.Mean))
.attr("x2", x(d.Mean))
.attr("y1", -20)
.attr("y2", height)
.style("stroke", "#600000")
d3.selectAll(this).append("text")
.attr("id", "cutofflbl")
.attr("dx",5)
.attr("x", 150)
.attr("y", -10)
.style("font-family","Franklin Gothic Book")
.style("font-size","11px")
.style("fill", "#600000")
.text("This Plan")
})
//bell curve
var Z_MAX = 6;
function poz(z) {
var y, x, w;
if (z == 0.0) {
x = 0.0;
} else {
y = 0.5 * Math.abs(z);
if (y > (Z_MAX * 0.5)) {
x = 1.0;
} else if (y < 1.0) {
w = y * y;
x = ((((((((0.000124818987 * w
- 0.001075204047) * w + 0.005198775019) * w
- 0.019198292004) * w + 0.059054035642) * w
- 0.151968751364) * w + 0.319152932694) * w
- 0.531923007300) * w + 0.797884560593) * y * 2.0;
} else {
y -= 2.0;
x = (((((((((((((-0.000045255659 * y
+ 0.000152529290) * y - 0.000019538132) * y
- 0.000676904986) * y + 0.001390604284) * y
- 0.000794620820) * y - 0.002034254874) * y
+ 0.006549791214) * y - 0.010557625006) * y
+ 0.011630447319) * y - 0.009279453341) * y
+ 0.005353579108) * y - 0.002141268741) * y
+ 0.000535310849) * y + 0.999936657524;
}
}
return z > 0.0 ? ((x + 1.0) * 0.5) : ((1.0 - x) * 0.5);
}
/* CRITZ -- Compute critical normal z value to
produce given p. We just do a bisection
search for a value within CHI_EPSILON,
relying on the monotonicity of pochisq(). */
function critz(p) {
var Z_EPSILON = 0.000001; /* Accuracy of z approximation */
var minz = -Z_MAX;
var maxz = Z_MAX;
var zval = 0.0;
var pval;
if( p < 0.0 ) p = 0.0;
if( p > 1.0 ) p = 1.0;
while ((maxz - minz) > Z_EPSILON) {
pval = poz(zval);
if (pval > p) {
maxz = zval;
} else {
minz = zval;
}
zval = (maxz + minz) * 0.5;
}
return(zval);
}
function updateBell(pcnt){
var cutoff_Zscore = critz(pcnt/100);
var cutoff_val = cutoff_Zscore*stddev + mean;
d3.select("#rect-clip").select("rect")
.attr("x",x(cutoff_val))
.attr("y",0)
.style("fill", "#FE4A49")
d3.select("#cutoffline")
.attr("x1",x(cutoff_val))
.attr("x2",x(cutoff_val))
d3.select("#cutofflbl")
.attr("x",x(cutoff_val))
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment