This commit is contained in:
parent
5ecdab0466
commit
cdd941c02f
5 changed files with 97 additions and 89 deletions
|
@ -3,5 +3,4 @@ fdfe:8d0:7450:200::/56,DE,DE-BY,Nuremberg,
|
|||
fdfe:8d0:7450:300::/56,PL,PL-14,Warsaw,
|
||||
fdfe:8d0:7450:400::/56,FR,FR-IDF,Paris,
|
||||
fdfe:8d0:7450:500::/56,SE,SE-AB,Stockholm,
|
||||
fdfe:8d0:7450:700::/56,DE,DE-HE,Frankfurt,
|
||||
fdfe:8d0:7450:ffff::/64,,,,
|
||||
|
|
|
13
nodes.md
13
nodes.md
|
@ -8,13 +8,13 @@ Prefix hostname with `ipv4.` to force IPv4 \
|
|||
|
||||
### Amsterdam, Netherlands
|
||||
- `nl1.420129.xyz` 500 Mbps (v6 + v4)
|
||||
- Public key: `iZfLBtF6BiQvdKXx4Yl02u+OL6ls35gSpWCRmB9q4lU=`
|
||||
- Public key: `m724+s6dks1bHZbEj9JvQb17mAC45z1WkaHSTSgxcRk=`
|
||||
- Link local: `fe80::129:1`
|
||||
- Pingable: `fdfe:8d0:7450:100::1`
|
||||
|
||||
### Nuremberg, Germany
|
||||
- `de1.420129.xyz` 1 Gbps (v6 + v4)
|
||||
- Public key: `N9rGceoiFcc/obnHrqMAmVlrb/E2Br55+doekTKwNF8=`
|
||||
- Public key: `m724+jzo06ECw9TEGEqaJcF6lCk63z8I3k4KDg9sxwM=`
|
||||
- Link local: `fe80::129:2`
|
||||
- Pingable: `fdfe:8d0:7450:200::1`
|
||||
- Provider: [Advin Servers](https://clients.advinservers.com/aff.php?aff=323)
|
||||
|
@ -37,11 +37,4 @@ Prefix hostname with `ipv4.` to force IPv4 \
|
|||
- Public key: `m724+na8merDXnOAWbFDJPhzyujDekX8vR5Ibgt4oyY=`
|
||||
- Link local: `fe80::129:5`
|
||||
- Pingable: `fdfe:8d0:7450:500::1`
|
||||
- Provider: [No Ack Hosting](https://order.noackhosting.se/?affid=1)
|
||||
|
||||
### Frankfurt, Germany
|
||||
- **(!) Unstable right now**
|
||||
- `de2.420129.xyz` 100 Mbps (v6 + v4)
|
||||
- Public key: `VJMKJEuteSa9izj5f+bUD8bhQL99NnITnxyy0+1Gblw=`
|
||||
- Link local: `fe80::129:7`
|
||||
- Pingable: `fdfe:8d0:7450:700::1`
|
||||
- Provider: [No Ack Hosting](https://order.noackhosting.se/?affid=1)
|
|
@ -13,8 +13,10 @@
|
|||
<body>
|
||||
<div id="sidebar">
|
||||
<div id="sidebarContent">
|
||||
<h2>AS4242420129</h2>
|
||||
<div id="nodes"></div>
|
||||
<h2>
|
||||
<span>AS424242</span>0129
|
||||
</h2>
|
||||
<div id="nodeList"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="map"></div>
|
||||
|
|
142
src/map/map.js
142
src/map/map.js
|
@ -4,28 +4,22 @@ import 'leaflet/dist/leaflet.css';
|
|||
import 'leaflet-defaulticon-compatibility';
|
||||
import 'leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css';
|
||||
|
||||
var map = L.map('map', {
|
||||
/* ------ */
|
||||
|
||||
const map = L.map('map', {
|
||||
minZoom: 5,
|
||||
maxZoom: 8,
|
||||
worldCopyJump: true
|
||||
}).setView([50,18], 5);
|
||||
|
||||
L.tileLayer('https://tforwarder.b-cdn.net/spinal-map/{z}/{x}/{y}.png?apikey={apikey}', {
|
||||
attribution: '© <a href="http://www.thunderforest.com/">Thunderforest</a>, © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
|
||||
apikey: 'db5ae1f5778a448ca662554581f283c5',
|
||||
}).addTo(map);
|
||||
|
||||
var de1t = [50.085448739143715, 8.461733038044116];
|
||||
|
||||
// title, hostname, popup, location
|
||||
var nodes = {
|
||||
const nodes = {
|
||||
pl1: {
|
||||
country: 'pl',
|
||||
location: [52.1904441909767, 20.922122237417636],
|
||||
city: "Warsaw, Poland",
|
||||
hostname: "pl1.420129.xyz",
|
||||
datacenter: "equinix wa3",
|
||||
description: ``
|
||||
description: `Eastern Europe presence`
|
||||
},
|
||||
de1: {
|
||||
country: 'de',
|
||||
|
@ -33,7 +27,7 @@ var nodes = {
|
|||
city: "Nuremberg, Germany",
|
||||
hostname: "de1.420129.xyz",
|
||||
datacenter: "Hetzner",
|
||||
description: ``
|
||||
description: `Central Europe presence`
|
||||
},
|
||||
nl1: {
|
||||
country: 'nl',
|
||||
|
@ -41,7 +35,7 @@ var nodes = {
|
|||
city: "Amsterdam, Netherlands",
|
||||
hostname: "nl1.420129.xyz",
|
||||
datacenter: "oracle cloud eu-amsterdam-1",
|
||||
description: ``
|
||||
description: `Western Europe presence`
|
||||
},
|
||||
fr1: {
|
||||
country: 'fr',
|
||||
|
@ -49,7 +43,7 @@ var nodes = {
|
|||
city: "Paris, France",
|
||||
hostname: "fr1.420129.xyz",
|
||||
datacenter: "scaleway PAR 1",
|
||||
description: ``
|
||||
description: `France presence`
|
||||
},
|
||||
se1: {
|
||||
country: 'se',
|
||||
|
@ -57,65 +51,64 @@ var nodes = {
|
|||
city: "Stockholm, Sweden",
|
||||
hostname: "fr1.420129.xyz",
|
||||
datacenter: "unknown",
|
||||
description: ``
|
||||
},
|
||||
de2: {
|
||||
country: 'de',
|
||||
location: [50.0968987, 8.6441317],
|
||||
city: "Frankfurt, Germany",
|
||||
hostname: "de2.420129.xyz",
|
||||
datacenter: "Equinix FR7",
|
||||
description: ``
|
||||
},
|
||||
description: `Nordic presence`
|
||||
}
|
||||
}
|
||||
|
||||
function line(from, to, popup) {
|
||||
L.polyline([from, to], {opacity: 0.5}).addTo(map).bindPopup(popup);
|
||||
}
|
||||
const connections = [
|
||||
{ from: 'nl1', to: 'se1', latency: 20 },
|
||||
{ from: 'nl1', to: 'de1', latency: 10 },
|
||||
{ from: 'nl1', to: 'fr1', latency: 10 },
|
||||
{ from: 'de1', to: 'pl1', latency: 25 },
|
||||
];
|
||||
|
||||
/* ------ */
|
||||
|
||||
L.tileLayer('https://tforwarder.b-cdn.net/spinal-map/{z}/{x}/{y}.png?apikey={apikey}', {
|
||||
attribution: '© <a href="http://www.thunderforest.com/">Thunderforest</a>, © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
|
||||
apikey: 'db5ae1f5778a448ca662554581f283c5',
|
||||
}).addTo(map);
|
||||
|
||||
var opened = null;
|
||||
|
||||
const sidebarContent = document.getElementById("sidebarContent");
|
||||
const nodesElement = document.getElementById("nodes");
|
||||
const nodeListElement = document.getElementById("nodeList");
|
||||
|
||||
|
||||
function dismissPopup(hideMarker) {
|
||||
console.log('dismissing')
|
||||
console.log('dismissPopup');
|
||||
|
||||
if (opened == null) return;
|
||||
const popup = opened[0];
|
||||
|
||||
const rect = opened[1].getBoundingClientRect();
|
||||
const popupElement = opened.popupElement;
|
||||
const rect = opened.clickedElement.getBoundingClientRect();
|
||||
|
||||
console.log('a')
|
||||
//sidebarContent.removeChild(opened);
|
||||
popup.offsetHeight;
|
||||
popup.style.height = rect.height - 20 + 'px';
|
||||
popup.style.transform = 'none';
|
||||
nodesElement.style.opacity = 1;
|
||||
popupElement.style.height = rect.height - 20 + 'px';
|
||||
popupElement.style.transform = 'none';
|
||||
|
||||
nodeListElement.style.opacity = 1;
|
||||
sidebarContent.style.backgroundColor = null;
|
||||
|
||||
opened = null;
|
||||
if (hideMarker) map.closePopup();
|
||||
|
||||
setTimeout(() => {
|
||||
sidebarContent.removeChild(popup);
|
||||
}, 300);
|
||||
sidebarContent.removeChild(popupElement);
|
||||
}, 300);
|
||||
|
||||
console.log("Popup dismissed");
|
||||
};
|
||||
|
||||
//map.on('popupClose', dismissPopup);
|
||||
sidebarContent.onclick = dismissPopup;
|
||||
function onSidebarNodeClick(node, clickedElement) {
|
||||
console.log('onSidebarNodeClick', node, opened);
|
||||
|
||||
function onNodeClick(ev, node, clicked) {
|
||||
console.log('b')
|
||||
console.log(opened)
|
||||
if (opened != null) {
|
||||
return;
|
||||
}
|
||||
const rect = clicked.getBoundingClientRect();
|
||||
if (opened != null) return;
|
||||
|
||||
nodesElement.style.opacity = 0;
|
||||
const rect = clickedElement.getBoundingClientRect();
|
||||
|
||||
nodeListElement.style.opacity = 0;
|
||||
|
||||
let ele = clicked.cloneNode(true);
|
||||
let ele = clickedElement.cloneNode(true);
|
||||
ele.innerHTML += `<br><br>Datacenter: <span class="code">${node.datacenter}</span><br><br><small>${node.description.split('\n').slice(1).join('<br>')}</small>`;
|
||||
ele.onclick = (ev) => {ev.stopPropagation()};
|
||||
|
||||
|
@ -133,11 +126,20 @@ function onNodeClick(ev, node, clicked) {
|
|||
ele.style.height = window.innerHeight / 3 + 'px';
|
||||
sidebarContent.style.backgroundColor = "#111";
|
||||
|
||||
opened = [ele, clicked, node];
|
||||
console.log("opened")
|
||||
opened = {
|
||||
popupElement: ele,
|
||||
clickedElement: clickedElement,
|
||||
node: node
|
||||
};
|
||||
|
||||
console.log("Node information opened");
|
||||
}
|
||||
|
||||
for (let node of Object.values(nodes)) {
|
||||
|
||||
for (let nodeId of Object.keys(nodes)) {
|
||||
let node = nodes[nodeId];
|
||||
console.log(`Adding node: ${nodeId} (${node.city}; ${node.hostname})`);
|
||||
|
||||
let marker = L.marker(node.location).addTo(map).bindPopup(`<strong>${node.city}</strong><br>DC: ${node.datacenter}`);
|
||||
|
||||
let ele = document.createElement("div");
|
||||
|
@ -147,29 +149,29 @@ for (let node of Object.values(nodes)) {
|
|||
ele.onclick = (ev) => {
|
||||
marker.openPopup();
|
||||
map.panTo(node.location, {
|
||||
padding: [1000, 1000], // TODO I could use this to fix the small screen issue
|
||||
duration: 0.3
|
||||
});
|
||||
//onNodeClick(ev, node, ele);
|
||||
ev.stopPropagation();
|
||||
ev.stopPropagation(); // because
|
||||
};
|
||||
|
||||
marker.on('popupopen', (ev) => {
|
||||
console.log(ev)
|
||||
console.log('popened');
|
||||
onNodeClick(ev, node, ele);
|
||||
});
|
||||
marker.on('popupclose', () => {
|
||||
console.log('closed')
|
||||
dismissPopup()
|
||||
onSidebarNodeClick(node, ele);
|
||||
});
|
||||
|
||||
nodesElement.appendChild(ele);
|
||||
marker.on('popupclose', () => {
|
||||
dismissPopup();
|
||||
});
|
||||
|
||||
nodeListElement.appendChild(ele);
|
||||
}
|
||||
|
||||
line(nodes.nl1.location, nodes.se1.location, "nl1 - se1<br><strong>20ms</strong>");
|
||||
line(nodes.nl1.location, nodes.de1.location, "nl1 - de1<br><strong>10ms</strong>");
|
||||
line(nodes.nl1.location, nodes.fr1.location, "nl1 - fr1<br><strong>10ms</strong>");
|
||||
line(nodes.nl1.location, nodes.de2.location, "nl1 - de2<br><strong>7ms</strong>");
|
||||
for (let connection of connections) {
|
||||
let label = `${connection.from} - ${connection.to}<br><strong>${connection.latency}</strong>`;
|
||||
|
||||
line(nodes.de1.location, nodes.de2.location, "de2 - de1<br><strong>5ms</strong>");
|
||||
line(nodes.de2.location, nodes.pl1.location, "de2 - pl1<br><strong>24ms</strong>");
|
||||
L.polyline(
|
||||
[ nodes[connection.from].location, nodes[connection.to].location ],
|
||||
{ opacity: 0.5 }
|
||||
).addTo(map).bindPopup(label);
|
||||
}
|
||||
|
||||
sidebarContent.onclick = dismissPopup;
|
|
@ -2,6 +2,7 @@ html, body {
|
|||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
#map {
|
||||
|
@ -23,7 +24,6 @@ html, body {
|
|||
padding: 10px 20px;
|
||||
margin: 10px;
|
||||
width: calc(100% - 60px);
|
||||
height: auto;
|
||||
border-radius: 8px;
|
||||
z-index: 9998;
|
||||
}
|
||||
|
@ -41,6 +41,16 @@ html, body {
|
|||
|
||||
mask-image: linear-gradient(90deg, black 300px, transparent 320px);
|
||||
|
||||
h2 {
|
||||
font-family: serif;
|
||||
|
||||
span {
|
||||
background-image: linear-gradient(to right, #eeeeee, #fafafa);
|
||||
color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
}
|
||||
|
||||
#sidebarContent {
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
|
@ -49,7 +59,7 @@ html, body {
|
|||
|
||||
overflow-x: scroll;
|
||||
|
||||
#nodes {
|
||||
#nodeList {
|
||||
width: 100%;
|
||||
transition: opacity .3s ease;
|
||||
|
||||
|
@ -73,6 +83,8 @@ html, body {
|
|||
height: 100%;
|
||||
}
|
||||
|
||||
/* Below are leaflet hacks */
|
||||
|
||||
.leaflet-left {
|
||||
margin-left: 310px;
|
||||
}
|
||||
|
@ -114,18 +126,18 @@ html, body {
|
|||
@media screen and (max-width: 600px) {
|
||||
#sidebar {
|
||||
width: 100%;
|
||||
height: calc(50vh + 20px);
|
||||
height: calc(30vh + 20px);
|
||||
|
||||
mask-image: linear-gradient(180deg, black 50vh, transparent calc(50vh + 20px));
|
||||
mask-image: linear-gradient(180deg, black 30vh, transparent calc(30vh + 20px));
|
||||
|
||||
#sidebarContent {
|
||||
width: 100%;
|
||||
height: 50vh;
|
||||
height: 30vh;
|
||||
}
|
||||
}
|
||||
|
||||
.leaflet-left {
|
||||
margin-left: 5px;
|
||||
margin-top: calc(50vh + 10px); /* looks finer without the 10px but then can't click through, so I instead added some left margin */
|
||||
margin-top: calc(30vh + 10px); /* looks finer without the 10px but then can't click */
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue