Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/network stats #931

Merged
merged 52 commits into from
Mar 16, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
d21c3cb
refactoring styles
Nikita-Polyakov Jan 24, 2023
eebe210
refactoring letter-spacing
Nikita-Polyakov Jan 24, 2023
30c22af
network-stats-row
Nikita-Polyakov Jan 25, 2023
3d62e6a
improve network stats adaptive
Nikita-Polyakov Jan 25, 2023
1848884
refactoring columns data
Nikita-Polyakov Jan 26, 2023
fdc5549
merge origin/develop
Nikita-Polyakov Jan 26, 2023
bb9322f
change group data logic
Nikita-Polyakov Jan 26, 2023
8683d03
tvl chart wip
Nikita-Polyakov Jan 26, 2023
4447eee
add ChartSkeleton component
Nikita-Polyakov Jan 27, 2023
42f294d
handle chart error & update tooltip
Nikita-Polyakov Jan 27, 2023
c26171c
Merge branch 'develop' into feature/network-stats
Nikita-Polyakov Jan 27, 2023
fdf8b84
add volume chart example
Nikita-Polyakov Jan 27, 2023
a985941
Merge branch 'develop' into feature/network-stats
Nikita-Polyakov Jan 27, 2023
a1bb4c6
Merge remote-tracking branch 'origin/develop' into feature/network-stats
Nikita-Polyakov Jan 30, 2023
caf5b0f
refactoring specs
Nikita-Polyakov Jan 30, 2023
faafdfe
Merge remote-tracking branch 'origin/develop' into feature/network-stats
Nikita-Polyakov Jan 30, 2023
22f5cd4
refactoring components folder structure
Nikita-Polyakov Jan 30, 2023
d3aef66
wip refactoring folders structure
Nikita-Polyakov Jan 31, 2023
b6ace32
refactoring components folders
Nikita-Polyakov Jan 31, 2023
3b7029f
wip fees chart
Nikita-Polyakov Feb 1, 2023
5073851
fix charts fetching
Nikita-Polyakov Feb 1, 2023
8530789
data fetching for supply chart
Nikita-Polyakov Feb 1, 2023
9921fa0
add token-dropdown to supply chart
Nikita-Polyakov Feb 2, 2023
9e5efe7
skeleton fixes
Nikita-Polyakov Feb 2, 2023
5fead3d
fixes
Nikita-Polyakov Feb 3, 2023
e855e09
fix error
Nikita-Polyakov Feb 3, 2023
5048e9c
Merge remote-tracking branch 'origin/develop' into feature/network-stats
Nikita-Polyakov Feb 6, 2023
9cbe615
refactoring
Nikita-Polyakov Feb 6, 2023
c27fd96
merge origin/develop
Nikita-Polyakov Feb 9, 2023
5ae7e7d
Merge remote-tracking branch 'origin/develop' into feature/network-stats
Nikita-Polyakov Feb 15, 2023
64450f6
fix imports
Nikita-Polyakov Feb 15, 2023
c3fe218
Merge branch 'develop' into feature/network-stats
Nikita-Polyakov Feb 15, 2023
efb0d2c
update network stats components
Nikita-Polyakov Feb 15, 2023
0e26f40
refactoring charts data fetching
Nikita-Polyakov Feb 15, 2023
6413423
update translations
Nikita-Polyakov Feb 15, 2023
1e32688
Merge branch 'develop' into feature/network-stats
stefashkaa Feb 17, 2023
0de72d4
test
wpi86 Feb 17, 2023
f2ada46
revert lib
wpi86 Feb 17, 2023
92c9087
Merge branch 'develop' into feature/network-stats
Nikita-Polyakov Feb 20, 2023
511aaf4
refactoring imports
Nikita-Polyakov Feb 20, 2023
e2250c3
refactoring MarketAlgorithm paths
Nikita-Polyakov Feb 20, 2023
99b2b3f
fix weekly stats, legend, x axis overlap
Nikita-Polyakov Feb 23, 2023
39823e1
SimpleNotification from wallet
Nikita-Polyakov Feb 24, 2023
540c010
update according qa
Nikita-Polyakov Mar 1, 2023
89a4dac
update translations
Nikita-Polyakov Mar 1, 2023
1562b97
network stats chart fixes
Nikita-Polyakov Mar 1, 2023
5f42aea
supply bar chart
Nikita-Polyakov Mar 1, 2023
5004d4c
Merge remote-tracking branch 'origin/develop' into feature/network-stats
Nikita-Polyakov Mar 10, 2023
04fdf43
Merge remote-tracking branch 'origin/develop' into feature/network-stats
Nikita-Polyakov Mar 15, 2023
9bfc02e
update supply color, explore method
Nikita-Polyakov Mar 15, 2023
0346fdd
merge origin/develop
Nikita-Polyakov Mar 15, 2023
546df79
Merge branch 'develop' into feature/network-stats
stefashkaa Mar 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
tvl chart wip
  • Loading branch information
