github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/dashboard/assets/components/Footer.jsx (about)

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