@react-google-maps/api

问题描述

TL;DR: 在@react-google-maps/api 中,我希望能够根据集群中的标记以饼图的样式制作动态集群图标/符号,但我似乎只能从静态数组中制作图标,而不能将标记作为参数传递。

完整说明: 我正在使用打字稿对@react-google-maps/api 包进行反应,并且我试图找到一种使用 ClustererComponent/MarkerClusterer 进行回调或类似的方法,以便能够为每个集群都基于给定集群中的标记

目前的问题是我理解的方式,我仅限于图标的静态网址数组,并且认为我可以在其中制作一个 svg,我无法将参数传递到那些 svgs,因为唯一的包允许我选择样式的方式是样式数组中的索引。

我已经阅读了以下材料,但无法找到一种基于标记动态制作图标的方法

我找到了这样的库:https://github.com/hassanlatif/google-map-chart-marker-clusterer,应该可以用作解决方案,但它们似乎不适用于@react-google-maps/api,仅适用于早期版本谷歌地图。如果情况并非如此,并且这些可以直接使用,那么我会更满意的答案是描述如何将上述库与@react-google-maps/api 一起使用,因为这应该允许以与下图相同的方式进行聚类。

编辑:正如我在评论中被提醒的那样,这是我目前拥有的代码

我的尝试:我试图找到任何方法来设置 svg 元素而不是 url,但此后我决定使用 svg 数据创建一个 url,如图所示以下。我试图编辑 MarkerClusterer 下集群的 url 认为 onClusteringBeginonClusteringEndonLoad 的回调,但到目前为止,没有运气.

我如何将 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 }];

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...