perf: improve display of visitor map if data is too much

This commit is contained in:
moonrailgun 2024-10-04 21:19:20 +08:00
parent 9d559b93d1
commit 9bc8c63fe2
2 changed files with 35 additions and 5 deletions

View File

@ -5,7 +5,7 @@ import {
PointLayer,
PointLayerProps,
} from '@antv/larkmap';
import React from 'react';
import React, { useMemo } from 'react';
import { AppRouterOutput } from '../../../api/trpc';
import { useGlobalConfig } from '../../../hooks/useConfig';
import { useSettingsStore } from '../../../store/settings';
@ -76,10 +76,18 @@ export const VisitorLarkMap: React.FC<{
parser: { type: 'json', x: 'longitude', y: 'latitude' },
};
const size = useMemo(() => {
if (props.data.length > 5000) {
return 3;
}
return 5;
}, [props.data.length]);
return (
<LarkMap {...config} style={{ height: '60vh' }}>
<FullscreenControl />
<PointLayer {...layerOptions} source={source} />
<PointLayer {...layerOptions} size={size} source={source} />
</LarkMap>
);
});

View File

@ -1,4 +1,4 @@
import React from 'react';
import React, { useMemo } from 'react';
import { AppRouterOutput } from '../../../api/trpc';
import { MapContainer, CircleMarker, Popup, TileLayer } from 'react-leaflet';
import { mapCenter } from './utils';
@ -7,11 +7,13 @@ import './VisitorLeafletMap.css';
import { useTranslation } from '@i18next-toolkit/react';
export const UserDataPoint: React.FC<{
pointRadius?: number;
longitude: number;
latitude: number;
count: number;
}> = React.memo((props) => {
const { t } = useTranslation();
const pointRadius = props.pointRadius ?? 5;
return (
<CircleMarker
@ -19,7 +21,7 @@ export const UserDataPoint: React.FC<{
lat: props.latitude,
lng: props.longitude,
}}
radius={5}
radius={pointRadius}
stroke={false}
fill={true}
fillColor="rgb(236,112,20)"
@ -38,6 +40,22 @@ UserDataPoint.displayName = 'UserDataPoint';
export const VisitorLeafletMap: React.FC<{
data: AppRouterOutput['website']['geoStats'];
}> = React.memo((props) => {
const pointRadius = useMemo(() => {
if (props.data.length > 20000) {
return 1;
}
if (props.data.length > 5000) {
return 2;
}
if (props.data.length > 1000) {
return 3;
}
return 5;
}, [props.data.length]);
return (
<MapContainer
className="h-[60vh] w-full"
@ -50,7 +68,11 @@ export const VisitorLeafletMap: React.FC<{
<TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
{props.data.map((item) => (
<UserDataPoint key={`${item.longitude},${item.latitude}`} {...item} />
<UserDataPoint
key={`${item.longitude},${item.latitude}`}
pointRadius={pointRadius}
{...item}
/>
))}
</MapContainer>
);