github.com/vantum/vantum@v0.0.0-20180815184342-fe37d5f7a990/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('Geth', 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);