Nikita-Polyakov committed Jan 26, 2023
commit 8683d0306bdd9e08e847dc43c846689add945c90
54 changes: 8 additions & 46 deletions src/components/Stats/components/NetworkStats.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ import { KnownSymbols } from '@sora-substrate/util/build/assets/consts';

import { lazyComponent } from '@/router';
import { Components } from '@/consts';
import { SECONDS_IN_TYPE } from '@/consts/snapshots';
import { Timeframes, SnapshotTypes } from '@/types/filters';
import { SECONDS_IN_TYPE, NETWORK_STATS_FILTERS } from '@/consts/snapshots';
import { SnapshotTypes } from '@/types/filters';
import { calcPriceChange, formatAmountWithSuffix } from '@/utils';

import type { AmountWithSuffix } from '@/types/formats';
Expand Down Expand Up @@ -81,44 +81,6 @@ const StatsQuery = gql`
}
`;

const NETWORK_STATS_FILTERS = [
{
name: Timeframes.DAY,
label: '1D',
type: SnapshotTypes.HOUR,
count: 48,
group: 24,
},
{
name: Timeframes.WEEK,
label: '1W',
type: SnapshotTypes.DAY,
count: 14,
group: 7,
},
{
name: Timeframes.MONTH,
label: '1M',
type: SnapshotTypes.DAY,
count: 60,
group: 30,
},
{
name: Timeframes.QUARTER,
label: '3M',
type: SnapshotTypes.MONTH,
count: 6,
group: 3,
},
{
name: Timeframes.YEAR,
label: '1Y',
type: SnapshotTypes.MONTH,
count: 24,
group: 12,
},
];

