block by fil 79b9f17979c4070dee3cbba1c5283502

geoVoronoi circumcircles

Full Screen

Skeletal demo for d3.geoVoronoi

by Philippe Rivière.

index.html

<!DOCTYPE html>
<meta charset="utf-8">
<style> 0
    #sphere {
        fill: #ccc;
        stroke: #444;
        stroke-width: 2;
    }
    .triangles {
        stroke: none; /* we do their stroke with .links, allowing Urquhart variant */
    }
    
    .links {
        stroke: white;
        stroke-width: 2; 
        fill: none;
    }

    .links .secondary {
        stroke-width: .5;
        stroke-dasharray: 3 1;
    }
    
    .sites {
        stroke: black;
        fill: white;
    }
    
    .circum {
        stroke: white;
        stroke-width: 2;
        fill: rgba(255,255,255,0.5);
      pointer-events: none;
    }
    .circum.ray {
        stroke-dasharray: 1 1;
        fill: none;
    }
    
</style>
<svg width="960" height="600"></svg>

<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://unpkg.com/d3-delaunay@5"></script>
<script src="https://unpkg.com/d3-geo-voronoi@1.5"></script>

<script>

var points = {
    type: "FeatureCollection",
    features: d3.range(100).map(function() {
        return {
            type: "Point",
            coordinates: [ 360 * Math.random(), 90 * (Math.random() - Math.random()) ]
        }
    })
}

var v = d3.geoVoronoi()(points);

var projection = d3.geoEqualEarth(),
    path = d3.geoPath().projection(projection);


var svg = d3.select("svg");

svg.append('path')
    .attr('id', 'sphere')
    .datum({ type: "Sphere" })
    .attr('d', path);

svg.append('g')
    .attr('class', 'triangles')
    .selectAll('path')
    .data(v.triangles().features)
    .enter()
    .append('path')
    .attr('d', path)
    .attr('fill', function() { return d3.hsl(Math.random()*360, .8, .65); })
//    .attr('fill', 'rgba(255,255,255,0.01)');
    ;

svg.append('g')
    .attr('class', 'links')
    .selectAll('path')
    .data(v.links().features)
    .enter()
    .append('path')
    .classed('secondary', function(d) {
        return !d.properties.urquhart;
    })
    .attr('d', path);

svg.selectAll('.triangles path')
    .on('mouseover', function(d){
  console.warn({d})
        var radius = 180 / Math.PI * d3.geoLength({
                type: "LineString",
                coordinates: [ d.properties.circumcenter, d.geometry.coordinates[0][0] ]
            });
        var circle = d3.geoCircle()
            .center(d.properties.circumcenter);
        svg.append('path')
            .attr('class', 'circum circle')
            .datum(circle.radius(radius)())
            .attr('d', path);
        svg.selectAll('.ray')
            .data(d.geometry.coordinates[0].slice(0,3).map(function(vertex) {
                return {
                    type: "LineString",
                    coordinates: [d.properties.circumcenter, vertex]
                };
            }))
            .enter()
            .append('path')
            .attr('class', 'circum ray')
            .attr('d', path);
    })
    .on('mouseout', function(d){
        svg.selectAll('.circum')
            .remove();
    })


svg.append('g')
    .attr('class', 'sites')
    .selectAll('path')
    .data(points.features)
    .enter()
    .append('path')
    .attr('d', path);

// gentle animation
if (false) d3.interval(function(elapsed) {
    projection.rotate([ elapsed / 150, 0 ]);
    svg.selectAll('path')
        .attr('d', path);
}, 50);

</script>