Edit in JSFiddle

REPULTION_RANGE = 10;
var kill = false;

var paper = Raphael("diagram");

var circles = [];
circles.push(paper.circle(130, 150, 0, 0));
circles.push(paper.circle(145, 129, 0, 0));
circles.push(paper.circle(120, 122, 0, 0));
circles.push(paper.circle(120, 120, 0, 0));
circles.push(paper.circle(100, 140, 0, 0));
circles.push(paper.circle(105, 100, 0, 0));
circles.push(paper.circle(109, 109, 0, 0));

circles[0].animate({r: 20}, 1000, "ease-in-out");
circles[1].animate({r: 12}, 1000, "ease-in-out");
circles[2].animate({r: 19}, 1000, "ease-in-out");
circles[3].animate({r: 10}, 1000, "ease-in-out");
circles[4].animate({r: 22}, 1000, "ease-in-out");
circles[5].animate({r: 22}, 1000, "ease-in-out");
circles[6].animate({r: 30}, 1000, "ease-in-out", function() {
    kill = true;
});

function spread() {

	// For each circle...
	for ( var a = 0; a < circles.length; a++) {
		// Check the proximity to other circles
		for ( var b = 0; b < circles.length; b++) {
		
			if (a == b) continue;
			
			var	dx = circles[a].attr("cx") - circles[b].attr("cx"),
				dy = circles[a].attr("cy") - circles[b].attr("cy"),
				radiusA = circles[a].attr("r"),
				radiusB = circles[b].attr("r");
			
			// Use pythagorus theorum to work out how close the balls are
			var proximity = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)) - radiusA - radiusB;
			
			// If the balls are too close...
			if (proximity < REPULTION_RANGE) {
                // ... work out the new dx and dy
                var theta = Math.atan(dx / dy);
                var targetProximity = radiusA + radiusB + REPULTION_RANGE;
                
                // There are two dx and dy combinations for each arctan - ensure we are working with the correct one 
                var xPolarity = (dx == 0) ? 1 : dx / Math.abs(dx),
                    yPolarity = (dy == 0) ? 1 : dy / Math.abs(dy);
                
                var dx2 = Math.abs(targetProximity * Math.sin(theta)) * xPolarity,
                    dy2 = Math.abs(targetProximity * Math.cos(theta)) * yPolarity;

                // ... and the change in dx, dy                
                var ddx = dx2 - dx,
                    ddy = dy2 - dy;
                
                // See which mall has the most inertia
                var totalSize = Math.pow(radiusA, 2) + Math.pow(radiusB, 2); // proportional to Pi
                var inertia = {
                    a: (totalSize == 0) ? 0.5 : Math.pow(radiusB, 2) / totalSize,
                    b: (totalSize == 0) ? 0.5 : Math.pow(radiusA, 2) / totalSize
                };
                
                // ... finally, move the balls
                circles[a].attr({
                    cx: circles[a].attr("cx") + (ddx * inertia.a),
                    cy: circles[a].attr("cy") + (ddy * inertia.a)
                });
                circles[b].attr({
                    cx: circles[b].attr("cx") - (ddx * inertia.b),
                    cy: circles[b].attr("cy") - (ddy * inertia.b)
                });
			}
		}
	}
	
    if (!kill) {
	    setTimeout(spread, 50);
    }
}

spread();