P8-Panels/app/components/p8p_chart_hooks.js

137 lines
5.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
Парус 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 };