Show channel on the map in channel page
This commit is contained in:
		
							parent
							
								
									7012a480e8
								
							
						
					
					
						commit
						db41aed44b
					
				@ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user