UNPKG

fcn-wrtc

Version:

Fully Connected Network over WebRTC connection

233 lines (191 loc) 5.72 kB
'use strict'; localStorage.debug = 'neighborhood-wrtc,fcn-wrtc' const FCN = require('fcn-wrtc').Fcn; const uuid = require('fcn-wrtc').uuid; const id = uuid(); let o = []; const max = 5; let IS = []; for(let i = 0; i < max; ++i) { const options = { webrtc: { trickle: true, iceServers : IS }, room:'fcn-wrtc-example-'+id, signalingAdress: 'https://signaling.herokuapp.com/', verbose:true }; o[i] = new FCN(options); } const connection = (time2wait = 1000) => { for(let j = 1; j < max; ++j) { o[j].connection(o[0]); o[0].connection(o[j]); } }; const neigh = () => { console.log('My id: ', p.getInviewId()); o.forEach(p => console.log(p.getNeighbours())); }; const peers = () => { o.forEach(p => { console.log('My ids: i:', p.getInviewId(), ' o: ', p.getOutviewId()); console.log(p.getPeers()); }); }; const addPeer = () => { const options = { webrtc: { trickle: true, iceServers : IS }, room:'fcn-wrtc-example-'+id, signalingAdress: 'https://signaling.herokuapp.com/', verbose:true }; let fcn = new FCN(options); fcn.connection(o[0]).then(s => { console.log('New peer connected.'); o.push(fcn); // wait two seconds for a proper connection establishment setTimeout(() => { drawRps(); }, 2000); }); } // ====================================================================================================================== // ================================================== GRAPH CONSTRUCTION ================================================ // ====================================================================================================================== const d3 = window.d3; let linkRps, nodeRps, textRps; let svgRps; let colorRps = d3.scale.category20(); let userColorRps = []; const constructRpsGraph = () => { let result = []; let i = 0; o.forEach(over => { userColorRps[over.getOutviewId()+'$'+over.getInviewId()] = { color: colorRps(i), description: ` O-ID:${over.getOutviewId()} #i:${over.getPeers().i.length} | #o:${over.getPeers().o.length} ` }; userColorRps[over.getOutviewId()] = over.getInviewId(); userColorRps[over.getInviewId()] = over.getOutviewId(); i++; }); o.forEach(over => { if(over.getPeers().o.length === 0) { result.push({ source: over.getOutviewId()+'$'+over.getInviewId(), target: over.getOutviewId()+'$'+over.getInviewId(), data: { colorLink: '#FF3737' } }); } over.getPeers().o.forEach(p => { result.push({ source: over.getOutviewId()+'$'+over.getInviewId(), target: userColorRps[p]+'$'+p, data: { colorLink: '#FF3737' } }); }); }); return result; }; const drawRpsGraph = () => { let nodes = {}; let links = constructRpsGraph(); // Compute the distinct nodes from the links. links.forEach(function (link) { link.source = nodes[link.source] || (nodes[link.source] = {name: link.source, data: link.data}); link.target = nodes[link.target] || (nodes[link.target] = {name: link.target, data: link.data}); }); let width = document.getElementById('graphRps').offsetWidth, height = document.getElementById('graphRps').offsetHeight; svgRps = d3.select('#graphRps').append('svg') .attr('width', width) .attr('height', height); let force = d3.layout.force() .nodes(d3.values(nodes)) .links(links) .size([ width, height ]) .linkDistance(300) .charge(-500) .on('tick', tickRps) .start(); // build the arrow. svgRps.append('defs').selectAll('marker') .data( [ 'endRps' ] ) // Different link/path types can be defined here .enter().append('marker') // This section adds in the arrows .attr('id', String).attr('viewBox', '0 -5 10 10').attr('refX', 15) .attr('refY', -1.5).attr('markerWidth', 6).attr('markerHeight', 6) .attr('orient', 'auto').append('path').attr('d', 'M0,-5L10,0L0,5'); linkRps = svgRps.append('g').selectAll('path') .data(force.links()) .enter().append('path') .attr('class', 'link').attr('marker-end', 'url(#endRps)') .style('stroke', function (d) { return d.data.colorLink; }) .style('fill', 'none'); nodeRps = svgRps.append('g').selectAll('circle') .data(force.nodes()) .enter().append('circle') .attr('r', 6) .style('fill', function (d) { return userColorRps[d.name].color; }) .on('mouseover', mouseover) .on('mouseout', mouseout) .call(force.drag); textRps = svgRps.append('g').selectAll('text') .data(force.nodes()) .enter().append('text') .attr('x', 8) .attr('y', '.31em') .text(function (d) { return userColorRps[d.name].description; }); }; const drawRps = () => { if(svgRps) svgRps.remove(); drawRpsGraph(); }; function linkArc (d) { let dx = d.target.x - d.source.x, dy = d.target.y - d.source.y, dr = Math.sqrt(dx * dx + dy * dy) * 4; return 'M' + d.source.x + ',' + d.source.y + 'A' + dr + ',' + dr + ' 0 0,1 ' + d.target.x + ',' + d.target.y; } function transform (d) { return 'translate(' + d.x + ',' + d.y + ')'; } function tickRps () { linkRps.attr('x1', function (d) { return d.source.x; }).attr('y1', function (d) { return d.source.y; }).attr('x2', function (d) { return d.target.x; }).attr('y2', function (d) { return d.target.y; }); linkRps.attr('d', linkArc); nodeRps.attr('transform', transform); textRps.attr('transform', transform); } function mouseoverOverlay () { const d = d3.select(this).data()[0]; console.log('profile', userColorOverlay[d.name].profile ); console.log('views:', userColorOverlay[d.name].views); } function mouseover () { d3.select(this).transition() .duration(750) .attr('r', 16); } function mouseout () { d3.select(this).transition() .duration(750) .attr('r', 8); }