Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/demos/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export { layerPopup } from './layer-popup';
export { marker } from './marker';
export { markerCluster } from './marker-cluster';
export { markerClusterVerify } from './marker-cluster-verify';
export { popup } from './popup';
export { swipe } from './swipe';
export { zoom } from './zoom';
150 changes: 150 additions & 0 deletions examples/demos/components/marker-cluster-verify.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import { Marker, MarkerLayer, Popup } from '@antv/l7';
import type { TestCase } from '../../types';
import { CaseScene } from '../../utils';

export const markerClusterVerify: TestCase = async (options) => {
const scene = await CaseScene({
...options,
mapConfig: {
center: [105.79, 30],
zoom: 3,
},
});

// create a layer with markerOption defaults to verify defaults application
const markerLayer = new MarkerLayer({
cluster: true,
markerOption: {
color: '#ff5722',
style: { width: '26px', height: '26px', borderRadius: '50%' },
className: 'demo-marker-default',
},
});

// sample points: three clustered points and one isolated point
const coords = [
[105.79, 30.0],
[105.795, 30.002],
[105.788, 29.998],
// isolated single-point far away
[110.0, 35.0],
];

const markers: Marker[] = [];

coords.forEach((c, i) => {
const m = new Marker({
// do not pass element so markerOption defaults get applied
extData: { id: `m-${i}`, idx: i },
} as any).setLnglat({ lng: c[0], lat: c[1] });

// attach a simple listener to validate event binding and show a popup
m.on('click', (ev: any) => {
console.log('[marker click]', i, ev.data, 'lngLat:', ev.lngLat);
try {
const popup = new Popup({
lngLat: ev.lngLat,
html: `<div style="padding:6px">id: ${ev.data?.id || 'unknown'}<br/>idx: ${ev.data?.idx}</div>`,
className: `marker-popup-${i}`,
});
m.setPopup(popup);
m.openPopup();
} catch (e) {
// ignore popup errors in environments without Popup implementation
void e;
}
});

markers.push(m);
markerLayer.addMarker(m);
});

scene.addMarkerLayer(markerLayer);
// layer-level event for cluster markers
markerLayer.on &&
markerLayer.on('marker:click', (ev: any) => {
console.log('[layer marker click]', ev && ev.data, ev && ev.lngLat);
try {
const data = ev && ev.data;
const popup = new Popup({
lngLat: ev && ev.lngLat,
html: `<div style="padding:6px">cluster: ${JSON.stringify(data)}</div>`,
});
ev.marker && ev.marker.setPopup && ev.marker.setPopup(popup);
ev.marker && ev.marker.openPopup && ev.marker.openPopup();
} catch (e) {
void e;
}
});

// GUI helpers to verify behaviors
markerClusterVerify.extendGUI = (gui) => {
return [
gui.add(
{
setZoom: () => scene.setZoom(6),
hideFirst: () => {
const m = markers[0];
m.hide();
},
showFirst: () => {
const m = markers[0];
m.show();
},
removeFirst: () => {
const m = markers[0];
markerLayer.removeMarker(m);
},
addNew: () => {
const i = markers.length;
const nm = new Marker({ extData: { id: `m-${i}` } } as any).setLnglat({
lng: 105.79 + Math.random() * 0.01,
lat: 30 + Math.random() * 0.01,
});
nm.on('click', (e: any) => console.log('[new marker click]', e.data));
markers.push(nm);
markerLayer.addMarker(nm);
},
},
'setZoom',
),
];
};

scene.render();

// Debug helper: wait until cluster markers are rendered, then attach raw DOM listeners
const attachDomListeners = () => {
const items = markerLayer.getMarkers();
if (!items || items.length === 0) return false;
items.forEach((mm: any, idx: number) => {
try {
const el = mm.getElement && mm.getElement();
if (el) {
// avoid duplicate listeners
if (!(el as any).__verify_click_attached) {
el.addEventListener('click', () => {
console.log('[DOM click]', idx, mm.getExtData && mm.getExtData());
});
(el as any).__verify_click_attached = true;
}
}
} catch (e) {
void e;
}
});
return true;
};

const maxTry = 20;
let tryCount = 0;
const interval = setInterval(() => {
tryCount += 1;
const ok = attachDomListeners();
if (ok || tryCount >= maxTry) {
clearInterval(interval);
}
}, 300);

return scene;
};
58 changes: 58 additions & 0 deletions examples/demos/components/marker-cluster.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Marker, MarkerLayer } from '@antv/l7';
import type { TestCase } from '../../types';
import { CaseScene } from '../../utils';

export const markerCluster: TestCase = async (options) => {
const scene = await CaseScene({
...options,
mapConfig: {
center: [105.790327, 30],
zoom: 2,
},
});

const resp = await fetch(
'https://gw.alipayobjects.com/os/basement_prod/d3564b06-670f-46ea-8edb-842f7010a7c6.json',
);
const data = await resp.json();

const markerLayer = new MarkerLayer({
cluster: true,
});

for (let i = 0; i < data.features.length; i++) {
const { coordinates } = data.features[i].geometry;
// create marker with configurable style and color
const color = i % 2 === 0 ? '#ff5722' : '#5B8FF9';
const marker = new Marker({
color,
style: {
width: '28px',
height: '28px',
},
}).setLnglat({
lng: coordinates[0],
lat: coordinates[1],
});
markerLayer.addMarker(marker);
}

scene.addMarkerLayer(markerLayer);

scene.render();

markerCluster.extendGUI = (gui) => {
return [
gui.add(
{
setZoom: () => {
scene.setZoom(5);
},
},
'setZoom',
),
];
};

return scene;
};
9 changes: 9 additions & 0 deletions packages/component/src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,13 @@ export interface IMarkerStyleOption {
export interface IMarkerLayerOption {
cluster: boolean;
clusterOption: Partial<IMarkerStyleOption>;
/**
* Default marker options applied to markers added to this layer when not overridden per-marker.
* Example: { color: '#ff0000', style: { width: '24px', height: '24px' }, className: 'my-marker' }
*/
markerOption?: Partial<{
color?: string;
style?: { [key: string]: any };
className?: string;
}>;
}
Loading
Loading