JSFiddle - React, Tailwind, and code Playground

by kentaromiura

HTML

<div id=container>
        
</div>

CSS

#container{
    position: relative;
    width: 620px;
    height: 720px;
    outline:3px #ececec dashed;
    padding:0 10px;
}

#container div {
    margin:0 -10px;
}

JavaScript

function DateEvent(details, index){
    this.start = details.start
    this.end = details.end
    this.index = index
    this.maxCollisions = 0
}
DateEvent.prototype.notifyCollisions = function(collisions){
    this.maxCollisions = Math.max(this.maxCollisions, collisions)
}
DateEvent.prototype.collides = function(min, max){    
    var result = false
    //it can collide at the end.
    if (this.end < max && this.end > min) result = true
    //it can collide at the beginning.
    if (this.start < max && this.start > min) result = true
    //it can collide right in the middle.
    return result;
}
DateEvent.prototype.lasercast = function(inputs){
    // this will use a raycast-like approach, only that raycast stop on first obstacole, while this have to 'go through' everything, hence the name lasercast, also lasers are cool.
    var collisions = 0, notifyLater = []
        
    for (var i = this.index +1, max = inputs.length; i<max; i++){
        var next = inputs[i]
        if (next.collides(this.start, this.end)){
            notifyLater.push(next) //can be optimized with indexOf
            console.log(i, 'collides with me, ', this.index)
            collisions ++;
        }
    }
    var toNotify
    while( toNotify = notifyLater.pop() ){
        toNotify.notifyCollisions(collisions)
    }
    this.notifyCollisions(collisions)
    
}

var input = [ {start: 30, end: 150}, {start: 540, end: 600}, {start: 560, end: 620}, {start: 610, end: 670} ];

    var res = input.map(function(details, index){ // copy so it doesn't modify the input.
        return new DateEvent(details, index)
    }).sort(function(a, b){ return a.start >= b.start });


var container = document.getElementById('container');

res.forEach(function(de, i){
    de.lasercast(res)
    var div = document.createElement('div')
    div.innerHTML = i;
    div.style.position = 'absolute'
    div.style.backgroundColor = 'rgba(12,12,12,0.3)'
    div.style.width = 100 / (de.maxCollisions + 1) + '%'
   ...