Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
<html>
<head>
<style type="text/css">
body {
font: 10px sans-serif;
}
.ball{
fill: steelblue;
opacity: 1;
box-shadow: -5px -5px 5px #888;
-webkit-box-shadow: -5px -5px 5px #888;
stroke: #fff;
opacity: 1;
}
.ball.mean{
fill: #ff6d00;
fill: #ffb958;
}
.bar text {
fill: #fff;
}
.axis path, .axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.triangle{
stroke-linejoin: round;
stroke: black;
fill: black;
stroke-width: 4;
}
.ball-group .btn-close .btn-bg{
fill: black;
opacity: 1;
}
.ball-group .btn-close text{
fill: white;
}
.ball-group .btn-close{
opacity: 0;
transition: all 0.1s;
}
.ball-group:hover .btn-close{
opacity: 1;
cursor: pointer;
}
.ball-group:active .btn-close{
display: none;
opacity: 0;
}
.ball-group:active .btn-close:active{
display: block;
opacity: 1;
}
</style>
</head>
<body>
<button id="add-ball"> add ball </button>
<button id="remove-all"> remove all but one </button>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script type="application/javascript">
var w = 800
, margin = { left : 10, right : 10 }
, h = 100
, svg = d3.select('body').append('svg')
.append('g')
.attr('transform'
, 'translate(' + margin.left + ',' + margin.right + ')')
, x = d3.scale.linear().domain([0, 100]).range([0, w])
, y = d3.scale.linear().domain([10, 0]).range([0, h])
, r = 20
, data = d3.range(0, 4).map(function(d){ return { x : 20 + d * 20, y: 2} })
, drag = d3.behavior.drag()
.on('drag', dragmove)
.on('dragend', dragend)
, circles = svg.selectAll('.ball-group')
, meanball = svg.append('circle')
.attr('class', 'ball mean')
.attr('r', r * 2)
.attr('cx', function(d){ return x(100) })
.attr('cy', function(d){ return y(2) })
function setupCircles(){
d3.selectAll('.ball-group').remove()
var d = circles.data(data)
d.exit().remove()
var g = d.enter()
.append('g')
.attr('class', 'ball-group')
.attr('transform', function(d){
return 'translate(' + x(d.x) + ',' + y(d.y) + ')'
})
.call(drag)
g.append('circle')
.attr('class', 'ball')
.attr('r', r)
var btn = g.append('g')
.attr('class', 'btn-close')
.attr('transform', 'translate(15,-15)')
var bg = btn.append('circle')
.attr('class', 'btn-bg')
.attr('r', '10')
btn.append('text')
.text('x')
.attr('font-size', '2em')
.attr('font-family', 'helvetica')
.attr('x', -5)
.attr('y', 5)
btn.on('click', function(d){
if(data.length <= 1) return
data.splice(data.indexOf(d),1)
setupCircles()
updateMean()
})
}
setupCircles()
function dragmove(d){
d.x += x.invert(d3.event.dx)
if(d.x > x.invert(w)) d.x = x.invert(w)
if(d.x < x.invert(0)) d.x = x.invert(0)
d3.select(this)
.attr('transform', function(d){
return 'translate(' + x(d.x) + ',' + y(d.y) + ')'
})
updateMean()
}
function dragend(d){
d.x = Math.round(d.x)
d3.select(this)
.attr('cx', x(d.x))
updateMean()
}
var axis = d3.svg.axis().scale(x).orient("bottom")
svg.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + h + ')')
.call(axis)
function updateMean(){
var set = data.map( function(d){ return d.x } )
meanball.attr('cx', Math.round( x( d3.mean( set ) ) ) )
}
updateMean()
document.getElementById('add-ball').onclick = function(){
data.push({ x : Math.random() * x.invert(w), y : 2})
setupCircles()
updateMean()
}
document.getElementById('remove-all').onclick = function(){
data = [{ x : 50 , y : 2 }]
setupCircles()
updateMean()
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment