Merge pull request #2273 from mempool/nymkappa/feature/channel-page-map

Show channel on the map in channel page
This commit is contained in:
wiz 2022-08-10 23:24:31 +09:00 committed by GitHub
commit 7fecea9cca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 91 additions and 8 deletions

View file

@ -96,7 +96,31 @@ class ChannelsApi {
public async $getChannel(id: string): Promise<any> {
try {
const query = `SELECT n1.alias AS alias_left, n2.alias AS alias_right, channels.*, ns1.channels AS channels_left, ns1.capacity AS capacity_left, ns2.channels AS channels_right, ns2.capacity AS capacity_right FROM channels LEFT JOIN nodes AS n1 ON n1.public_key = channels.node1_public_key LEFT JOIN nodes AS n2 ON n2.public_key = channels.node2_public_key LEFT JOIN node_stats AS ns1 ON ns1.public_key = channels.node1_public_key LEFT JOIN node_stats AS ns2 ON ns2.public_key = channels.node2_public_key WHERE (ns1.id = (SELECT MAX(id) FROM node_stats WHERE public_key = channels.node1_public_key) AND ns2.id = (SELECT MAX(id) FROM node_stats WHERE public_key = channels.node2_public_key)) AND channels.id = ?`;
const query = `
SELECT n1.alias AS alias_left, n1.longitude as node1_longitude, n1.latitude as node1_latitude,
n2.alias AS alias_right, n2.longitude as node2_longitude, n2.latitude as node2_latitude,
channels.*,
ns1.channels AS channels_left, ns1.capacity AS capacity_left, ns2.channels AS channels_right, ns2.capacity AS capacity_right
FROM channels
LEFT JOIN nodes AS n1 ON n1.public_key = channels.node1_public_key
LEFT JOIN nodes AS n2 ON n2.public_key = channels.node2_public_key
LEFT JOIN node_stats AS ns1 ON ns1.public_key = channels.node1_public_key
LEFT JOIN node_stats AS ns2 ON ns2.public_key = channels.node2_public_key
WHERE (
ns1.id = (
SELECT MAX(id)
FROM node_stats
WHERE public_key = channels.node1_public_key
)
AND ns2.id = (
SELECT MAX(id)
FROM node_stats
WHERE public_key = channels.node2_public_key
)
)
AND channels.id = ?
`;
const [rows]: any = await DB.query(query, [id]);
if (rows[0]) {
return this.convertChannel(rows[0]);
@ -289,6 +313,8 @@ class ChannelsApi {
'max_htlc_mtokens': channel.node1_max_htlc_mtokens,
'min_htlc_mtokens': channel.node1_min_htlc_mtokens,
'updated_at': channel.node1_updated_at,
'longitude': channel.node1_longitude,
'latitude': channel.node1_latitude,
},
'node_right': {
'alias': channel.alias_right,
@ -302,6 +328,8 @@ class ChannelsApi {
'max_htlc_mtokens': channel.node2_max_htlc_mtokens,
'min_htlc_mtokens': channel.node2_min_htlc_mtokens,
'updated_at': channel.node2_updated_at,
'longitude': channel.node2_longitude,
'latitude': channel.node2_latitude,
},
};
}

View file

@ -32,6 +32,9 @@ class ChannelsRoutes {
res.status(404).send('Channel not found');
return;
}
res.header('Pragma', 'public');
res.header('Cache-control', 'public');
res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
res.json(channel);
} catch (e) {
res.status(500).send(e instanceof Error ? e.message : e);

View file

@ -14,7 +14,9 @@
<div class="clearfix"></div>
<div class="box">
<app-nodes-channels-map *ngIf="!error" [style]="'channelpage'" [channel]="channelGeo"></app-nodes-channels-map>
<div class="box">
<div class="row">
<div class="col-md">

View file

@ -1,7 +1,7 @@
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';
import { Observable, of } from 'rxjs';
import { catchError, switchMap } from 'rxjs/operators';
import { catchError, switchMap, tap } from 'rxjs/operators';
import { SeoService } from 'src/app/services/seo.service';
import { LightningApiService } from '../lightning-api.service';
@ -14,6 +14,7 @@ import { LightningApiService } from '../lightning-api.service';
export class ChannelComponent implements OnInit {
channel$: Observable<any>;
error: any = null;
channelGeo: number[] = [];
constructor(
private lightningApiService: LightningApiService,
@ -29,9 +30,23 @@ export class ChannelComponent implements OnInit {
this.seoService.setTitle(`Channel: ${params.get('short_id')}`);
return this.lightningApiService.getChannel$(params.get('short_id'))
.pipe(
tap((data) => {
if (!data.node_left.longitude || !data.node_left.latitude ||
!data.node_right.longitude || !data.node_right.latitude) {
this.channelGeo = [];
} else {
this.channelGeo = [
data.node_left.public_key,
data.node_left.alias,
data.node_left.longitude, data.node_left.latitude,
data.node_right.public_key,
data.node_right.alias,
data.node_right.longitude, data.node_right.latitude,
];
}
}),
catchError((err) => {
this.error = err;
console.log(this.error);
return of(null);
})
);

View file

@ -16,8 +16,9 @@ import 'echarts-gl';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class NodesChannelsMap implements OnInit, OnDestroy {
@Input() style: 'graph' | 'nodepage' | 'widget' = 'graph';
@Input() style: 'graph' | 'nodepage' | 'widget' | 'channelpage' = 'graph';
@Input() publicKey: string | undefined;
@Input() channel: any[] = [];
observable$: Observable<any>;
@ -25,6 +26,8 @@ export class NodesChannelsMap implements OnInit, OnDestroy {
zoom: number | undefined;
channelWidth = 0.6;
channelOpacity = 0.1;
channelColor = '#466d9d';
channelCurve = 0;
chartInstance = undefined;
chartOptions: EChartsOption = {};
@ -67,13 +70,29 @@ export class NodesChannelsMap implements OnInit, OnDestroy {
const nodes = [];
const nodesPubkeys = {};
let thisNodeGPS: number[] | undefined = undefined;
for (const channel of data[1]) {
let geoloc = data[1];
if (this.style === 'channelpage') {
if (this.channel.length === 0) {
geoloc = [];
} else {
geoloc = [this.channel];
}
}
for (const channel of geoloc) {
if (!thisNodeGPS && data[2] === channel[0]) {
thisNodeGPS = [channel[2], channel[3]];
} else if (!thisNodeGPS && data[2] === channel[4]) {
thisNodeGPS = [channel[6], channel[7]];
}
// 0 - node1 pubkey
// 1 - node1 alias
// 2,3 - node1 GPS
// 4 - node2 pubkey
// 5 - node2 alias
// 6,7 - node2 GPS
// 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;
@ -115,6 +134,22 @@ export class NodesChannelsMap implements OnInit, OnDestroy {
this.channelWidth = 1;
this.channelOpacity = 1;
}
if (this.style === 'channelpage' && this.channel.length > 0) {
this.channelWidth = 2;
this.channelOpacity = 1;
this.channelColor = '#bafcff';
this.channelCurve = 0.1;
this.center = [
(this.channel[2] + this.channel[6]) / 2,
(this.channel[3] + this.channel[7]) / 2
];
const distance = Math.sqrt(
Math.pow(this.channel[7] - this.channel[3], 2) +
Math.pow(this.channel[6] - this.channel[2], 2)
);
this.zoom = -0.05 * distance + 8;
}
this.prepareChartOptions(nodes, channelsLoc);
}));
@ -202,8 +237,8 @@ export class NodesChannelsMap implements OnInit, OnDestroy {
lineStyle: {
opacity: this.channelOpacity,
width: this.channelWidth,
curveness: 0,
color: '#466d9d',
curveness: this.channelCurve,
color: this.channelColor,
},
blendMode: 'lighter',
tooltip: {