AWS AppSync GraphQL의 Subscription을 사용해서 데이터가 실시간으로 들어오면 기존 배열에 새로운 값을 추가해서 실시간 차트를 구현했다.
const [series, setSeries] = useState([]);
const [categories, setCategories] = useState([]);
const [newValue, setNewValue] = useState({});
useEffect(() => {
const subscription = API.graphql(
graphqlOperation(subscriptions.onCreateDeviceEvent, {
deviceId: deviceId,
})
).subscribe({
next: (data) => {
// console.log('new data', data.value.data.onCreateDeviceEvent);
if (data.value.data.onCreateDeviceEvent.modeledData !== '{}') {
setNewValue(data.value.data.onCreateDeviceEvent);
}
},
});
return () => {
subscription.unsubscribe();
};
}, []);
useDidMountEffect(() => {
// newValue의 modeledData를 string에서 json 형태로 parsing
const newData = JSON.parse(newValue.modeledData);
// 기존 카테고리에 newValue의 createdTime을 milisecond 단위로 변환해서 추가
// 새로운 카테고리 배열 생성
const newCategory = [...categories];
newCategory.push(newValue.createdTime * 1000);
// json 형태의 newData에서 key, value를 분리한다
const keyArr = Object.keys(newData);
const valueArr = Object.values(newData);
let newSeries = [];
// series의 length 가 0이면 기존에 값이 없다는 뜻.
// series 형태를 만들어서 넣어줘야 함.
if (series.length === 0) {
newSeries = keyArr.map((item, idx) => {
const tempdata = { name: item, data: [valueArr[idx]] };
return tempdata;
});
} else { // 기존 series 값이 있음
const seriesArr = keyArr.map((item, idx) => {
let tempSeries = {};
// series에서 name이 key 값과 일치하는 항목이 있는지 확인
// 없으면 undefined 반환
tempSeries = series.find((e) => e.name === item);
// name이 key값과 일치하면
if (tempSeries !== undefined) {
// data 배열에 value를 추가함
tempSeries.data.push(valueArr[idx]);
}
return tempSeries;
});
// 위에서 tempSeries가 undefined로 나온 것들을 filtering
newSeries = seriesArr.filter((e) => e !== undefined);
}
// console.log('new graph value', newSeries, newCategory);
setSeries(newSeries);
setCategories(newCategory);
}, [newValue]);