Balance of power arcs
Made with blockup.
const data = [
{ party: 'dem', seats: 25 },
{ party: 'ind', seats: 25 },
{ party: 'none', seats: 25 },
{ party: 'gop', seats: 25 },
]
const width = 100
const height = width/2
const svg = d3.select('svg')
.attr('viewBox', `0 0 ${width} ${height}`)
.append('g')
.attr('transform', `translate(${width/2}, ${height})`)
const updateElement = (selector, value) =>
document.querySelector(selector).textContent = value
const drawData = () => {
const dem = +document.querySelector('input.dem').value
const ind = +document.querySelector('input.ind').value
const gop = +document.querySelector('input.gop').value
updateElement('span.dem', dem)
updateElement('span.ind', ind)
updateElement('span.gop', gop)
const totalSeats = 435
const none = totalSeats - (dem + ind + gop)
const data = [
{ party: 'dem', seats: dem },
{ party: 'ind', seats: ind },
{ party: 'none', seats: none },
{ party: 'gop', seats: gop },
]
const pie = d3.pie()
.value(d => d.seats)
.startAngle(-Math.PI/2)
.endAngle(Math.PI/2)
.sort(null)
(data)
const arc = d3.arc()
.outerRadius(width/2)
.innerRadius(width/4)
svg.selectAll('*').remove()
svg.selectAll('path')
.data(pie)
.enter().append('path')
.attr('d', arc)
.attr('class', d => d.data.party)
}
d3.selectAll('input').on('input', d => drawData())
drawData()
<!DOCTYPE html>
<title>Balance of power arcs</title>
<link href='dist.css' rel='stylesheet' />
<body>
<div class='container'>
<div class='controls'>
<div class='control'>
<div class='left'>
<span class='dem label'>100</span>
</div>
<div class='right'>
<input class='dem' type='range' min='0' max='435' value='100' />
</div>
</div>
<div class='control'>
<div class='left'>
<span class='ind label'>100</span>
</div>
<div class='right'>
<input class='ind' type='range' min='0' max='435' value='100' />
</div>
</div>
<div class='control'>
<div class='left'>
<span class='gop label'>100</span>
</div>
<div class='right'>
<input class='gop' type='range' min='0' max='435' value='100' />
</div>
</div>
</div>
<svg></svg>
</div>
<script src='https://d3js.org/d3.v4.min.js'></script>
<script src='dist.js'></script>
</body>
body{font-family:sans-serif}.container{padding:0;position:relative;width:100%;width:500px;overflow:hidden;margin:0 auto}.controls{position:absolute;bottom:0;z-index:1;width:40%;left:30%}.controls .control{width:100%;overflow:hidden}.controls .control .left{float:left;width:15%;text-align:right}.controls .control .right{float:left;width:84%}svg{display:block;position:relative}svg path{fill:none;stroke:#000;stroke-width:.1px}svg path.dem{fill:#9dae97}svg path.ind{fill:#918b62}svg path.none{fill:#f7e4bd}svg path.gop{fill:#ecb08f}span.label{font-weight:700;padding-right:.25em}input{width:100%}
var data=[{party:"dem",seats:25},{party:"ind",seats:25},{party:"none",seats:25},{party:"gop",seats:25}],width=100,height=width/2,svg=d3.select("svg").attr("viewBox","0 0 "+width+" "+height).append("g").attr("transform","translate("+width/2+", "+height+")"),updateElement=function(t,e){return document.querySelector(t).textContent=e},drawData=function(){var t=+document.querySelector("input.dem").value,e=+document.querySelector("input.ind").value,a=+document.querySelector("input.gop").value;updateElement("span.dem",t),updateElement("span.ind",e),updateElement("span.gop",a);var n=435,r=n-(t+e+a),d=[{party:"dem",seats:t},{party:"ind",seats:e},{party:"none",seats:r},{party:"gop",seats:a}],s=d3.pie().value(function(t){return t.seats}).startAngle(-Math.PI/2).endAngle(Math.PI/2).sort(null)(d),u=d3.arc().outerRadius(width/2).innerRadius(width/4);svg.selectAll("*").remove(),svg.selectAll("path").data(s).enter().append("path").attr("d",u).attr("class",function(t){return t.data.party})};d3.selectAll("input").on("input",function(t){return drawData()}),drawData();
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNjcmlwdC5qcyJdLCJuYW1lcyI6WyJjb25zdCIsImRhdGEiLCJwYXJ0eSIsInNlYXRzIiwid2lkdGgiLCJoZWlnaHQiLCJzdmciLCJkMyIsInNlbGVjdCIsImF0dHIiLCJhcHBlbmQiLCJ1cGRhdGVFbGVtZW50Iiwic2VsZWN0b3IiLCJ2YWx1ZSIsImRvY3VtZW50IiwicXVlcnlTZWxlY3RvciIsInRleHRDb250ZW50IiwiZHJhd0RhdGEiLCJkZW0iLCJpbmQiLCJnb3AiLCJ0b3RhbFNlYXRzIiwibm9uZSIsInBpZSIsImQiLCJzdGFydEFuZ2xlIiwiTWF0aCIsIlBJIiwiZW5kQW5nbGUiLCJzb3J0IiwiYXJjIiwib3V0ZXJSYWRpdXMiLCJpbm5lclJhZGl1cyIsInNlbGVjdEFsbCIsInJlbW92ZSIsImVudGVyIiwib24iXSwibWFwcGluZ3MiOiJBQUFBQSxHQUFNQyxRQUNIQyxNQUFPLE1BQU9DLE1BQU8sS0FDckJELE1BQU8sTUFBT0MsTUFBTyxLQUNyQkQsTUFBTyxPQUFRQyxNQUFPLEtBQ3RCRCxNQUFPLE1BQU9DLE1BQU8sS0FHbEJDLE1BQVEsSUFDUkMsT0FBU0QsTUFBTyxFQUVoQkUsSUFBUUMsR0FBQ0MsT0FBTyxPQUNuQkMsS0FBSyxVQUFXLE9BQUtMLE1BQUUsSUFBS0MsUUFDN0JLLE9BQU8sS0FDTkQsS0FBSyxZQUFhLGFBQVdMLE1BQUUsRUFBQSxLQUFPQyxPQUFBLEtBRW5DTSxjQUFnQixTQUFBQyxFQUFDQyxHQUFVLE1BQ2hDQyxVQUFTQyxjQUFjSCxHQUFVSSxZQUFjSCxHQUUxQ0ksU0FBVyxXQUdoQmpCLEdBQU1rQixJQUFPSixTQUFTQyxjQUFjLGFBQWFGLE1BQzNDTSxHQUFPTCxTQUFTQyxjQUFjLGFBQWFGLE1BQ2pETyxHQUFhTixTQUFDQyxjQUFnQixhQUFBRixLQUM5QkYsZUFBYyxXQUFZTyxHQUMxQlAsY0FBYyxXQUFZUSxHQUMxQm5CLGNBQWdCLFdBQU1vQixFQUF0QnBCLElBQU1xQixHQUFhLElBRWJDLEVBQU9ELEdBQWNILEVBQU1DLEVBQU1DLEdBR3BDbkIsSUFDQUMsTUFBTyxNQUFPQyxNQUFPZSxJQUNyQmhCLE1BQU8sTUFBTUMsTUFBT2dCLElBQ3BCakIsTUFBTyxPQUFPQyxNQUFPbUIsSUFDdkJwQixNQUFBLE1BQUFDLE1BQUFpQixJQUdDRyxFQUFNaEIsR0FBQWdCLE1BQ05WLE1BQUEsU0FBQVcsR0FBQSxNQUFXQSxHQUFDckIsUUFDWnNCLFlBQVNDLEtBQVFDLEdBQUUsR0FDbkJDLFNBQVNGLEtBQUNDLEdBQUEsR0FDVkUsS0FBSyxNQUFMNUIsR0FHQTZCLEVBQUF2QixHQUFZdUIsTUFDWkMsWUFBWTNCLE1BQU0sR0FBbEI0QixZQUFZNUIsTUFBTSxFQUVwQkUsS0FBSTJCLFVBQVUsS0FBS0MsU0FFbkI1QixJQUNHMkIsVUFBUyxRQUNWaEMsS0FBS3NCLEdBQUxZLFFBQ016QixPQUFTLFFBQ2RELEtBQUssSUFBQXFCLEdBQUxyQixLQUFLLFFBQVMsU0FBQWUsR0FBRSxNQUFHQSxHQUFFdkIsS0FBS0MsUUFLOUJLLElBQUEwQixVQUFVLFNBQUFHLEdBQUEsUUFBQSxTQUFBWixHQUFBLE1BQUFQLGNBQVZBIiwiZmlsZSI6InNjcmlwdC5qcyIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IGRhdGEgPSBbXG5cdHsgcGFydHk6ICdkZW0nLCBzZWF0czogMjUgfSxcblx0eyBwYXJ0eTogJ2luZCcsIHNlYXRzOiAyNSB9LFxuXHR7IHBhcnR5OiAnbm9uZScsIHNlYXRzOiAyNSB9LFxuXHR7IHBhcnR5OiAnZ29wJywgc2VhdHM6IDI1IH0sXG5dXG5cbmNvbnN0IHdpZHRoID0gMTAwXG5jb25zdCBoZWlnaHQgPSB3aWR0aC8yXG5cbmNvbnN0IHN2ZyA9IGQzLnNlbGVjdCgnc3ZnJylcblx0XHQuYXR0cigndmlld0JveCcsIGAwIDAgJHt3aWR0aH0gJHtoZWlnaHR9YClcblx0LmFwcGVuZCgnZycpXG5cdFx0LmF0dHIoJ3RyYW5zZm9ybScsIGB0cmFuc2xhdGUoJHt3aWR0aC8yfSwgJHtoZWlnaHR9KWApXG5cbmNvbnN0IHVwZGF0ZUVsZW1lbnQgPSAoc2VsZWN0b3IsIHZhbHVlKSA9PlxuXHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKS50ZXh0Q29udGVudCA9IHZhbHVlXG5cbmNvbnN0IGRyYXdEYXRhID0gKCkgPT4ge1xuXG5cdGNvbnN0IGRlbSA9ICtkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdpbnB1dC5kZW0nKS52YWx1ZVxuXHRjb25zdCBpbmQgPSArZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaW5wdXQuaW5kJykudmFsdWVcblx0Y29uc3QgZ29wID0gK2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0LmdvcCcpLnZhbHVlXG5cdHVwZGF0ZUVsZW1lbnQoJ3NwYW4uZGVtJywgZGVtKVxuXHR1cGRhdGVFbGVtZW50KCdzcGFuLmluZCcsIGluZClcblx0dXBkYXRlRWxlbWVudCgnc3Bhbi5nb3AnLCBnb3ApXG5cdGNvbnN0IHRvdGFsU2VhdHMgPSA0MzVcblxuXHRjb25zdCBub25lID0gdG90YWxTZWF0cyAtIChkZW0gKyBpbmQgKyBnb3ApXG5cblx0Y29uc3QgZGF0YSA9IFtcblx0XHR7IHBhcnR5OiAnZGVtJywgc2VhdHM6IGRlbSB9LFxuXHRcdHsgcGFydHk6ICdpbmQnLCBzZWF0czogaW5kIH0sXG5cdFx0eyBwYXJ0eTogJ25vbmUnLCBzZWF0czogbm9uZSB9LFxuXHRcdHsgcGFydHk6ICdnb3AnLCBzZWF0czogZ29wIH0sXG5cdF1cblxuXHRjb25zdCBwaWUgPSBkMy5waWUoKVxuXHRcdC52YWx1ZShkID0+IGQuc2VhdHMpXG5cdFx0LnN0YXJ0QW5nbGUoLU1hdGguUEkvMilcblx0XHQuZW5kQW5nbGUoTWF0aC5QSS8yKVxuXHRcdC5zb3J0KG51bGwpXG5cdFx0KGRhdGEpXG5cblx0Y29uc3QgYXJjID0gZDMuYXJjKClcblx0XHQub3V0ZXJSYWRpdXMod2lkdGgvMilcblx0XHQuaW5uZXJSYWRpdXMod2lkdGgvNClcblxuXHRzdmcuc2VsZWN0QWxsKCcqJykucmVtb3ZlKClcblxuXHRzdmcuc2VsZWN0QWxsKCdwYXRoJylcblx0XHRcdC5kYXRhKHBpZSlcblx0XHQuZW50ZXIoKS5hcHBlbmQoJ3BhdGgnKVxuXHRcdFx0LmF0dHIoJ2QnLCBhcmMpXG5cdFx0XHQuYXR0cignY2xhc3MnLCBkID0+IGQuZGF0YS5wYXJ0eSlcblxufVxuXG5kMy5zZWxlY3RBbGwoJ2lucHV0Jykub24oJ2lucHV0JywgZCA9PiBkcmF3RGF0YSgpKVxuZHJhd0RhdGEoKVxuIl19
$red = #ecb08f
$green = #918b62
$blue = #9dae97
$grey = #f7e4bd
body
font-family sans-serif
.container
padding 0
position relative
width 100%
width 500px
overflow hidden
margin 0 auto
.controls
position absolute
bottom 0
z-index 1
width 40%
left 30%
.control
width 100%
overflow hidden
.left
float left
width 15%
text-align right
.right
float left
width 84%
svg
display block
position relative
path
fill none
stroke black
stroke-width 0.1px
path
&.dem
fill $blue
&.ind
fill $green
&.none
fill $grey
&.gop
fill $red
span.label
font-weight bold
padding-right 0.25em
input
width 100%