From 54512d2d67bdb21a8583020eb0a13d042a95ea78 Mon Sep 17 00:00:00 2001 From: Husam Ibrahim Date: Wed, 24 Aug 2022 22:34:38 +0200 Subject: [PATCH 1/2] chore: cleanup info window code --- src/components/InfoWindow.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/InfoWindow.vue b/src/components/InfoWindow.vue index 2f4a192..2fea6b1 100644 --- a/src/components/InfoWindow.vue +++ b/src/components/InfoWindow.vue @@ -61,7 +61,7 @@ export default defineComponent({ if (!anchor.value) infoWindow.value.open({ map: map.value }); } else { - infoWindow.value = infoWindow.value = markRaw( + infoWindow.value = markRaw( new api.value.InfoWindow({ ...options, content: hasSlotContent.value ? infoWindowRef.value : options.content, From d9616368e3aa263b45ad805058d73ae7e5c25ed2 Mon Sep 17 00:00:00 2001 From: Husam Ibrahim Date: Wed, 24 Aug 2022 22:35:13 +0200 Subject: [PATCH 2/2] feat: heatmap layer --- src/components/HeatmapLayer.ts | 70 ++++++++++++++++++++++++++++++++++ src/components/index.ts | 1 + 2 files changed, 71 insertions(+) create mode 100644 src/components/HeatmapLayer.ts diff --git a/src/components/HeatmapLayer.ts b/src/components/HeatmapLayer.ts new file mode 100644 index 0000000..76a1a7d --- /dev/null +++ b/src/components/HeatmapLayer.ts @@ -0,0 +1,70 @@ +import { defineComponent, PropType, ref, inject, watch, markRaw, onBeforeUnmount } from "vue"; +import { mapSymbol, apiSymbol } from "../shared/index"; + +type HeatmapLayerOptions = google.maps.visualization.HeatmapLayerOptions; + +interface ExtendedHeatmapLayerOptions extends Omit { + data: HeatmapLayerOptions["data"] | (google.maps.LatLngLiteral | { location: google.maps.LatLngLiteral })[]; +} + +export default defineComponent({ + name: "HeatmapLayer", + props: { + options: { + type: Object as PropType, + default: () => ({}), + }, + }, + setup(props) { + const heatmapLayer = ref(); + const map = inject(mapSymbol, ref()); + const api = inject(apiSymbol, ref()); + + watch( + [map, () => props.options], + ([_, options], [oldMap, oldOptions]) => { + const checkIfChanged = JSON.stringify(options) !== JSON.stringify(oldOptions) || map.value !== oldMap; + if (map.value && api.value && checkIfChanged) { + if (options.data && !(options.data instanceof api.value.MVCArray)) { + const LatLng = api.value.LatLng; + + options.data = options.data?.map((point) => { + if ( + point instanceof LatLng || + ("location" in point && (point.location instanceof LatLng || point.location === null)) + ) { + return point; + } else { + if ("location" in point) { + return { ...point, location: new LatLng(point.location as google.maps.LatLngLiteral) }; + } + + return new LatLng(point); + } + }) as HeatmapLayerOptions["data"]; + } + + if (heatmapLayer.value) { + heatmapLayer.value.setOptions(options as HeatmapLayerOptions); + } else { + heatmapLayer.value = markRaw( + new api.value.visualization.HeatmapLayer({ + ...options, + map: map.value, + } as HeatmapLayerOptions) + ); + } + } + }, + { immediate: true } + ); + + onBeforeUnmount(() => { + if (heatmapLayer.value) { + heatmapLayer.value.setMap(null); + } + }); + + return heatmapLayer; + }, +}); diff --git a/src/components/index.ts b/src/components/index.ts index e3ba077..72e66d2 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -8,3 +8,4 @@ export { default as CustomControl } from "./CustomControl.vue"; export { default as InfoWindow } from "./InfoWindow.vue"; export { default as MarkerCluster } from "./MarkerCluster"; export { default as CustomMarker } from "./CustomMarker.vue"; +export { default as HeatmapLayer } from "./HeatmapLayer";