js/highcharts-master/samples/highcharts/studies/distribution-algorithm/demo.js
/**
 * General distribution algorithm for distributing labels of differing size along a
 * confined length in two dimensions.
 */
General distribution algorithm for distributing labels of differing size along a
confined length in two dimensions.
General distribution algorithm for distributing labels of differing size along a confined length in two dimensions .
function distribute(boxes, len) {
    var i,
        overlapping = true,
        origBoxes,
        total = 0;
    function joinBoxes(box) {
        var target = (Math.min.apply(0, box.targets) + Math.max.apply(0, box.targets)) / 2;
        box.pos = Math.min(Math.max(0, target - box.size / 2), len - box.size);
    }
    i = boxes.length;
    while (i--) {
        total += boxes[i].size;
    }
    if (total > len) {
        boxes.sort(function (a, b) {
            return (b.rank || 0) - (a.rank || 0);
        });
        i = 0;
        total = 0;
        while (total <= len) {
            total += boxes[i].size;
            i++;
        }
        boxes = boxes.slice(0, i - 1);
    }
    boxes.sort(function (a, b) {
        return a.target - b.target;
    });
    origBoxes = boxes;
    boxes = map(boxes.slice(0), function (box) {
        return {
            size: box.size,
            targets: [box.target]
        };
    });
    while (overlapping) {
        each(boxes, joinBoxes);
        i = boxes.length;
        overlapping = false;
        while (i--) {
            if (i > 0 && boxes[i - 1].pos + boxes[i - 1].size > boxes[i].pos) { 
                boxes[i - 1].size += boxes[i].size; 
                boxes[i - 1].targets = boxes[i - 1].targets.concat(boxes[i].targets);
                ping right, push left
                if (boxes[i - 1].pos + boxes[i - 1].size > len) {
                    boxes[i - 1].pos = len - boxes[i - 1].size;
                }
                boxes.splice(i, 1); 
                overlapping = true;
            }
        }
    }
    i = 0;
    each(boxes, function (box) {
        var posInCompositeBox = 0;
        each(box.targets, function () {
            origBoxes[i].pos = box.pos + posInCompositeBox;
            posInCompositeBox += origBoxes[i].size;
            i++;
        });
    });
}
function distribute ( boxes , len ) { var i , overlapping = true , origBoxes , total = 0 ; function joinBoxes ( box ) { var target = ( Math . min . apply ( 0 , box . targets ) + Math . max . apply ( 0 , box . targets ) ) / 2 ; box . pos = Math . min ( Math . max ( 0 , target - box . size / 2 ) , len - box . size ) ; } i = boxes . length ; while ( i -- ) { total += boxes [ i ] . size ; } if ( total > len ) { boxes . sort ( function ( a , b ) { return ( b . rank || 0 ) - ( a . rank || 0 ) ; } ) ; i = 0 ; total = 0 ; while ( total <= len ) { total += boxes [ i ] . size ; i ++ ; } boxes = boxes . slice ( 0 , i - 1 ) ; } boxes . sort ( function ( a , b ) { return a . target - b . target ; } ) ; origBoxes = boxes ; boxes = map ( boxes . slice ( 0 ) , function ( box ) { return { size : box . size , targets : [ box . target ] } ; } ) ; while ( overlapping ) { each ( boxes , joinBoxes ) ; i = boxes . length ; overlapping = false ; while ( i -- ) { if ( i > 0 && boxes [ i - 1 ] . pos + boxes [ i - 1 ] . size > boxes [ i ] . pos ) { boxes [ i - 1 ] . size += boxes [ i ] . size ; boxes [ i - 1 ] . targets = boxes [ i - 1 ] . targets . concat ( boxes [ i ] . targets ) ; if ( boxes [ i - 1 ] . pos + boxes [ i - 1 ] . size > len ) { boxes [ i - 1 ] . pos = len - boxes [ i - 1 ] . size ; } boxes . splice ( i , 1 ) ; overlapping = true ; } } } i = 0 ; each ( boxes , function ( box ) { var posInCompositeBox = 0 ; each ( box . targets , function ( ) { origBoxes [ i ] . pos = box . pos + posInCompositeBox ; posInCompositeBox += origBoxes [ i ] . size ; i ++ ; } ) ; } ) ; }
General distribution algorithm for distributing labels of differing size along a
 confined length in two dimensions.
General distribution algorithm for distributing labels of differing size along a confined length in two dimensions .
/**
     * Create a composite box, average of targets
     */ // If the total size exceeds the len, remove those boxes with the lowest rank // Sort by rank, then slice away overshoot // Order // Create a copy with target arrays // Initial positions: target centered in box // Detect overlap and join boxes // Overlap // Add this size to the previous box // Overlapping right, push left // Remove this item // Now the composite boxes are placed, we just need to put the original boxes within them