Skip to content

Commit

Permalink
Better Charts
Browse files Browse the repository at this point in the history
  • Loading branch information
Louis-Riel committed Jan 30, 2023
1 parent 196de90 commit 9d3c516
Show file tree
Hide file tree
Showing 14 changed files with 595 additions and 186 deletions.
391 changes: 298 additions & 93 deletions data/main.jsx

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions site/src/components/home/config/configItem.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const ConfigItem = withStyles(configStyle)(props => {
const { name, value, configItemUpdated, datatype, classes } = props;
const [ editing, setEditing] = React.useState(false);
const [ configValue, setConfigValue] = React.useState(value);
const [ editing, setEditing] = useState(false);
const [ configValue, setConfigValue] = useState(value);
const getConfigValue = (value, type) => {
switch (type) {
case "int":
Expand Down
16 changes: 8 additions & 8 deletions site/src/components/home/home.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
const MainApp = withStyles(mainAppStyle)(props => {
const { classes } = props;
const [drawerOpened, setDrawerOpened] = React.useState(false);
const [mode, setMode] = React.useState('dark');
const [stats, setStats] = React.useState(true);
const [designer, setDesigner] = React.useState(false);
const [config, setConfig] = React.useState(false);
const [statsRefreshRate, setStatsRefreshRate ] = React.useState(3);
const [maxSamples, setMaxSamples ] = React.useState(50);
const [animateChart, setAnimateChart ] = React.useState(false);
const [drawerOpened, setDrawerOpened] = useState(false);
const [mode, setMode] = useState('dark');
const [stats, setStats] = useState(true);
const [designer, setDesigner] = useState(false);
const [config, setConfig] = useState(false);
const [statsRefreshRate, setStatsRefreshRate ] = useState(3);
const [maxSamples, setMaxSamples ] = useState(50);
const [animateChart, setAnimateChart ] = useState(false);

const siteConfig = {
statsRefreshRate: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@
const AreaStat = withStyles(chartStyle)(props => {
const { classes, name, rawvalue, ignored, statsAnimateChange, maxSamples, registerStatCallback, headerField , idleField, category, detail } = props;
const [value, setValue] = React.useState(Object.entries(rawvalue)
const AreaStat = withStyles(areaChartStyle)(props => {
const { classes, name, rawvalue, ignored, statsAnimateChange, maxSamples, headerFields , idleField, category, detail } = props;
const getChartValues = (value) => Object.entries(value)
.filter(entry=>!ignored.includes(entry[0]))
.reduce((ret,entry)=>{ret[entry[0]] = entry[1]; return ret},{}));
const [lastStates, setLastStates] = React.useState([value ? Object.entries(value)
.reduce((ret,stat)=>{ret[stat[0]]=stat[1]; return ret},{ts: new Date().getTime()}):[]]);
.reduce((ret,entry)=>{ret[entry[0]] = entry[1]; return ret},{});
const [lastStates, setLastStates] = useState([Object.entries(getChartValues(rawvalue))
.filter(entry=>!ignored.includes(entry[0]))
.reduce((ret,stat)=>{ret[stat[0]]=stat[1]; return ret},{ts: new Date().getTime()})] );
const getValue = (value) => value !== undefined && !Number.isInteger(value) ? (isNaN(value) ? value : value.toFixed(2)) : value;
const theme = useTheme();

React.useEffect(() => {
registerStatCallback && registerStatCallback(name, (value) => {
setValue(value);
setLastStates(prevState => value === undefined ? prevState : [...prevState,Object.entries(value)
.filter(entry=>!ignored.includes(entry[0]))
.reduce((ret,stat)=>{ret[stat[0]]=stat[1]; return ret},{ts: new Date().getTime()})]
.filter((_val,idx,arr) => arr.length >= maxSamples ? idx > arr.length - maxSamples : true));
});

return () => registerStatCallback(name,undefined);
},[maxSamples,registerStatCallback]);

useMemo(()=>{
setLastStates(lastStates === undefined ? [Object.entries(getChartValues(rawvalue))] : [...lastStates,Object.entries(getChartValues(rawvalue))
.filter(entry=>!ignored.includes(entry[0]))
.reduce((ret,stat)=>{ret[stat[0]]=stat[1]; return ret},{ts: new Date().getTime()})]
.filter((_val,idx,arr) => arr.length >= maxSamples ? idx > arr.length - maxSamples : true));
},[rawvalue]);

const getFillColor = ({step, isIdle}) => {
if (isIdle) {
return theme.palette.taskManager.idleColor;
}
return (theme.palette.taskManager[`(${category === "Memory" ? "b" : ""})color${step+1}`]);
return (theme.palette.taskManager[`${category === "Memory" ? "b" : ""}color${step+1}`]);
}

const getStatTooltip = (data, classes) => {
Expand All @@ -50,7 +46,9 @@ const AreaStat = withStyles(chartStyle)(props => {

return <Box className={classes.root}>
{detail && <Box className={classes.header}>
<Typography variant="h7">{name} {headerField && rawvalue[headerField] !== undefined && (`${headerField}: ${rawvalue[headerField]}`)}</Typography>
<Typography className={classes.headerLine} variant="subtitle1">{name} {headerFields && Object.values(headerFields).map(headerField=>
<Typography key={headerField} className={classes.headerField} variant="subtitle2">{`${headerField}: ${rawvalue[headerField]}`}</Typography>)}
</Typography>
<List className={classes.stats}>
{Object.entries(rawvalue)
.filter(entry=>!ignored.includes(entry[0]))
Expand All @@ -65,10 +63,9 @@ const AreaStat = withStyles(chartStyle)(props => {
data={lastStates}
height={detail ? 300 : 80}
width={detail ? 500 : 200}
className="chart"
stackOffset="expand">
<defs>
{Object.entries(value)
{Object.entries(getChartValues(rawvalue))
.filter(entry => entry[1] !== undefined)
.map((entry,idx,arr) => <linearGradient key={`color${entry[0]}`} id={`color${entry[0]}`} x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor={getFillColor({numOfSteps: arr.length, step: idx, isIdle: entry[0] === idleField})} stopOpacity={0.8}/>
Expand All @@ -83,9 +80,9 @@ const AreaStat = withStyles(chartStyle)(props => {
<CartesianGrid strokeDasharray="3 3"/>
<Tooltip content={data => getStatTooltip(data, classes)}
labelFormatter={t => new Date(t).toLocaleString()}></Tooltip>
{Object.entries(value)
{Object.entries(getChartValues(rawvalue))
.filter(entry => entry[1] !== undefined)
.sort((a,b) => sortStats({name:a[0],value:a[1]},{name:b[0],value:b[1]}))
.sort((a,b) => sortStats({name:a[0],chartValue:a[1]},{name:b[0],chartValue:b[1]}))
.map((entry) =>
<Area
key={entry[0]}
Expand Down
107 changes: 107 additions & 0 deletions site/src/components/home/statistics/areachart/style.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
const areaChartStyle = theme => ({
root: {
"display": "flex",
"flex-direction": "column",
"flex-wrap": "wrap",
"align-content": "flex-start",
"justify-content": "flex-start",
"align-items": "stretch"
},
header: {
"display": "flex",
"flex-direction": "column",
"flex-wrap": "nowrap",
"justify-content": "center",
"align-items": "stretch"
},
headerLine: {
"display": "flex",
"flex-direction": "row",
"flex-wrap": "nowrap",
"justify-content": "space-between",
"align-items": "center",
"width": "100%",
"color": theme.palette.text.primary
},
headerField: {
"display": "flex",
"flex-direction": "row",
"flex-wrap": "nowrap",
"justify-content": "center",
"align-items": "center",
"width": "inherit",
"color": theme.palette.text.secondary
},
stats: {
"display": "flex",
"flex-direction": "row",
"flex-wrap": "nowrap",
"justify-content": "center",
"align-items": "center",
"padding": "0px",
"color": theme.palette.text.secondary
},
stat: {
"display": "flex",
"padding": "0px",
"flex-wrap": "nowrap",
"align-items": "center",
"flex-direction": "row",
"justify-content": "center"
},
tooltipContent: {
"display": "flex",
"flex-direction": "column",
"flex-wrap": "nowrap",
"align-content": "center",
"justify-content": "center",
"align-items": "stretch",
"background-color": "black",
"padding": "5px"
},
tooltipHeader: {
"font-size": "medium",
"display": "flex",
"flex-direction": "column",
"flex-wrap": "nowrap",
"align-content": "center",
"align-items": "center",
"justify-content": "center",
"border-bottom": "solid 1px"
},
threads: {
"margin": "0px",
"padding": "0px",
"display": "flex",
"flex-direction": "column",
"flex-wrap": "nowrap",
"align-content": "center",
"justify-content": "center",
"align-items": "stretch",
"font-size": "small",
},
thread: {
"display": "flex",
"flex-direction": "row",
"flex-wrap": "nowrap",
"align-content": "center",
"justify-content": "space-between",
"align-items": "center",
"column-gap": "5px",
},
threadValue: {
"display": "flex",
"flex-direction": "row",
"flex-wrap": "nowrap",
"align-content": "center",
"justify-content": "center",
"align-items": "center",
"font-size": "smaller",
"color": "aquamarine",
"column-gap": "3px"
},
threadSummary: {
"font-size": "x-small",
"color": "aqua"
}
});
51 changes: 51 additions & 0 deletions site/src/components/home/statistics/barchart/barchart.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
const BarStat = withStyles(barChartStyle)(props => {
const { classes, name, rawvalue, ignored, statsAnimateChange , idleField, category, detail } = props;
const theme = useTheme();

const getFillColor = ({step, isIdle}) => {
if (isIdle) {
return theme.palette.taskManager.idleColor;
}
return (theme.palette.taskManager[`${category === "Memory" ? "b" : ""}color${step+1}`]);
}

return (
<Box className={`${classes.summary} ${!detail && classes.minimized}`}>
<BarChart
height={detail ? 300 : 80}
width={detail ? 150 : 100}
data={[Object.entries(rawvalue)
.filter(entry=>!["name",...ignored].includes(entry[0]))
.reduce((ret,entry)=>{ret[entry[0]] = entry[1]; return ret},{name:name})]}
margin={{
top: 20,
right: 30,
left: 20,
bottom: 5}}>
<XAxis hide={true} dataKey="name" />
<YAxis hide={true} />
{Object.keys(rawvalue)
.filter(field => !ignored.includes(field))
.sort(sortStats)
.map((field,idx) => <Bar dataKey={field}
key={field}
stackId="a"
fill={getFillColor({step: idx, isIdle: field === idleField})}
isAnimationActive={statsAnimateChange}
type="monotone"
fillOpacity={1}/>)
}
</BarChart>
<Typography variant="summary">{(Object.entries(rawvalue)
.filter(entry => ![idleField,...ignored].includes(entry[0]))
.reduce((ret,stat)=>ret+stat[1],0.0)/
Object.entries(rawvalue)
.filter(entry => !ignored.includes(entry[0]))
.reduce((ret,stat)=>ret+stat[1],0.0)*100).toFixed(0)}%</Typography>
</Box>)

function sortStats(a, b) {
return a === idleField && b !== idleField ? 1 : (a !== idleField && b === idleField ? -1 : a.localeCompare(b));
}
});

Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
const chartStyle = theme => ({
root: {
const barChartStyle = theme => ({
summary: {
"display": "flex",
"flex-direction": "column",
"flex-wrap": "wrap",
"align-content": "flex-start",
"justify-content": "flex-start",
"align-items": "stretch"
"align-items": "center"
},
minimized: {
"margin-top":"-20px",
"margin-right": "-25px"
},
header: {
"display": "flex",
Expand Down
6 changes: 3 additions & 3 deletions site/src/components/home/statistics/static/static.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
const StaticStatsPanel = withStyles(statsStyle)(props => {
const StaticStatsPanel = withStyles(staticStatStyle)(props => {
const { classes, stat, name, detail } = props;

return <Box className={classes.root}>
<Typography variant={detail ? "h4" : "h7"}>{name}</Typography>
<Typography variant={detail ? "h5" : "h6"}>{name}</Typography>
{detail && <List>
{Object.entries(stat.stat)
.map(entry=>
<ListItem key={entry[0]}>
<Typography variant="littleHeader">{entry[0]}</Typography>:
<Typography variant="littleValue" >{entry[1]}</Typography>
<Typography className={classes.attribute} variant="littleValue" >{entry[1]}</Typography>
</ListItem>)}
</List>}
</Box>
Expand Down
5 changes: 4 additions & 1 deletion site/src/components/home/statistics/static/style.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ const staticStatStyle = theme => ({
"flex-direction": "row",
"flex-wrap": "wrap",
"align-content": "flex-start",
"justify-content": "flex-start",
"justify-content": "space-between",
"align-items": "flex-start"
},
attribute: {
"color": theme.palette.text.secondary
}
});
Loading

0 comments on commit 9d3c516

Please sign in to comment.