Improve logs
This commit is contained in:
parent
5efa4a6c31
commit
2073b41031
|
@ -12,6 +12,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "craco start",
|
"start": "craco start",
|
||||||
"build": "craco build",
|
"build": "craco build",
|
||||||
|
"build:stats": "craco build --stats",
|
||||||
"test": "craco test",
|
"test": "craco test",
|
||||||
"lint": "tsc && eslint --max-warnings=0 src",
|
"lint": "tsc && eslint --max-warnings=0 src",
|
||||||
"lint:fix": "eslint --fix src"
|
"lint:fix": "eslint --fix src"
|
||||||
|
|
|
@ -104,5 +104,5 @@ html, body {
|
||||||
|
|
||||||
.log-canvas {
|
.log-canvas {
|
||||||
color: @text;
|
color: @text;
|
||||||
--background-overlay: transparent;
|
--background-overlay: rgba(34, 38, 41, 0.9);
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,9 +215,6 @@ const Log = ({ ui, config, loadedLogs }: { ui: UIState, config: Config, loadedLo
|
||||||
Files
|
Files
|
||||||
</PerfectScrollbar>
|
</PerfectScrollbar>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
<TabPane tab={<DashboardOutlined />} key="gauges">
|
|
||||||
Gauges
|
|
||||||
</TabPane>
|
|
||||||
</Tabs>
|
</Tabs>
|
||||||
}
|
}
|
||||||
</Sider>
|
</Sider>
|
||||||
|
@ -229,7 +226,7 @@ const Log = ({ ui, config, loadedLogs }: { ui: UIState, config: Config, loadedLo
|
||||||
<LogCanvas
|
<LogCanvas
|
||||||
data={loadedLogs || (logs!.records as Logs)}
|
data={loadedLogs || (logs!.records as Logs)}
|
||||||
width={canvasWidth}
|
width={canvasWidth}
|
||||||
height={800}
|
height={canvasWidth * 0.45}
|
||||||
selectedFields={prepareSelectedFields}
|
selectedFields={prepareSelectedFields}
|
||||||
/>
|
/>
|
||||||
:
|
:
|
||||||
|
|
|
@ -8,8 +8,16 @@ import {
|
||||||
Logs,
|
Logs,
|
||||||
LogEntry,
|
LogEntry,
|
||||||
} from '@speedy-tuner/types';
|
} from '@speedy-tuner/types';
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
Space,
|
||||||
|
Typography,
|
||||||
|
Grid,
|
||||||
|
} from 'antd';
|
||||||
|
import { QuestionCircleOutlined } from '@ant-design/icons';
|
||||||
import TimeChart from 'timechart';
|
import TimeChart from 'timechart';
|
||||||
import { colorHsl } from '../../utils/number';
|
import { colorHsl } from '../../utils/number';
|
||||||
|
import LandscapeNotice from '../Dialog/LandscapeNotice';
|
||||||
|
|
||||||
// enum Colors {
|
// enum Colors {
|
||||||
// RED = '#f32450',
|
// RED = '#f32450',
|
||||||
|
@ -23,6 +31,9 @@ import { colorHsl } from '../../utils/number';
|
||||||
// BG = '#222629',
|
// BG = '#222629',
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
const { Text } = Typography;
|
||||||
|
const { useBreakpoint } = Grid;
|
||||||
|
|
||||||
export interface SelectedField {
|
export interface SelectedField {
|
||||||
name: string;
|
name: string;
|
||||||
label: string;
|
label: string;
|
||||||
|
@ -49,8 +60,8 @@ export interface PlottableField {
|
||||||
};
|
};
|
||||||
|
|
||||||
const LogCanvas = ({ data, width, height, selectedFields }: Props) => {
|
const LogCanvas = ({ data, width, height, selectedFields }: Props) => {
|
||||||
|
const { sm } = useBreakpoint();
|
||||||
const canvasRef = useRef<HTMLDivElement | null>(null);
|
const canvasRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
|
||||||
const hsl = useCallback((fieldIndex: number, allFields: number) => {
|
const hsl = useCallback((fieldIndex: number, allFields: number) => {
|
||||||
const [hue] = colorHsl(0, allFields - 1, fieldIndex);
|
const [hue] = colorHsl(0, allFields - 1, fieldIndex);
|
||||||
return `hsl(${hue}, 90%, 50%)`;
|
return `hsl(${hue}, 90%, 50%)`;
|
||||||
|
@ -60,8 +71,6 @@ const LogCanvas = ({ data, width, height, selectedFields }: Props) => {
|
||||||
|
|
||||||
const filtered = useMemo(() => data.filter(fieldsOnly), [data]);
|
const filtered = useMemo(() => data.filter(fieldsOnly), [data]);
|
||||||
|
|
||||||
// find max values for each selected field so we can calculate scale
|
|
||||||
// TODO: unused
|
|
||||||
const fieldsToPlot = useMemo(() => {
|
const fieldsToPlot = useMemo(() => {
|
||||||
const temp: { [index: string]: PlottableField } = {};
|
const temp: { [index: string]: PlottableField } = {};
|
||||||
|
|
||||||
|
@ -94,35 +103,60 @@ const LogCanvas = ({ data, width, height, selectedFields }: Props) => {
|
||||||
}, [filtered, selectedFields]);
|
}, [filtered, selectedFields]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const series = selectedFields.map((field) => ({
|
const series = Object.keys(fieldsToPlot).map((label, index) => ({
|
||||||
name: field.label,
|
name: fieldsToPlot[label].units ? `${label} (${fieldsToPlot[label].units})` : label,
|
||||||
color: hsl(selectedFields.indexOf(field), selectedFields.length),
|
color: hsl(index, selectedFields.length),
|
||||||
data: data.map((entry) => ({
|
data: data.map((entry) => ({
|
||||||
x: entry.Time as number,
|
x: entry.Time as number,
|
||||||
y: entry[field.label] as number,
|
y: entry[label] as number,
|
||||||
})).filter((entry) => entry.x !== undefined || entry.y !== undefined),
|
})).filter((entry) => entry.x !== undefined || entry.y !== undefined),
|
||||||
}));
|
}));
|
||||||
|
let chart: TimeChart;
|
||||||
|
|
||||||
const chart = new TimeChart(canvasRef.current!, {
|
if (canvasRef.current) {
|
||||||
series,
|
chart = new TimeChart(canvasRef.current, {
|
||||||
lineWidth: 2,
|
series,
|
||||||
tooltip: true,
|
lineWidth: 2,
|
||||||
legend: false,
|
tooltip: true,
|
||||||
zoom: {
|
legend: false,
|
||||||
x: { autoRange: true },
|
zoom: {
|
||||||
y: { autoRange: true },
|
x: { autoRange: true },
|
||||||
},
|
},
|
||||||
});
|
tooltipXLabel: 'Time (s)',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return () => chart.dispose();
|
return () => chart && chart.dispose();
|
||||||
}, [data, fieldsToPlot, filtered, hsl, selectedFields, width, height]);
|
}, [data, fieldsToPlot, filtered, hsl, selectedFields, width, height]);
|
||||||
|
|
||||||
|
if (!sm) {
|
||||||
|
return <LandscapeNotice />;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<>
|
||||||
ref={canvasRef}
|
<div style={{ marginTop: -20, marginBottom: 10, textAlign: 'left', marginLeft: 20 }}>
|
||||||
style={{ width, height }}
|
<Popover
|
||||||
className="log-canvas"
|
placement="bottom"
|
||||||
/>
|
content={
|
||||||
|
<Space direction="vertical">
|
||||||
|
<Typography.Title level={5}>Navigation</Typography.Title>
|
||||||
|
<Text>Pinch to zoom</Text>
|
||||||
|
<Text>Drag to pan</Text>
|
||||||
|
<Text>Ctrl + wheel scroll to zoom X axis</Text>
|
||||||
|
<Text>Hold Shift to speed up zoom 5 times</Text>
|
||||||
|
</Space>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<QuestionCircleOutlined />
|
||||||
|
</Popover>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
ref={canvasRef}
|
||||||
|
style={{ width, height }}
|
||||||
|
className="log-canvas"
|
||||||
|
/>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue