jquery - 如何用内部标记的颜色填充簇的颜色?

标签 jquery leaflet marker markerclusterer

在自定义传单 map 上,我正在尝试构建一个函数,以根据群集内标记的颜色填充群集图标的背景颜色。例如,如果一个簇有 7 个绿色标记和 2 个红色标记,则将该簇填充为 77% 绿色,其他填充为红色。

我正在使用markerCluster插件,和 awesome marker plugin一起。

目前,这就是我所拥有的:

var clusters = L.markerClusterGroup({
  spiderfyOnMaxZoom: false,
  showCoverageOnHover: false,
  zoomToBoundsOnClick: true,
  iconCreateFunction: function (cluster) {
    var markers = cluster.getAllChildMarkers();
    console.log(markers);
    markers.forEach(function (m) {
      var color = m.defaultOptions.icon.options.markerColor;
      console.log(color);
    });
    var html =
      '<span class="circle circle-' + markers[0].feature.properties["Examen"] +
      '">' + markers.length + "</span>";
    return L.divIcon({ html: html, className: "marker-cluster", iconSize: L.point(32, 32) });
  },
});

我发现我可以获取每个簇内的标记数量以及相关的颜色,如下所示。 enter image description here

所以我的问题是,由此,我如何循环遍历“颜色”来获取簇内每种颜色的百分比?

我的目标是使用这个百分比来填充簇的背景颜色..得到这样的东西?

enter image description here

我看到了很多关于这个的例子,比如here here here herehere但我想知道如果没有像这些示例中那样的大量复杂代码,我是否无法拥有类似的东西?

编辑:

好的,感谢@IvanSanchez 的帮助,我将提供的代码复制到我的项目中并且它正在工作!我必须对其进行一些更改才能使其正常工作,并尝试使用图标渐变线性渐变

下面是我的最终 culsterGroup 函数,我展示了两个版本的完整示例 here (标志性的CSS)和here (线性渐变)。很抱歉我无法将其发布在这里,因为代码对于这个编辑器来说太长了:)

实现后,我做了一些更改。 - 因为我只得到颜色的第一个字母,所以 CSS 不起作用。所以我写道:

stops.push(color + ' ' + startPercent + '%');
stops.push(color + ' ' + endPercent + '%');

而不是

 stops.push(color[i] + ' ' + startPercent + '%');
 stops.push(color[i] + ' ' + endPercent + '%');
  • 我还必须通过 div 更改“h​​tml”变量中的跨度,因为默认情况下将标记簇 css 应用在 div 上。

    var cluster = L.markerClusterGroup({ SpiderfyOnMaxZoom:假, showCoverageOnHover: false, ZoomToBoundsOnClick:true,

        iconCreateFunction: function (cluster) {
            var markers = cluster.getAllChildMarkers();
            var childCount = cluster.getChildCount();
            console.log(markers);
            var stops = [];
    
            for (let i=0, l=markers.length; i<l; i++) {
                var color = markers[i].defaultOptions.icon.options.markerColor;         
                let startPercent = 100 * (i/l);
                let endPercent = 100 * (i+1)/l;
                stops.push(color + ' ' + startPercent + '%');
                stops.push(color + ' ' + endPercent + '%');     
            }
            var html = '<div class="circleMarker" style="background: linear-gradient(to right,' + stops.join(',') + '" >' + markers.length + "</div>";
            return L.divIcon({ html: html, className: "marker-cluster", iconSize: L.point(40, 40) });
    
          },
    });
    
  • 此外,某些颜色混合不再适用于此技术:如果我们查看 AwesomeMarker 插件的调色板,某些颜色在 css 中没有等效颜色,例如“lightRed”或“dardkRed”。因此,为了适合我在项目中使用的颜色,我更改了渐变的颜色,使簇颜色完美适合我个人标记的颜色。

  • 由于 Firefox 和 IE 不支持 icon-gradient,因此我添加了一个条件,以便在 chrome 上显示 icon-gradient cluster,并在 firefox 和 IE 上显示标准的 Linear-gradient。

这是最后一段代码:

     var clusters = L.markerClusterGroup({
        spiderfyOnMaxZoom: false,
        showCoverageOnHover: false,
        zoomToBoundsOnClick: true,

        iconCreateFunction: function (cluster) {
            var markers = cluster.getAllChildMarkers();
            var childCount = cluster.getChildCount();
            console.log(markers);
            var stops = [];
            for (let i=0, l=markers.length; i<l; i++) {
            var color= markers[i].defaultOptions.icon.options.markerColor;  
            if (color==="red"){ 
            color="#D13D29";
            }else if( color === "orange"){
            color="#F69730";
            }else if(color === "green"){
            color="#6FAC25";
            }else if(color === "cadetblue"){
            color="#406473";
            }else if(color ==="darkred"){
            color="#A03336 ";
            }else if(color === "beige"){
            color="#FFC78C";
            }else if(color === "darkgreen"){
            color="#708023";
            }else if(color === "lightgreen"){
            color="#B8F471";
            }else if(color === "blue"){
            color="#37A7D9 ";
            }else if(color === "darkblue"){
            color="#0065A0";
            }else if(color === "lightblue"){
            color="#88DAFF";
            }else if(color === "purple"){
            color="#CD50B5";
            }else if(color === "darkpurple"){
            color="#593869";
            }else if(color === "pink"){
            color="#FF90E8";
            }else if(color === "gray"){
            color="#575757";
            }else if(color === "lightgray"){
            color="#A3A3A3";
            }
                let startPercent = 100 * (i/l);
                let endPercent = 100 * (i+1)/l;
                stops.push(color + ' ' + startPercent + '%');
                stops.push(color + ' ' + endPercent + '%');     
            }
            if(navigator.userAgent.toLowerCase().indexOf('firefox') > -1  || navigator.userAgent.indexOf("MSIE") != -1 || !!document.documentMode == true ){
                var html = '<div class="circleMarker" style="background: linear-gradient(to right, ' + stops.join(',') + '" >' + markers.length + "</div>";
                return L.divIcon({ html: html, className: "marker-cluster", iconSize: L.point(40, 40) });
            }else{
                var html = '<div class="circleMarker" style="background: conic-gradient(' + stops.join(',') + '" >' + markers.length + "</div>";
                return L.divIcon({ html: html, className: "marker-cluster", iconSize: L.point(40, 40) });

            }
          },
    });

