perf: improve display of visitor map if data is too much
This commit is contained in:
parent
9d559b93d1
commit
9bc8c63fe2
@ -5,7 +5,7 @@ import {
|
|||||||
PointLayer,
|
PointLayer,
|
||||||
PointLayerProps,
|
PointLayerProps,
|
||||||
} from '@antv/larkmap';
|
} from '@antv/larkmap';
|
||||||
import React from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { AppRouterOutput } from '../../../api/trpc';
|
import { AppRouterOutput } from '../../../api/trpc';
|
||||||
import { useGlobalConfig } from '../../../hooks/useConfig';
|
import { useGlobalConfig } from '../../../hooks/useConfig';
|
||||||
import { useSettingsStore } from '../../../store/settings';
|
import { useSettingsStore } from '../../../store/settings';
|
||||||
@ -76,10 +76,18 @@ export const VisitorLarkMap: React.FC<{
|
|||||||
parser: { type: 'json', x: 'longitude', y: 'latitude' },
|
parser: { type: 'json', x: 'longitude', y: 'latitude' },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const size = useMemo(() => {
|
||||||
|
if (props.data.length > 5000) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 5;
|
||||||
|
}, [props.data.length]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LarkMap {...config} style={{ height: '60vh' }}>
|
<LarkMap {...config} style={{ height: '60vh' }}>
|
||||||
<FullscreenControl />
|
<FullscreenControl />
|
||||||
<PointLayer {...layerOptions} source={source} />
|
<PointLayer {...layerOptions} size={size} source={source} />
|
||||||
</LarkMap>
|
</LarkMap>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { AppRouterOutput } from '../../../api/trpc';
|
import { AppRouterOutput } from '../../../api/trpc';
|
||||||
import { MapContainer, CircleMarker, Popup, TileLayer } from 'react-leaflet';
|
import { MapContainer, CircleMarker, Popup, TileLayer } from 'react-leaflet';
|
||||||
import { mapCenter } from './utils';
|
import { mapCenter } from './utils';
|
||||||
@ -7,11 +7,13 @@ import './VisitorLeafletMap.css';
|
|||||||
import { useTranslation } from '@i18next-toolkit/react';
|
import { useTranslation } from '@i18next-toolkit/react';
|
||||||
|
|
||||||
export const UserDataPoint: React.FC<{
|
export const UserDataPoint: React.FC<{
|
||||||
|
pointRadius?: number;
|
||||||
longitude: number;
|
longitude: number;
|
||||||
latitude: number;
|
latitude: number;
|
||||||
count: number;
|
count: number;
|
||||||
}> = React.memo((props) => {
|
}> = React.memo((props) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const pointRadius = props.pointRadius ?? 5;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CircleMarker
|
<CircleMarker
|
||||||
@ -19,7 +21,7 @@ export const UserDataPoint: React.FC<{
|
|||||||
lat: props.latitude,
|
lat: props.latitude,
|
||||||
lng: props.longitude,
|
lng: props.longitude,
|
||||||
}}
|
}}
|
||||||
radius={5}
|
radius={pointRadius}
|
||||||
stroke={false}
|
stroke={false}
|
||||||
fill={true}
|
fill={true}
|
||||||
fillColor="rgb(236,112,20)"
|
fillColor="rgb(236,112,20)"
|
||||||
@ -38,6 +40,22 @@ UserDataPoint.displayName = 'UserDataPoint';
|
|||||||
export const VisitorLeafletMap: React.FC<{
|
export const VisitorLeafletMap: React.FC<{
|
||||||
data: AppRouterOutput['website']['geoStats'];
|
data: AppRouterOutput['website']['geoStats'];
|
||||||
}> = React.memo((props) => {
|
}> = 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 (
|
return (
|
||||||
<MapContainer
|
<MapContainer
|
||||||
className="h-[60vh] w-full"
|
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" />
|
<TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
|
||||||
|
|
||||||
{props.data.map((item) => (
|
{props.data.map((item) => (
|
||||||
<UserDataPoint key={`${item.longitude},${item.latitude}`} {...item} />
|
<UserDataPoint
|
||||||
|
key={`${item.longitude},${item.latitude}`}
|
||||||
|
pointRadius={pointRadius}
|
||||||
|
{...item}
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
</MapContainer>
|
</MapContainer>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user