【发布时间】:2021-02-12 13:30:19
【问题描述】:
TL;DR: 在@react-google-maps/api 中,我希望能够根据集群中的标记制作饼图样式的动态集群图标/符号,但似乎我只能从静态数组中制作图标,并且不能将标记作为参数传递。
完整说明: 我正在使用 typescript 与包@react-google-maps/api 做出反应,并且我正在尝试使用 ClustererComponent/MarkerClusterer 找到一种方法来进行回调或类似操作,以便能够为每个集群基于给定集群中的标记。
当前的问题是我理解它的方式,我仅限于图标的静态 url 数组,并且认为我可以在其中制作一个 svg,我无法将参数传递给这些 svg,作为唯一的包允许我选择样式的方式是样式数组中的思想索引。
我已经阅读了以下材料,但无法找到一种基于标记动态制作图标的方法:
- @react-google-maps/api 的文档:https://react-google-maps-api-docs.netlify.app/#markerclustere
- 谷歌地图markerclusterer的文档:https://developers.google.com/maps/documentation/javascript/marker-clustering
我找到了这样的库:https://github.com/hassanlatif/google-map-chart-marker-clusterer,应该可以用作解决方案,但它们似乎不适用于 @react-google-maps/api,仅适用于早期版本的 google地图。如果不是这种情况,并且这些可以直接使用,那么我会更满意一个描述如何通过@react-google-maps/api 使用上述库的答案,因为这应该允许聚类方式如下图所示。
编辑: 我在 cmets 中得到提醒,这是我目前拥有的代码:
我尝试过的:我试图找到任何方法来设置 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' },
{ 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>
目前,我只能使用一些静态样式,但我有如下测试:
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',
}
];
【问题讨论】:
-
你能添加你迄今为止尝试过的东西吗?有一些代码。
-
@James 我编辑了它以显示我拥有的代码并试图给出更好的解释,但忘记提交它,然后我今天找到了一个解决方案,所以我将两者都上传为编辑,但感谢您提醒我更具体地了解我提交的代码问题。
-
很高兴听到这个消息。您能否将您的解决方案发布为该问题的答案,以便对其他人有所帮助?如果可能,我们允许并鼓励您在堆栈溢出时回答自己的问题
-
@James Done,我已将其从上次编辑更新移至答案。感谢您帮助我思考关于 StackOverflow 的第一个问题以及我的第一个答案
标签: reactjs typescript google-maps markerclusterer react-google-maps