如何用内部标记的颜色填充簇的颜色?
How to fill the color of a cluster with the colors of inside markers?
在自定义 传单地图 上,我正在尝试构建一个函数,用集群内标记的颜色填充集群图标的背景色。例如,如果一个簇有 7 个绿色标记和 2 个红色标记,则以 77% 的绿色和其他红色填充簇。
我正在一起使用 markerCluster plugin, and 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) });
},
});
我看到我可以得到每个簇内的标记数量和相关的颜色,就像这样。
所以我的问题是,据此,我如何循环遍历 "color" 以获得簇内每种颜色的百分比?
然后我的目标是使用这个百分比来填充集群的背景颜色..得到这样的东西?
我看到很多关于这个的例子,比如 here here here here and here 但我想知道如果没有像那些例子中那样的大量复杂代码,我是否不能得到类似的东西?
编辑:
好的,感谢@IvanSanchez 的帮助,我将提供的代码复制到我的项目中,它正在运行!我不得不稍微改变一下让它工作,我尝试使用 icon-gradient 和 linear gradient。
下面是我的最终 culsterGroup 函数,我展示了两个版本的完整示例 here (iconic css) and here(线性梯度)。很抱歉我不能在这里 post 因为代码对于这个编辑器来说太长了 :)
实施后,我进行了一些更改。
- 因为我只得到我颜色的第一个字母,所以 css 没有用。所以我写道:
stops.push(color + ' ' + startPercent + '%');
stops.push(color + ' ' + endPercent + '%');
而不是
stops.push(color[i] + ' ' + startPercent + '%');
stops.push(color[i] + ' ' + endPercent + '%');
我还必须通过 div 更改 'html' var 中的跨度,因为标记簇 css 应用于 div 默认。
var 簇 = L.markerClusterGroup({
spiderfyOnMaxZoom:假,
showCoverageOnHover:假,
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'。因此,为了适合我在项目中使用的颜色,我更改了渐变的颜色,使簇颜色完全适合我的 individuals 标记颜色。
并且由于 firefox 和 IE 不支持图标渐变,我添加了一个条件以在 chrome 上显示图标渐变簇,在 firefox 和 IE 上显示标准线性渐变。
这是最后一段代码:
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, which is a specific type of CSS gradient. As explained in the 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>
...看起来像:
还有类似...
<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>
...看起来像...
因此,假设您有一个表示 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%)
...当应用于网页中的元素时,它看起来像:
看到一个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 的人一起工作,则不应使用此技术,至少暂时如此。
在自定义 传单地图 上,我正在尝试构建一个函数,用集群内标记的颜色填充集群图标的背景色。例如,如果一个簇有 7 个绿色标记和 2 个红色标记,则以 77% 的绿色和其他红色填充簇。
我正在一起使用 markerCluster plugin, and 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) });
},
});
我看到我可以得到每个簇内的标记数量和相关的颜色,就像这样。
所以我的问题是,据此,我如何循环遍历 "color" 以获得簇内每种颜色的百分比?
然后我的目标是使用这个百分比来填充集群的背景颜色..得到这样的东西?
我看到很多关于这个的例子,比如 here here here here and here 但我想知道如果没有像那些例子中那样的大量复杂代码,我是否不能得到类似的东西?
编辑:
好的,感谢@IvanSanchez 的帮助,我将提供的代码复制到我的项目中,它正在运行!我不得不稍微改变一下让它工作,我尝试使用 icon-gradient 和 linear gradient。
下面是我的最终 culsterGroup 函数,我展示了两个版本的完整示例 here (iconic css) and here(线性梯度)。很抱歉我不能在这里 post 因为代码对于这个编辑器来说太长了 :)
实施后,我进行了一些更改。 - 因为我只得到我颜色的第一个字母,所以 css 没有用。所以我写道:
stops.push(color + ' ' + startPercent + '%');
stops.push(color + ' ' + endPercent + '%');
而不是
stops.push(color[i] + ' ' + startPercent + '%');
stops.push(color[i] + ' ' + endPercent + '%');
我还必须通过 div 更改 'html' var 中的跨度,因为标记簇 css 应用于 div 默认。
var 簇 = L.markerClusterGroup({ spiderfyOnMaxZoom:假, showCoverageOnHover:假, 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'。因此,为了适合我在项目中使用的颜色,我更改了渐变的颜色,使簇颜色完全适合我的 individuals 标记颜色。
并且由于 firefox 和 IE 不支持图标渐变,我添加了一个条件以在 chrome 上显示图标渐变簇,在 firefox 和 IE 上显示标准线性渐变。
这是最后一段代码:
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, which is a specific type of CSS gradient. As explained in the 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>
...看起来像:
还有类似...
<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>
...看起来像...
因此,假设您有一个表示 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%)
...当应用于网页中的元素时,它看起来像:
看到一个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 的人一起工作,则不应使用此技术,至少暂时如此。