var css = ` .graph { stroke: #f40024; stroke-opacity: 1; stroke-width: 2; } .polygons { fill: none; stroke: #dbdbdb; stroke-width: 1; } .sites { fill: #000; stroke: #fff; } `; var d3 = require('d3') , jsdom = require('jsdom') , run = (main) => { jsdom.env({ html: ``, done: function(err, window) { // pre-renders the dataviz inside the jsdom window document = window.document; main (d3.select(document.querySelector('body'))); // then exports the result to the notebook $$.html(d3.select('html').node().innerHTML); } }); }; function show_urquart(sel) { var svg = sel .append('svg') .attr('width', width) .attr('height', height); var sites = d3.range(nsites) .map(function(d) { return [Math.random() * width, Math.random() * height]; }) .map(function(d,i) { d.index = i; return d; }); var voronoi = d3.voronoi(); var polygon = svg.append("g") .attr("class", "polygons") .selectAll("path") .data(voronoi.polygons(sites)) .enter().append("path") .call(drawPolygon); var graph = svg.append('g') .attr('class', 'graph'); var site = svg.append('g') .attr('class', 'site') .selectAll('circle') .data(sites) .enter() .append('circle') .attr('r',2) .attr('fill','white') .attr('stroke','black') .call(drawSite) ; var diagram = voronoi(sites); diagram.urquhart = function(){ var urquhart = d3.map(); diagram.links() .forEach(function(link) { var v = d3.extent([link.source.index, link.target.index]); urquhart.set(v, link); }); urquhart._remove = []; diagram.triangles() .forEach(function(t) { var l = 0, length = 0, i, v; for (var j=0; j<3; j++) { var a = t[j], b = t[(j+1)%3]; v = d3.extent([a.index, b.index]); length = (a[0]-b[0]) * (a[0]-b[0]) + (a[1]-b[1]) * (a[1]-b[1]); if (length > l) { l = length; i = v; } } urquhart._remove.push(i); }); urquhart._remove.forEach(function(i) { if (urquhart.has(i)) urquhart.remove(i); }); return urquhart.values(); } drawgraph(); function drawgraph(){ var links = diagram.urquhart(); graph .selectAll('line') .data(links) .enter().append('line') .attr('x1', function(l){ return l.source[0];}) .attr('y1', function(l){ return l.source[1];}) .attr('x2', function(l){ return l.target[0];}) .attr('y2', function(l){ return l.target[1];}) } function drawPolygon(polygon) { polygon.attr("d", function(d) { if (d && !d.filter(function(n){ return !n}).length) { return "M" + d.join("L") + "Z"; } }); } function drawSite(site) { site .attr("transform", function(d) { return 'translate(' + d + ')'; }); } } // main var width = 400, height = 250, nsites = 100; run(show_urquart)