forked from CITKParus/P8-Panels
137 lines
5.7 KiB
JavaScript
137 lines
5.7 KiB
JavaScript
/*
|
||
Парус 8 - Панели мониторинга
|
||
Хуки для графиков
|
||
*/
|
||
|
||
//---------------------
|
||
//Подключение библиотек
|
||
//---------------------
|
||
|
||
import { useState, useCallback, useEffect, useContext, useRef, useMemo } from "react"; //Классы React
|
||
import { BackEndСtx } from "../context/backend"; //Контекст взаимодействия с сервером
|
||
|
||
//---------
|
||
//Константы
|
||
//---------
|
||
|
||
//Константы - значения по умолчанию
|
||
const RESP_ARG_DEF = "COUT"; //Имя параметра, содержащего информацию о графике
|
||
const CHART_NODE_NAME_DEF = "XCHART"; //Наименование узла, содержащего информацию о графике
|
||
|
||
//-----------
|
||
//Тело модуля
|
||
//-----------
|
||
|
||
//Хук для P8PChart
|
||
const useP8PChart = ({
|
||
stored,
|
||
respArg = RESP_ARG_DEF,
|
||
contentNodeName = CHART_NODE_NAME_DEF,
|
||
storedArgs = {},
|
||
executeStoredArgs = {},
|
||
allowDataLoad = () => true
|
||
}) => {
|
||
//Собственное состояние - график
|
||
const [chart, setChart] = useState({
|
||
type: null,
|
||
title: null,
|
||
legendPosition: null,
|
||
labels: [],
|
||
datasets: []
|
||
});
|
||
|
||
//Собственное состояние - признак загрузки данных
|
||
const [isDataLoaded, setIsDataLoaded] = useState(false);
|
||
|
||
//Собственное состояние - флаг загрузки
|
||
const [isLoading, setLoading] = useState(false);
|
||
|
||
//Собственное состояние - необходимость обновления данных
|
||
const [reload, setReload] = useState(true);
|
||
|
||
//Собственное состояние - дополнительные агрументы
|
||
const refStoredArgs = useRef(storedArgs);
|
||
|
||
//Собственное состояние - дополнительные параметры вызова процедуры
|
||
const refExecuteStoredArgs = useRef(executeStoredArgs);
|
||
|
||
//Признак допустимости обновления данных
|
||
const isAllowDataLoad = useMemo(() => {
|
||
return allowDataLoad();
|
||
}, [allowDataLoad]);
|
||
|
||
//Подключение к контексту взаимодействия с сервером
|
||
const { executeStored, isRespErr } = useContext(BackEndСtx);
|
||
|
||
//Загрузка данных графика с сервера
|
||
const loadData = useCallback(async () => {
|
||
try {
|
||
setLoading(true);
|
||
const data = await executeStored({ stored, respArg, args: { ...refStoredArgs.current }, ...refExecuteStoredArgs.current });
|
||
setChart(pv => ({ ...pv, ...data[contentNodeName] }));
|
||
//Устанавливаем признак загрузки данных с учетом возможных ошибок
|
||
setIsDataLoaded(!isRespErr(data));
|
||
} catch (e) {
|
||
//Если произошла ошибка - данные не загружены
|
||
setIsDataLoaded(false);
|
||
} finally {
|
||
//Сбрасываем признаки загрузки и перезагрузки данных
|
||
setLoading(false);
|
||
setReload(false);
|
||
}
|
||
}, [contentNodeName, executeStored, isRespErr, respArg, stored]);
|
||
|
||
//При необходимости обновления графика
|
||
const doReload = useCallback(() => {
|
||
setReload(true);
|
||
}, []);
|
||
|
||
//Проверка изменений параметров
|
||
const isArgsChanged = useCallback(
|
||
(currentArgs, args) => {
|
||
//Если дополнительные параметры изменились (и сейчас не происходит загрузка данных с сервера)
|
||
return !isLoading && JSON.stringify(currentArgs) != JSON.stringify(args);
|
||
},
|
||
[isLoading]
|
||
);
|
||
|
||
//При изменение дополнительных параметров процедуры
|
||
useEffect(() => {
|
||
//Если параметры изменились
|
||
if (isArgsChanged(refStoredArgs.current, storedArgs)) {
|
||
//Устанавливаем новые дополнительные параметры
|
||
refStoredArgs.current = storedArgs;
|
||
//При изменении дополнительных параметров необходимо перезагрузить данные
|
||
setReload(true);
|
||
}
|
||
}, [storedArgs, isArgsChanged]);
|
||
|
||
//При изменение дополнительных параметров вызова процедуры
|
||
useEffect(() => {
|
||
//Если параметры изменились
|
||
if (isArgsChanged(refExecuteStoredArgs.current, executeStoredArgs)) {
|
||
//Устанавливаем новые дополнительные параметры
|
||
refExecuteStoredArgs.current = executeStoredArgs;
|
||
//При изменении дополнительных параметров необходимо перезагрузить данные
|
||
setReload(true);
|
||
}
|
||
}, [executeStoredArgs, isArgsChanged]);
|
||
|
||
//При необходимости обновить данные графика
|
||
useEffect(() => {
|
||
//Если необходимо перезагрузить данные и это допустимо
|
||
if (isAllowDataLoad && reload) {
|
||
loadData();
|
||
}
|
||
}, [isAllowDataLoad, reload, loadData]);
|
||
|
||
//Возвращаем данные графика
|
||
return { chart, isDataLoaded, isLoading, doReload };
|
||
};
|
||
|
||
//----------------
|
||
//Интерфейс модуля
|
||
//----------------
|
||
|
||
export { useP8PChart };
|