Skip to content

Commit 29a187f

Browse files
committed
add ClusterCenterMarker (red dot)
1 parent 8b383fb commit 29a187f

2 files changed

Lines changed: 64 additions & 17 deletions

File tree

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
import React, { useMemo } from "react";
22
import { observer } from "mobx-react";
3+
import { Polyline, Marker } from "react-leaflet";
4+
import L from "leaflet";
5+
6+
import ClusterCenterMarker from "./markers/ClusterCenterMarker";
37
import { useAccidentMarkers } from "../../hooks/useAccidentMarkers";
48
import { clusterMarkers, generateClusterPositions } from "../../utils";
59
import MarkerSvg from "./MarkerSvg";
6-
import "./map.css";
710

811
const ClusteredMarkers: React.FC = observer(() => {
912
const markers = useAccidentMarkers();
1013
const clusteredMarkers = useMemo(() => clusterMarkers(markers), [markers]);
1114

1215
return (
1316
<>
14-
{clusteredMarkers.map((cluster, index) => {
17+
{clusteredMarkers.map((cluster) => {
18+
const center = cluster[0].position;
19+
1520
if (cluster.length === 1) {
16-
// Single marker or zoomed-out - show as normal marker
1721
return (
1822
<MarkerSvg
1923
key={cluster[0].key}
@@ -24,23 +28,38 @@ const ClusteredMarkers: React.FC = observer(() => {
2428
markerIconsType={cluster[0].markerIconsType}
2529
/>
2630
);
27-
} else {
28-
// Clustered markers - show as spiral arrangement
29-
const flowerPositions = generateClusterPositions(cluster[0].position, cluster.length);
30-
return flowerPositions.map((position, i) => (
31-
<MarkerSvg
32-
key={`${cluster[0].key}-${i}`}
33-
position={position}
34-
data={cluster[i].data}
35-
language={cluster[i].language}
36-
colorBy={cluster[i].colorBy}
37-
markerIconsType={cluster[i].markerIconsType}
38-
/>
39-
));
4031
}
32+
33+
const flowerPositions = generateClusterPositions(center, cluster.length);
34+
35+
return (
36+
<React.Fragment key={cluster[0].key}>
37+
{/* center red dot */}
38+
<ClusterCenterMarker position={center} />
39+
{flowerPositions.map((position, i) => (
40+
<React.Fragment key={`${cluster[0].key}-${i}`}>
41+
{/* line to center */}
42+
<Polyline
43+
positions={[position, center]}
44+
color="gray"
45+
weight={1}
46+
opacity={0.7}
47+
/>
48+
{/* marker */}
49+
<MarkerSvg
50+
position={position}
51+
data={cluster[i].data}
52+
language={cluster[i].language}
53+
colorBy={cluster[i].colorBy}
54+
markerIconsType={cluster[i].markerIconsType}
55+
/>
56+
</React.Fragment>
57+
))}
58+
</React.Fragment>
59+
);
4160
})}
4261
</>
4362
);
4463
});
4564

46-
export default ClusteredMarkers;
65+
export default ClusteredMarkers;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React from "react";
2+
import { Marker } from "react-leaflet";
3+
import L from "leaflet";
4+
import { LatLngExpression } from "leaflet";
5+
6+
type Props = {
7+
position: LatLngExpression;
8+
};
9+
10+
const centerIcon = new L.DivIcon({
11+
className: "cluster-center-dot",
12+
iconAnchor: [5, 5],
13+
html: `
14+
<div style="
15+
width: 10px;
16+
height: 10px;
17+
background: red;
18+
border-radius: 50%;
19+
box-shadow: 0 0 0 2px white;
20+
"></div>
21+
`,
22+
});
23+
24+
const ClusterCenterMarker: React.FC<Props> = ({ position }) => {
25+
return <Marker position={position} icon={centerIcon} />;
26+
};
27+
28+
export default ClusterCenterMarker;

0 commit comments

Comments
 (0)