Skip to content

Commit

Permalink
Merge pull request #6 from shm11C3/udpate_hardware-service
Browse files Browse the repository at this point in the history
update: ハードウェア使用率更新処理の修正
  • Loading branch information
shm11C3 authored Aug 31, 2024
2 parents e4f32e3 + c4b3aac commit 8f86793
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 59 deletions.
5 changes: 5 additions & 0 deletions src/atom/chart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { atom } from "jotai";

export const cpuUsageHistoryAtom = atom<number[]>([]);
export const memoryUsageHistoryAtom = atom<number[]>([]);
export const graphicUsageHistoryAtom = atom<number[]>([]);
6 changes: 5 additions & 1 deletion src/atom/main.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import type { Settings } from "@/types/settingsType";
import { atom } from "jotai";

export const settingsAtom = atom<Settings | null>(null);
export const settingsAtom = atom<Settings>({
language: "en",
theme: "light",
display_targets: [],
});
6 changes: 6 additions & 0 deletions src/consts/chart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const chartConfig = {
/**
* グラフの履歴の長さ(秒)
*/
historyLengthSec: 60,
} as const;
61 changes: 61 additions & 0 deletions src/hooks/useHardwareData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import {
cpuUsageHistoryAtom,
graphicUsageHistoryAtom,
memoryUsageHistoryAtom,
} from "@/atom/chart";
import { chartConfig } from "@/consts/chart";
import {
getCpuUsage,
getGpuUsage,
getMemoryUsage,
} from "@/services/hardwareService";
import type { ChartDataType } from "@/types/chartType";
import { type PrimitiveAtom, useSetAtom } from "jotai";
import { useEffect } from "react";

type AtomActionMapping = {
atom: PrimitiveAtom<number[]>;
action: () => Promise<number>;
};

/**
* ハードウェア使用率の履歴を更新する
*/
export const useUsageUpdater = (dataType: ChartDataType) => {
const mapping: Record<ChartDataType, AtomActionMapping> = {
cpu: {
atom: cpuUsageHistoryAtom,
action: getCpuUsage,
},
memory: {
atom: memoryUsageHistoryAtom,
action: getMemoryUsage,
},
gpu: {
atom: graphicUsageHistoryAtom,
action: getGpuUsage,
},
};

const setHistory = useSetAtom(mapping[dataType].atom);
const getUsage = mapping[dataType].action;

useEffect(() => {
const intervalId = setInterval(async () => {
const usage = await getUsage();
setHistory((prev) => {
const newHistory = [...prev, usage];

// 履歴保持数に満たない場合は0で埋める
const paddedHistory = Array(
Math.max(chartConfig.historyLengthSec - newHistory.length, 0),
)
.fill(null)
.concat(newHistory);
return paddedHistory.slice(-chartConfig.historyLengthSec);
});
}, 1000);

return () => clearInterval(intervalId);
}, [setHistory, getUsage]);
};
99 changes: 42 additions & 57 deletions src/template/Chart.tsx
Original file line number Diff line number Diff line change
@@ -1,76 +1,61 @@
import {
cpuUsageHistoryAtom,
graphicUsageHistoryAtom,
memoryUsageHistoryAtom,
} from "@/atom/chart";
import { settingsAtom } from "@/atom/main";
import LineChart from "@/components/LineChart";
import {
getCpuMemoryHistory,
getCpuUsageHistory,
getGpuUsageHistory,
} from "@/services/hardwareService";
import { chartConfig } from "@/consts/chart";
import { useUsageUpdater } from "@/hooks/useHardwareData";

import { useAtom } from "jotai";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useMemo } from "react";

const ChartTemplate = () => {
const [cpuData, setCpuData] = useState<number[]>([]);
const [memoryData, setMemoryData] = useState<number[]>([]);
const [gpuData, setGpuData] = useState<number[]>([]);
const [labels, setLabels] = useState<string[]>([]);
const labels = Array(chartConfig.historyLengthSec).fill("");

const [settings] = useAtom(settingsAtom);
const CpuUsageChart = () => {
const [cpuUsageHistory] = useAtom(cpuUsageHistoryAtom);
useUsageUpdater("cpu");

const fetchData = useCallback(async () => {
const seconds = 60;
return (
<LineChart labels={labels} chartData={cpuUsageHistory} dataType="cpu" />
);
};

const newCpuDataPromise = settings?.display_targets.includes("cpu")
? getCpuUsageHistory(seconds)
: Promise.resolve([]);
const newMemoryDataPromise = settings?.display_targets.includes("memory")
? getCpuMemoryHistory(seconds)
: Promise.resolve([]);
const newGpuDataPromise = settings?.display_targets.includes("gpu")
? getGpuUsageHistory(seconds)
: Promise.resolve([]);
const MemoryUsageChart = () => {
const [memoryUsageHistory] = useAtom(memoryUsageHistoryAtom);
useUsageUpdater("memory");

return (
<LineChart
labels={labels}
chartData={memoryUsageHistory}
dataType="memory"
/>
);
};

const [newCpuData, newMemoryData, newGpuData] = await Promise.all([
newCpuDataPromise,
newMemoryDataPromise,
newGpuDataPromise,
]);
const GpuUsageChart = () => {
const [graphicUsageHistory] = useAtom(graphicUsageHistoryAtom);
useUsageUpdater("gpu");

if (cpuData.length < seconds) {
setCpuData([...cpuData, newCpuData[newCpuData.length - 1]]);
setMemoryData([...memoryData, newMemoryData[newMemoryData.length - 1]]);
setGpuData([...gpuData, newGpuData[newGpuData.length - 1]]);
setLabels([...labels, ""]);
} else {
setCpuData([...cpuData.slice(1), newCpuData[newCpuData.length - 1]]);
setMemoryData([
...memoryData.slice(1),
newMemoryData[newMemoryData.length - 1],
]);
setGpuData([...gpuData.slice(1), newGpuData[newGpuData.length - 1]]);
setLabels([...labels.slice(1), ""]);
}
}, [settings, cpuData, memoryData, gpuData, labels]);
return (
<LineChart labels={labels} chartData={graphicUsageHistory} dataType="gpu" />
);
};

useEffect(() => {
const interval = setInterval(fetchData, 1000);
return () => clearInterval(interval);
}, [fetchData]);
const ChartTemplate = () => {
const [settings] = useAtom(settingsAtom);

const renderedCharts = useMemo(() => {
return (
<>
{settings?.display_targets.includes("cpu") && (
<LineChart labels={labels} chartData={cpuData} dataType="cpu" />
)}
{settings?.display_targets.includes("memory") && (
<LineChart labels={labels} chartData={memoryData} dataType="memory" />
)}
{settings?.display_targets.includes("gpu") && (
<LineChart labels={labels} chartData={gpuData} dataType="gpu" />
)}
{settings?.display_targets.includes("cpu") && <CpuUsageChart />}
{settings?.display_targets.includes("memory") && <MemoryUsageChart />}
{settings?.display_targets.includes("gpu") && <GpuUsageChart />}
</>
);
}, [labels, cpuData, memoryData, gpuData, settings]);
}, [settings]);

return <div className="chart-container">{renderedCharts}</div>;
};
Expand Down
4 changes: 3 additions & 1 deletion src/types/settingsType.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { ChartDataType } from "./chartType";

export type Settings = {
language: string;
theme: "light" | "dark";
display_targets: "cpu" | "memory" | "gpu";
display_targets: Array<ChartDataType>;
};

0 comments on commit 8f86793

Please sign in to comment.