mirror of
https://github.com/pezkuwichain/pezkuwi-telemetry.git
synced 2026-06-13 02:11:01 +00:00
Sparklines (#65)
This commit is contained in:
@@ -23,6 +23,11 @@
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.Node-Row .Node-Row-Tooltip {
|
||||
position: initial;
|
||||
padding: inherit;
|
||||
}
|
||||
|
||||
.Node-Row-synced {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { formatNumber, milliOrSecond, secondsWithPrecision } from '../../utils';
|
||||
import { State as AppState, Node } from '../../state';
|
||||
import { PersistentSet } from '../../persist';
|
||||
import { SEMVER_PATTERN } from './';
|
||||
import { Ago, Icon } from '../';
|
||||
import { Ago, Icon, Tooltip, Sparkline } from '../';
|
||||
|
||||
import nodeIcon from '../../icons/server.svg';
|
||||
import nodeLocationIcon from '../../icons/location.svg';
|
||||
@@ -45,10 +45,33 @@ interface Column {
|
||||
render: (node: Node) => React.ReactElement<any> | string;
|
||||
}
|
||||
|
||||
function Truncate(props: { text: string }): React.ReactElement<any> {
|
||||
const { text } = props;
|
||||
function Truncate(props: { text: string, position?: 'left' | 'right' | 'center' }): React.ReactElement<any> {
|
||||
const { text, position } = props;
|
||||
|
||||
return <div className="Node-Row-truncate" title={text}>{text}</div>;
|
||||
return (
|
||||
<Tooltip text={text} position={position} className="Node-Row-Tooltip">
|
||||
<div className="Node-Row-truncate">{text}</div>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
function formatMemory(kbs: number): string {
|
||||
const mbs = kbs / 1024 | 0;
|
||||
|
||||
if (mbs >= 1000) {
|
||||
return `${(mbs / 1024).toFixed(1)} GB`;
|
||||
} else {
|
||||
return `${mbs} MB`;
|
||||
}
|
||||
}
|
||||
|
||||
function formatCPU(cpu: number): string {
|
||||
const fractionDigits = cpu > 100 ? 0
|
||||
: cpu > 10 ? 1
|
||||
: cpu > 1 ? 2
|
||||
: 3;
|
||||
|
||||
return `${cpu.toFixed(fractionDigits)}%`;
|
||||
}
|
||||
|
||||
export default class Row extends React.Component<RowProps, {}> {
|
||||
@@ -56,7 +79,7 @@ export default class Row extends React.Component<RowProps, {}> {
|
||||
{
|
||||
label: 'Node',
|
||||
icon: nodeIcon,
|
||||
render: ({ name }) => <Truncate text={name} />
|
||||
render: ({ name }) => <Truncate text={name} position="left" />
|
||||
},
|
||||
{
|
||||
label: 'Validator',
|
||||
@@ -64,7 +87,7 @@ export default class Row extends React.Component<RowProps, {}> {
|
||||
width: 26,
|
||||
setting: 'validator',
|
||||
render: ({ validator }) => {
|
||||
return validator ? <span className="Node-Row-validator" title={validator}><Identicon id={validator} size={16} /></span> : '-';
|
||||
return validator ? <Tooltip text={validator}><span className="Node-Row-validator"><Identicon id={validator} size={16} /></span></Tooltip> : '-';
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -72,7 +95,7 @@ export default class Row extends React.Component<RowProps, {}> {
|
||||
icon: nodeLocationIcon,
|
||||
width: 140,
|
||||
setting: 'location',
|
||||
render: ({ city }) => city ? <Truncate text={city} /> : '-'
|
||||
render: ({ city }) => city ? <Truncate position="left" text={city} /> : '-'
|
||||
},
|
||||
{
|
||||
label: 'Implementation',
|
||||
@@ -85,7 +108,11 @@ export default class Row extends React.Component<RowProps, {}> {
|
||||
: implementation === 'substrate-node' ? paritySubstrateIcon
|
||||
: unknownImplementationIcon;
|
||||
|
||||
return <span title={`${implementation} v${version}`}><Icon src={implIcon} /> {semver}</span>;
|
||||
return (
|
||||
<Tooltip text={`${implementation} v${version}`}>
|
||||
<Icon src={implIcon} /> {semver}
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -105,16 +132,32 @@ export default class Row extends React.Component<RowProps, {}> {
|
||||
{
|
||||
label: '% CPU Use',
|
||||
icon: cpuIcon,
|
||||
width: 26,
|
||||
width: 40,
|
||||
setting: 'cpu',
|
||||
render: ({ cpu }) => cpu ? `${cpu.toFixed(1)}%` : '-'
|
||||
render: ({ cpu }) => {
|
||||
if (cpu.length < 3) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
return (
|
||||
<Sparkline width={48} height={16} stroke={1} format={formatCPU} values={cpu} />
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Memory Use',
|
||||
icon: memoryIcon,
|
||||
width: 26,
|
||||
width: 40,
|
||||
setting: 'mem',
|
||||
render: ({ mem }) => mem ? <span title={`${mem}kb`}>{mem / 1024 | 0}mb</span> : '-'
|
||||
render: ({ mem }) => {
|
||||
if (mem.length < 3) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
return (
|
||||
<Sparkline width={48} height={16} stroke={1} format={formatMemory} values={mem} />
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Block',
|
||||
@@ -128,7 +171,7 @@ export default class Row extends React.Component<RowProps, {}> {
|
||||
icon: blockHashIcon,
|
||||
width: 154,
|
||||
setting: 'blockhash',
|
||||
render: ({ hash }) => <Truncate text={hash} />
|
||||
render: ({ hash }) => <Truncate position="right" text={hash} />
|
||||
},
|
||||
{
|
||||
label: 'Block Time',
|
||||
@@ -155,16 +198,24 @@ export default class Row extends React.Component<RowProps, {}> {
|
||||
|
||||
public static Header = (props: HeaderProps) => {
|
||||
const { settings } = props;
|
||||
const columns = Row.columns.filter(({ setting }) => setting == null || settings[setting]);
|
||||
const last = columns.length - 1;
|
||||
|
||||
return (
|
||||
<thead>
|
||||
<tr className="Node-Row-Header">
|
||||
{
|
||||
Row.columns
|
||||
.filter(({ setting }) => setting == null || settings[setting])
|
||||
.map(({ icon, width, label }, index) => (
|
||||
<th key={index} style={width ? { width } : undefined}><Icon src={icon} alt={label} /></th>
|
||||
))
|
||||
columns.map(({ icon, width, label }, index) => {
|
||||
const position = index === 0 ? 'left'
|
||||
: index === last ? 'right'
|
||||
: 'center';
|
||||
|
||||
return (
|
||||
<th key={index} style={width ? { width } : undefined}>
|
||||
<Tooltip text={label} inline={true} position={position}><Icon src={icon} /></Tooltip>
|
||||
</th>
|
||||
)
|
||||
})
|
||||
}
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
Reference in New Issue
Block a user