From c2f288a8618b4960537544c2c640a31b1878774c Mon Sep 17 00:00:00 2001 From: Miguel Medeiros Date: Fri, 1 Oct 2021 00:16:37 -0300 Subject: [PATCH 1/5] Add mempool chart filtering. --- .../mempool-graph/mempool-graph.component.ts | 178 ++++++++++++------ .../statistics/statistics.component.html | 3 +- .../television/television.component.html | 2 +- 3 files changed, 122 insertions(+), 61 deletions(-) diff --git a/frontend/src/app/components/mempool-graph/mempool-graph.component.ts b/frontend/src/app/components/mempool-graph/mempool-graph.component.ts index c02e8d3f7..1dab981ed 100644 --- a/frontend/src/app/components/mempool-graph/mempool-graph.component.ts +++ b/frontend/src/app/components/mempool-graph/mempool-graph.component.ts @@ -68,9 +68,39 @@ export class MempoolGraphComponent implements OnInit, OnChanges { } onChartReady(myChart: any) { - myChart.getZr().on('mousemove', e => { - if (e.target !== undefined) { - this.hoverIndexSerie = e.target.parent.parent.__ecComponentInfo.index; + myChart.getZr().on('mousemove', (e: any) => { + if (e.target !== undefined && + e.target.parent !== undefined && + e.target.parent.parent !== null && + e.target.parent.parent.__ecComponentInfo !== undefined) { + this.hoverIndexSerie = e.target.parent.parent.__ecComponentInfo.index; + } + }); + + myChart.on('legendselectchanged', (params) => { + let control = false; + Object.entries(params.selected).forEach(([key]) => { + if (control) { + myChart.dispatchAction({ + type: 'legendUnSelect', + name: key + }); + } else { + myChart.dispatchAction({ + type: 'legendSelect', + name: key + }); + } + if (params.name === key) { + control = true; + } + }); + for (let i = 0; i < params.length; i++) { + if (i === 0) { + this.feeLevelsOrdered.push('0 - 1'); + } else { + this.feeLevelsOrdered.push(`${params[i - 1]} - ${params[i]}`); + } } }); } @@ -158,6 +188,26 @@ export class MempoolGraphComponent implements OnInit, OnChanges { series: this.inverted ? [...seriesGraph].reverse() : seriesGraph, hover: true, color: this.inverted ? [...this.chartColorsOrdered].reverse() : this.chartColorsOrdered, + legend: { + bottom: 20, + data: this.inverted ? this.feeLevelsOrdered : [...this.feeLevelsOrdered].reverse(), + left: 0, + icon: 'square', + inactiveColor: '#444', + orient: 'vertical', + pageIconSize: 12, + pageIconColor: '#fff', + pageIconInactiveColor: '#444', + pageTextStyle: { + color: '#666', + }, + show: (this.template === 'advanced') ? true : false, + textStyle: { + color: '#888', + }, + top: 20, + type: 'scroll', + }, tooltip: { show: (window.innerWidth >= 768) ? true : false, trigger: 'axis', @@ -175,85 +225,81 @@ export class MempoolGraphComponent implements OnInit, OnChanges { type: 'line', }, formatter: (params: any) => { - const colorSpan = (index: any) => ` - - ${this.feeLevelsOrdered[index]} - `; - const totals = (values: any) => { - let totalValueTemp = 0; - const totalValueArrayTemp = []; - const valuesInverted = this.inverted ? values : [...values].reverse(); - for (const item of valuesInverted) { - totalValueTemp += item.value; - totalValueArrayTemp.push(totalValueTemp); - } - return { - totalValue: totalValueTemp, - totalValueArray: totalValueArrayTemp.reverse(), - valuesOrdered: this.inverted ? [...values].reverse() : values, - }; - }; - const { totalValue, totalValueArray, valuesOrdered } = totals(params); - const title = `
- ${params[0].axisValue} - - ${this.vbytesPipe.transform(totalValue, 2, 'vB', 'MvB', false)} - -
`; + const { totalValue, totalValueArray } = this.getTotalValues(params); const itemFormatted = []; let totalParcial = 0; let progressPercentageText = ''; - params.map((item: any, index: number) => { + const items = this.inverted ? [...params].reverse() : params; + items.map((item: any, index: number) => { totalParcial += item.value; let progressPercentage = 0; let progressPercentageSum = 0; - if (index <= this.feeLimitIndex) { - progressPercentage = (item.value / totalValue) * 100; - progressPercentageSum = (totalValueArray[index] / totalValue) * 100; - let activeItemClass = ''; - const hoverActive = (this.inverted) ? Math.abs(item.seriesIndex - params.length + 1) : item.seriesIndex; - if (this.hoverIndexSerie === hoverActive) { - progressPercentageText = `
- - ${formatNumber(progressPercentage, this.locale, '1.2-2')} - % + progressPercentage = (item.value / totalValue) * 100; + progressPercentageSum = (totalValueArray[index] / totalValue) * 100; + let activeItemClass = ''; + let hoverActive: number; + if (this.inverted) { + hoverActive = Math.abs(this.feeLevelsOrdered.length - item.seriesIndex - this.feeLevelsOrdered.length); + } else { + hoverActive = item.seriesIndex; + } + if (this.hoverIndexSerie === hoverActive) { + progressPercentageText = `
+ + ${formatNumber(progressPercentage, this.locale, '1.2-2')} + % + + + ${this.vbytesPipe.transform(totalParcial, 2, 'vB', 'MvB', false)} + +
+ + - - ${this.vbytesPipe.transform(totalParcial, 2, 'vB', 'MvB', false)} - -
- - - -
-
`; - activeItemClass = 'active'; - } - itemFormatted.push(` +
+
`; + activeItemClass = 'active'; + } + itemFormatted.push(` - ${colorSpan(item.seriesIndex)} - - + - ${this.vbytesPipe.transform(valuesOrdered[item.seriesIndex].value, 2, 'vB', 'MvB', false)} + ${this.inverted ? this.feeLevelsOrdered[index] : item.seriesName} - ${this.vbytesPipe.transform(totalValueArray[item.seriesIndex], 2, 'vB', 'MvB', false)} + ${this.vbytesPipe.transform(item.value, 2, 'vB', 'MvB', false)} + + + + + ${this.vbytesPipe.transform(totalValueArray[index], 2, 'vB', 'MvB', false)} - + `); - } }); const classActive = (this.template === 'advanced') ? 'fees-wrapper-tooltip-chart-advanced' : ''; return `
- ${title} +
+ ${params[0].axisValue} + + ${this.vbytesPipe.transform(totalValue, 2, 'vB', 'MvB', false)} + +
@@ -332,5 +378,19 @@ export class MempoolGraphComponent implements OnInit, OnChanges { }, }; } + + getTotalValues = (values: any) => { + let totalValueTemp = 0; + const totalValueArray = []; + const valuesInverted = this.inverted ? values : [...values].reverse(); + for (const item of valuesInverted) { + totalValueTemp += item.value; + totalValueArray.push(totalValueTemp); + } + return { + totalValue: totalValueTemp, + totalValueArray: totalValueArray.reverse(), + }; + } } diff --git a/frontend/src/app/components/statistics/statistics.component.html b/frontend/src/app/components/statistics/statistics.component.html index 9f80de314..1d11e8e8e 100644 --- a/frontend/src/app/components/statistics/statistics.component.html +++ b/frontend/src/app/components/statistics/statistics.component.html @@ -46,7 +46,8 @@ [template]="'advanced'" [limitFee]="500" [height]="500" - [left]="65" + [left]="155" + [right]="10" [data]="mempoolStats" > diff --git a/frontend/src/app/components/television/television.component.html b/frontend/src/app/components/television/television.component.html index e5134c9bd..0143d530d 100644 --- a/frontend/src/app/components/television/television.component.html +++ b/frontend/src/app/components/television/television.component.html @@ -10,7 +10,7 @@ [template]="'advanced'" [limitFee]="500" [height]="600" - [left]="60" + [left]="150" [data]="mempoolStats" [showZoom]="false" > From a2e866d15a315386d086b82876aa3249a9693077 Mon Sep 17 00:00:00 2001 From: Miguel Medeiros Date: Wed, 6 Oct 2021 01:08:13 -0300 Subject: [PATCH 2/5] Change filters to dropdown selection menu. --- .../mempool-graph/mempool-graph.component.ts | 32 +++++++++-------- .../statistics/statistics.component.html | 36 +++++++++++++++++-- .../statistics/statistics.component.scss | 36 +++++++++++++++++++ .../statistics/statistics.component.ts | 14 +++++++- .../television/television.component.html | 3 +- 5 files changed, 103 insertions(+), 18 deletions(-) diff --git a/frontend/src/app/components/mempool-graph/mempool-graph.component.ts b/frontend/src/app/components/mempool-graph/mempool-graph.component.ts index 1dab981ed..4e50f4af2 100644 --- a/frontend/src/app/components/mempool-graph/mempool-graph.component.ts +++ b/frontend/src/app/components/mempool-graph/mempool-graph.component.ts @@ -45,19 +45,6 @@ export class MempoolGraphComponent implements OnInit, OnChanges { ngOnInit(): void { this.inverted = this.storageService.getValue('inverted-graph') === 'true'; - for (let i = 0; i < feeLevels.length; i++) { - if (feeLevels[i] === this.limitFee) { - this.feeLimitIndex = i; - } - if (feeLevels[i] <= this.limitFee) { - if (i === 0) { - this.feeLevelsOrdered.push('0 - 1'); - } else { - this.feeLevelsOrdered.push(`${feeLevels[i - 1]} - ${feeLevels[i]}`); - } - } - } - this.chartColorsOrdered = chartColors.slice(0, this.feeLevelsOrdered.length); this.mountFeeChart(); } @@ -136,6 +123,7 @@ export class MempoolGraphComponent implements OnInit, OnChanges { } mountFeeChart() { + this.orderLevels(); const { labels, series } = this.mempoolVsizeFeesData; const seriesGraph = series.map((value: Array, index: number) => { @@ -201,7 +189,7 @@ export class MempoolGraphComponent implements OnInit, OnChanges { pageTextStyle: { color: '#666', }, - show: (this.template === 'advanced') ? true : false, + show: false, textStyle: { color: '#888', }, @@ -392,5 +380,21 @@ export class MempoolGraphComponent implements OnInit, OnChanges { totalValueArray: totalValueArray.reverse(), }; } + + orderLevels() { + for (let i = 0; i < feeLevels.length; i++) { + if (feeLevels[i] === this.limitFee) { + this.feeLimitIndex = i; + } + if (feeLevels[i] <= this.limitFee) { + if (i === 0) { + this.feeLevelsOrdered.push('0 - 1'); + } else { + this.feeLevelsOrdered.push(`${feeLevels[i - 1]} - ${feeLevels[i]}`); + } + } + } + this.chartColorsOrdered = chartColors.slice(0, this.feeLevelsOrdered.length); + } } diff --git a/frontend/src/app/components/statistics/statistics.component.html b/frontend/src/app/components/statistics/statistics.component.html index 1d11e8e8e..395f37a13 100644 --- a/frontend/src/app/components/statistics/statistics.component.html +++ b/frontend/src/app/components/statistics/statistics.component.html @@ -36,6 +36,38 @@ 1Y + +
+ + +
+ @@ -44,9 +76,9 @@ diff --git a/frontend/src/app/components/statistics/statistics.component.scss b/frontend/src/app/components/statistics/statistics.component.scss index 31eecb8c3..39d5de1b1 100644 --- a/frontend/src/app/components/statistics/statistics.component.scss +++ b/frontend/src/app/components/statistics/statistics.component.scss @@ -61,3 +61,39 @@ .incoming-transactions-graph { height: 600px; } + + +.dropdown-fees { + padding: 10px 0px; + min-width: 130px; + padding: 2px ​20px 0px; + li { + width: 100%; + font-size: 14px; + padding: 0px 0px; + padding-left: 20px; + transition: 200ms all ease-in-out; + &:hover { + background-color: #10121e; + cursor: pointer; + } + } + .square { + transition: 200ms all ease-in-out; + height: 12px; + width: 12px; + margin-right: 10px; + border-radius: 1px; + display: inline-block; + position: relative; + top: 1px; + } + .inactive { + .square { + background-color: #aaa !important; + } + .fee-text { + text-decoration: line-through; + } + } +} diff --git a/frontend/src/app/components/statistics/statistics.component.ts b/frontend/src/app/components/statistics/statistics.component.ts index bd05dc6a1..9302d8d0d 100644 --- a/frontend/src/app/components/statistics/statistics.component.ts +++ b/frontend/src/app/components/statistics/statistics.component.ts @@ -11,6 +11,7 @@ import { ApiService } from '../../services/api.service'; import { StateService } from 'src/app/services/state.service'; import { SeoService } from 'src/app/services/seo.service'; import { StorageService } from 'src/app/services/storage.service'; +import { feeLevels, chartColors } from 'src/app/app.constants'; @Component({ selector: 'app-statistics', @@ -22,6 +23,9 @@ export class StatisticsComponent implements OnInit { loading = true; spinnerLoading = false; + feeLevels = feeLevels; + chartColors = chartColors; + filterFeeIndex = 200; mempoolStats: OptimizedMempoolStats[] = []; @@ -30,7 +34,7 @@ export class StatisticsComponent implements OnInit { mempoolTransactionsWeightPerSecondData: any; radioGroupForm: FormGroup; - graphWindowPreference: String; + graphWindowPreference: string; inverted: boolean; constructor( @@ -46,6 +50,10 @@ export class StatisticsComponent implements OnInit { ngOnInit() { this.inverted = this.storageService.getValue('inverted-graph') === 'true'; + if (!this.inverted) { + this.feeLevels = [...feeLevels].reverse(); + this.chartColors = [...chartColors].reverse(); + } this.seoService.setTitle($localize`:@@5d4f792f048fcaa6df5948575d7cb325c9393383:Graphs`); this.stateService.networkChanged$.subscribe((network) => this.network = network); this.graphWindowPreference = this.storageService.getValue('graphWindowPreference') ? this.storageService.getValue('graphWindowPreference').trim() : '2h'; @@ -131,4 +139,8 @@ export class StatisticsComponent implements OnInit { this.storageService.setValue('inverted-graph', !this.inverted); document.location.reload(); } + + filterFees(index: number) { + this.filterFeeIndex = index; + } } diff --git a/frontend/src/app/components/television/television.component.html b/frontend/src/app/components/television/television.component.html index 0143d530d..4e1a588cc 100644 --- a/frontend/src/app/components/television/television.component.html +++ b/frontend/src/app/components/television/television.component.html @@ -10,7 +10,8 @@ [template]="'advanced'" [limitFee]="500" [height]="600" - [left]="150" + [left]="75" + [right]="10" [data]="mempoolStats" [showZoom]="false" > From 14b7b6427a8578b560138df16a66712a296b9cb5 Mon Sep 17 00:00:00 2001 From: Miguel Medeiros Date: Wed, 6 Oct 2021 01:17:35 -0300 Subject: [PATCH 3/5] Change dropdown button text. --- .../src/app/components/statistics/statistics.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/app/components/statistics/statistics.component.html b/frontend/src/app/components/statistics/statistics.component.html index 395f37a13..6f3a2d4d4 100644 --- a/frontend/src/app/components/statistics/statistics.component.html +++ b/frontend/src/app/components/statistics/statistics.component.html @@ -38,7 +38,7 @@
- +
- +
diff --git a/frontend/src/app/components/statistics/statistics.component.scss b/frontend/src/app/components/statistics/statistics.component.scss index 39d5de1b1..ca367bf17 100644 --- a/frontend/src/app/components/statistics/statistics.component.scss +++ b/frontend/src/app/components/statistics/statistics.component.scss @@ -67,6 +67,14 @@ padding: 10px 0px; min-width: 130px; padding: 2px ​20px 0px; + left: -38px !important; + position: absolute !important; + + ul { + list-style: none; + padding: 0px; + margin-bottom: 0px; + } li { width: 100%; font-size: 14px; @@ -90,10 +98,11 @@ } .inactive { .square { - background-color: #aaa !important; + background-color: #ffffff66 !important; } .fee-text { text-decoration: line-through; + color: #777; } } } diff --git a/frontend/src/app/components/statistics/statistics.component.ts b/frontend/src/app/components/statistics/statistics.component.ts index 9302d8d0d..c55b9b4e1 100644 --- a/frontend/src/app/components/statistics/statistics.component.ts +++ b/frontend/src/app/components/statistics/statistics.component.ts @@ -25,7 +25,8 @@ export class StatisticsComponent implements OnInit { spinnerLoading = false; feeLevels = feeLevels; chartColors = chartColors; - filterFeeIndex = 200; + filterFeeIndex = 500; + dropDownOpen = false; mempoolStats: OptimizedMempoolStats[] = []; @@ -143,4 +144,8 @@ export class StatisticsComponent implements OnInit { filterFees(index: number) { this.filterFeeIndex = index; } + + filterClick() { + this.dropDownOpen = !this.dropDownOpen; + } } diff --git a/frontend/src/app/components/television/television.component.html b/frontend/src/app/components/television/television.component.html index 4e1a588cc..3644c4d6a 100644 --- a/frontend/src/app/components/television/television.component.html +++ b/frontend/src/app/components/television/television.component.html @@ -10,7 +10,7 @@ [template]="'advanced'" [limitFee]="500" [height]="600" - [left]="75" + [left]="60" [right]="10" [data]="mempoolStats" [showZoom]="false" From a43cd48795ff7e02329438e11ce7d202e5e596e3 Mon Sep 17 00:00:00 2001 From: Miguel Medeiros Date: Thu, 7 Oct 2021 16:03:21 -0300 Subject: [PATCH 5/5] Remove unecessary code to controle legends. Fix order of active and inactive fee ranges. --- .../mempool-graph/mempool-graph.component.ts | 52 ++----------------- .../statistics/statistics.component.html | 7 +-- .../statistics/statistics.component.ts | 2 +- 3 files changed, 8 insertions(+), 53 deletions(-) diff --git a/frontend/src/app/components/mempool-graph/mempool-graph.component.ts b/frontend/src/app/components/mempool-graph/mempool-graph.component.ts index 4e50f4af2..43f652fad 100644 --- a/frontend/src/app/components/mempool-graph/mempool-graph.component.ts +++ b/frontend/src/app/components/mempool-graph/mempool-graph.component.ts @@ -17,6 +17,7 @@ import { feeLevels, chartColors } from 'src/app/app.constants'; export class MempoolGraphComponent implements OnInit, OnChanges { @Input() data: any[]; @Input() limitFee = 350; + @Input() limitFilterFee = 1; @Input() height: number | string = 200; @Input() top: number | string = 20; @Input() right: number | string = 10; @@ -63,33 +64,6 @@ export class MempoolGraphComponent implements OnInit, OnChanges { this.hoverIndexSerie = e.target.parent.parent.__ecComponentInfo.index; } }); - - myChart.on('legendselectchanged', (params) => { - let control = false; - Object.entries(params.selected).forEach(([key]) => { - if (control) { - myChart.dispatchAction({ - type: 'legendUnSelect', - name: key - }); - } else { - myChart.dispatchAction({ - type: 'legendSelect', - name: key - }); - } - if (params.name === key) { - control = true; - } - }); - for (let i = 0; i < params.length; i++) { - if (i === 0) { - this.feeLevelsOrdered.push('0 - 1'); - } else { - this.feeLevelsOrdered.push(`${params[i - 1]} - ${params[i]}`); - } - } - }); } handleNewMempoolData(mempoolStats: OptimizedMempoolStats[]) { @@ -127,7 +101,7 @@ export class MempoolGraphComponent implements OnInit, OnChanges { const { labels, series } = this.mempoolVsizeFeesData; const seriesGraph = series.map((value: Array, index: number) => { - if (index <= this.feeLimitIndex){ + if (index >= this.feeLimitIndex){ return { name: this.feeLevelsOrdered[index], type: 'line', @@ -176,26 +150,6 @@ export class MempoolGraphComponent implements OnInit, OnChanges { series: this.inverted ? [...seriesGraph].reverse() : seriesGraph, hover: true, color: this.inverted ? [...this.chartColorsOrdered].reverse() : this.chartColorsOrdered, - legend: { - bottom: 20, - data: this.inverted ? this.feeLevelsOrdered : [...this.feeLevelsOrdered].reverse(), - left: 0, - icon: 'square', - inactiveColor: '#444', - orient: 'vertical', - pageIconSize: 12, - pageIconColor: '#fff', - pageIconInactiveColor: '#444', - pageTextStyle: { - color: '#666', - }, - show: false, - textStyle: { - color: '#888', - }, - top: 20, - type: 'scroll', - }, tooltip: { show: (window.innerWidth >= 768) ? true : false, trigger: 'axis', @@ -383,7 +337,7 @@ export class MempoolGraphComponent implements OnInit, OnChanges { orderLevels() { for (let i = 0; i < feeLevels.length; i++) { - if (feeLevels[i] === this.limitFee) { + if (feeLevels[i] === this.limitFilterFee) { this.feeLimitIndex = i; } if (feeLevels[i] <= this.limitFee) { diff --git a/frontend/src/app/components/statistics/statistics.component.html b/frontend/src/app/components/statistics/statistics.component.html index ec12da928..df372db3f 100644 --- a/frontend/src/app/components/statistics/statistics.component.html +++ b/frontend/src/app/components/statistics/statistics.component.html @@ -45,7 +45,7 @@
    -
  • +
  • @@ -56,7 +56,7 @@
  • -
  • +
  • {{feeLevels[i - 1]}} - {{ fee }} @@ -80,7 +80,8 @@