mirror of
https://github.com/umami-software/umami.git
synced 2026-02-05 05:07:15 +01:00
Refactored realtime page. Fixed render issue.
This commit is contained in:
parent
42f184584f
commit
35fde36b61
11 changed files with 152 additions and 172 deletions
|
|
@ -2,6 +2,7 @@ export * from './queries/useApi';
|
|||
export * from './queries/useConfig';
|
||||
export * from './queries/useFilterQuery';
|
||||
export * from './queries/useLogin';
|
||||
export * from './queries/useRealtime';
|
||||
export * from './queries/useReport';
|
||||
export * from './queries/useReports';
|
||||
export * from './queries/useShareToken';
|
||||
|
|
|
|||
87
src/components/hooks/queries/useRealtime.ts
Normal file
87
src/components/hooks/queries/useRealtime.ts
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
import { useMemo, useRef } from 'react';
|
||||
import { RealtimeData } from 'lib/types';
|
||||
import { useApi } from 'components/hooks';
|
||||
import { REALTIME_INTERVAL, REALTIME_RANGE } from 'lib/constants';
|
||||
import { startOfMinute, subMinutes } from 'date-fns';
|
||||
import { percentFilter } from 'lib/filters';
|
||||
import thenby from 'thenby';
|
||||
|
||||
function mergeData(state = [], data = [], time: number) {
|
||||
const ids = state.map(({ id }) => id);
|
||||
return state
|
||||
.concat(data.filter(({ id }) => !ids.includes(id)))
|
||||
.filter(({ timestamp }) => timestamp >= time);
|
||||
}
|
||||
|
||||
export function useRealtime(websiteId: string) {
|
||||
const currentData = useRef({
|
||||
pageviews: [],
|
||||
sessions: [],
|
||||
events: [],
|
||||
countries: [],
|
||||
visitors: [],
|
||||
timestamp: 0,
|
||||
});
|
||||
const { get, useQuery } = useApi();
|
||||
const { data, isLoading, error } = useQuery<RealtimeData>({
|
||||
queryKey: ['realtime', websiteId],
|
||||
queryFn: async () => {
|
||||
const state = currentData.current;
|
||||
const data = await get(`/realtime/${websiteId}`, { startAt: state?.timestamp || 0 });
|
||||
const date = subMinutes(startOfMinute(new Date()), REALTIME_RANGE);
|
||||
const time = date.getTime();
|
||||
const { pageviews, sessions, events, timestamp } = data;
|
||||
|
||||
return {
|
||||
pageviews: mergeData(state?.pageviews, pageviews, time),
|
||||
sessions: mergeData(state?.sessions, sessions, time),
|
||||
events: mergeData(state?.events, events, time),
|
||||
timestamp,
|
||||
};
|
||||
},
|
||||
enabled: !!websiteId,
|
||||
refetchInterval: REALTIME_INTERVAL,
|
||||
});
|
||||
|
||||
const realtimeData: RealtimeData = useMemo(() => {
|
||||
if (!data) {
|
||||
return { pageviews: [], sessions: [], events: [], countries: [], visitors: [], timestamp: 0 };
|
||||
}
|
||||
|
||||
data.countries = percentFilter(
|
||||
data.sessions
|
||||
.reduce((arr, data) => {
|
||||
if (!arr.find(({ id }) => id === data.id)) {
|
||||
return arr.concat(data);
|
||||
}
|
||||
return arr;
|
||||
}, [])
|
||||
.reduce((arr: { x: any; y: number }[], { country }: any) => {
|
||||
if (country) {
|
||||
const row = arr.find(({ x }) => x === country);
|
||||
|
||||
if (!row) {
|
||||
arr.push({ x: country, y: 1 });
|
||||
} else {
|
||||
row.y += 1;
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}, [])
|
||||
.sort(thenby.firstBy('y', -1)),
|
||||
);
|
||||
|
||||
data.visitors = data.sessions.reduce((arr, val) => {
|
||||
if (!arr.find(({ id }) => id === val.id)) {
|
||||
return arr.concat(val);
|
||||
}
|
||||
return arr;
|
||||
}, []);
|
||||
|
||||
return data;
|
||||
}, [data]);
|
||||
|
||||
return { data: realtimeData, isLoading, error };
|
||||
}
|
||||
|
||||
export default useRealtime;
|
||||
|
|
@ -21,6 +21,7 @@ export interface BarChartProps {
|
|||
XAxisType?: string;
|
||||
YAxisType?: string;
|
||||
renderTooltipPopup?: (setTooltipPopup: (data: any) => void, model: any) => void;
|
||||
updateMode?: string;
|
||||
onCreate?: (chart: any) => void;
|
||||
onUpdate?: (chart: any) => void;
|
||||
className?: string;
|
||||
|
|
@ -37,6 +38,7 @@ export function BarChart({
|
|||
XAxisType = 'time',
|
||||
YAxisType = 'linear',
|
||||
renderTooltipPopup,
|
||||
updateMode,
|
||||
onCreate,
|
||||
onUpdate,
|
||||
className,
|
||||
|
|
@ -136,25 +138,16 @@ export function BarChart({
|
|||
const updateChart = (datasets: any[]) => {
|
||||
setTooltipPopup(null);
|
||||
|
||||
const diff = chart.current.data.datasets.reduce(
|
||||
(found: boolean, dataset: { data: any[] }, set: number) => {
|
||||
if (!found) {
|
||||
return dataset.data.find((value, index) => {
|
||||
return datasets[set].data[index].y !== value.y;
|
||||
});
|
||||
}
|
||||
return found;
|
||||
},
|
||||
false,
|
||||
);
|
||||
chart.current.data.datasets.forEach((dataset: { data: any }, index: string | number) => {
|
||||
dataset.data = datasets[index].data;
|
||||
});
|
||||
|
||||
if (diff) {
|
||||
chart.current.data.datasets = datasets;
|
||||
chart.current.options = getOptions();
|
||||
chart.current.update();
|
||||
chart.current.options = getOptions();
|
||||
|
||||
onUpdate?.(chart.current);
|
||||
}
|
||||
// Allow config changes before update
|
||||
onUpdate?.(chart.current);
|
||||
|
||||
chart.current.update(updateMode);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue