(click to highlight) A visualization looking at multivariate dataset grouped by Drug Schedule. Chose radar charts hoping to see some similar shapes within drug classification. Whether a fault of the viz chosen or the classification itself, no consistent shape appears in drug classes. And while the source is questionable, experimenting with different ways of displaying multivariate data was worthwhile. Data from: https://www.thelancet.com/journals/lancet/article/PIIS0140-6736(07)60464-4/fulltext
Last active
September 28, 2019 15:26
-
-
Save timchu90/d199b6615d609fb864634721ae0557bb to your computer and use it in GitHub Desktop.
Drug Harm Radars
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
height:800 |
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
Drug Acute Chronic Intravenous Pleasure Psychological Physical Intoxication Social harm Health-care Schedule | |
Heroin 2.8 2.5 3 3 3 3 1.6 3 3 1 | |
Cocaine 2 2 3 3 2.8 1.3 1.8 2.5 2.3 2 | |
Barbiturates 2.3 1.9 2.5 2 2.2 1.8 2.4 1.9 1.7 3 | |
Tobacco 0.9 2.9 0 2.3 2.6 1.8 0.8 1.1 2.4 0 | |
Alcohol 1.9 2.4 0 2.3 1.9 1.6 2.2 2.4 2.1 0 | |
Street methadone 2.5 1.7 1.4 1.8 2.3 2.3 1.6 1.9 2 2 | |
Ketamine 2.1 1.7 2.1 1.9 1.7 1 2 1.5 1.5 3 | |
Amphetamine 1.3 1.8 2.4 2 1.9 1.1 1.4 1.5 1.6 2 | |
Benzodiazepines 1.5 1.7 1.8 1.7 2.1 1.8 2 1.5 1.5 4 | |
4-MTA 2.2 2.1 0 1 1.7 0.8 1.2 1 1 1 | |
Buprenorphine 1.2 1.3 2.3 2 1.5 1.5 1.6 1.5 1.4 3 | |
Cannabis 0.9 2.1 0 1.9 1.7 0.8 1.7 1.3 1.5 1 | |
Solvents 2.1 1.7 0 1.7 1.2 0.1 1.9 1.5 1.2 0 | |
Ecstasy 1.6 1.6 0 1.5 1.2 0.7 1.2 1 1.1 1 | |
Methylphenidate 1.2 1.3 1.6 1.4 1.3 1 1.1 0.8 1.1 2 | |
GHB 1.4 1.2 0 1.4 1.1 1.1 1.4 1.3 1.2 1 | |
LSD 1.7 1.4 0.3 2.2 1.1 0.3 1.6 1.3 1.1 1 | |
Anabolic steroids 0.8 2 1.7 1.1 0.8 0.8 1.3 0.8 1.3 3 | |
Khat 0.3 1.2 0 1.6 1.2 0.3 0.7 1.1 0.8 1 | |
Alkyl nitrites 1.6 0.9 0.3 1.6 0.7 0.3 0.8 0.7 1.4 0 |
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> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<style> | |
#chart { | |
position: fixed; | |
left: 0px; | |
right: 0px; | |
top: 0px; | |
bottom: 0px; | |
z-index: -2; | |
height: 100%; | |
} | |
body { | |
font-family: sans-serif | |
} | |
div.tooltip { | |
position: absolute; | |
text-align: left; | |
padding: 2px; | |
border: 0px; | |
border-radius: 2px; | |
pointer-events: none; | |
background: white; | |
} | |
.drugLabel { | |
paint-order: stroke; | |
stroke-linecap: butt; | |
stroke-linejoin: miter; | |
} | |
.Acute { | |
fill: #fdb462; | |
} | |
.Chronic { | |
fill: #ffffb3; | |
font-size:0px; | |
} | |
.Intravenous { | |
fill: #fb8072; | |
font-size:0px; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="chart"> | |
</div> | |
<script> | |
var chartDiv = document.getElementById("chart"); | |
var width = chartDiv.clientWidth - 20; | |
var height = chartDiv.clientHeight - 20; | |
var xscale = d3.scaleLinear().range([0,width]).domain([0,30]) | |
var y = d3.scaleLinear().range([0,height]).domain([0,21.5]) | |
var scale = d3.scaleLinear().range([0,height]).domain([0,1000]) | |
var div = d3.select("body").append("div") | |
.attr("class", "tooltip") | |
.attr("font-size",scale(60)) | |
.style("opacity", 0); | |
var svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height) | |
var harms = ['Acute','Chronic','Intravenous','Pleasure','Psychological','Physical','Intoxication','Social harm','Health-care'] | |
var harmsAlign = ['start','start','start','middle','middle','middle','end','end','end'] | |
var harmsColor = ['#7570b3','#7570b3','#7570b3','#d95f02','#d95f02','#d95f02','#1b9e77','#1b9e77','#1b9e77'] | |
var colors1 = ['#b10026','#e31a1c','#fc4e2a','#fd8d3c','#feb24c','#fed976','#ffffb2'] | |
var colors2 = ['#6e016b','#88419d','#8c6bb1','#8c96c6'] | |
var colors3 = ['#005a32','#238443','#41ab5d','#78c679','#addd8e'] | |
var colors0 = ['#0c2c84','#225ea8','#1d91c0','#41b6c4','#7fcdbb','#c7e9b4'] | |
var textAlignScale = d3.scaleOrdinal() | |
.domain(harms) | |
.range(harmsAlign) | |
var textColorScale = d3.scaleOrdinal() | |
.domain(harms) | |
.range(harmsColor) | |
var angleScale = d3.scaleBand() | |
.domain(harms) | |
.range([-70 * Math.PI/180, 290 * Math.PI/180]) | |
var lineRadial = d3.lineRadial() | |
.angle(function(d){return angleScale(d.harm) +(Math.PI /2)}) | |
.radius(function(d){return xscale(d.value)}) | |
.curve(d3.curveCardinalClosed.tension(1)) | |
var drawLegendMarker = function(distance,x,y,legend ){ | |
for (var i = 0; i < harms.length-1; i++){ | |
legend.append('line') | |
.attr('x1',x) | |
.attr('y1',y) | |
.attr('x2', x + (xscale(3.2) * Math.cos(angleScale(harms[i])))) | |
.attr('y2', y + (xscale(3.2) * Math.sin(angleScale(harms[i])))) | |
.attr('stroke','black') | |
.attr('stroke-width',scale(0.5)) | |
.attr('opacity','0.5') | |
legend.append('line') | |
.attr('x1', x + (xscale(distance) * Math.cos(angleScale(harms[i])))) | |
.attr('y1', y + (xscale(distance) * Math.sin(angleScale(harms[i])))) | |
.attr('x2', x + (xscale(distance) * Math.cos(angleScale(harms[i+1])))) | |
.attr('y2', y + (xscale(distance) * Math.sin(angleScale(harms[i+1])))) | |
.attr('stroke','black') | |
.attr('stroke-width',scale(0.5)) | |
.attr('opacity','0.5') | |
} | |
legend.append('line') | |
.attr('x1',x) | |
.attr('y1',y) | |
.attr('x2', x + (xscale(3.2) * Math.cos(angleScale(harms[harms.length-1])))) | |
.attr('y2', y + (xscale(3.2) * Math.sin(angleScale(harms[harms.length-1])))) | |
.attr('stroke','black') | |
.attr('stroke-width',scale(0.5)) | |
.attr('opacity','0.5') | |
legend.append('line') | |
.attr('x1', x + (xscale(distance) * Math.cos(angleScale(harms[0])))) | |
.attr('y1', y + (xscale(distance) * Math.sin(angleScale(harms[0])))) | |
.attr('x2', x + (xscale(distance) * Math.cos(angleScale(harms[harms.length-1])))) | |
.attr('y2', y + (xscale(distance) * Math.sin(angleScale(harms[harms.length-1])))) | |
.attr('stroke','black') | |
.attr('stroke-width',scale(1)) | |
.attr('stroke-width',scale(0.5)) | |
.attr('opacity','0.5') | |
} | |
//start drawing actual data | |
d3.tsv('drugHarm.txt', function(error,data){ | |
if (error) throw error; | |
//console.log(data) | |
data1 = data.filter(function(drug){return drug.Schedule == 1}) | |
data2 = data.filter(function(drug){return drug.Schedule == 2}) | |
data3 = data.filter(function(drug){return drug.Schedule == 3}) | |
data0 = data.filter(function(drug){return drug.Schedule == 0}) | |
var drawRadials = function(data, colors, x, y, classname, title){ | |
//console.log(data) | |
for (var i in data){ | |
data[i].data = [] | |
for (var harm in harms){ | |
data[i].data.push({'harm':harms[harm], 'value': data[i][harms[harm]]}) | |
} | |
} | |
//draw radial fills | |
var circle = svg.selectAll('.circle') | |
.data(data).enter() | |
.append('g') | |
.attr('class', classname) | |
.attr('transform','translate(' + x + ',' + y + ')') | |
var fill = circle.append('path') | |
.attr('fill',function(d,i){return colors[i]}) | |
.attr('d',function(d){return lineRadial(d.data)}) | |
.attr('opacity','0.55') | |
.on('click',function(d,i){ | |
d3.selectAll('#highlight') | |
.remove() | |
div.html(d.Drug) | |
div.style("left", x +scale(20)+ d3.mouse(this)[0] + 'px') | |
div.style("top",y + scale(20) + d3.mouse(this)[1] + 'px') | |
div.style('opacity','0.8') | |
svg.append('path') | |
.attr('transform','translate(' + x + ',' + y + ')') | |
.attr('fill',colors[i]) | |
.attr('d',lineRadial(d.data)) | |
.attr('id','highlight') | |
.attr('stroke','black') | |
.attr('stroke-width',scale(0)) | |
.attr('opacity','0.55') | |
.on('mousemove',function(){ | |
div.style("left", x +scale(20)+ d3.mouse(this)[0] + 'px') | |
div.style("top",y + scale(20) + d3.mouse(this)[1] + 'px') | |
div.style('opacity','0.8') | |
}) | |
.on('mouseout',function(){ | |
div.style('opacity','0') | |
}) | |
.transition() | |
.duration(200) | |
.attr('stroke-width',scale(3)) | |
.attr('opacity','0.8') | |
}) | |
//draw legend | |
var legend = svg.append('g') | |
.attr('class','legend') | |
for (harm in harms){ | |
legend.append('text') | |
.text(harms[harm]) | |
.attr('x', x + (xscale(3.5) * Math.cos(angleScale(harms[harm])))) | |
.attr('y', y + (xscale(3.5) * Math.sin(angleScale(harms[harm])))) | |
.attr('text-anchor', textAlignScale(harms[harm])) | |
.attr('font-size',scale(15)) | |
.attr('fill',textColorScale(harms[harm])) | |
} | |
//labels | |
legend.append('text') | |
.text('Physical Harm') | |
.attr('x', x + (xscale(5) * Math.cos(angleScale('Chronic')))) | |
.attr('y', y + (xscale(5) * Math.sin(angleScale('Chronic')))) | |
.attr('text-anchor', 'start') | |
.attr('font-size',scale(18)) | |
.attr('font-weight','bold') | |
.attr('fill','#7570b3') | |
legend.append('text') | |
.text('Societial Cost') | |
.attr('x', x + (xscale(5) * Math.cos(angleScale('Social harm')))) | |
.attr('y', y + (xscale(5) * Math.sin(angleScale('Social harm')))) | |
.attr('text-anchor', 'end') | |
.attr('font-size',scale(18)) | |
.attr('font-weight','bold') | |
.attr('fill','#1b9e77') | |
legend.append('text') | |
.text('Dependence') | |
.attr('x', x ) | |
.attr('y', y + xscale(4.5)) | |
.attr('text-anchor', 'middle') | |
.attr('font-size',scale(18)) | |
.attr('font-weight','bold') | |
.attr('fill','#d95f02') | |
legend.append('text') | |
.text(title) | |
.attr('x', x ) | |
.attr('y', y - xscale(4)) | |
.attr('text-anchor', 'middle') | |
.attr('font-size',scale(20)) | |
.attr('font-weight','bold') | |
.attr('fill','black') | |
drawLegendMarker(3,x,y,legend) | |
drawLegendMarker(2,x,y,legend) | |
drawLegendMarker(1,x,y,legend) | |
} | |
var background = svg.append('rect') | |
.attr("width", width) | |
.attr("height", height) | |
.attr('fill','white') | |
.on('click',function(d){ | |
d3.selectAll('#highlight') | |
.remove() | |
}) | |
drawRadials(data1,colors1, width/4, height/4, "sched1",'SCHEDULE I') | |
drawRadials(data2,colors2, 3*width/4, height/4, "sched2",'SCHEDULE II') | |
drawRadials(data3,colors3, width/4, 3*height/4, "sched3",'SCHEDULE III') | |
drawRadials(data0,colors0, 3*width/4, 3*height/4, "sched0",'LEGAL') | |
}) | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment