[英]Need dynamic icon for MarkerClusterer in @react-google-maps/api
TL;DR:在@react-google-maps/api 中,我希望能夠根據集群中的標記制作餅圖樣式的動態集群圖標/符號,但似乎我只能從static 數組,並且不能將標記作為參數傳遞。
完整描述:我正在使用 typescript 與 package @react-google-maps/api 發生反應,並且我正在嘗試使用 ClustererComponent/MarkerClusterer 找到一種方法來進行回調或類似操作,以便能夠創建基於給定集群中的標記,每個集群的 svg。
當前的問題是我理解它的方式,我僅限於一個 static 數組的 url 到圖標,並認為我可以在其中制作一個 svg,我無法將參數傳遞到這些 svgs 中,作為 ZEFE8407A8DZZDEE78A 的唯一方法允許我選擇一種樣式是樣式數組中的思想索引。
我已經閱讀了以下材料,但無法找到一種基於標記動態制作圖標的方法:
我找到了這樣的庫: https://github.com/hassanlatif/google-map-chart-marker-clusterer ,應該可以用作解決方案,但它們似乎不適用於@react -google-maps/api,僅適用於早期版本的 google map。 如果不是這種情況,並且這些可以直接使用,那么我會更滿意一個描述如何通過@react-google-maps/api 使用上述庫的答案,因為這應該允許以與下圖相同的方式進行聚類。
編輯:正如我在評論中提醒的那樣,這是我到目前為止的代碼:
What I've tried: I have tried to find any way to set in an svg element instead of a url, but have since just decided to make a url with the svg data, as shown below. 我試圖編輯 MarkerClusterer 下集群的 url 認為onClusteringBegin , onClusteringEnd和onLoad的回調,但到目前為止,還沒有運氣。
我如何將 svg 制作成 url-data,所以它可以用於 img src
/*
* Pie Chart SVG Icon in URL form
*
* Inspiration taken from: https://medium.com/hackernoon/a-simple-pie-chart-in-svg-dbdd653b6936
*
* Note: As of right now, I am identifying the difference in marker types by setting the type-number I use in the title of the marker
*/
const serializeXmlNode = (xmlNode: any) => {
if (typeof window.XMLSerializer != "undefined") {
return (new window.XMLSerializer()).serializeToString(xmlNode);
} else if (typeof xmlNode.xml != "undefined") {
return xmlNode.xml;
}
return "";
}
function getCoordinatesForPercent(percent: number) {
const x = Math.cos(2 * Math.PI * percent);
const y = Math.sin(2 * Math.PI * percent);
return [x, y];
}
const makePieChartIcon = (slices: any[]) => {
const svgNS = 'http://www.w3.org/2000/svg';
var svg = document.createElementNS(svgNS, 'svg')
svg.setAttribute('viewBox', '-1.1 -1.1 2.2 2.2')
svg.setAttribute('style', 'transform: rotate(-90deg)')
svg.setAttribute('height', '60')
var circle = document.createElementNS(svgNS, 'circle')
circle.setAttribute('r', '1.1')
circle.setAttribute('fill', 'white')
svg.appendChild(circle);
let cumulativePercent = 0;
slices.map((slice: any) => {
const [startX, startY] = getCoordinatesForPercent(cumulativePercent);
cumulativePercent += slice.percent;
const [endX, endY] = getCoordinatesForPercent(cumulativePercent);
const largeArcFlag = slice.percent > .5 ? 1 : 0;
const pathData = [
`M ${startX} ${startY}`, // Move
`A 1 1 0 ${largeArcFlag} 1 ${endX} ${endY}`, // Arc
`L 0 0`, // Line
].join(' ');
const path = document.createElementNS(svgNS, 'path');
path.setAttribute('d', pathData);
path.setAttribute('fill', slice.color);
svg.appendChild(path);
})
var svgUrl = 'data:image/svg+xml;charset=UTF-8,' + serializeXmlNode(svg)
return svgUrl
}
const makeDynamicClusterIcon = (markers: any[]) => {
var numMarkers = markers.length;
var slices = markers.reduce((acc: any, marker: any) => {
acc[parseInt(marker.title)].percent += 1 / numMarkers;
return acc;
}, [
{ percent: 0, color: 'Green' },
{ percent: 0, color: 'Blue' },
{ percent: 0, color: 'Red' },
])
var newIconURL = makePieChartIcon(slices)
return newIconURL;
}
我如何使用 MarkerClusterer 組件
<MarkerClusterer
options={{
averageCenter: true,
styles: clusterStyles,
}}
>
{(clusterer) =>
markerData.map((marker: any) => (
<Marker
key={marker.key}
title={String(marker.type)}
position={{ lat: marker.lat, lng: marker.lng }}
clusterer={clusterer}
/>
))
}
</MarkerClusterer>
目前,我只能使用一些 static styles,但我有如下測試:
const clusterStyles = [
{
height: 50, textColor: '#ffffff', width: 50,
url: 'data:image/svg+xml;charset=UTF-8,%3Csvg xmlns="http://www.w3.org/2000/svg" height="50" width="100"%3E%3Ccircle cx="25" cy="25" r="20" stroke="black" stroke-width="3" fill="green" /%3E%3C/svg%3E',
},
{
height: 50, textColor: '#ffffff', width: 50,
url: 'data:image/svg+xml;charset=UTF-8,%3Csvg xmlns="http://www.w3.org/2000/svg" height="50" width="100"%3E%3Ccircle cx="25" cy="25" r="20" stroke="black" stroke-width="3" fill="red" /%3E%3C/svg%3E',
}
];
我找到了一個解決方案,通過發現可以更改每個集群(ClusterStyles)的樣式數組,然后我用給定集群中特定標記的數據對其進行了更改。 我最終在回調 onClusteringEnd 中執行此操作,如下所示:
{/* Added to the MarkerClusterer */}
onClusteringEnd={(clusterer) => {
clusterer.clusters.map((cluster) => {
cluster.clusterIcon.styles = makeDynamicClusterIcon(cluster.markers)
})
}}
我將最后一行更改為返回上面顯示的makeDynamicClusterIcon function 改為:
return [{ url: newIconURL, height: 60, width: 60, textColor: '#FFFFFF', textSize: 22 }];
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.