Skip to content
This repository has been archived by the owner on Feb 27, 2021. It is now read-only.

Commit

Permalink
Merge pull request #1 from etclabscore/feature/add-dashboard
Browse files Browse the repository at this point in the history
Feature/add dashboard
  • Loading branch information
shanejonas authored Jan 17, 2019
2 parents 342c39b + 08a86ac commit c6996e0
Show file tree
Hide file tree
Showing 12 changed files with 664 additions and 574 deletions.
958 changes: 451 additions & 507 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
"emerald-js": "git+https://github.com/ETCDEVTeam/emerald-js.git",
"emerald-js-ui": "git+https://github.com/ETCDEVTeam/emerald-js-ui.git#material-ui-one",
"ethereumjs-util": "^5.2.0",
"json-rpc-engine": "^3.7.3",
"qs": "^6.5.2",
"raf": "^3.4.0",
"react": "^16.4.2",
Expand All @@ -70,6 +69,7 @@
"redux": "^4.0.1",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.3.0",
"victory": "^31.1.0",
"webpack-dev-server": "^3.1.14"
},
"devDependencies": {
Expand Down
3 changes: 2 additions & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Emerald Starter Kit</title>
<title>Jade Explorer</title>
<style>a { color: black } </style>
</head>

<body>
Expand Down
55 changes: 31 additions & 24 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ import { history } from './store';
import Page from 'emerald-js-ui/lib/components/Page';
import { Provider } from 'react-redux'

import { AppBar, NetworkSelector, EmeraldProvider } from 'emerald-js-ui';
import { AppBar, NetworkSelector } from 'emerald-js-ui';
import { VaultJsonRpcProvider } from 'emerald-js-ui/lib/providers/VaultJsonRpcProvider';
import { EthJsonRpcProvider } from 'emerald-js-ui/lib/providers/EthJsonRpcProvider';


const routes = [
{ path: '/', component: Dashboard, title: 'Dashboard', exact: true },
Expand All @@ -26,34 +29,38 @@ const routes = [

class App extends React.Component {
render() {
const ethUrl = "http://localhost:8545";
const vaultUrl = "http://localhost:9120";
return (
<Provider store={store}>
<EmeraldProvider ethUrl="http://localhost:8545">
<div>
<EthJsonRpcProvider url={ethUrl}>
<VaultJsonRpcProvider url={vaultUrl}>
<div>
<AppBar title="Emerald" subtitle="Explorer">
<NetworkSelector />
</AppBar>
</div>
<div style={{ margin: '20px' }}>
<ConnectedRouter history={history}>
<Switch>
{
routes.map((routeProps, i) => {
let wrapped = (props) => (
<Page title={routeProps.title}>
{routeProps.component({ ...props, history })}
</Page>
);
<div>
<AppBar title="Jade" subtitle="Explorer">
<NetworkSelector />
</AppBar>
</div>
<div style={{ margin: '20px' }}>
<ConnectedRouter history={history}>
<Switch>
{
routes.map((routeProps, i) => {
let wrapped = (props) => (
<Page title={routeProps.title}>
{routeProps.component({ ...props, history })}
</Page>
);

return (<Route key={i} path={routeProps.path} component={wrapped} exact={routeProps.exact} />);
})
}
</Switch>
</ConnectedRouter>
return (<Route key={i} path={routeProps.path} component={wrapped} exact={routeProps.exact} />);
})
}
</Switch>
</ConnectedRouter>
</div>
</div>
</div>
</EmeraldProvider>
</VaultJsonRpcProvider>
</EthJsonRpcProvider>
</Provider>
);
}
Expand Down
13 changes: 9 additions & 4 deletions src/components/BlockList/BlockList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@ export interface BlockListProps {
blocks: Array<BlockWithoutTxData>;
}


const rightPaddingFix = {
paddingRight: '24px'
}

function BlockList({ blocks }: BlockListProps) {
const sortedBlocks = blocks.sort((_a, _b) => {
return _a.number - _b.number;
return _b.number - _a.number;
})
return (
<Table>
Expand All @@ -32,11 +37,11 @@ function BlockList({ blocks }: BlockListProps) {
return (
<TableRow key={b.number!}>
<TableCell component="th" scope="row"><Typography>{b.number}</Typography></TableCell>
<TableCell><Link to={`/block/${b.hash}`}>{b.hash}</Link></TableCell>
<TableCell>
<TableCell style={rightPaddingFix}><Link to={`/block/${b.hash}`}>{b.hash}</Link></TableCell>
<TableCell style={rightPaddingFix}>
<Typography>{b.timestamp}</Typography>
</TableCell>
<TableCell>
<TableCell style={rightPaddingFix}>
<Typography>{b.transactions.length}</Typography>
</TableCell>
</TableRow>
Expand Down
14 changes: 14 additions & 0 deletions src/components/HashChart/HashChart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import * as React from 'react';
import { VictoryChart, VictoryLine, VictoryLabel } from 'victory';

export default function HashChart(props: any) {
const { title, data, width, height } = props;


return (
<VictoryChart title={title} height={height} width={width}>
<VictoryLabel x={25} y={24} text={title}/>
<VictoryLine data={data} height={height} width={width}/>
</VictoryChart>
)
}
2 changes: 2 additions & 0 deletions src/components/HashChart/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import HashChart from './HashChart';
export default HashChart;
2 changes: 1 addition & 1 deletion src/components/HashRate/HashRate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ import { hashesToGH } from '../formatters';

export default function HashRate(props: any) {
const { block, blockTime } = props;
return props.children(hashesToGH(block.difficulty / blockTime))
return props.children(hashesToGH(block.difficulty.dividedBy(blockTime)))
}
11 changes: 10 additions & 1 deletion src/components/formatters.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
export function hashesToGH(hashes: number) {
return (hashes / 1000000000).toFixed(2);
return parseInt((hashes / 1000000000).toFixed(2), 10);
}


export function weiToGwei(wei: any) {
if (wei === 0) {
return wei;
}

return wei / 1000000000;
}
8 changes: 4 additions & 4 deletions src/containers/BlockList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ class BlockListContainer extends React.Component<Props, State> {
const { from, to } = this.props;
return (
<div>
Blocks from {from} to {to}
<EthRpc method="ext.getBlocks" params={[this.props.from, this.props.to]}>
{blocks => (<BlockList blocks={blocks} />)}
</EthRpc>
Blocks from {from} to {to}
<EthRpc method="ext.getBlocks" params={[this.props.from, this.props.to]}>
{blocks => (<BlockList blocks={blocks} />)}
</EthRpc>
</div>
);
}
Expand Down
162 changes: 134 additions & 28 deletions src/containers/Dashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,143 @@
import * as React from 'react';
import HashRate from '../components/HashRate';
import HashChart from '../components/HashChart';
import BlockList from './BlockList';
import { EthRpc } from 'emerald-js-ui';
import Card from '@material-ui/core/Card';
import CardContent from '@material-ui/core/CardContent';
import Typography from '@material-ui/core/Typography';
import { hashesToGH } from '../components/formatters';
import { VictoryChart, VictoryBar, VictoryLabel } from 'victory';
import { weiToGwei } from '../components/formatters';
import Button from '@material-ui/core/Button';
import Grid from '@material-ui/core/Grid';


const config = {
blockTime: 15, // seconds
blockHistoryLength: 1200,
chartHeight: 200,
chartWidth: 400
}

const blockMapGasUsed = (block) => {
return {
x: block.number,
y: block.gasUsed / 1000000
}
}

const blockMapUncles = (block) => {
return {
x: block.number,
y: block.uncles.length
}
}

const blockMapHashRate = (block) => {
return {
x: block.number,
y: hashesToGH(block.difficulty.dividedBy(config.blockTime))
}
}

const blockMapTransactionCount = (block) => {
return {
x: block.number,
y: block.transactions.length
}
}

const getStyles = () => {
return {
topItems: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center'
}
}
}

export default (props: any) => {
const styles = getStyles();
return (
<div style={{display: 'flex'}}>
<Card style={{width: '350px', marginRight: '10px'}}>
<CardContent>
<Typography variant="headline">
Network Hash Rate
</Typography>
<EthRpc method="eth.getBlock" params={['latest', true]} refresh={3000}>
{block => (
<HashRate block={block} blockTime={15}>
{hashRate => <Typography>{hashRate} GH/s</Typography>}
</HashRate>
)}
</EthRpc>
</CardContent>
</Card>
<Card style={{width: '350px'}}>
<CardContent>
<Typography variant="headline">
Block Height
</Typography>
<EthRpc method="eth.getBlock" params={['latest', true]} refresh={3000}>
{block => <Typography>{block.number}</Typography>}
</EthRpc>
</CardContent>
</Card>
</div>
<EthRpc method="eth.getBlock" params={['latest', true]}>
{block => (
<EthRpc method="eth.gasPrice">
{gasPrice => (
<div>
<Grid container spacing={24}>
<Grid style={styles.topItems} item xs={12}>
<div>
<Typography variant="headline">
Block Height
</Typography>
<Typography>{block.number}</Typography>
</div>
<div>
<Typography variant="headline">
Gas Price
</Typography>
<Typography>{weiToGwei(gasPrice.toNumber())} Gwei</Typography>
</div>
<div>
<Typography variant="headline">
Network Hash Rate
</Typography>
<HashRate block={block} blockTime={config.blockTime}>
{hashRate => <Typography>{hashRate} GH/s</Typography>}
</HashRate>
</div>
<div>
<Typography variant="headline">
Peers
</Typography>
<EthRpc method="net.peerCount">
{peerCount => <Typography>{peerCount}</Typography>}
</EthRpc>
</div>
</Grid>

<EthRpc method="ext.getBlocks" params={[Math.max(block.number - config.blockHistoryLength + 1, 0), block.number]}>
{blocks => {
if (gasPrice.toNumber() === 0) {
return null;
}
return [
<Grid item xs={12} sm={6} lg={3}>
<HashChart height={config.chartHeight} title={`Hash Rate Last ${blocks.length} blocks`} data={blocks.map(blockMapHashRate)} />,
</Grid>,
<Grid item xs={12} sm={6} lg={3}>
<VictoryChart height={config.chartHeight} width={config.chartWidth}>
<VictoryLabel x={25} y={24} text={`Transaction count last ${blocks.length} blocks`}/>
<VictoryBar data={blocks.map(blockMapTransactionCount)} />
</VictoryChart>
</Grid>,
<Grid item xs={12} sm={6} lg={3}>
<VictoryChart height={config.chartHeight} width={config.chartWidth}>
<VictoryLabel x={25} y={24} text={`Gas Used Last ${blocks.length} blocks`}/>
<VictoryBar data={blocks.map(blockMapGasUsed)} />
</VictoryChart>
</Grid>,
<Grid item xs={12} sm={6} lg={3}>
<VictoryChart height={config.chartHeight} width={config.chartWidth}>
<VictoryLabel x={25} y={24} text={`Uncles Last ${blocks.length} blocks`}/>
<VictoryBar data={blocks.map(blockMapUncles)} />
</VictoryChart>
</Grid>,
]
}}
</EthRpc>
<Grid item>
<Typography variant="headline">
Last 10 blocks
</Typography>
<Button href={"#/blocks"}>View All</Button>
<BlockList from={Math.max(block.number - 11, 0)} to={block.number} />
</Grid>
</Grid>
</div>
)}
</EthRpc>
)}
</EthRpc>
)
}
8 changes: 5 additions & 3 deletions src/containers/NodeView.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import * as React from 'react';
import BlockList from './BlockList';
import { EthRpc } from 'emerald-js-ui';
import Button from '@material-ui/core/Button';

export default function NodeView(props: any) {
return (
return [
<EthRpc method="eth.getBlockNumber">
{blockNumber => (<BlockList from={Math.max(blockNumber - 15, 0)} to={blockNumber} />)}
</EthRpc>
);
</EthRpc>,
<Button>Load More</Button>
];
}

0 comments on commit c6996e0

Please sign in to comment.