in frontend/apps/quantgrid/src/app/hooks/useCharts.tsx [14:232]
export function useCharts() {
const { viewGridData } = useContext(ViewportContext);
const {
projectName,
projectBucket,
projectPath,
sheetName,
projectSheets,
sheetContent,
getCurrentProjectViewport,
} = useContext(ProjectContext);
const [charts, setCharts] = useState<GridChart[]>([]);
const [chartData, setChartData] = useState<ChartsData>({});
// Handle lazy loading of the chart keys in the chart key dropdown
const getMoreChartKeys = useCallback(
(tableName: string, fieldName: string) => {
if (!projectName || !sheetName || !sheetContent || !projectSheets) return;
const viewportRequest = viewGridData.buildGetMoreChartKeysViewportRequest(
tableName,
fieldName
);
if (Object.keys(viewportRequest).length === 0) return;
getCurrentProjectViewport(viewportRequest);
},
[
projectName,
sheetName,
sheetContent,
projectSheets,
viewGridData,
getCurrentProjectViewport,
]
);
// Prepare and send content viewport request for charts
const sendChartViewports = useCallback(
(selectedKeys: SelectedChartKey[]) => {
if (
!projectName ||
!sheetName ||
!sheetContent ||
!projectSheets ||
selectedKeys.length === 0
)
return;
const chartViewportRequest =
viewGridData.buildChartViewportRequest(selectedKeys);
if (chartViewportRequest.length === 0) return;
getCurrentProjectViewport(chartViewportRequest);
},
[
getCurrentProjectViewport,
projectName,
projectSheets,
sheetContent,
sheetName,
viewGridData,
]
);
// Handle selected key from the chart key dropdown
const selectChartKey = useCallback(
(tableName: string, fieldName: string, key: string) => {
if (!projectName || !projectBucket) return;
sendChartViewports([{ tableName, fieldName, key }]);
saveChartKey(
tableName,
fieldName,
key,
projectName,
projectBucket,
projectPath
);
},
[projectBucket, projectName, projectPath, sendChartViewports]
);
useEffect(() => {
if (!projectName || !sheetName) return;
const handleDataUpdate = (chartUpdates: ChartUpdate[]) => {
if (!chartUpdates.some((chartUpdate) => !!chartUpdate.isChartDataUpdate))
return;
setChartData(viewGridData.getChartsData());
};
// init data update call, if component had unmounted
setChartData(viewGridData.getChartsData());
const dataUpdateSubscription =
viewGridData.chartUpdate.subscribe(handleDataUpdate);
return () => {
dataUpdateSubscription.unsubscribe();
};
}, [projectName, sheetName, viewGridData]);
useEffect(() => {
if (!projectName || !sheetName || !projectBucket) return;
const handleUpdateChartStructure = (chartUpdates: ChartUpdate[]) => {
const charts = viewGridData.getCharts(
projectName,
projectBucket,
projectPath
);
const selectedChartKeys: SelectedChartKey[] = [];
if (!chartUpdates.length) return;
if (
chartUpdates.length === 1 &&
Object.keys(chartUpdates[0]).length === 0
) {
setCharts(charts);
return;
}
// TODO: Remove request grouping
for (const chartUpdate of chartUpdates) {
const { chartName, isKeyUpdate } = chartUpdate;
if (!isKeyUpdate || !chartName) continue;
const currentChart = charts.find(
(chart) => chart.tableName === chartName
);
if (!currentChart) return;
const { availableKeys, selectedKeys } = currentChart;
const fieldKeys = Object.keys(selectedKeys);
for (const fieldKey of fieldKeys) {
const availableKeysForFieldKey = availableKeys[fieldKey];
const currentSelectedKey = selectedKeys[fieldKey];
if (
!availableKeysForFieldKey ||
!availableKeysForFieldKey.length ||
!currentSelectedKey
) {
continue;
}
if (availableKeysForFieldKey.includes(currentSelectedKey)) {
selectedChartKeys.push({
tableName: chartName,
fieldName: fieldKey,
key: currentSelectedKey,
});
continue;
}
const newKey = availableKeysForFieldKey[0];
currentChart.selectedKeys[fieldKey] = newKey;
saveChartKey(
chartName,
fieldKey,
newKey,
projectName,
projectBucket,
projectPath
);
selectedChartKeys.push({
tableName: chartName,
fieldName: fieldKey,
key: newKey,
});
}
}
sendChartViewports(selectedChartKeys);
setCharts(charts);
};
// if component had unmounted
setCharts(viewGridData.getCharts(projectName, projectBucket, projectPath));
const chartUpdateStructureSubscription = viewGridData.chartUpdate.subscribe(
handleUpdateChartStructure
);
return () => {
chartUpdateStructureSubscription.unsubscribe();
};
}, [
projectBucket,
projectName,
projectPath,
sendChartViewports,
sheetName,
sheetContent,
viewGridData,
]);
return {
getMoreChartKeys,
selectChartKey,
chartData,
charts,
};
}