Skip to content

Instantly share code, notes, and snippets.

@mforando
Last active October 11, 2019 13:04
Show Gist options
  • Save mforando/df696ec8a280df26ce12931312e09291 to your computer and use it in GitHub Desktop.
Save mforando/df696ec8a280df26ce12931312e09291 to your computer and use it in GitHub Desktop.
PSI90 Visual
license: mit
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
#cont{
position:relative;
margin:55px;
}
svg{
position:absolute;
top:0px;
}
#cont div{
text-align:center;
}
</style>
</head>
<div id="cont">
<svg></svg>
</div>
<body>
<script>
var measuredata = [{"MeasureID":"PSI-13","MeasureName":"Blood stream infection after surgery","Category":"CompWgt9","Weight":0.247}
,{"MeasureID":"PSI-13","MeasureName":"Blood stream infection after surgery","Category":"CompWgt9 Difference","Weight":0.753}
,{"MeasureID":"PSI-11","MeasureName":"Postoperative Respiratory Failure Rate","Category":"CompWgt9","Weight":0.212}
,{"MeasureID":"PSI-11","MeasureName":"Postoperative Respiratory Failure Rate","Category":"CompWgt9 Difference","Weight":0.788}
,{"MeasureID":"PSI-12","MeasureName":"Serious blood clots after surgery","Category":"CompWgt9","Weight":0.185}
,{"MeasureID":"PSI-12","MeasureName":"Serious blood clots after surgery","Category":"CompWgt9 Difference","Weight":0.815}
,{"MeasureID":"PSI-3","MeasureName":"Pressure sores","Category":"CompWgt9","Weight":0.134}
,{"MeasureID":"PSI-3","MeasureName":"Pressure sores","Category":"CompWgt9 Difference","Weight":0.866}
,{"MeasureID":"PSI-10","MeasureName":"Postoperative Acute Kidney Injury Requiring Dialysis Rate","Category":"CompWgt9","Weight":0.078}
,{"MeasureID":"PSI-10","MeasureName":"Postoperative Acute Kidney Injury Requiring Dialysis Rate","Category":"CompWgt9 Difference","Weight":0.922}
,{"MeasureID":"PSI-9","MeasureName":"Perioperative Hemorrhage or Hematoma Rate","Category":"CompWgt9","Weight":0.042}
,{"MeasureID":"PSI-9","MeasureName":"Perioperative Hemorrhage or Hematoma Rate","Category":"CompWgt9 Difference","Weight":0.958}
,{"MeasureID":"PSI-6","MeasureName":"Collapsed lung due to medical treatment","Category":"CompWgt9","Weight":0.041}
,{"MeasureID":"PSI-6","MeasureName":"Collapsed lung due to medical treatment","Category":"CompWgt9 Difference","Weight":0.959}
,{"MeasureID":"PSI-15","MeasureName":"Accidental cuts and tears from medical treatment","Category":"CompWgt9","Weight":0.037}
,{"MeasureID":"PSI-15","MeasureName":"Accidental cuts and tears from medical treatment","Category":"CompWgt9 Difference","Weight":0.963}
,{"MeasureID":"PSI-8","MeasureName":"Broken hip from a fall after surgery","Category":"CompWgt9","Weight":0.015}
,{"MeasureID":"PSI-8","MeasureName":"Broken hip from a fall after surgery","Category":"CompWgt9 Difference","Weight":0.985}
,{"MeasureID":"PSI-14","MeasureName":"A wound that splits open after surgery on the abdomen or pelvis","Category":"CompWgt9","Weight":0.009}
,{"MeasureID":"PSI-14","MeasureName":"A wound that splits open after surgery on the abdomen or pelvis","Category":"CompWgt9 Difference","Weight":0.991}
];
var measurenest = d3.nest()
.key(function(d){return d.MeasureID})
.entries(measuredata)
var scaleRadial = d3.scaleBand()
.range([0,Math.PI*2])
.domain(measurenest.map(d=>{return d.key}))
var width = 800;
var pad = 100;
var radius = width/2 - pad*2;
// Feel free to change or delete any of the code you see in this editor!
var svg = d3.select("#cont").select("svg")
.attr("width", width)
.attr("height", width)
.append("g")
.attr("transform","translate(" + width/2 + "," + width/2 + ")")
svg.append("circle")
.attr("r", radius*.6)
.attr("fill", "gray")
.attr("stroke", "black")
.style("stroke-width","3px")
svg.append("circle")
.attr("r", radius)
.attr("fill", "none")
.attr("stroke-width","5px")
.attr("stroke", "rgba(131,101,0,.2)")
svg.append("text")
.text("PSI-90")
.attr("fill", "black")
.attr("dy","-10px")
.style("font-family","Franklin Gothic Medium")
.style("font-size","40px")
.style("text-anchor","middle")
.style("stroke-width","3px")
svg.append("text")
.text("Composite")
.attr("dy","30px")
.attr("fill", "black")
.style("font-family","Franklin Gothic Medium")
.style("font-size","40px")
.style("text-anchor","middle")
.style("stroke-width","3px")
svg.append("text")
.text("(CMS Version 9.0)")
.attr("dy","50px")
.attr("fill", "black")
.style("font-family","Franklin Gothic Medium")
.style("font-size","14px")
.style("text-anchor","middle")
.style("stroke-width","3px")
var measure_g = svg.selectAll(".measure_g").data(measurenest)
measure_g.enter()
.append("g")
.attr("class","measure_g")
.attr("transform",(d)=>{return "translate(" + Math.cos(scaleRadial(d.key))*radius + "," + Math.sin(scaleRadial(d.key))*radius + ")"})
var arcGenerator = d3.arc()
.innerRadius(0)
.outerRadius(25)
.padAngle(0)
.padRadius(0)
.cornerRadius(0);
var pieslice = d3.selectAll(".measure_g").selectAll(".pieslices")
.data(function(d){
//prep pie data.
var piedata = d3.pie().value(function(d){return d.Weight})(d.values)
return piedata;
})
pieslice.enter()
.append("path")
.attr("fill",(d)=>{
if(d.data.Category == "CompWgt9"){
return "black";
}
return "rgb(220,220,220)"
})
.style("stroke","black")
.attr("d",arcGenerator)
.text('foo')
var pielabels = d3.selectAll(".measure_g").selectAll(".pielabels")
.data(function(d){
//prep pie data.
var piedata = d3.pie().value(function(d){return d.Weight})(d.values)
return [piedata[0]];
})
pielabels.enter()
.append("text")
.style("text-anchor","middle")
.attr("dy",13)
.style("font-size","12px")
.style("font-family","Franklin Gothic Book")
.attr("class","pielabels")
.attr("fill","black")
.text((d)=>{return d3.format('0.1f')(d.data.Weight*100) + "%"})
var labeldivs = svg.selectAll(".labeldivs").data(measurenest)
labeldivs.enter()
.append("foreignObject")
.attr("class","labeldivs")
.style('overflow','visible')
.attr("xmlns","http://www.w3.org/1999/xhtml")
.attr("x",(d)=>{
if(['PSI-15','PSI-8','PSI-14','PSI-6'].indexOf(d.key)>=0){
return Math.cos(scaleRadial(d.key))*radius*1.5
}
return Math.cos(scaleRadial(d.key))*radius*1.6
})
.attr("y",(d)=>{
if(['PSI-15','PSI-8','PSI-14','PSI-6'].indexOf(d.key)>=0){
return Math.sin(scaleRadial(d.key))*radius*1.45
}
return Math.sin(scaleRadial(d.key))*radius*1.3
})
// .style("transform","translateX(-50%)")
.style("width","145px")
.style("display","inline-block")
// .style("position","absolute")
.html((d)=>{
return '<div style="transform:translate(-50%,-50%);text-align:left;font:13px Franklin Gothic Book" position="relative" display="block">' + '<span style="font:16px Franklin Gothic Medium" position="relative" display="block">' + d.key + '</span> ' + d.values[0].MeasureName + '</div>'
})
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment