Merge pull request #2519 from mempool/nymkappa/bugfix/show-hybrid-nodes-chart
Show tor+clearnet node series in chart
This commit is contained in:
		
						commit
						fd8d61e742
					
				| @ -6,7 +6,8 @@ class StatisticsApi { | |||||||
|   public async $getStatistics(interval: string | null = null): Promise<any> { |   public async $getStatistics(interval: string | null = null): Promise<any> { | ||||||
|     interval = Common.getSqlInterval(interval); |     interval = Common.getSqlInterval(interval); | ||||||
| 
 | 
 | ||||||
|     let query = `SELECT UNIX_TIMESTAMP(added) AS added, channel_count, total_capacity, tor_nodes, clearnet_nodes, unannounced_nodes
 |     let query = `SELECT UNIX_TIMESTAMP(added) AS added, channel_count, total_capacity,
 | ||||||
|  |       tor_nodes, clearnet_nodes, unannounced_nodes, clearnet_tor_nodes | ||||||
|       FROM lightning_stats`;
 |       FROM lightning_stats`;
 | ||||||
| 
 | 
 | ||||||
|     if (interval) { |     if (interval) { | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit, HostBinding } from '@angular/core'; | import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit, HostBinding } from '@angular/core'; | ||||||
| import { EChartsOption, graphic} from 'echarts'; | import { EChartsOption, graphic, LineSeriesOption} from 'echarts'; | ||||||
| import { Observable } from 'rxjs'; | import { Observable } from 'rxjs'; | ||||||
| import { map, share, startWith, switchMap, tap } from 'rxjs/operators'; | import { map, share, startWith, switchMap, tap } from 'rxjs/operators'; | ||||||
| import { formatNumber } from '@angular/common'; | import { formatNumber } from '@angular/common'; | ||||||
| @ -89,10 +89,11 @@ export class NodesNetworksChartComponent implements OnInit { | |||||||
|                   tor_nodes: data.map(val => [val.added * 1000, val.tor_nodes]), |                   tor_nodes: data.map(val => [val.added * 1000, val.tor_nodes]), | ||||||
|                   clearnet_nodes: data.map(val => [val.added * 1000, val.clearnet_nodes]), |                   clearnet_nodes: data.map(val => [val.added * 1000, val.clearnet_nodes]), | ||||||
|                   unannounced_nodes: data.map(val => [val.added * 1000, val.unannounced_nodes]), |                   unannounced_nodes: data.map(val => [val.added * 1000, val.unannounced_nodes]), | ||||||
|  |                   clearnet_tor_nodes: data.map(val => [val.added * 1000, val.clearnet_tor_nodes]), | ||||||
|                 }; |                 }; | ||||||
|                 let maxYAxis = 0; |                 let maxYAxis = 0; | ||||||
|                 for (const day of data) { |                 for (const day of data) { | ||||||
|                   maxYAxis = Math.max(maxYAxis, day.tor_nodes + day.clearnet_nodes + day.unannounced_nodes); |                   maxYAxis = Math.max(maxYAxis, day.tor_nodes + day.clearnet_nodes + day.unannounced_nodes + day.clearnet_tor_nodes); | ||||||
|                 } |                 } | ||||||
|                 maxYAxis = Math.ceil(maxYAxis / 3000) * 3000; |                 maxYAxis = Math.ceil(maxYAxis / 3000) * 3000; | ||||||
|                 this.prepareChartOptions(chartData, maxYAxis); |                 this.prepareChartOptions(chartData, maxYAxis); | ||||||
| @ -134,6 +135,94 @@ export class NodesNetworksChartComponent implements OnInit { | |||||||
|       }; |       }; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     const series: LineSeriesOption[] = [ | ||||||
|  |       { | ||||||
|  |         zlevel: 1, | ||||||
|  |         yAxisIndex: 0, | ||||||
|  |         name: $localize`Unknown`, | ||||||
|  |         showSymbol: false, | ||||||
|  |         symbol: 'none', | ||||||
|  |         data: data.unannounced_nodes, | ||||||
|  |         type: 'line', | ||||||
|  |         lineStyle: { | ||||||
|  |           width: 2, | ||||||
|  |         }, | ||||||
|  |         areaStyle: { | ||||||
|  |           opacity: 0.5, | ||||||
|  |         }, | ||||||
|  |         stack: 'Total', | ||||||
|  |         color: new graphic.LinearGradient(0, 0.75, 0, 1, [ | ||||||
|  |           { offset: 0, color: '#D81B60' }, | ||||||
|  |           { offset: 1, color: '#D81B60AA' }, | ||||||
|  |         ]), | ||||||
|  | 
 | ||||||
|  |         smooth: false, | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         zlevel: 1, | ||||||
|  |         yAxisIndex: 0, | ||||||
|  |         name: $localize`Reachable on Clearnet Only`, | ||||||
|  |         showSymbol: false, | ||||||
|  |         symbol: 'none', | ||||||
|  |         data: data.clearnet_nodes, | ||||||
|  |         type: 'line', | ||||||
|  |         lineStyle: { | ||||||
|  |           width: 2, | ||||||
|  |         }, | ||||||
|  |         areaStyle: { | ||||||
|  |           opacity: 0.5, | ||||||
|  |         }, | ||||||
|  |         stack: 'Total', | ||||||
|  |         color: new graphic.LinearGradient(0, 0.75, 0, 1, [ | ||||||
|  |           { offset: 0, color: '#FFB300' }, | ||||||
|  |           { offset: 1, color: '#FFB300AA' }, | ||||||
|  |         ]), | ||||||
|  |         smooth: false, | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         zlevel: 1, | ||||||
|  |         yAxisIndex: 0, | ||||||
|  |         name: $localize`Reachable on Clearnet and Darknet`, | ||||||
|  |         showSymbol: false, | ||||||
|  |         symbol: 'none', | ||||||
|  |         data: data.clearnet_tor_nodes, | ||||||
|  |         type: 'line', | ||||||
|  |         lineStyle: { | ||||||
|  |           width: 2, | ||||||
|  |         }, | ||||||
|  |         areaStyle: { | ||||||
|  |           opacity: 0.5, | ||||||
|  |         }, | ||||||
|  |         stack: 'Total', | ||||||
|  |         color: new graphic.LinearGradient(0, 0.75, 0, 1, [ | ||||||
|  |           { offset: 0, color: '#be7d4c' }, | ||||||
|  |           { offset: 1, color: '#be7d4cAA' }, | ||||||
|  |         ]), | ||||||
|  |         smooth: false, | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         zlevel: 1, | ||||||
|  |         yAxisIndex: 0, | ||||||
|  |         name: $localize`Reachable on Darknet Only`, | ||||||
|  |         showSymbol: false, | ||||||
|  |         symbol: 'none', | ||||||
|  |         data: data.tor_nodes, | ||||||
|  |         type: 'line', | ||||||
|  |         lineStyle: { | ||||||
|  |           width: 2, | ||||||
|  |         }, | ||||||
|  |         areaStyle: { | ||||||
|  |           opacity: 0.5, | ||||||
|  |         }, | ||||||
|  |         stack: 'Total', | ||||||
|  |         color: new graphic.LinearGradient(0, 0.75, 0, 1, [ | ||||||
|  |           { offset: 0, color: '#7D4698' }, | ||||||
|  |           { offset: 1, color: '#7D4698AA' }, | ||||||
|  |         ]), | ||||||
|  |         smooth: false, | ||||||
|  |       }, | ||||||
|  |     ]; | ||||||
|  | 
 | ||||||
|     this.chartOptions = { |     this.chartOptions = { | ||||||
|       title: title, |       title: title, | ||||||
|       animation: false, |       animation: false, | ||||||
| @ -164,12 +253,17 @@ export class NodesNetworksChartComponent implements OnInit { | |||||||
|           let tooltip = `<b style="color: white; margin-left: 2px">${date}</b><br>`; |           let tooltip = `<b style="color: white; margin-left: 2px">${date}</b><br>`; | ||||||
| 
 | 
 | ||||||
|           for (const tick of ticks.reverse()) { |           for (const tick of ticks.reverse()) { | ||||||
|  |             if (tick.seriesName.indexOf('ignored') !== -1) { | ||||||
|  |               continue; | ||||||
|  |             } | ||||||
|             if (tick.seriesIndex === 0) { // Tor
 |             if (tick.seriesIndex === 0) { // Tor
 | ||||||
|               tooltip += `${tick.marker} ${tick.seriesName}: ${formatNumber(tick.data[1], this.locale, '1.0-0')}`; |               tooltip += `${tick.marker} ${tick.seriesName}: ${formatNumber(tick.data[1], this.locale, '1.0-0')}`; | ||||||
|             } else if (tick.seriesIndex === 1) { // Clearnet
 |             } else if (tick.seriesIndex === 1) { // Clearnet
 | ||||||
|               tooltip += `${tick.marker} ${tick.seriesName}: ${formatNumber(tick.data[1], this.locale, '1.0-0')}`; |               tooltip += `${tick.marker} ${tick.seriesName}: ${formatNumber(tick.data[1], this.locale, '1.0-0')}`; | ||||||
|             } else if (tick.seriesIndex === 2) { // Unannounced
 |             } else if (tick.seriesIndex === 2) { // Unannounced
 | ||||||
|               tooltip += `${tick.marker} ${tick.seriesName}: ${formatNumber(tick.data[1], this.locale, '1.0-0')}`; |               tooltip += `${tick.marker} ${tick.seriesName}: ${formatNumber(tick.data[1], this.locale, '1.0-0')}`; | ||||||
|  |             } else if (tick.seriesIndex === 3) { // Tor + Clearnet
 | ||||||
|  |               tooltip += `${tick.marker} ${tick.seriesName}: ${formatNumber(tick.data[1], this.locale, '1.0-0')}`; | ||||||
|             } |             } | ||||||
|             tooltip += `<br>`; |             tooltip += `<br>`; | ||||||
|             total += tick.data[1]; |             total += tick.data[1]; | ||||||
| @ -190,7 +284,7 @@ export class NodesNetworksChartComponent implements OnInit { | |||||||
|         padding: 10, |         padding: 10, | ||||||
|         data: [ |         data: [ | ||||||
|           { |           { | ||||||
|             name: $localize`Total`, |             name: $localize`Reachable on Darknet Only`, | ||||||
|             inactiveColor: 'rgb(110, 112, 121)', |             inactiveColor: 'rgb(110, 112, 121)', | ||||||
|             textStyle: { |             textStyle: { | ||||||
|               color: 'white', |               color: 'white', | ||||||
| @ -198,7 +292,7 @@ export class NodesNetworksChartComponent implements OnInit { | |||||||
|             icon: 'roundRect', |             icon: 'roundRect', | ||||||
|           }, |           }, | ||||||
|           { |           { | ||||||
|             name: $localize`Tor`, |             name: $localize`Reachable on Clearnet and Darknet`, | ||||||
|             inactiveColor: 'rgb(110, 112, 121)', |             inactiveColor: 'rgb(110, 112, 121)', | ||||||
|             textStyle: { |             textStyle: { | ||||||
|               color: 'white', |               color: 'white', | ||||||
| @ -206,7 +300,7 @@ export class NodesNetworksChartComponent implements OnInit { | |||||||
|             icon: 'roundRect', |             icon: 'roundRect', | ||||||
|           }, |           }, | ||||||
|           { |           { | ||||||
|             name: $localize`Clearnet`, |             name: $localize`Reachable on Clearnet Only`, | ||||||
|             inactiveColor: 'rgb(110, 112, 121)', |             inactiveColor: 'rgb(110, 112, 121)', | ||||||
|             textStyle: { |             textStyle: { | ||||||
|               color: 'white', |               color: 'white', | ||||||
| @ -214,7 +308,7 @@ export class NodesNetworksChartComponent implements OnInit { | |||||||
|             icon: 'roundRect', |             icon: 'roundRect', | ||||||
|           }, |           }, | ||||||
|           { |           { | ||||||
|             name: $localize`Unannounced`, |             name: $localize`Unknown`, | ||||||
|             inactiveColor: 'rgb(110, 112, 121)', |             inactiveColor: 'rgb(110, 112, 121)', | ||||||
|             textStyle: { |             textStyle: { | ||||||
|               color: 'white', |               color: 'white', | ||||||
| @ -223,10 +317,10 @@ export class NodesNetworksChartComponent implements OnInit { | |||||||
|           }, |           }, | ||||||
|         ], |         ], | ||||||
|         selected: this.widget ? undefined : JSON.parse(this.storageService.getValue('nodes_networks_legend'))  ?? { |         selected: this.widget ? undefined : JSON.parse(this.storageService.getValue('nodes_networks_legend'))  ?? { | ||||||
|           'Total': true, |           '$localize`Reachable on Darknet Only`': true, | ||||||
|           'Tor': true, |           '$localize`Reachable on Clearnet Only`': true, | ||||||
|           'Clearnet': true, |           '$localize`Reachable on Clearnet and Darknet`': true, | ||||||
|           'Unannounced': true, |           '$localize`Unknown`': true, | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|       yAxis: data.tor_nodes.length === 0 ? undefined : [ |       yAxis: data.tor_nodes.length === 0 ? undefined : [ | ||||||
| @ -250,7 +344,6 @@ export class NodesNetworksChartComponent implements OnInit { | |||||||
|               opacity: 0.25, |               opacity: 0.25, | ||||||
|             }, |             }, | ||||||
|           }, |           }, | ||||||
|           max: maxYAxis, |  | ||||||
|           min: 0, |           min: 0, | ||||||
|           interval: 3000, |           interval: 3000, | ||||||
|         }, |         }, | ||||||
| @ -274,77 +367,25 @@ export class NodesNetworksChartComponent implements OnInit { | |||||||
|               opacity: 0.25, |               opacity: 0.25, | ||||||
|             }, |             }, | ||||||
|           }, |           }, | ||||||
|           max: maxYAxis, |  | ||||||
|           min: 0, |           min: 0, | ||||||
|           interval: 3000, |           interval: 3000, | ||||||
|         } |         } | ||||||
|       ], |       ], | ||||||
|       series: data.tor_nodes.length === 0 ? [] : [ |       series: data.tor_nodes.length === 0 ? [] : series.concat(series.map((serie) => { | ||||||
|         { |         // We create dummy duplicated series so when we use the data zoom, the y axis
 | ||||||
|           zlevel: 1, |         // both scales properly
 | ||||||
|           yAxisIndex: 0, |         const invisibleSerie = {...serie}; | ||||||
|           name: $localize`Unannounced`, |         invisibleSerie.name = 'ignored' + Math.random().toString();  | ||||||
|           showSymbol: false, |         invisibleSerie.stack = 'ignored'; | ||||||
|           symbol: 'none', |         invisibleSerie.yAxisIndex = 1; | ||||||
|           data: data.unannounced_nodes, |         invisibleSerie.lineStyle = { | ||||||
|           type: 'line', |           opacity: 0, | ||||||
|           lineStyle: { |         }; | ||||||
|             width: 2, |         invisibleSerie.areaStyle = { | ||||||
|           }, |           opacity: 0, | ||||||
|           areaStyle: { |         }; | ||||||
|             opacity: 0.5, |         return invisibleSerie; | ||||||
|           }, |       })), | ||||||
|           stack: 'Total', |  | ||||||
|           color: new graphic.LinearGradient(0, 0.75, 0, 1, [ |  | ||||||
|             { offset: 0, color: '#D81B60' }, |  | ||||||
|             { offset: 1, color: '#D81B60AA' }, |  | ||||||
|           ]), |  | ||||||
| 
 |  | ||||||
|           smooth: false, |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|           zlevel: 1, |  | ||||||
|           yAxisIndex: 0, |  | ||||||
|           name: $localize`Clearnet`, |  | ||||||
|           showSymbol: false, |  | ||||||
|           symbol: 'none', |  | ||||||
|           data: data.clearnet_nodes, |  | ||||||
|           type: 'line', |  | ||||||
|           lineStyle: { |  | ||||||
|             width: 2, |  | ||||||
|           }, |  | ||||||
|           areaStyle: { |  | ||||||
|             opacity: 0.5, |  | ||||||
|           }, |  | ||||||
|           stack: 'Total', |  | ||||||
|           color: new graphic.LinearGradient(0, 0.75, 0, 1, [ |  | ||||||
|             { offset: 0, color: '#FFB300' }, |  | ||||||
|             { offset: 1, color: '#FFB300AA' }, |  | ||||||
|           ]), |  | ||||||
|           smooth: false, |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|           zlevel: 1, |  | ||||||
|           yAxisIndex: 1, |  | ||||||
|           name: $localize`Tor`, |  | ||||||
|           showSymbol: false, |  | ||||||
|           symbol: 'none', |  | ||||||
|           data: data.tor_nodes, |  | ||||||
|           type: 'line', |  | ||||||
|           lineStyle: { |  | ||||||
|             width: 2, |  | ||||||
|           }, |  | ||||||
|           areaStyle: { |  | ||||||
|             opacity: 0.5, |  | ||||||
|           }, |  | ||||||
|           stack: 'Total', |  | ||||||
|           color: new graphic.LinearGradient(0, 0.75, 0, 1, [ |  | ||||||
|             { offset: 0, color: '#7D4698' }, |  | ||||||
|             { offset: 1, color: '#7D4698AA' }, |  | ||||||
|           ]), |  | ||||||
|           smooth: false, |  | ||||||
|         }, |  | ||||||
|       ], |  | ||||||
|       dataZoom: this.widget ? null : [{ |       dataZoom: this.widget ? null : [{ | ||||||
|         type: 'inside', |         type: 'inside', | ||||||
|         realtime: true, |         realtime: true, | ||||||
| @ -371,6 +412,11 @@ export class NodesNetworksChartComponent implements OnInit { | |||||||
|         }, |         }, | ||||||
|       }], |       }], | ||||||
|     }; |     }; | ||||||
|  | 
 | ||||||
|  |     if (isMobile()) { | ||||||
|  |       // @ts-ignore
 | ||||||
|  |       this.chartOptions.legend.left = 50; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   onChartInit(ec): void { |   onChartInit(ec): void { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user