Skip to content

Instantly share code, notes, and snippets.

@widged
Last active April 15, 2021 16:26
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save widged/5780720 to your computer and use it in GitHub Desktop.
Save widged/5780720 to your computer and use it in GitHub Desktop.
Rapid implementation of a ternary plot with d3js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>D3 Ternary Plot</title>
<style>
line.axis {
stroke-width: 2;
stroke: #363636;
}
line.tick {
stroke-width: 1;
stroke: #c3c3c3;
}
line.tick-a, text.tick-a {
stroke: #c30000;
}
line.tick-b, text.tick-b {
stroke: #0000c3;
}
line.tick-c, text.tick-c {
stroke: #008000;
}
text.tick-text {
font-family: "sans-serif";
font-size: 10px;
fill: #000000;
}
circle {
fill: green;
}
</style>
</head>
<div id="plot">
</div>
<script charset="UTF-8" src="http://cdnjs.cloudflare.com/ajax/libs/d3/3.1.6/d3.min.js"></script>
<script>
(function() {
var svg = d3.select('#plot').append('svg')
.attr("width", 400)
.attr("height", 400);
var w = 300;
var h = 260;
var m = 20;
var corners = [[m,h+m], [w+m,h+m], [(w/2)+m,m]]
corners.forEach(function(corner, idx) {
var c1 = idx, c2 = idx + 1; if(c2 >= corners.length) { c2 = 0;}
svg.append("line")
.attr("x1", corners[c1][0])
.attr("y1", corners[c1][1])
.attr("x2", corners[c2][0])
.attr("y2", corners[c2][1])
.classed('axis', true);
})
var ticks = [0,20,40,60,80,100], n = ticks.length;
ticks.forEach(function(v) {
var coord1 = coord(v, 0, 100-v);
var coord2 = coord(v, 100-v, 0);
var coord3 = coord(0, 100-v, v);
var coord4 = coord(100-v, 0, v);
if(v !== 0 && v !== 100) {
svg.append("line")
.attr("x1", coord1[0])
.attr("y1", coord1[1])
.attr("x2", coord2[0])
.attr("y2", coord2[1])
.classed('tick tick-a', true);
svg.append("line")
.attr("x1", coord2[0])
.attr("y1", coord2[1])
.attr("x2", coord3[0])
.attr("y2", coord3[1])
.classed('tick tick-b', true);
svg.append("line")
.attr("x1", coord3[0])
.attr("y1", coord3[1])
.attr("x2", coord4[0])
.attr("y2", coord4[1])
.classed('tick tick-c', true);
}
svg.append("text")
.attr("x", coord1[0] - 15)
.attr("y", coord1[1] )
.text( function (d) { return v; })
.classed('tick-text tick-a', true);
svg.append("text")
.attr("x", coord2[0] - 6)
.attr("y", coord2[1] + 10 )
.text( function (d) { return (100- v); })
.classed('tick-text tick-b', true);
svg.append("text")
.attr("x", coord3[0] + 6)
.attr("y", coord3[1] )
.text( function (d) { return v; })
.classed('tick-text tick-c', true);
})
var circles = svg.selectAll("circle").data([coord(10, 20, 70), coord(20, 30, 50), coord(40, 20, 40), coord(20, 80, 0)]);
circles.enter().append("circle")
.attr("cx", function (d) { return d[0]; })
.attr("cy", function (d) { return d[1]; })
.attr("r", 6);
function coord(a, b, c){
var sum, pos = [0,0];
sum = a + b + c;
if(sum !== 0) {
a /= sum;
b /= sum;
c /= sum;
pos[0] = corners[0][0] * a + corners[1][0] * b + corners[2][0] * c;
pos[1] = corners[0][1] * a + corners[1][1] * b + corners[2][1] * c;
}
return pos;
}
function scale(/* point */ p, factor) {
return [p[0] * factor, p[1] * factor];
}
})()
</script>
</body>
</html>
@tomgp
Copy link

tomgp commented May 3, 2014

Hi, Thanks for posting this. After forking and fiddling with your code to understand it I wrote a new version, you may be interested ... http://bl.ocks.org/tomgp/7766353

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment