Skip to content

Commit

Permalink
feat: add node geo distribution chart
Browse files Browse the repository at this point in the history
  • Loading branch information
Keith-CY committed Apr 7, 2024
1 parent d3b829e commit ae72700
Show file tree
Hide file tree
Showing 11 changed files with 190 additions and 29 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"dayjs": "1.11.10",
"default-passive-events": "2.0.0",
"echarts": "4.9.0",
"echarts-gl": "1.1.2",
"history": "5.3.0",
"i18next": "20.6.1",
"jsbi": "3.2.5",
Expand Down
Binary file added public/images/chart/dark.webp
Binary file not shown.
Binary file added public/images/chart/earth.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/chart/geo_cover_mainnet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/chart/geo_cover_testnet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@
"city": "City",
"node_count": "Node Count",
"node_distribution": "Node Distribution",
"node_geo_distribution": "Node Geo Distribution",
"total_supply": "Total Supply",
"circulating_supply": "Circulating Supply",
"burnt": "Burnt",
Expand Down
1 change: 1 addition & 0 deletions src/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@
"city": "城市",
"node_count": "节点数量",
"node_distribution": "节点分布",
"node_geo_distribution": "节点地理分布",
"total_supply": "总供给量",
"circulating_supply": "总流通量",
"burnt": "销毁量",
Expand Down
6 changes: 6 additions & 0 deletions src/pages/StatisticsChart/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { LiquidityChart } from './monetary/Liquidity'
import { MinerAddressDistributionChart } from './mining/MinerAddressDistribution'
import { MinerVersionDistributionChart } from './mining/MinerVersionDistribution'
import { NodeCountryDistributionChart } from './mining/NodeCountryDistribution'
import NodeGeoDistributionChart from './mining/NodeGeoDistribution'
import { useIsMobile } from '../../hooks'
import { HelpTip } from '../../components/HelpTip'
import { Link } from '../../components/Link'
Expand Down Expand Up @@ -138,6 +139,11 @@ const useChartsData = () => {
chart: <NodeCountryDistributionChart isThumbnail />,
path: '/charts/node-country-distribution',
},
{
title: `${t('statistic.node_geo_distribution')}`,
chart: <NodeGeoDistributionChart isThumbnail />,
path: '/charts/node-geo-distribution',
},
],
},
{
Expand Down
159 changes: 159 additions & 0 deletions src/pages/StatisticsChart/mining/NodeGeoDistribution.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import { useEffect, useRef } from 'react'
import { useQuery } from '@tanstack/react-query'
import 'echarts-gl'
import echarts from 'echarts/lib/echarts'
import Loading from '../../../components/Loading/SmallLoading'
import { getPeers, RawPeer } from '../../../services/NodeProbService'
import { getPrimaryColor, IS_MAINNET } from '../../../constants/common'

const fetchData = async (): Promise<[[number, number], [number, number]][]> => {
const list: RawPeer[] = await getPeers()
const points: [number, number][] = list.map(peer => [peer.longitude, peer.latitude])
const lines: [[number, number], [number, number]][] = []
for (let i = 0; i < points.length - 1; i++) {
for (let j = i + 1; j < points.length; j++) {
const p1: [number, number] = points[i]
const p2: [number, number] = points[j]
lines.push([p1, p2])
}
}

return lines
}

const option = {
backgroundColor: '#000',
globe: {
environment: '/images/chart/dark.webp',
baseTexture: '/images/chart/earth.jpg',
heightTexture: '/images/chart/earth.jpg',
displacementScale: 0.04,
displacementQuality: 'high',
shading: 'realistic',
realisticMaterial: {
roughness: 0.9,
metalness: 0,
},
temporalSuperSampling: {
enable: true,
},
postEffect: {
enable: true,
depthOfField: {
enable: false,
focalDistance: 150,
},
},
light: {
main: {
intensity: 10,
shadow: true,
time: new Date(0x16e70e6985c), // launch time of CKB mainnet
},
},
viewControl: {
autoRotate: true,
autoRotateSpeed: 1,
distance: 800,
},
silent: true,
},
}

const color = getPrimaryColor()

export const NodeGeoDistribution = ({ isThumbnail = false }: { isThumbnail?: boolean }) => {
const containerRef = useRef<HTMLDivElement | null>(null)
const { data, isLoading } = useQuery(['node distribution'], fetchData, { enabled: !isThumbnail })

useEffect(() => {
if (!containerRef.current) return
if (!data) return
let ins = echarts.getInstanceByDom(containerRef.current)
if (!ins) {
ins = echarts.init(containerRef.current)
}

const series = [
{
type: 'lines3D',
name: 'blocks',
coordinateSystem: 'globe',
blendMode: 'lighter',
symbolSize: 2,
itemStyle: {
color,
opacity: 0.1,
},
effect: {
show: true,
trailWidth: 1,
trailLength: 0.15,
trailOpacity: 0.1,
constantSpeed: 10,
},
lineStyle: {
width: 1,
color,
opacity: 0.02,
},
data,
},
{
type: 'scatter3D',
coordinateSystem: 'globe',
blendMode: 'lighter',
symbolSize: 30,
itemStyle: {
color,
opacity: 0.2,
},
silent: true,
data: data.flat(),
},
]

ins.setOption({
...option,
series,
} as any)
}, [data])

useEffect(() => {
if (!containerRef.current) return
const ins = echarts.getInstanceByDom(containerRef.current)
const handleResize = () => {
if (ins) {
ins.resize()
}
}
window.addEventListener('resize', handleResize)
return () => {
window.removeEventListener('resize', handleResize)
}
})

if (isThumbnail) {
return (
<div
style={{
width: '280px',
height: 200,
background: `center / cover url(/images/chart/geo_cover_${IS_MAINNET ? 'mainnet' : 'testnet'}.png)`,
}}
/>
)
}

if (isLoading) {
return <Loading />
}

if (!data) {
return <div>Fail to load data</div>
}

return <div style={{ width: '100vw', height: '100vh' }} ref={containerRef} />
}

export default NodeGeoDistribution
5 changes: 5 additions & 0 deletions src/routes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const UncleRateChart = lazy(() => import('../pages/StatisticsChart/mining/UncleR
const MinerAddressDistributionChart = lazy(() => import('../pages/StatisticsChart/mining/MinerAddressDistribution'))
const MinerVersionDistributionChart = lazy(() => import('../pages/StatisticsChart/mining/MinerVersionDistribution'))
const NodeCountryDistributionChart = lazy(() => import('../pages/StatisticsChart/mining/NodeCountryDistribution'))
const NodeGeoDistributionChart = lazy(() => import('../pages/StatisticsChart/mining/NodeGeoDistribution'))
const TransactionCountChart = lazy(() => import('../pages/StatisticsChart/activities/TransactionCount'))
const AddressCountChart = lazy(() => import('../pages/StatisticsChart/activities/AddressCount'))
const CellCountChart = lazy(() => import('../pages/StatisticsChart/activities/CellCount'))
Expand Down Expand Up @@ -189,6 +190,10 @@ const routes: RouteProps[] = [
path: '/charts/node-country-distribution',
component: NodeCountryDistributionChart,
},
{
path: '/charts/node-geo-distribution',
component: NodeGeoDistributionChart,
},
{
path: '/charts/transaction-count',
component: TransactionCountChart,
Expand Down
46 changes: 17 additions & 29 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7808,6 +7808,11 @@ [email protected], classnames@^2.2.1, classnames@^2.2.3, classnames@^2.2.5, classna
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924"
integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==

claygl@^1.2.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/claygl/-/claygl-1.3.0.tgz#7a6e2903210519ac358848f5d78070ed211685f3"
integrity sha512-+gGtJjT6SSHD2l2yC3MCubW/sCV40tZuSs5opdtn79vFSGUgp/lH139RNEQ6Jy078/L0aV8odCw8RSrUcMfLaQ==

clean-css@^5.2.2:
version "5.3.1"
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.1.tgz#d0610b0b90d125196a2894d35366f734e5d7aa32"
Expand Down Expand Up @@ -8975,6 +8980,14 @@ eastasianwidth@^0.2.0:
resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==

[email protected]:
version "1.1.2"
resolved "https://registry.yarnpkg.com/echarts-gl/-/echarts-gl-1.1.2.tgz#fb38454031bb64c91afb84c57b1a99c370e4571e"
integrity sha512-EVGx9RS2eMzaCgAMJSDCeLId4g8oFCFn78Fdh+0xIXASiZw/gPnJqr1vQgnQhmXhiUKixkIhIzfdc//qrct/Hg==
dependencies:
claygl "^1.2.1"
zrender "^4.0.4"

[email protected]:
version "4.9.0"
resolved "https://registry.yarnpkg.com/echarts/-/echarts-4.9.0.tgz#a9b9baa03f03a2a731e6340c55befb57a9e1347d"
Expand Down Expand Up @@ -16485,16 +16498,7 @@ string-natural-compare@^3.0.1:
resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4"
integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==

"string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"

string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
Expand Down Expand Up @@ -16649,14 +16653,7 @@ stringify-object@^3.3.0:
is-obj "^1.0.1"
is-regexp "^1.0.0"

"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"

strip-ansi@^6.0.0, strip-ansi@^6.0.1:
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
Expand Down Expand Up @@ -18386,7 +18383,7 @@ [email protected]:
"@types/trusted-types" "^2.0.2"
workbox-core "6.5.4"

"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
Expand All @@ -18404,15 +18401,6 @@ wrap-ansi@^6.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"

wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"

wrap-ansi@^8.0.1, wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
Expand Down Expand Up @@ -18608,7 +18596,7 @@ yocto-queue@^1.0.0:
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251"
integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==

[email protected]:
[email protected], zrender@^4.0.4:
version "4.3.2"
resolved "https://registry.yarnpkg.com/zrender/-/zrender-4.3.2.tgz#ec7432f9415c82c73584b6b7b8c47e1b016209c6"
integrity sha512-bIusJLS8c4DkIcdiK+s13HiQ/zjQQVgpNohtd8d94Y2DnJqgM1yjh/jpDb8DoL6hd7r8Awagw8e3qK/oLaWr3g==

0 comments on commit ae72700

Please sign in to comment.