const COLUMNS = [
{
title: 'Transactions',
Expand Down Expand Up @@ -183,11 +145,11 @@ export default class NetworkStats extends Mixins(mixins.LoadingMixin) {
}

private groupData(data: NetworkSnapshot[]): Nullable<NetworkSnapshot> {
return data.reduce((buffer, item) => {
return data.reduce<Nullable<NetworkSnapshot>>((buffer, item) => {
if (!buffer) return item;

for (const prop in buffer) {
buffer[prop] = buffer[prop].add(item[prop]);
for (const { prop } of COLUMNS) {
(buffer[prop] as FPNumber) = (buffer[prop] as FPNumber).add(item[prop]);
}

return buffer;
Expand All @@ -196,11 +158,11 @@ export default class NetworkStats extends Mixins(mixins.LoadingMixin) {

private async updateData(): Promise<void> {
await this.withLoading(async () => {
const { type, group } = this.filter;
const { type, count } = this.filter;
const seconds = SECONDS_IN_TYPE[type];
const now = Math.floor(Date.now() / (seconds * 1000)) * seconds; // rounded to latest snapshot type
const aTime = now - seconds * group;
const bTime = aTime - seconds * group;
const aTime = now - seconds * count;
const bTime = aTime - seconds * count;

const [curr, prev] = await Promise.all([this.fetchData(now, aTime, type), this.fetchData(aTime, bTime, type)]);

Expand Down
188 changes: 188 additions & 0 deletions src/components/Stats/components/TvlChart.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
<template>
<stats-card>
<template #title>TVL</template>

<template #filters>
<stats-filter :filters="filters" :value="filter" @input="changeFilter" />
</template>

<v-chart ref="chart" class="chart" :option="chartSpec" autoresize />
</stats-card>
</template>

<script lang="ts">
import dayjs from 'dayjs';
import { graphic } from 'echarts';
import { gql } from '@urql/core';
import { Component, Mixins } from 'vue-property-decorator';
import { components, mixins, SubqueryExplorerService, WALLET_CONSTS } from '@soramitsu/soraneo-wallet-web';

import { lazyComponent } from '@/router';
import { Components } from '@/consts';
import { SECONDS_IN_TYPE, NETWORK_STATS_FILTERS } from '@/consts/snapshots';
import { Timeframes, SnapshotTypes } from '@/types/filters';

import type { SnapshotFilter } from '@/types/filters';

type NetworkTvlSnapshot = {
timestamp: number;
value: number;
};

const NetworkTvlQuery = gql`
query NetworkTvlQuery($type: SnapshotType, $from: Int, $to: Int) {
networkSnapshots(
orderBy: TIMESTAMP_DESC
filter: {
and: [
{ type: { equalTo: $type } }
{ timestamp: { lessThanOrEqualTo: $from } }
{ timestamp: { greaterThanOrEqualTo: $to } }
]
}
) {
nodes {
timestamp
liquidityUSD
}
}
}
`;

@Component({
components: {
PriceChange: lazyComponent(Components.PriceChange),
StatsCard: lazyComponent(Components.StatsCard),
StatsFilter: lazyComponent(Components.StatsFilter),
FormattedAmount: components.FormattedAmount,
},
})
export default class TvlChart extends Mixins(mixins.LoadingMixin) {
readonly filters = NETWORK_STATS_FILTERS;

filter: SnapshotFilter = NETWORK_STATS_FILTERS[0];

data: NetworkTvlSnapshot[] = [];

created(): void {
this.updateData();
}

get chartSpec() {
return {
grid: {
top: 20,
left: 10,
right: 10,
bottom: 20,
},
xAxis: {
type: 'category',
boundaryGap: false,
data: this.data.map((item) => item.timestamp),
axisLabel: {
formatter(value) {
return dayjs(+value).format('DD');
},
},
axisPointer: {
show: true,
type: 'line',
animation: false,
label: {
show: false,
},
lineStyle: {
color: '#ADB9CE',
type: 'solid',
},
},
axisTick: {
show: false,
},
axisLine: {
show: false,
},
},
yAxis: {
show: false,
type: 'value',
},
series: [
{
data: this.data.map((item) => item.value),
type: 'line',
showSymbol: false,
itemStyle: {
color: '#0263F5',
},
areaStyle: {
opacity: 0.8,
color: new graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: 'rgba(248, 8, 123, 0.25)',
},
{
offset: 1,
color: 'rgba(255, 49, 148, 0.03)',
},
]),
},
emphasis: {
disabled: true,
},
},
],
};
}

changeFilter(filter: SnapshotFilter): void {
this.filter = filter;
this.updateData();
}

private async updateData(): Promise<void> {
await this.withLoading(async () => {
const { type, count } = this.filter;
const seconds = SECONDS_IN_TYPE[type];
const now = Math.floor(Date.now() / (seconds * 1000)) * seconds; // rounded to latest snapshot type
const to = now - seconds * count;

this.data = await this.fetchData(now, to, type);
});
}

private async fetchData(from: number, to: number, type: SnapshotTypes): Promise<NetworkTvlSnapshot[]> {
try {
const response = await SubqueryExplorerService.request(NetworkTvlQuery, { from, to, type });

if (!response || !response.networkSnapshots) return [];

const data = response.networkSnapshots.nodes.map((node) => {
return {
timestamp: +node.timestamp * 1000,
value: +node.liquidityUSD,
};
});

return data;
} catch (error) {
console.log(error);
return [];
}
}
}
</script>

<style lang="scss" scoped>
.chart {
height: 283px;
}

@include large-desktop {
.chart {
height: 323px;
}
}
</style>
2 changes: 1 addition & 1 deletion src/components/Swap/Chart.vue
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@

<script lang="ts">
import dayjs from 'dayjs';
import { graphic } from 'echarts';
import isEqual from 'lodash/fp/isEqual';
import last from 'lodash/fp/last';
import { graphic } from 'echarts';
import { Component, Mixins, Watch, Prop } from 'vue-property-decorator';
import { FPNumber } from '@sora-substrate/util';
import { SSkeleton, SSkeletonItem } from '@soramitsu/soramitsu-js-ui/lib/components/Skeleton';
Expand Down
1 change: 1 addition & 0 deletions src/consts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ export enum Components {
StatsCard = 'Stats/StatsCard',
StatsFilter = 'Stats/StatsFilter',
NetworkStats = 'Stats/components/NetworkStats',
NetworkTvlChart = 'Stats/components/TvlChart',
}

export enum RewardsTabsItems {
Expand Down
37 changes: 36 additions & 1 deletion src/consts/snapshots.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,43 @@
import { SnapshotTypes } from '@/types/filters';
import { SnapshotTypes, Timeframes } from '@/types/filters';

import type { SnapshotFilter } from '@/types/filters';

export const SECONDS_IN_TYPE = {
[SnapshotTypes.DEFAULT]: 5 * 60,
[SnapshotTypes.HOUR]: 60 * 60,
[SnapshotTypes.DAY]: 24 * 60 * 60,
[SnapshotTypes.MONTH]: 30 * 24 * 60 * 60,
};

export const NETWORK_STATS_FILTERS: SnapshotFilter[] = [
{
name: Timeframes.DAY,
label: '1D',
type: SnapshotTypes.HOUR,
count: 24,
},
{
name: Timeframes.WEEK,
label: '1W',
type: SnapshotTypes.DAY,
count: 7,
},
{
name: Timeframes.MONTH,
label: '1M',
type: SnapshotTypes.DAY,
count: 30,
},
{
name: Timeframes.QUARTER,
label: '3M',
type: SnapshotTypes.MONTH,
count: 3,
},
{
name: Timeframes.YEAR,
label: '1Y',
type: SnapshotTypes.MONTH,
count: 12,
},
];
3 changes: 2 additions & 1 deletion src/views/Stats.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div class="stats-container">
<network-stats class="grid-item" />

<div class="grid-item grid-item--50">TVL</div>
<network-tvl-chart class="grid-item grid-item--50" />

<div class="grid-item grid-item--50">Volume</div>
</div>
Expand All @@ -17,6 +17,7 @@ import { Components } from '@/consts';
@Component({
components: {
NetworkStats: lazyComponent(Components.NetworkStats),
NetworkTvlChart: lazyComponent(Components.NetworkTvlChart),
},
})
export default class Stats extends Mixins() {}
Expand Down