Skip to content

Instantly share code, notes, and snippets.

@timchu90
Last active January 7, 2019 19:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timchu90/5b2f0f449a094055d8c47e121feba464 to your computer and use it in GitHub Desktop.
Save timchu90/5b2f0f449a094055d8c47e121feba464 to your computer and use it in GitHub Desktop.
CaterpillarPlot_circle

Caterpillar Plot (circle)

Circular plot showing variants of PTEN

<!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: center;
right: 10%;
bottom: 10%;
width: 20%;
height: 15%;
padding: 2px;
font: 30px sans-serif;
border: 0px;
border-radius: 2px;
pointer-events: none;
}
</style>
</head>
<body>
<div id="chart">
</div>
<script>
var chartDiv = document.getElementById("chart");
var width = chartDiv.clientWidth -20;
var height = chartDiv.clientHeight -20;
var x = d3.scaleLinear().range([0,width]).domain([0,1000])
var y = d3.scaleLinear().range([0,height]).domain([1000,0])
var scale = d3.scaleLinear().range([0,height]).domain([0,1000])
// add the tooltip
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
//center and radius of gene arc
var arc_x = x(500);
var arc_y = y(500);
var arc_r = scale(325);
function calcArc(deg) {
return {
x:arc_x + arc_r * Math.cos(deg * (Math.PI / 180)),
y:arc_y + arc_r * Math.sin(deg * (Math.PI / 180)),
};
}
//circle for testing
/*
svg.append('circle')
.attr('fill','none')
.attr('stroke','black')
.attr('cx',arc_x)
.attr('cy',arc_y)
.attr('r',arc_r)
*/
var pie = d3.pie()
.sort(null)
.value(function(d) { return d.numsample; });
var spine = svg.append('g').attr('class','spine')
var lines = spine.append('g')
//draw donut charts
var calcDonutUp = function(deg,dist){
return {
x: dist * Math.cos(deg * (Math.PI/180)) + calcArc(deg).x ,
y: dist * Math.sin(deg * (Math.PI/180)) + calcArc(deg).y
}
}
var calcDonutDown = function(deg,dist){
return {
x: -1 * dist * Math.cos(deg * (Math.PI/180)) + calcArc(deg).x ,
y: -1 * dist * Math.sin(deg * (Math.PI/180)) + calcArc(deg).y
}
}
var donutGen = function(input, radius, r_out, font, angle, distance, direction, labeldir){
if(direction == 'up'){
var donut = svg.append("g")
.attr("transform", "translate(" + calcDonutUp(angle,distance).x + "," + calcDonutUp(angle,distance).y + ")")
.attr('class','donut')
lines.append('line')
.attr('x1',calcArc(angle).x)
.attr('y1',calcArc(angle).y)
.attr('x2', distance * Math.cos(angle * (Math.PI/180)) + calcArc(angle).x )
.attr('y2', distance * Math.sin(angle * (Math.PI/180)) + calcArc(angle).y )
.attr('stroke','black')
.attr('stroke-width','1.5px')
.attr('opacity',0)
.transition()
.delay(2000)
.duration(500)
.attr('opacity',1)
spine.append('circle')
.attr('cx',distance * Math.cos(angle * (Math.PI/180)) + calcArc(angle).x)
.attr('cy',distance * Math.sin(angle * (Math.PI/180)) + calcArc(angle).y)
.attr('r', radius)
.attr('stroke','none')
.attr('fill','green')
.attr('opacity',0)
.transition()
.delay(1800)
.duration(500)
.attr('opacity',1)
} else {
var donut = svg.append("g")
.attr("transform", "translate(" + calcDonutDown(angle,distance).x + "," + calcDonutDown(angle,distance).y + ")")
.attr('class','donut')
lines.append('line')
.attr('x1',calcArc(angle).x)
.attr('y1',calcArc(angle).y)
.attr('x2', -1 * distance * Math.cos(angle * (Math.PI/180)) + calcArc(angle).x )
.attr('y2', -1 * distance * Math.sin(angle * (Math.PI/180)) + calcArc(angle).y )
.attr('stroke','black')
.attr('stroke-width','1.5px')
.attr('opacity',0)
.transition()
.delay(2000)
.duration(500)
.attr('opacity',1)
spine.append('circle')
.attr('cx', -1 * distance * Math.cos(angle * (Math.PI/180)) + calcArc(angle).x)
.attr('cy', -1 * distance * Math.sin(angle * (Math.PI/180)) + calcArc(angle).y)
.attr('r', radius)
.attr('stroke','none')
.attr('fill','green')
.attr('opacity',0)
.transition()
.delay(1800)
.duration(500)
.attr('opacity',1)
}
//mutation label
if(labeldir == 'right'){
donut.append('text')
.attr('class','mutlabel')
.text(input)
.attr('dx', (radius + 1))
.attr('dy', font/3 )
.attr('font-size', font)
.attr('opacity',0)
.transition()
.delay(1800)
.duration(500)
.attr('opacity',1)
} else {
donut.append('text')
.attr('class','mutlabel')
.text(input)
.style("text-anchor", "end")
.attr('dx', (radius + 1) * -1)
.attr('dy', font/3)
.attr('font-size', font)
.attr('opacity',0)
.transition()
.delay(1800)
.duration(500)
.attr('opacity',1)
}
}
//init parameters of arc and gene
var startAngle = 5
var endAngle = 355
var geneLength = 403
//use pie function to specify the gene arc
var backbone_pie = d3.pie()
.sort(null)
.startAngle(startAngle * (Math.PI / 180))
.endAngle(endAngle * (Math.PI / 180))
.value(function(d) { return d.length; });
//function to calculate amino acid positions in relation to arc
var getAminoAngle = function(angle){
return (angle /geneLength * (endAngle - startAngle)) + startAngle - 90
}
//draw donuts
donutGen('Y68H', scale(15), scale(0), scale(35), getAminoAngle(68), scale(80) , 'up', 'right')
donutGen('N69Y', scale(15), scale(2), scale(35), getAminoAngle(69), scale(80), 'down', 'left')
donutGen('F90S', scale(15), scale(2), scale(35), getAminoAngle(90), scale(80), 'up', 'right')
donutGen('H93Y', scale(15), scale(2), scale(35), getAminoAngle(93), scale(80), 'down', 'left')
donutGen('D107Y', scale(15), scale(2), scale(35), getAminoAngle(107), scale(80), 'up', 'right')
donutGen('R130*', scale(15), scale(2), scale(35), getAminoAngle(130), scale(80), 'up', 'right')
donutGen('G132D', scale(15), scale(2), scale(35), getAminoAngle(132), scale(80), 'down', 'left')
donutGen('K147*', scale(15), scale(2), scale(35), getAminoAngle(147), scale(80), 'up', 'right')
donutGen('R173C', scale(15), scale(2), scale(35), getAminoAngle(173), scale(80), 'up', 'right')
donutGen('R233*', scale(15), scale(2), scale(35), getAminoAngle(233), scale(80), 'up', 'left')
donutGen('L247fs*9', scale(15), scale(2), scale(35), getAminoAngle(247), scale(80), 'down', 'right')
donutGen('D252Y', scale(15), scale(2), scale(35), getAminoAngle(252), scale(80), 'up', 'left')
donutGen('N276fs*13', scale(15), scale(2), scale(35), getAminoAngle(276), scale(80), 'up', 'left')
donutGen('L295fs', scale(15), scale(2), scale(35), getAminoAngle(295), scale(80), 'down', 'right')
donutGen('T319fs*1', scale(15), scale(2), scale(35), getAminoAngle(319), scale(80), 'up', 'left')
//draw gene arc
var g = svg.selectAll(".backbone_arc")
.data(backbone_pie([
{length:14, color:'gray', innerRadius: arc_r - scale(5), outerRadius: arc_r + scale(5), cornerRadius: 0, text:''},
{length:171, color:'yellowgreen', innerRadius: arc_r - scale(25), outerRadius: arc_r + scale(25), cornerRadius: 35, text:'Phosphatase'},
{length:5, color:'gray', innerRadius: arc_r - scale(5), outerRadius: arc_r + scale(5), cornerRadius: 0, text:''},
{length:160, color:'firebrick', innerRadius: arc_r - scale(25), outerRadius: arc_r + scale(25), cornerRadius: 35, text:'C2'},
{length:53, color:'gray', innerRadius: arc_r - scale(5), outerRadius: arc_r + scale(5), cornerRadius: 0, text:''}
]))
.enter().append("g")
.attr("class", "gene_arc")
.attr('transform','translate(' + arc_x + ',' + arc_y + ')')
g.append("path")
.attr('id',function(d){return d.data.text})
.style('fill',function(d){
return d.data.color
})
.transition()
.duration(500)
.delay(function(d, i) {
return i * 500;
})
.attrTween('d', function(d) {
var arc = d3.arc()
.innerRadius(d.data.innerRadius)
.outerRadius(d.data.outerRadius)
.cornerRadius(d.data.cornerRadius)
var i = d3.interpolate(d.startAngle+0.1, d.endAngle);
return function(t) {
d.endAngle = i(t);
return arc(d);
}
})
g.append('text')
.attr('dy',scale(35))
.attr('dx',scale(0))
.style('font-size',scale(35))
.style('fill','white')
.append('textPath')
.transition()
.delay(2500)
.attr('xlink:href', function(d){return '#'+d.data.text})
.style('text-anchor','middle')
.attr('startOffset','25%')
.text(function(d){return d.data.text})
svg.append('text')
.attr('x',x(50))
.attr('y',y(900))
.style('font-size',scale(60))
.style('fill','black')
.text('PTEN')
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment