mirror of
https://github.com/mempool/mempool.git
synced 2025-02-22 14:22:44 +01:00
Merge pull request #2273 from mempool/nymkappa/feature/channel-page-map
Show channel on the map in channel page
This commit is contained in:
commit
7fecea9cca
5 changed files with 91 additions and 8 deletions
|
@ -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,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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);
|
||||
})
|
||||
);
|
||||
|
|
|
@ -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: {
|
||||
|
|
Loading…
Add table
Reference in a new issue