Rewrite channels map component using native echart

This commit is contained in:
nymkappa 2022-08-10 11:28:54 +02:00
parent c0e6b7af58
commit d6a42cdf6b
No known key found for this signature in database
GPG Key ID: E155910B16E8BD04

View File

@ -20,7 +20,11 @@ export class NodesChannelsMap implements OnInit, OnDestroy {
@Input() publicKey: string | undefined; @Input() publicKey: string | undefined;
observable$: Observable<any>; observable$: Observable<any>;
center: number[] | undefined = undefined;
center: number[] | undefined;
zoom: number | undefined;
channelWidth = 0.6;
channelOpacity = 0.1;
chartInstance = undefined; chartInstance = undefined;
chartOptions: EChartsOption = {}; chartOptions: EChartsOption = {};
@ -42,7 +46,8 @@ export class NodesChannelsMap implements OnInit, OnDestroy {
ngOnDestroy(): void {} ngOnDestroy(): void {}
ngOnInit(): void { ngOnInit(): void {
this.center = this.style === 'widget' ? [0, 0, -10] : undefined; this.center = this.style === 'widget' ? [0, 40] : [0, 5];
this.zoom = this.style === 'widget' ? 3.5 : 1.3;
if (this.style === 'graph') { if (this.style === 'graph') {
this.seoService.setTitle($localize`Lightning nodes channels world map`); this.seoService.setTitle($localize`Lightning nodes channels world map`);
@ -69,29 +74,46 @@ export class NodesChannelsMap implements OnInit, OnDestroy {
thisNodeGPS = [channel[6], channel[7]]; thisNodeGPS = [channel[6], channel[7]];
} }
channelsLoc.push([[channel[2], channel[3]], [channel[6], channel[7]]]); // We add a bit of noise so nodes at the same location are not all
// on top of each other
let random = Math.random() * 2 * Math.PI;
let random2 = Math.random() * 0.01;
if (!nodesPubkeys[channel[0]]) { if (!nodesPubkeys[channel[0]]) {
nodes.push({ nodes.push([
publicKey: channel[0], channel[2] + random2 * Math.cos(random),
name: channel[1], channel[3] + random2 * Math.sin(random),
value: [channel[2], channel[3]], 1,
}); channel[0],
nodesPubkeys[channel[0]] = true; channel[1]
]);
nodesPubkeys[channel[0]] = nodes[nodes.length - 1];
} }
random = Math.random() * 2 * Math.PI;
random2 = Math.random() * 0.01;
if (!nodesPubkeys[channel[4]]) { if (!nodesPubkeys[channel[4]]) {
nodes.push({ nodes.push([
publicKey: channel[4], channel[6] + random2 * Math.cos(random),
name: channel[5], channel[7] + random2 * Math.sin(random),
value: [channel[6], channel[7]], 1,
}); channel[4],
nodesPubkeys[channel[4]] = true; channel[5]
]);
nodesPubkeys[channel[4]] = nodes[nodes.length - 1];
} }
const channelLoc = [];
channelLoc.push(nodesPubkeys[channel[0]].slice(0, 2));
channelLoc.push(nodesPubkeys[channel[4]].slice(0, 2));
channelsLoc.push(channelLoc);
} }
if (this.style === 'nodepage' && thisNodeGPS) { if (this.style === 'nodepage' && thisNodeGPS) {
// 1ML 0217890e3aad8d35bc054f43acc00084b25229ecff0ab68debd82883ad65ee8266 this.center = [thisNodeGPS[0], thisNodeGPS[1]];
// New York GPS [-74.0068, 40.7123] this.zoom = 10;
// Map center [-20.55, 0, -9.85] this.channelWidth = 1;
this.center = [thisNodeGPS[0] * -20.55 / -74.0068, 0, thisNodeGPS[1] * -9.85 / 40.7123]; this.channelOpacity = 1;
} }
this.prepareChartOptions(nodes, channelsLoc); this.prepareChartOptions(nodes, channelsLoc);
@ -115,87 +137,84 @@ export class NodesChannelsMap implements OnInit, OnDestroy {
} }
this.chartOptions = { this.chartOptions = {
silent: this.style === 'widget' ? true : false, silent: this.style === 'widget',
title: title ?? undefined, title: title ?? undefined,
geo3D: { tooltip: {},
map: 'world', geo: {
shading: 'color', animation: false,
silent: true, silent: true,
postEffect: { center: this.center,
enable: true, zoom: this.zoom,
bloom: { tooltip: {
intensity: 0.1, show: true
}
},
viewControl: {
center: this.center,
minDistance: 1,
maxDistance: 60,
distance: this.style === 'widget' ? 22 : this.style === 'nodepage' ? 22 : 60,
alpha: 90,
rotateSensitivity: 0,
panSensitivity: this.style === 'widget' ? 0 : 1,
zoomSensitivity: this.style === 'widget' ? 0 : 0.5,
panMouseButton: this.style === 'widget' ? null : 'left',
rotateMouseButton: undefined,
}, },
map: 'world',
roam: this.style === 'widget' ? false : true,
itemStyle: { itemStyle: {
color: 'white',
opacity: 0.02,
borderWidth: 1,
borderColor: 'black', borderColor: 'black',
color: '#ffffff44'
}, },
regionHeight: 0.01, scaleLimit: {
min: 1.3,
max: 100000,
}
}, },
series: [ series: [
{ {
// @ts-ignore large: true,
type: 'lines3D', progressive: 200,
coordinateSystem: 'geo3D', type: 'scatter',
blendMode: 'lighter', data: nodes,
lineStyle: { coordinateSystem: 'geo',
width: 1, geoIndex: 0,
opacity: ['widget', 'graph'].includes(this.style) ? 0.025 : 1, symbolSize: 4,
tooltip: {
backgroundColor: 'rgba(17, 19, 31, 1)',
borderRadius: 4,
shadowColor: 'rgba(0, 0, 0, 0.5)',
textStyle: {
color: '#b1b1b1',
align: 'left',
},
borderColor: '#000',
formatter: (value) => {
const data = value.data;
const alias = data[4].length > 0 ? data[4] : data[3].slice(0, 20);
return `<b style="color: white">${alias}</b>`;
}
}, },
data: channels itemStyle: {
color: 'white',
borderColor: 'black',
borderWidth: 2,
opacity: 1,
},
blendMode: 'lighter',
zlevel: 1,
}, },
{ {
// @ts-ignore large: true,
type: 'scatter3D', progressive: 200,
symbol: 'circle', silent: true,
blendMode: 'lighter', type: 'lines',
coordinateSystem: 'geo3D', coordinateSystem: 'geo',
symbolSize: 3, data: channels,
itemStyle: { lineStyle: {
color: '#BBFFFF', opacity: this.channelOpacity,
opacity: 1, width: this.channelWidth,
borderColor: '#FFFFFF00', curveness: 0,
color: '#466d9d',
}, },
data: nodes, blendMode: 'lighter',
emphasis: { tooltip: {
label: { show: false,
position: 'top', },
color: 'white', zlevel: 2,
fontSize: 16, }
formatter: function(value) {
return value.name;
},
show: true,
}
}
},
] ]
}; };
} }
@HostListener('window:wheel', ['$event'])
onWindowScroll(e): void {
// Not very smooth when using the mouse
if (this.style === 'widget' && e.target.tagName === 'CANVAS') {
window.scrollBy({left: 0, top: e.deltaY, behavior: 'auto'});
}
}
onChartInit(ec) { onChartInit(ec) {
if (this.chartInstance !== undefined) { if (this.chartInstance !== undefined) {
return; return;
@ -213,12 +232,32 @@ export class NodesChannelsMap implements OnInit, OnDestroy {
} }
this.chartInstance.on('click', (e) => { this.chartInstance.on('click', (e) => {
if (e.data && e.data.publicKey) { if (e.data) {
this.zone.run(() => { this.zone.run(() => {
const url = new RelativeUrlPipe(this.stateService).transform(`/lightning/node/${e.data.publicKey}`); const url = new RelativeUrlPipe(this.stateService).transform(`/lightning/node/${e.data[3]}`);
this.router.navigate([url]); this.router.navigate([url]);
}); });
} }
}); });
this.chartInstance.on('georoam', (e) => {
if (!e.zoom || this.style === 'nodepage') {
return;
}
const speed = 0.005;
const chartOptions = {
series: this.chartOptions.series
};
chartOptions.series[1].lineStyle.opacity += e.zoom > 1 ? speed : -speed;
chartOptions.series[1].lineStyle.width += e.zoom > 1 ? speed : -speed;
chartOptions.series[0].symbolSize += e.zoom > 1 ? speed * 10 : -speed * 10;
chartOptions.series[1].lineStyle.opacity = Math.max(0.05, Math.min(0.5, chartOptions.series[1].lineStyle.opacity));
chartOptions.series[1].lineStyle.width = Math.max(0.5, Math.min(1, chartOptions.series[1].lineStyle.width));
chartOptions.series[0].symbolSize = Math.max(4, Math.min(5.5, chartOptions.series[0].symbolSize));
this.chartInstance.setOption(chartOptions);
});
} }
} }