This commit is contained in:
sebseb7
2025-12-25 00:19:02 +01:00
parent 077e76735e
commit 0eb05b1cd5
4 changed files with 452 additions and 33 deletions

View File

@@ -3,7 +3,7 @@ import { Paper, Typography, Box, CircularProgress } from '@mui/material';
import { LineChart } from '@mui/x-charts/LineChart';
import { useTheme } from '@mui/material/styles';
export default function Chart({ selectedChannels = [], channelConfig = null }) {
export default function Chart({ selectedChannels = [], channelConfig = null, axisConfig = null }) {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
const theme = useTheme();
@@ -66,11 +66,15 @@ export default function Chart({ selectedChannels = [], channelConfig = null }) {
if (effectiveChannels.length === 0) return <Box sx={{ p: 4 }}><Typography>No channels selected.</Typography></Box>;
const series = effectiveChannels.map(id => {
// Find alias if config exists
// Find alias and axis if config exists
let label = id;
let yAxisKey = 'left';
if (channelConfig) {
const item = channelConfig.find(c => c.id === id);
if (item && item.alias) label = item.alias;
if (item) {
if (item.alias) label = item.alias;
if (item.yAxis) yAxisKey = item.yAxis;
}
}
return {
@@ -78,9 +82,64 @@ export default function Chart({ selectedChannels = [], channelConfig = null }) {
label: label,
connectNulls: true,
showMark: false,
yAxisKey: yAxisKey,
};
});
const hasRightAxis = series.some(s => s.yAxisKey === 'right');
const computeAxisLimits = (axisKey) => {
// Collect all data points for this axis
let axisMin = Infinity;
let axisMax = -Infinity;
const axisSeries = series.filter(s => s.yAxisKey === axisKey).map(s => s.dataKey);
if (axisSeries.length === 0) return {}; // No data for this axis
// Check if config exists for this axis
let cfgMin = NaN;
let cfgMax = NaN;
if (axisConfig && axisConfig[axisKey]) {
cfgMin = parseFloat(axisConfig[axisKey].min);
cfgMax = parseFloat(axisConfig[axisKey].max);
}
// Optimization: If no config set, just return empty and let chart autoscale fully.
if (isNaN(cfgMin) && isNaN(cfgMax)) return {};
// Calculate data bounds
let hasData = false;
data.forEach(row => {
axisSeries.forEach(key => {
const val = row[key];
if (val !== null && val !== undefined) {
hasData = true;
if (val < axisMin) axisMin = val;
if (val > axisMax) axisMax = val;
}
});
});
if (!hasData) return {}; // No valid data points
// Apply config soft limits
if (!isNaN(cfgMin)) axisMin = Math.min(axisMin, cfgMin);
if (!isNaN(cfgMax)) axisMax = Math.max(axisMax, cfgMax);
return { min: axisMin, max: axisMax };
};
const leftLimits = computeAxisLimits('left');
const rightLimits = computeAxisLimits('right');
const yAxes = [
{ id: 'left', scaleType: 'linear', ...leftLimits }
];
if (hasRightAxis) {
yAxes.push({ id: 'right', scaleType: 'linear', ...rightLimits });
}
return (
<Box sx={{ width: '100%', height: '80vh', p: 2 }}>
<Typography variant="h6" gutterBottom>Last 24 Hours</Typography>
@@ -94,6 +153,8 @@ export default function Chart({ selectedChannels = [], channelConfig = null }) {
scaleType: 'time',
valueFormatter: (date) => date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
}]}
yAxis={yAxes}
rightAxis={hasRightAxis ? 'right' : null}
slotProps={{
legend: {
direction: 'row',