如何解决@react-google-maps/api
TL;DR: 在@react-google-maps/api 中,我希望能够根据集群中的标记以饼图的样式制作动态集群图标/符号,但我似乎只能从静态数组中制作图标,而不能将标记作为参数传递。
完整说明: 我正在使用打字稿对@react-google-maps/api 包进行反应,并且我试图找到一种使用 ClustererComponent/MarkerClusterer 进行回调或类似的方法,以便能够为每个集群都基于给定集群中的标记。
目前的问题是我理解的方式,我仅限于图标的静态网址数组,并且认为我可以在其中制作一个 svg,我无法将参数传递到那些 svgs,因为唯一的包允许我选择样式的方式是样式数组中的索引。
我已经阅读了以下材料,但无法找到一种基于标记动态制作图标的方法:
- @react-google-maps/api 的文档:https://react-google-maps-api-docs.netlify.app/#markerclustere
- 谷歌地图标记集群的文档:https://developers.google.com/maps/documentation/javascript/marker-clustering
我找到了这样的库:https://github.com/hassanlatif/google-map-chart-marker-clusterer,应该可以用作解决方案,但它们似乎不适用于@react-google-maps/api,仅适用于早期版本谷歌地图。如果情况并非如此,并且这些可以直接使用,那么我会更满意的答案是描述如何将上述库与@react-google-maps/api 一起使用,因为这应该允许以与下图相同的方式进行聚类。
我的尝试:我试图找到任何方法来设置 svg 元素而不是 url,但此后我决定使用 svg 数据创建一个 url,如图所示以下。我试图编辑 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' },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>
目前,我只能使用一些静态样式,但我将它们作为以下进行测试:
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,%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 函数,改为:
return [{ url: newIconURL,height: 60,width: 60,textColor: '#FFFFFF',textSize: 22 }];
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。