Skip to content

Commit

Permalink
dashboard: CPU, memory, diskIO and traffic on the footer (ethereum#15950
Browse files Browse the repository at this point in the history
)

* 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
  • Loading branch information
kurkomisi authored and karalabe committed Jan 23, 2018
1 parent ec96216 commit 05ade19
Show file tree
Hide file tree
Showing 111 changed files with 13,461 additions and 3,457 deletions.
5,988 changes: 3,106 additions & 2,882 deletions dashboard/assets.go

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion dashboard/assets/.eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
'react/jsx-indent': ['error', 'tab'],
'react/jsx-indent-props': ['error', 'tab'],
'react/prefer-stateless-function': 'off',
'jsx-quotes': ['error', 'prefer-single'],
'no-plusplus': 'off',
'no-console': ['error', { allow: ['error'] }],

// Specifies the maximum length of a line.
'max-len': ['warn', 120, 2, {
Expand All @@ -49,7 +52,7 @@
'ignoreStrings': true,
'ignoreTemplateLiterals': true,
}],
// Enforces spacing between keys and values in object literal properties.
// Enforces consistent spacing between keys and values in object literal properties.
'key-spacing': ['error', {'align': {
'beforeColon': false,
'afterColon': true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,9 @@ export type MenuProp = {|...ProvidedMenuProp, id: string|};
export const MENU: Map<string, {...MenuProp}> = new Map(menuSkeletons.map(({id, menu}) => ([id, {id, ...menu}])));

export const DURATION = 200;

export const styles = {
light: {
color: 'rgba(255, 255, 255, 0.54)',
},
}
19 changes: 8 additions & 11 deletions dashboard/assets/components/Body.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,32 @@

import React, {Component} from 'react';

import withStyles from 'material-ui/styles/withStyles';

import SideBar from './SideBar';
import Main from './Main';
import type {Content} from '../types/content';

// Styles for the Body component.
const styles = () => ({
// styles contains the constant styles of the component.
const styles = {
body: {
display: 'flex',
width: '100%',
height: '100%',
},
});
};

export type Props = {
classes: Object,
opened: boolean,
changeContent: () => {},
changeContent: string => void,
active: string,
content: Content,
shouldUpdate: Object,
};

// Body renders the body of the dashboard.
class Body extends Component<Props> {
render() {
const {classes} = this.props; // The classes property is injected by withStyles().

return (
<div className={classes.body}>
<div style={styles.body}>
<SideBar
opened={this.props.opened}
changeContent={this.props.changeContent}
Expand All @@ -61,4 +58,4 @@ class Body extends Component<Props> {
}
}

export default withStyles(styles)(Body);
export default Body;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @flow

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

import React, {Component} from 'react';
import type {Node} from 'react';
import type {ChildrenArray} from 'react';

import Grid from 'material-ui/Grid';
import {ResponsiveContainer} from 'recharts';

// styles contains the constant styles of the component.
const styles = {
container: {
flexWrap: 'nowrap',
height: '100%',
maxWidth: '100%',
margin: 0,
},
item: {
flex: 1,
padding: 0,
},
}

export type Props = {
spacing: number,
children: Node,
children: ChildrenArray<React$Element<any>>,
};
// ChartGrid renders a grid container for responsive charts.
// The children are Recharts components extended with the Material-UI's xs property.
class ChartGrid extends Component<Props> {

// ChartRow renders a row of equally sized responsive charts.
class ChartRow extends Component<Props> {
render() {
return (
<Grid container spacing={this.props.spacing}>
{
React.Children.map(this.props.children, child => (
<Grid item xs={child.props.xs}>
<ResponsiveContainer width="100%" height={child.props.height}>
{React.cloneElement(child, {data: child.props.values.map(value => ({value}))})}
</ResponsiveContainer>
</Grid>
))
}
<Grid container direction='row' style={styles.container} justify='space-between'>
{React.Children.map(this.props.children, child => (
<Grid item xs style={styles.item}>
{child}
</Grid>
))}
</Grid>
);
}
}

export default ChartGrid;
export default ChartRow;
95 changes: 95 additions & 0 deletions dashboard/assets/components/CustomTooltip.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// @flow

// Copyright 2018 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

import React, {Component} from 'react';

import Typography from 'material-ui/Typography';
import {styles} from '../common';

// multiplier multiplies a number by another.
export const multiplier = <T>(by: number = 1) => (x: number) => x * by;

// percentPlotter renders a tooltip, which displays the value of the payload followed by a percent sign.
export const percentPlotter = <T>(text: string, mapper: (T => T) = multiplier(1)) => (payload: T) => {
const p = mapper(payload);
if (typeof p !== 'number') {
return null;
}
return (
<Typography type='caption' color='inherit'>
<span style={styles.light}>{text}</span> {p.toFixed(2)} %
</Typography>
);
};

// unit contains the units for the bytePlotter.
const unit = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];

// simplifyBytes returns the simplified version of the given value followed by the unit.
const simplifyBytes = (x: number) => {
let i = 0;
for (; x > 1024 && i < 5; i++) {
x /= 1024;
}
return x.toFixed(2).toString().concat(' ', unit[i]);
};

// bytePlotter renders a tooltip, which displays the payload as a byte value.
export const bytePlotter = <T>(text: string, mapper: (T => T) = multiplier(1)) => (payload: T) => {
const p = mapper(payload);
if (typeof p !== 'number') {
return null;
}
return (
<Typography type='caption' color='inherit'>
<span style={styles.light}>{text}</span> {simplifyBytes(p)}
</Typography>
);
};

// bytePlotter renders a tooltip, which displays the payload as a byte value followed by '/s'.
export const bytePerSecPlotter = <T>(text: string, mapper: (T => T) = multiplier(1)) => (payload: T) => {
const p = mapper(payload);
if (typeof p !== 'number') {
return null;
}
return (
<Typography type='caption' color='inherit'>
<span style={styles.light}>{text}</span> {simplifyBytes(p)}/s
</Typography>
);
};

export type Props = {
active: boolean,
payload: Object,
tooltip: <T>(text: string, mapper?: T => T) => (payload: mixed) => null | React$Element<any>,
};

// CustomTooltip takes a tooltip function, and uses it to plot the active value of the chart.
class CustomTooltip extends Component<Props> {
render() {
const {active, payload, tooltip} = this.props;
if (!active || typeof tooltip !== 'function') {
return null;
}
return tooltip(payload[0].value);
}
}

export default CustomTooltip;
Loading

0 comments on commit 05ade19

Please sign in to comment.