最后经过测试,线性渐变在IE浏览器上不起作用。所以我最终遇到了这些情况

var isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);
        if(isChrome){
        var html = '<div class="circleMarker" style="background: conic-gradient(' + stops.join(',') + '" >' + markers.length + '</div>';
            return L.divIcon({ html: html, className: "marker-cluster", iconSize: L.point(40, 40) });
        }

        else if(navigator.userAgent.toLowerCase().indexOf('firefox') > -1  ){
            var html = '<div class="circleMarker" style="background: linear-gradient(to right, ' + stops.join(',') + '" >' + markers.length + '</div>';
            return L.divIcon({ html: html, className: "marker-cluster", iconSize: L.point(40, 40) });
        }else {
             var html = '<div class="markerCluster"><span>' + markers.length + '</span></div>';
            return L.divIcon({ html: html, className: "marker-cluster" });
            }
      },

现在如果是chrome,我使用icon-gradient,如果是Firefox,我使用线性渐变,如果是IE,我就像原来的簇图标一样画圆圈。

我没有找到一种方法来恢复 IE 浏览器的正常簇图标..

最佳答案

由于您明确提到了集群标记的背景颜色,我建议利用 conic-gradient CSS function ,这是一种特定类型的 CSS 渐变。正如 MDN article about using CSS gradients 中所述,使用具有重复停止点的渐变可以在此类渐变中创建锐利的边缘。

例如类似...

<div style='width:50px; height:50px;
  background:  linear-gradient(to right, 
    lime 0%, lime 25%, 
    red 25%, red 50%,
    cyan 50%, cyan 75%, 
    yellow 75%, yellow 100% ); 
'></div>

...看起来像:

enter image description here

还有类似...

<div style='width:50px; height:50px;
  border-radius:25px;
  background:  conic-gradient(
    lime 0%, lime 40%, 
    red 40%, red 60%,
    cyan 60%, cyan 88%, 
    yellow 88%, yellow 100% ); 
'></div>

...看起来像...

sample conic gradient

因此,假设您有一个表示 CSS 颜色的字符串数组,您可以进行一些字符串操作,将其转换为表示渐变的 CSS 函数的字符串,例如:

let colours = ['red','red','red','purple','green','green'];

let stops = [];

for (let i=0, l=colours.length; i<l; i++) {
  let startPercent = 100 * (i/l);
  let endPercent = 100 * (i+1)/l;
  stops.push(colours[i] + ' ' + startPercent + '%');
  stops.push(colours[i] + ' ' + endPercent + '%');
}

let gradient = "conic-gradient(" + stops.join(',') + ")";

...这将创建一个 gradient 变量,其中包含一个字符串,例如...

conic-gradient(red 0%,red 16.666666666666668%,red 16.666666666666664%,red 33.333333333333336%,red 33.33333333333333%,red 50%,purple 50%,purple 66.66666666666667%,green 66.66666666666666%,green 83.33333333333333%,green 83.33333333333334%,green 100%)

...当应用于网页中的元素时,它看起来像:

dynamic conic gradient

查看working demo here .


您可能需要稍微调整一下以使此技术适应您的代码,但我建议如下:

var stops = [];

for (let i=0, l=markers.length; i<l; i++) {
    var color = m.defaultOptions.icon.options.markerColor;
    let startPercent = 100 * (i/l);
    let endPercent = 100 * (i+1)/l;
    stops.push(colours[i] + ' ' + startPercent + '%');
    stops.push(colours[i] + ' ' + endPercent + '%');    
});
var html = '<span ' +
    'class="circle circle-' + markers[0].feature.properties["Examen"] + '" ' +
    'style="background: conic-gradient(' + stops.join(',') + '" ' +
>' + markers.length + "</span>";

请注意,在撰写本文时,browser support for the conic-gradient CSS function不一致。因此,如果您想让某些东西与使用 Firefox 的人一起工作,则不应使用此技术,至少目前是这样。

关于jquery - 如何用内部标记的颜色填充簇的颜色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61647637/

相关文章:

python - 更改 matplotlib 散点图中的标记粗细

google-maps - 如何在谷歌地图的跟踪路径上添加方向

javascript - 渐变跟随鼠标但没有 catch

javascript - 收到错误 : Failed to execute 'appendChild' on 'Node' : parameter 1 is not of type 'Node'

javascript - 以编程方式折叠 Leaflet JS 层控件

android - AudioTrack - 如何知道声音何时开始/结束?

javascript - 如何显示具有 XML 数据的字符串

jquery 删除部分文本

json - 将 GeoJSON 文件导入 React-Leaflet

javascript - 如何在 Mapbox 中将 geojson + CSV 文件与杂食动物传单连接起来,将数据映射为多边形?