mirror of
https://github.com/cwinfo/yggdrasil-map
synced 2024-11-09 16:00:27 +00:00
Remove old index.html
This commit is contained in:
parent
81405faf3e
commit
7ad3ffb92b
662
web/index.html
662
web/index.html
@ -1,662 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>fc00::/8</title>
|
|
||||||
<script src="jquery-2.0.3.min.js"></script>
|
|
||||||
<script src="jquery.autocomplete.min.js"></script>
|
|
||||||
<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro|Droid+Sans|Duru+Sans|Quattrocento+Sans|Open+Sans' rel='stylesheet' type='text/css'>
|
|
||||||
<style type="text/css">
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Inconsolata';
|
|
||||||
src: url("Inconsolata.otf");
|
|
||||||
}
|
|
||||||
|
|
||||||
* {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
html, body {
|
|
||||||
font-family: 'Source Sans Pro';
|
|
||||||
background: #F5F5F5;
|
|
||||||
}
|
|
||||||
|
|
||||||
#header {
|
|
||||||
background: #FFF;
|
|
||||||
height: 48px;
|
|
||||||
line-height: 48px;
|
|
||||||
/*box-shadow: 0 5px 3px rgba(0, 0, 0, 0.1);*/
|
|
||||||
z-index: 0;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-family: 'Inconsolata';
|
|
||||||
font-size: 32px;
|
|
||||||
float: left;
|
|
||||||
padding: 0 40px;
|
|
||||||
font-weight: 100;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
small {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grey {
|
|
||||||
color: #999;
|
|
||||||
/*font-size: 16px;*/
|
|
||||||
/*vertical-align: middle;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
list-style-type: none;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
li {
|
|
||||||
float: left;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#header a {
|
|
||||||
color: #777;
|
|
||||||
padding: 0 20px;
|
|
||||||
font-family: 'Source Sans Pro';
|
|
||||||
font-size: 14px;
|
|
||||||
text-decoration: none;
|
|
||||||
height: 100%;
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#header a:hover {
|
|
||||||
background: #EEE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*#map-wrapper {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
z-index: -1;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#general-info {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
font-size: 10px;
|
|
||||||
padding: 5px;
|
|
||||||
line-height: 150%;
|
|
||||||
z-index: 999;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#sidebar {
|
|
||||||
padding: 20px 20px;
|
|
||||||
background: rgba(220, 220, 220, 0.8);
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
/*bottom: 0;*/
|
|
||||||
min-width: 200px;
|
|
||||||
z-index: 999;
|
|
||||||
/*overflow-y: scroll;*/
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#search-wrapper {
|
|
||||||
width: 100%;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
/*position: absolute;*/
|
|
||||||
/*top: 0;*/
|
|
||||||
/*right: 10px;*/
|
|
||||||
/*z-index: 5;*/
|
|
||||||
}
|
|
||||||
#search-box {
|
|
||||||
width: 100%;
|
|
||||||
padding: 5px;
|
|
||||||
outline: none;
|
|
||||||
border: none;
|
|
||||||
/*border: 1px solid #CCC;*/
|
|
||||||
margin: -5px;
|
|
||||||
font-size: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: #333;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
a:hover {
|
|
||||||
color: #AAA;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
color: #29BBFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
#node-info table {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#node-info td + td {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
#node-info strong {
|
|
||||||
color: #29BBFF;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tt {
|
|
||||||
font-family: 'Source Code Pro', Consolas, monospace;
|
|
||||||
font-size: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autocomplete-suggestions {
|
|
||||||
font-family: 'Source Code Pro', Consolas, monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
border: 1px solid #FFF;
|
|
||||||
background: #FFF;
|
|
||||||
overflow: auto;
|
|
||||||
color: #555;
|
|
||||||
}
|
|
||||||
.autocomplete-suggestion {
|
|
||||||
padding: 2px 5px;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.autocomplete-selected { background: #7FD6FF; }
|
|
||||||
.autocomplete-suggestions strong {
|
|
||||||
color: #000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
#canvas-wrapper {
|
|
||||||
position: absolute;
|
|
||||||
top: 48px;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#map {
|
|
||||||
position: absolute;
|
|
||||||
width:100%;
|
|
||||||
height:100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="header">
|
|
||||||
<h1>fc00<span class="grey">::/8</span></h1>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><a href="#">Network</a></li>
|
|
||||||
<li><a href="#">World map</a></li>
|
|
||||||
<li><a href="#">Tools</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- <div id="search-wrapper">
|
|
||||||
<input id="search-box" class="tt" type="text" placeholder="Search nodes...">
|
|
||||||
</div> -->
|
|
||||||
<!-- <div id="map-wrapper"> -->
|
|
||||||
|
|
||||||
|
|
||||||
<div id="general-info">
|
|
||||||
<!-- <br> -->
|
|
||||||
Nodes: <span id="number-of-nodes">-</span><br>
|
|
||||||
Links: <span id="number-of-connections">-</span><br>
|
|
||||||
Updated <span id="update-time">-</span><br>
|
|
||||||
</div>
|
|
||||||
<div id="sidebar">
|
|
||||||
<div id="search-wrapper">
|
|
||||||
<input id="search-box" class="tt" type="text" placeholder="Search nodes...">
|
|
||||||
</div>
|
|
||||||
<div id="node-info">
|
|
||||||
<span class="tt" style="opacity: 0">0000:0000:0000:0000:0000:0000:0000:0000</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="canvas-wrapper">
|
|
||||||
<canvas id="map"></canvas>
|
|
||||||
</div>
|
|
||||||
<!-- </div> -->
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var nodes = [];
|
|
||||||
var edges = [];
|
|
||||||
var canvas = null;
|
|
||||||
var ctx = null;
|
|
||||||
var mapOffset = {x: 0, y: 0};
|
|
||||||
var zoom = 1.0;
|
|
||||||
|
|
||||||
function changeHash(hash) {
|
|
||||||
window.location.replace(('' + window.location).split('#')[0] + '#' + hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateCanvasSize() {
|
|
||||||
$(canvas).attr({height: $(canvas).height(), width: $(canvas).width()});
|
|
||||||
ctx.translate(mapOffset.x, mapOffset.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawCircle(ctx, x, y, radius, color) {
|
|
||||||
ctx.fillStyle = color;
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(x, y, radius, 0, Math.PI*2, true);
|
|
||||||
ctx.fill();
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawLine(ctx, x1, y1, x2, y2, color) {
|
|
||||||
ctx.strokeStyle = color;
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(x1, y1);
|
|
||||||
ctx.lineTo(x2, y2);
|
|
||||||
ctx.closePath();
|
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawText(ctx, x, y, text, color, font) {
|
|
||||||
// ctx.save();
|
|
||||||
// ctx.translate(x, y);
|
|
||||||
// ctx.rotate(Math.PI/4);
|
|
||||||
ctx.fillStyle = color;
|
|
||||||
ctx.font = font;
|
|
||||||
ctx.textAlign = 'center';
|
|
||||||
ctx.fillText(text, x, y);
|
|
||||||
// ctx.restore();
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawNetwork() {
|
|
||||||
ctx.save();
|
|
||||||
ctx.resetTransform();
|
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
||||||
ctx.restore();
|
|
||||||
|
|
||||||
|
|
||||||
// Draw edges
|
|
||||||
for (var i = 0; i < edges.length; ++i) {
|
|
||||||
var edge = edges[i];
|
|
||||||
var highlight = edge.sourceNode.hover || edge.targetNode.hover;
|
|
||||||
var color = highlight ? 'rgba(0, 0, 0, 0.5)' : 'rgba(0, 0, 0, 0.15)';
|
|
||||||
|
|
||||||
drawLine(ctx,
|
|
||||||
edge.sourceNode.x, edge.sourceNode.y,
|
|
||||||
edge.targetNode.x, edge.targetNode.y,
|
|
||||||
color);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw nodes
|
|
||||||
for (var i = 0; i < nodes.length; ++i) {
|
|
||||||
var node = nodes[i];
|
|
||||||
|
|
||||||
drawCircle(ctx, node.x, node.y, node.radius, node.color);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw labels
|
|
||||||
for (var i = 0; i < nodes.length; ++i) {
|
|
||||||
var node = nodes[i];
|
|
||||||
|
|
||||||
if (node.radius > 2 || node.selected || node.hover) {
|
|
||||||
var fontSize = 4 + node.radius * 0.4;
|
|
||||||
|
|
||||||
drawText(ctx, node.x, node.y - node.radius - 1,
|
|
||||||
node.label, node.textColor, fontSize + 'pt "ubuntu mono"');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNodeAt(x, y) {
|
|
||||||
x -= mapOffset.x;
|
|
||||||
y -= mapOffset.y;
|
|
||||||
for (var i = nodes.length - 1; i >= 0; --i) {
|
|
||||||
var node = nodes[i];
|
|
||||||
var distPow2 = (node.x - x) * (node.x - x) + (node.y - y) * (node.y - y);
|
|
||||||
|
|
||||||
if (distPow2 <= node.radius * node.radius) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function searchNode(id) {
|
|
||||||
for (var i = 0; i < nodes.length; ++i) {
|
|
||||||
if (nodes[i].id == id)
|
|
||||||
return nodes[i];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearNodes() {
|
|
||||||
changeHash('');
|
|
||||||
$('#node-info').html('');
|
|
||||||
|
|
||||||
for (var i = 0; i < nodes.length; ++i) {
|
|
||||||
var node = nodes[i];
|
|
||||||
node.depth = 0xFFFF;
|
|
||||||
node.color = node.originalColor;
|
|
||||||
node.textColor = node.color;
|
|
||||||
node.selected = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function selectNode(node, redraw) {
|
|
||||||
clearNodes();
|
|
||||||
|
|
||||||
changeHash(node.id);
|
|
||||||
|
|
||||||
node.selected = true;
|
|
||||||
showNodeInfo(node);
|
|
||||||
|
|
||||||
markPeers(node, 0);
|
|
||||||
if (redraw)
|
|
||||||
drawNetwork();
|
|
||||||
}
|
|
||||||
|
|
||||||
function markPeers(node, depth) {
|
|
||||||
node.depth = depth;
|
|
||||||
|
|
||||||
// var colors = ['#000000', '#333333', '#555555', '#777777', '#999999', '#BBBBBB', '#DDDDDD'];
|
|
||||||
// var colors = ['#000000', '#29BBFF', '#09E844', '#FFBD0F', '#FF5E14', '#FF3C14', '#FF7357', '#FF9782', '#FFC8BD', '#FFE6E0'];
|
|
||||||
var colors = ['#000000', '#096EE8', '#09E8B8', '#36E809', '#ADE809', '#E8B809', '#E87509', '#E83A09'];
|
|
||||||
var txtCol = ['#000000', '#032247', '#034537', '#0E3D02', '#354703', '#403203', '#3D1F02', '#3B0E02'];
|
|
||||||
// var colors = ['#000000', '#064F8F', '#068F81', '#068F38', '#218F06', '#6F8F06', '#8F7806', '#8F5106'];
|
|
||||||
// var colors = ['#FFFFFF', '#29BBFF', '#17FF54', '#FFBD0F', '#FF3C14', '#590409'];
|
|
||||||
node.color = (depth >= colors.length) ? '#FFFFFF' : colors[depth];
|
|
||||||
node.textColor = (depth >= txtCol.length) ? '#FFFFFF' : txtCol[depth];
|
|
||||||
|
|
||||||
for (var i = 0; i < node.peers.length; ++i) {
|
|
||||||
var n = node.peers[i];
|
|
||||||
if (n.depth > depth + 1)
|
|
||||||
markPeers(n, depth + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function showNodeInfo(node) {
|
|
||||||
var ip_peers = [];
|
|
||||||
var dns_peers = [];
|
|
||||||
|
|
||||||
for (var i = 0; i < node.peers.length; ++i) {
|
|
||||||
var n = node.peers[i];
|
|
||||||
if (/^[0-9A-F]{4}$/i.test(n.label))
|
|
||||||
ip_peers.push(n);
|
|
||||||
else
|
|
||||||
dns_peers.push(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
var label_compare = function(a, b) {
|
|
||||||
return a.label.localeCompare(b.label);
|
|
||||||
}
|
|
||||||
|
|
||||||
dns_peers.sort(label_compare);
|
|
||||||
ip_peers.sort(label_compare);
|
|
||||||
|
|
||||||
var peers = dns_peers.concat(ip_peers);
|
|
||||||
|
|
||||||
var html =
|
|
||||||
'<h2>' + node.label + '</h2>' +
|
|
||||||
'<span class="tt">' + node.id + '</span><br>' +
|
|
||||||
'<br>' +
|
|
||||||
'<strong>Version:</strong> ' + node.version + '<br>' +
|
|
||||||
'<strong>Location:</strong> Helsinki, Finland<br>' +
|
|
||||||
'<strong>Peers:</strong> ' + node.peers.length + '<br>' +
|
|
||||||
'<table>' +
|
|
||||||
// '<tr><td></td><td><strong>Their peers #</strong></td></tr>' +
|
|
||||||
peers.map(function (n) {
|
|
||||||
return '<tr>' +
|
|
||||||
'<td><a href="#' + n.id + '" class="tt">' + n.label + '</a></td>' +
|
|
||||||
'<td>' + n.peers.length + '</td></tr>';
|
|
||||||
}).join('') +
|
|
||||||
'</table>';
|
|
||||||
|
|
||||||
$('#node-info').html(html);
|
|
||||||
}
|
|
||||||
|
|
||||||
function mousePos(e) {
|
|
||||||
var rect = canvas.getBoundingClientRect();
|
|
||||||
return {x: e.clientX - rect.left, y: e.clientY - rect.top};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
canvas = document.getElementById('map');
|
|
||||||
ctx = canvas.getContext('2d');
|
|
||||||
updateCanvasSize();
|
|
||||||
|
|
||||||
|
|
||||||
jQuery.getJSON('graph.json', function(data) {
|
|
||||||
nodes = data.nodes;
|
|
||||||
edges = data.edges;
|
|
||||||
|
|
||||||
// Calculate node radiuses
|
|
||||||
for (var i = 0; i < nodes.length; ++i) {
|
|
||||||
var node = nodes[i];
|
|
||||||
node.x = node.x * 1.2;
|
|
||||||
node.y = node.y * 1.2;
|
|
||||||
node.radius = 4 + node.size * 10;
|
|
||||||
node.hover = false;
|
|
||||||
node.selected = false;
|
|
||||||
node.edges = [];
|
|
||||||
node.peers = [];
|
|
||||||
node.depth = 0xFFFF;
|
|
||||||
// node.color = '#000';
|
|
||||||
node.originalColor = node.color;
|
|
||||||
node.textColor = node.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find node references for edges
|
|
||||||
for (var i = 0; i < edges.length; ++i) {
|
|
||||||
var edge = edges[i];
|
|
||||||
|
|
||||||
for (var n = 0; n < nodes.length; ++n) {
|
|
||||||
if (nodes[n].id == edge.sourceID) {
|
|
||||||
edge.sourceNode = nodes[n];
|
|
||||||
// edge.sourceNode.edges.append(edge);
|
|
||||||
}
|
|
||||||
else if (nodes[n].id == edge.targetID)
|
|
||||||
edge.targetNode = nodes[n];
|
|
||||||
}
|
|
||||||
|
|
||||||
edge.sourceNode.edges.push(edge);
|
|
||||||
edge.targetNode.edges.push(edge);
|
|
||||||
edge.sourceNode.peers.push(edge.targetNode);
|
|
||||||
edge.targetNode.peers.push(edge.sourceNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Set update time
|
|
||||||
var delta = Math.round(new Date().getTime() / 1000) - data.created;
|
|
||||||
var min = Math.floor(delta / 60);
|
|
||||||
var sec = delta % 60;
|
|
||||||
$('#update-time').text(min + ' min, ' + sec + ' s ago');
|
|
||||||
|
|
||||||
// Set stats
|
|
||||||
$('#number-of-nodes').text(nodes.length);
|
|
||||||
$('#number-of-connections').text(edges.length);
|
|
||||||
|
|
||||||
|
|
||||||
if (window.location.hash) {
|
|
||||||
var id = window.location.hash.substring(1);
|
|
||||||
var node = searchNode(id);
|
|
||||||
if (node) selectNode(node, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
drawNetwork();
|
|
||||||
|
|
||||||
$(window).resize(function() {
|
|
||||||
updateCanvasSize();
|
|
||||||
drawNetwork();
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// Initialize search
|
|
||||||
var searchArray = [];
|
|
||||||
for (var i = 0; i < nodes.length; ++i) {
|
|
||||||
var node = nodes[i];
|
|
||||||
|
|
||||||
searchArray.push({
|
|
||||||
value: node.label,
|
|
||||||
data: node
|
|
||||||
});
|
|
||||||
|
|
||||||
searchArray.push({
|
|
||||||
value: node.id,
|
|
||||||
data: node
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#search-box').autocomplete({
|
|
||||||
lookup: searchArray,
|
|
||||||
autoSelectFirst: true,
|
|
||||||
lookupLimit: 7,
|
|
||||||
onSelect: function(suggestion) {
|
|
||||||
selectNode(suggestion.data, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#search-box').keypress(function(e) {
|
|
||||||
if (e.which == 13) {
|
|
||||||
selectNode(searchNode($('#search-box').val()), true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).on('click', '#node-info a', function(e) {
|
|
||||||
var id = e.target.hash.substring(1);
|
|
||||||
selectNode(searchNode(id), true);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var mouseDownPos = null;
|
|
||||||
var mouseLastPos = null;
|
|
||||||
var mouseDownNode = null;
|
|
||||||
var mouseHoverNode = null;
|
|
||||||
|
|
||||||
|
|
||||||
$(canvas).mousemove(function(e) {
|
|
||||||
var mouse = mousePos(e);
|
|
||||||
|
|
||||||
// Dragging
|
|
||||||
if (mouseDownPos != null) {
|
|
||||||
$('body').css('cursor', 'move');
|
|
||||||
var dx = mouse.x - mouseLastPos.x;
|
|
||||||
var dy = mouse.y - mouseLastPos.y;
|
|
||||||
mapOffset.x += dx;
|
|
||||||
mapOffset.y += dy;
|
|
||||||
ctx.translate(dx, dy);
|
|
||||||
mouseLastPos = {x: mouse.x, y: mouse.y};
|
|
||||||
drawNetwork();
|
|
||||||
}
|
|
||||||
// Hovering
|
|
||||||
else {
|
|
||||||
var node = getNodeAt(mouse.x, mouse.y);
|
|
||||||
|
|
||||||
if (node == mouseHoverNode)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (node == null) {
|
|
||||||
nodeMouseOut(mouseHoverNode);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (mouseHoverNode != null)
|
|
||||||
nodeMouseOut(mouseHoverNode);
|
|
||||||
|
|
||||||
nodeMouseIn(node);
|
|
||||||
}
|
|
||||||
mouseHoverNode = node;
|
|
||||||
|
|
||||||
drawNetwork();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
$(canvas).mousedown(function(e) {
|
|
||||||
var mouse = mousePos(e);
|
|
||||||
mouseLastPos = mouseDownPos = {x: mouse.x, y: mouse.y};
|
|
||||||
mouseDownNode = getNodeAt(mouse.x, mouse.y);
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
$(canvas).mouseup(function(e) {
|
|
||||||
var mouse = mousePos(e);
|
|
||||||
var mouseMoved =
|
|
||||||
Math.abs(mouse.x - mouseDownPos.x) +
|
|
||||||
Math.abs(mouse.y - mouseDownPos.y) > 3
|
|
||||||
|
|
||||||
if (!mouseMoved) {
|
|
||||||
if (mouseDownNode)
|
|
||||||
selectNode(mouseDownNode, true);
|
|
||||||
else {
|
|
||||||
clearNodes();
|
|
||||||
drawNetwork();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$('body').css('cursor', 'auto');
|
|
||||||
}
|
|
||||||
|
|
||||||
mouseDownPos = null;
|
|
||||||
mouseDownNode = null;
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
function handleScroll(e) {
|
|
||||||
var mouse = mousePos(e);
|
|
||||||
var e = window.event;
|
|
||||||
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
|
|
||||||
|
|
||||||
var ratio = (delta < 0) ? (3 / 4) : 1 + (1 / 3);
|
|
||||||
var mx = mouse.x - mapOffset.x;
|
|
||||||
var my = mouse.y - mapOffset.y;
|
|
||||||
|
|
||||||
zoom *= ratio;
|
|
||||||
|
|
||||||
for (var i = 0; i < nodes.length; ++i) {
|
|
||||||
var node = nodes[i];
|
|
||||||
node.x = (node.x - mx) * ratio + mx;
|
|
||||||
node.y = (node.y - my) * ratio + my;
|
|
||||||
// node.x *= ratio;
|
|
||||||
// node.y *= ratio;
|
|
||||||
// node.radius *= ratio;
|
|
||||||
node.radius = (4 + node.size * 8) * zoom;
|
|
||||||
}
|
|
||||||
|
|
||||||
drawNetwork();
|
|
||||||
}
|
|
||||||
canvas.addEventListener("mousewheel", handleScroll, false);
|
|
||||||
canvas.addEventListener("DOMMouseScroll", handleScroll, false);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
function nodeMouseIn(node) {
|
|
||||||
node.hover = true;
|
|
||||||
$('body').css('cursor', 'pointer');
|
|
||||||
}
|
|
||||||
|
|
||||||
function nodeMouseOut(node) {
|
|
||||||
node.hover = false;
|
|
||||||
$('body').css('cursor', 'auto');
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Loading…
Reference in New Issue
Block a user