github.com/beyonderyue/gochain@v2.2.26+incompatible/dashboard/assets/components/Footer.jsx (about)

     1  // @flow
     2  
     3  // Copyright 2017 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 withStyles from 'material-ui/styles/withStyles';
    22  import Typography from 'material-ui/Typography';
    23  import Grid from 'material-ui/Grid';
    24  import {ResponsiveContainer, AreaChart, Area, Tooltip} from 'recharts';
    25  
    26  import ChartRow from './ChartRow';
    27  import CustomTooltip, {bytePlotter, bytePerSecPlotter, percentPlotter, multiplier} from './CustomTooltip';
    28  import {styles as commonStyles} from '../common';
    29  import type {Content} from '../types/content';
    30  
    31  // styles contains the constant styles of the component.
    32  const styles = {
    33  	footer: {
    34  		maxWidth: '100%',
    35  		flexWrap: 'nowrap',
    36  		margin:   0,
    37  	},
    38  	chartRowWrapper: {
    39  		height:  '100%',
    40  		padding: 0,
    41  	},
    42  	doubleChartWrapper: {
    43  		height:     '100%',
    44  		width:      '99%',
    45  		paddingTop: 5,
    46  	},
    47  };
    48  
    49  // themeStyles returns the styles generated from the theme for the component.
    50  const themeStyles: Object = (theme: Object) => ({
    51  	footer: {
    52  		backgroundColor: theme.palette.background.appBar,
    53  		color:           theme.palette.getContrastText(theme.palette.background.appBar),
    54  		zIndex:          theme.zIndex.appBar,
    55  		height:          theme.spacing.unit * 10,
    56  	},
    57  });
    58  
    59  export type Props = {
    60  	classes: Object, // injected by withStyles()
    61  	theme: Object,
    62  	content: Content,
    63  	shouldUpdate: Object,
    64  };
    65  
    66  // Footer renders the footer of the dashboard.
    67  class Footer extends Component<Props> {
    68  	shouldComponentUpdate(nextProps) {
    69  		return typeof nextProps.shouldUpdate.home !== 'undefined';
    70  	}
    71  
    72  	// info renders a label with the given values.
    73  	info = (about: string, value: ?string) => (value ? (
    74  		<Typography type='caption' color='inherit'>
    75  			<span style={commonStyles.light}>{about}</span> {value}
    76  		</Typography>
    77  	) : null);
    78  
    79  	// doubleChart renders a pair of charts separated by the baseline.
    80  	doubleChart = (syncId, topChart, bottomChart) => {
    81  		const topKey = 'topKey';
    82  		const bottomKey = 'bottomKey';
    83  		const topDefault = topChart.default ? topChart.default : 0;
    84  		const bottomDefault = bottomChart.default ? bottomChart.default : 0;
    85  		const topTooltip = topChart.tooltip ? (
    86  			<Tooltip cursor={false} content={<CustomTooltip tooltip={topChart.tooltip} />} />
    87  		) : null;
    88  		const bottomTooltip = bottomChart.tooltip ? (
    89  			<Tooltip cursor={false} content={<CustomTooltip tooltip={bottomChart.tooltip} />} />
    90  		) : null;
    91  		const topColor = '#8884d8';
    92  		const bottomColor = '#82ca9d';
    93  
    94  		// Put the samples of the two charts into the same array in order to avoid problems
    95  		// at the synchronized area charts. If one of the two arrays doesn't have value at
    96  		// a given position, give it a 0 default value.
    97  		let data = [...topChart.data.map(({value}) => {
    98  			const d = {};
    99  			d[topKey] = value || topDefault;
   100  			return d;
   101  		})];
   102  		for (let i = 0; i < data.length && i < bottomChart.data.length; i++) {
   103  			// The value needs to be negative in order to plot it upside down.
   104  			const d = bottomChart.data[i];
   105  			data[i][bottomKey] = d && d.value ? -d.value : bottomDefault;
   106  		}
   107  		data = [...data, ...bottomChart.data.slice(data.length).map(({value}) => {
   108  			const d = {};
   109  			d[topKey] = topDefault;
   110  			d[bottomKey] = -value || bottomDefault;
   111  			return d;
   112  		})];
   113  
   114  		return (
   115  			<div style={styles.doubleChartWrapper}>
   116  				<ResponsiveContainer width='100%' height='50%'>
   117  					<AreaChart data={data} syncId={syncId} >
   118  						{topTooltip}
   119  						<Area type='monotone' dataKey={topKey} stroke={topColor} fill={topColor} />
   120  					</AreaChart>
   121  				</ResponsiveContainer>
   122  				<div style={{marginTop: -10, width: '100%', height: '50%'}}>
   123  					<ResponsiveContainer width='100%' height='100%'>
   124  						<AreaChart data={data} syncId={syncId} >
   125  							{bottomTooltip}
   126  							<Area type='monotone' dataKey={bottomKey} stroke={bottomColor} fill={bottomColor} />
   127  						</AreaChart>
   128  					</ResponsiveContainer>
   129  				</div>
   130  			</div>
   131  		);
   132  	}
   133  
   134  	render() {
   135  		const {content} = this.props;
   136  		const {general, home} = content;
   137  
   138  		return (
   139  			<Grid container className={this.props.classes.footer} direction='row' alignItems='center' style={styles.footer}>
   140  				<Grid item xs style={styles.chartRowWrapper}>
   141  					<ChartRow>
   142  						{this.doubleChart(
   143  							'all',
   144  							{data: home.processCPU, tooltip: percentPlotter('Process')},
   145  							{data: home.systemCPU, tooltip: percentPlotter('System', multiplier(-1))},
   146  						)}
   147  						{this.doubleChart(
   148  							'all',
   149  							{data: home.activeMemory, tooltip: bytePlotter('Active')},
   150  							{data: home.virtualMemory, tooltip: bytePlotter('Virtual', multiplier(-1))},
   151  						)}
   152  						{this.doubleChart(
   153  							'all',
   154  							{data: home.diskRead, tooltip: bytePerSecPlotter('Disk Read')},
   155  							{data: home.diskWrite, tooltip: bytePerSecPlotter('Disk Write', multiplier(-1))},
   156  						)}
   157  						{this.doubleChart(
   158  							'all',
   159  							{data: home.networkIngress, tooltip: bytePerSecPlotter('Download')},
   160  							{data: home.networkEgress, tooltip: bytePerSecPlotter('Upload', multiplier(-1))},
   161  						)}
   162  					</ChartRow>
   163  				</Grid>
   164  				<Grid item >
   165  					{this.info('GoChain', general.version)}
   166  					{this.info('Commit', general.commit ? general.commit.substring(0, 7) : null)}
   167  				</Grid>
   168  			</Grid>
   169  		);
   170  	}
   171  }
   172  
   173  export default withStyles(themeStyles)(Footer);