Clustering Algolrythme 2

Clustering repeat to reduce number of clusters

by Ben Clayton

HTML

<script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
<button class='but1'>Cluster</button>
<div class="pp dd nd">2</div>
<div class="pp dd nd">1</div>
<div class="pp dd nd">5</div>
<div class="pp dd nd">1</div>
<div class="pp dd nd">1</div>
<div class="pp dd nd">4</div>
<div class="pp dd nd">3</div>
<div class="pp dd nd">1</div>

CSS

.pp {
        border: 2px solid #aaaaaa;
        border-radius:50%;
        text-align:center;
        position:absolute;
        z-index:2;
    }  
.dd { cursor:pointer; }

.nd { 
        background-color:#C0C0C0;
    }


.pp { width: 18px; height: 18px;  }
.cc { 
        border: 2px solid #ff0000;
        background-color:#FFEEDD;
        z-index:1;
    }

JavaScript

$(function() {
    $(".dd").draggable({ zIndex: 100 });
    $(".pp").each(function(idx){
        $(this).css({
            top:(500*Math.random()+30)+'px',
            left:(500*Math.random()+30)+'px'
        })
    });
      
    $( ".but1" ).on( "click", function( event, ui ) {
        $(".cc").removeClass('cc').addClass('nd cc-old');
        if ($(".nd").length<2){
            $(".nd").removeClass('nd dd ui-draggable').addClass('cc');
            return;
        }
        //debugger;
        while ($(".nd").length > 1) {
            var $st = $(".nd").first().removeClass('nd');
            var d=null;
            var $nr=null;
            $(".nd").each(function(idx){
                var d2=distance($st,$(this));
                if(!d || (d2<d)){
                    d=d2;
                    $nr=$(this);
                }
            });
            $nr.removeClass('nd');
            var $nc = $("<div class='pp cc'></div>");
            $('body').append($nc);
            move_cl($nc,mid_point($st,$nr));
        }
        $(".nd").removeClass('nd dd ui-draggable').addClass('cc');
        $(".cc-old").remove();
    });
  });

function move_cl($cl,pt){
   $cl.css({top:pt.top+'px',left:pt.left+'px'}).html(pt.size);   
} 

function mid_point($pt1,$pt2){
    var v1 = parseInt($pt1.text(),10);
    var v2 = parseInt($pt2.text(),10);
    var vt = v1+v2;
    var p1 = $pt1.position();
    var p2 = $pt2.position();
    var pm ={};
    pm.top = (v1/vt*p1.top)+(v2/vt*p2.top);
    pm.left = (v1/vt*p1.left)+(v2/vt*p2.left);
    pm.size = vt;
    return pm;
} 
    
function distance($pt1,$pt2){
    var p1 = $pt1.position();
    var p2 = $pt2.position();
    var dt = p1.top-p2.top;
    var dl = p1.left-p2.left;
    var d = Math.sqrt( (dt*dt) + (dl*dl) );
    return d;
}