Skip to content

Commit 05ade19

Browse files
kurkomisikaralabe
authored andcommitted
dashboard: CPU, memory, diskIO and traffic on the footer (ethereum#15950)
* dashboard: footer, deep state update * dashboard: resolve asset path * dashboard: prevent state update on every reconnection * dashboard: fix linter issue * dashboard, cmd: minor UI fix, include commit hash * dashboard: gitCommit renamed to commit * dashboard: move the geth version to the right, make commit optional * dashboard: memory, traffic and CPU on footer * dashboard: fix merge * dashboard: CPU, diskIO on footer * dashboard: rename variables, use group declaration * dashboard: docs
1 parent ec96216 commit 05ade19

File tree

111 files changed

+13461
-3457
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+13461
-3457
lines changed

dashboard/assets.go

+3,106-2,882
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dashboard/assets/.eslintrc

+4-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@
4040
'react/jsx-indent': ['error', 'tab'],
4141
'react/jsx-indent-props': ['error', 'tab'],
4242
'react/prefer-stateless-function': 'off',
43+
'jsx-quotes': ['error', 'prefer-single'],
44+
'no-plusplus': 'off',
45+
'no-console': ['error', { allow: ['error'] }],
4346

4447
// Specifies the maximum length of a line.
4548
'max-len': ['warn', 120, 2, {
@@ -49,7 +52,7 @@
4952
'ignoreStrings': true,
5053
'ignoreTemplateLiterals': true,
5154
}],
52-
// Enforces spacing between keys and values in object literal properties.
55+
// Enforces consistent spacing between keys and values in object literal properties.
5356
'key-spacing': ['error', {'align': {
5457
'beforeColon': false,
5558
'afterColon': true,

dashboard/assets/components/Common.jsx dashboard/assets/common.jsx

+6
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,9 @@ export type MenuProp = {|...ProvidedMenuProp, id: string|};
6363
export const MENU: Map<string, {...MenuProp}> = new Map(menuSkeletons.map(({id, menu}) => ([id, {id, ...menu}])));
6464

6565
export const DURATION = 200;
66+
67+
export const styles = {
68+
light: {
69+
color: 'rgba(255, 255, 255, 0.54)',
70+
},
71+
}

dashboard/assets/components/Body.jsx

+8-11
Original file line numberDiff line numberDiff line change
@@ -18,35 +18,32 @@
1818

1919
import React, {Component} from 'react';
2020

21-
import withStyles from 'material-ui/styles/withStyles';
22-
2321
import SideBar from './SideBar';
2422
import Main from './Main';
2523
import type {Content} from '../types/content';
2624

27-
// Styles for the Body component.
28-
const styles = () => ({
25+
// styles contains the constant styles of the component.
26+
const styles = {
2927
body: {
3028
display: 'flex',
3129
width: '100%',
3230
height: '100%',
3331
},
34-
});
32+
};
33+
3534
export type Props = {
36-
classes: Object,
3735
opened: boolean,
38-
changeContent: () => {},
36+
changeContent: string => void,
3937
active: string,
4038
content: Content,
4139
shouldUpdate: Object,
4240
};
41+
4342
// Body renders the body of the dashboard.
4443
class Body extends Component<Props> {
4544
render() {
46-
const {classes} = this.props; // The classes property is injected by withStyles().
47-
4845
return (
49-
<div className={classes.body}>
46+
<div style={styles.body}>
5047
<SideBar
5148
opened={this.props.opened}
5249
changeContent={this.props.changeContent}
@@ -61,4 +58,4 @@ class Body extends Component<Props> {
6158
}
6259
}
6360

64-
export default withStyles(styles)(Body);
61+
export default Body;
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// @flow
22

3-
// Copyright 2017 The go-ethereum Authors
3+
// Copyright 2018 The go-ethereum Authors
44
// This file is part of the go-ethereum library.
55
//
66
// The go-ethereum library is free software: you can redistribute it and/or modify
@@ -17,33 +17,41 @@
1717
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
1818

1919
import React, {Component} from 'react';
20-
import type {Node} from 'react';
20+
import type {ChildrenArray} from 'react';
2121

2222
import Grid from 'material-ui/Grid';
23-
import {ResponsiveContainer} from 'recharts';
23+
24+
// styles contains the constant styles of the component.
25+
const styles = {
26+
container: {
27+
flexWrap: 'nowrap',
28+
height: '100%',
29+
maxWidth: '100%',
30+
margin: 0,
31+
},
32+
item: {
33+
flex: 1,
34+
padding: 0,
35+
},
36+
}
2437

2538
export type Props = {
26-
spacing: number,
27-
children: Node,
39+
children: ChildrenArray<React$Element<any>>,
2840
};
29-
// ChartGrid renders a grid container for responsive charts.
30-
// The children are Recharts components extended with the Material-UI's xs property.
31-
class ChartGrid extends Component<Props> {
41+
42+
// ChartRow renders a row of equally sized responsive charts.
43+
class ChartRow extends Component<Props> {
3244
render() {
3345
return (
34-
<Grid container spacing={this.props.spacing}>
35-
{
36-
React.Children.map(this.props.children, child => (
37-
<Grid item xs={child.props.xs}>
38-
<ResponsiveContainer width="100%" height={child.props.height}>
39-
{React.cloneElement(child, {data: child.props.values.map(value => ({value}))})}
40-
</ResponsiveContainer>
41-
</Grid>
42-
))
43-
}
46+
<Grid container direction='row' style={styles.container} justify='space-between'>
47+
{React.Children.map(this.props.children, child => (
48+
<Grid item xs style={styles.item}>
49+
{child}
50+
</Grid>
51+
))}
4452
</Grid>
4553
);
4654
}
4755
}
4856

49-
export default ChartGrid;
57+
export default ChartRow;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// @flow
2+
3+
// Copyright 2018 The go-ethereum Authors
4+
// This file is part of the go-ethereum library.
5+
//
6+
// The go-ethereum library is free software: you can redistribute it and/or modify
7+
// it under the terms of the GNU Lesser General Public License as published by
8+
// the Free Software Foundation, either version 3 of the License, or
9+
// (at your option) any later version.
10+
//
11+
// The go-ethereum library is distributed in the hope that it will be useful,
12+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
// GNU Lesser General Public License for more details.
15+
//
16+
// You should have received a copy of the GNU Lesser General Public License
17+
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
18+
19+
import React, {Component} from 'react';
20+
21+
import Typography from 'material-ui/Typography';
22+
import {styles} from '../common';
23+
24+
// multiplier multiplies a number by another.
25+
export const multiplier = <T>(by: number = 1) => (x: number) => x * by;
26+
27+
// percentPlotter renders a tooltip, which displays the value of the payload followed by a percent sign.
28+
export const percentPlotter = <T>(text: string, mapper: (T => T) = multiplier(1)) => (payload: T) => {
29+
const p = mapper(payload);
30+
if (typeof p !== 'number') {
31+
return null;
32+
}
33+
return (
34+
<Typography type='caption' color='inherit'>
35+
<span style={styles.light}>{text}</span> {p.toFixed(2)} %
36+
</Typography>
37+
);
38+
};
39+
40+
// unit contains the units for the bytePlotter.
41+
const unit = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
42+
43+
// simplifyBytes returns the simplified version of the given value followed by the unit.
44+
const simplifyBytes = (x: number) => {
45+
let i = 0;
46+
for (; x > 1024 && i < 5; i++) {
47+
x /= 1024;
48+
}
49+
return x.toFixed(2).toString().concat(' ', unit[i]);
50+
};
51+
52+
// bytePlotter renders a tooltip, which displays the payload as a byte value.
53+
export const bytePlotter = <T>(text: string, mapper: (T => T) = multiplier(1)) => (payload: T) => {
54+
const p = mapper(payload);
55+
if (typeof p !== 'number') {
56+
return null;
57+
}
58+
return (
59+
<Typography type='caption' color='inherit'>
60+
<span style={styles.light}>{text}</span> {simplifyBytes(p)}
61+
</Typography>
62+
);
63+
};
64+
65+
// bytePlotter renders a tooltip, which displays the payload as a byte value followed by '/s'.
66+
export const bytePerSecPlotter = <T>(text: string, mapper: (T => T) = multiplier(1)) => (payload: T) => {
67+
const p = mapper(payload);
68+
if (typeof p !== 'number') {
69+
return null;
70+
}
71+
return (
72+
<Typography type='caption' color='inherit'>
73+
<span style={styles.light}>{text}</span> {simplifyBytes(p)}/s
74+
</Typography>
75+
);
76+
};
77+
78+
export type Props = {
79+
active: boolean,
80+
payload: Object,
81+
tooltip: <T>(text: string, mapper?: T => T) => (payload: mixed) => null | React$Element<any>,
82+
};
83+
84+
// CustomTooltip takes a tooltip function, and uses it to plot the active value of the chart.
85+
class CustomTooltip extends Component<Props> {
86+
render() {
87+
const {active, payload, tooltip} = this.props;
88+
if (!active || typeof tooltip !== 'function') {
89+
return null;
90+
}
91+
return tooltip(payload[0].value);
92+
}
93+
}
94+
95+
export default CustomTooltip;

0 commit comments

Comments
 (0)