具有总和(不是计数)总计的聚类传单标记:如何像非聚类标记一样获得一致的圆形红色和标签格式
Clustered leaflet markers with sum (not count) totals: how to get consistent round red shape and label format like in unclustered markers
我想将传单分组功能的行为修改为总计分组,并根据值保留圆形红色气泡形状。
我的数据包含列:
经纬度sales_ytd
我想使用 clusterOptions = markerClusterOptions(iconCreateFunction=JS(sum.formula))
根据缩放对数据进行聚类
这是我的功能。我不懂 JS,但我尝试了很多示例,该函数通过对分组值求和来工作。
sum.formula = JS("function (cluster) {
var markers = cluster.getAllChildMarkers();
var sum = 0;
for (i = 0; i < markers.length; i++) {
sum += Number(markers[i].options.mag);
// sum += 1;
}
var size = sum/30000;
return new L.DivIcon({ html: sum , iconSize: L.point(size, size)});
}")
显然L.DivIcon() return是一个正方形... 有没有办法让它return变成圆形的红色气泡?
然后我尝试在闪亮的应用程序(R 代码)中使用它。
renderLeaflet({
leaflet(df_summary_towns()) %>%
addTiles() %>%
addCircleMarkers(
radius = ~sales_ytd/30000,
color = 'red',
stroke = FALSE,
fillOpacity = 0.5,
options = markerOptions(mag = ~ sales_ytd),
clusterOptions = markerClusterOptions(iconCreateFunction=JS(sum.formula))
) %>%
addLabelOnlyMarkers(
~lon, ~lat,
options = markerOptions(mag = ~ sales_ytd),
label = ~scales::number(sales_ytd),
labelOptions = labelOptions(noHide = T, direction = 'center', textOnly = T),
clusterOptions = markerClusterOptions(iconCreateFunction=JS(sum.formula)))
})
分组有点奏效,值是聚集数据的总和,如果我单击它们,传单会缩放并显示单个点(漂亮的红色圆圈,里面有值)。但是分组标记是白色方块,而不是像单个点那样的圆形红色圆圈。我也不知道如何实现一致的数字格式。在 R 中很容易,但分组标记的定义现在在 JS 中。
如何实现:形状、颜色和大小取决于未分组和分组标记中的值以及一致的数字格式?
还可以看到 我尝试在 R 中规范化大小,然后在 JS 中划分 size/1000 - 我不知道如何将 data.frame 列的总和传递给 JS.
对于 markers/layers 的总数,您可以使用 getLayers() 函数,它将 return 该集群的所有组件层的数组。
var testCluster = L.markerClusterGroup();
L.marker([event.latlng.lat,
event.latlng.lng]).addTo(testCluster);
testCluster.getLayers();
它将return每个标记的数组作为图层。
或者你可以使用这个:
map.eachLayer(function (layer) {
if (layer.getChildCount){
console.log(layer._childClusters.length)
console.log(layer._childCount);
}
});
您可以尝试调整自定义 sum.formula
函数以将 CSS class 添加到您可以自定义的标记,以及格式化数字以添加千位分隔符。
我在下面添加了一个 MWE 示例,我在图标中添加了 custom-cluster-icon
class,并使用 this post 中的正则表达式格式化了数字。
闪亮页面页眉中包含的 CSS 以及在 sum.formula
输出中添加的行有助于使标签居中,并添加红色标记圆圈。
library(leaflet)
library(shiny)
#dummy data for example
df_summary_towns=quakes
df_summary_towns$sales_ytd=sample(2000:5000,1000)
sum.formula = JS("function (cluster) {
var markers = cluster.getAllChildMarkers();
var sum = 0;
for (i = 0; i < markers.length; i++) {
sum += Number(markers[i].options.mag);
}
var size = sum/10000;
var formatted_number = Math.round(sum).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ' ');
return new L.DivIcon({ className: 'custom-cluster-icon', html: '<div style=\"line-height:'+size+'px; white-space: nowrap;\">'+formatted_number+'</div>' , iconSize: L.point(size, size) });
}")
ui <- fluidPage(
tags$head(
tags$style(HTML("
.custom-cluster-icon {
background: rgba(255, 0, 0, 0.3);
border-radius: 50%;
text-align: center;
}
"))
),
leafletOutput("mymap")
)
server <- function(input, output, session) {
points <- eventReactive(input$recalc, {
cbind(rnorm(40) * 2 + 13, rnorm(40) + 48)
}, ignoreNULL = FALSE)
output$mymap <- renderLeaflet({
leaflet(df_summary_towns) %>%
addTiles() %>%
addCircleMarkers(
radius = ~sales_ytd/10000,
color = 'red',
stroke = FALSE,
fillOpacity = 0.5,
options = markerOptions(mag = ~ sales_ytd, min_sales = ~min(sales_ytd), max_sales = ~ max(sales_ytd)),
clusterOptions = markerClusterOptions(iconCreateFunction=JS(sum.formula))
) %>%
addLabelOnlyMarkers(
~long, ~lat,
options = markerOptions(mag = ~ sales_ytd),
label = ~scales::number(sales_ytd),
labelOptions = labelOptions(noHide = T, direction = 'center', textOnly = T),
clusterOptions = markerClusterOptions(iconCreateFunction=JS(sum.formula)))
})
}
shinyApp(ui, server)
我想将传单分组功能的行为修改为总计分组,并根据值保留圆形红色气泡形状。
我的数据包含列:
经纬度sales_ytd
我想使用 clusterOptions = markerClusterOptions(iconCreateFunction=JS(sum.formula))
根据缩放对数据进行聚类这是我的功能。我不懂 JS,但我尝试了很多示例,该函数通过对分组值求和来工作。
sum.formula = JS("function (cluster) {
var markers = cluster.getAllChildMarkers();
var sum = 0;
for (i = 0; i < markers.length; i++) {
sum += Number(markers[i].options.mag);
// sum += 1;
}
var size = sum/30000;
return new L.DivIcon({ html: sum , iconSize: L.point(size, size)});
}")
显然L.DivIcon() return是一个正方形... 有没有办法让它return变成圆形的红色气泡?
然后我尝试在闪亮的应用程序(R 代码)中使用它。
renderLeaflet({
leaflet(df_summary_towns()) %>%
addTiles() %>%
addCircleMarkers(
radius = ~sales_ytd/30000,
color = 'red',
stroke = FALSE,
fillOpacity = 0.5,
options = markerOptions(mag = ~ sales_ytd),
clusterOptions = markerClusterOptions(iconCreateFunction=JS(sum.formula))
) %>%
addLabelOnlyMarkers(
~lon, ~lat,
options = markerOptions(mag = ~ sales_ytd),
label = ~scales::number(sales_ytd),
labelOptions = labelOptions(noHide = T, direction = 'center', textOnly = T),
clusterOptions = markerClusterOptions(iconCreateFunction=JS(sum.formula)))
})
分组有点奏效,值是聚集数据的总和,如果我单击它们,传单会缩放并显示单个点(漂亮的红色圆圈,里面有值)。但是分组标记是白色方块,而不是像单个点那样的圆形红色圆圈。我也不知道如何实现一致的数字格式。在 R 中很容易,但分组标记的定义现在在 JS 中。 如何实现:形状、颜色和大小取决于未分组和分组标记中的值以及一致的数字格式? 还可以看到 我尝试在 R 中规范化大小,然后在 JS 中划分 size/1000 - 我不知道如何将 data.frame 列的总和传递给 JS.
对于 markers/layers 的总数,您可以使用 getLayers() 函数,它将 return 该集群的所有组件层的数组。
var testCluster = L.markerClusterGroup();
L.marker([event.latlng.lat,
event.latlng.lng]).addTo(testCluster);
testCluster.getLayers();
它将return每个标记的数组作为图层。
或者你可以使用这个:
map.eachLayer(function (layer) {
if (layer.getChildCount){
console.log(layer._childClusters.length)
console.log(layer._childCount);
}
});
您可以尝试调整自定义 sum.formula
函数以将 CSS class 添加到您可以自定义的标记,以及格式化数字以添加千位分隔符。
我在下面添加了一个 MWE 示例,我在图标中添加了 custom-cluster-icon
class,并使用 this post 中的正则表达式格式化了数字。
闪亮页面页眉中包含的 CSS 以及在 sum.formula
输出中添加的行有助于使标签居中,并添加红色标记圆圈。
library(leaflet)
library(shiny)
#dummy data for example
df_summary_towns=quakes
df_summary_towns$sales_ytd=sample(2000:5000,1000)
sum.formula = JS("function (cluster) {
var markers = cluster.getAllChildMarkers();
var sum = 0;
for (i = 0; i < markers.length; i++) {
sum += Number(markers[i].options.mag);
}
var size = sum/10000;
var formatted_number = Math.round(sum).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ' ');
return new L.DivIcon({ className: 'custom-cluster-icon', html: '<div style=\"line-height:'+size+'px; white-space: nowrap;\">'+formatted_number+'</div>' , iconSize: L.point(size, size) });
}")
ui <- fluidPage(
tags$head(
tags$style(HTML("
.custom-cluster-icon {
background: rgba(255, 0, 0, 0.3);
border-radius: 50%;
text-align: center;
}
"))
),
leafletOutput("mymap")
)
server <- function(input, output, session) {
points <- eventReactive(input$recalc, {
cbind(rnorm(40) * 2 + 13, rnorm(40) + 48)
}, ignoreNULL = FALSE)
output$mymap <- renderLeaflet({
leaflet(df_summary_towns) %>%
addTiles() %>%
addCircleMarkers(
radius = ~sales_ytd/10000,
color = 'red',
stroke = FALSE,
fillOpacity = 0.5,
options = markerOptions(mag = ~ sales_ytd, min_sales = ~min(sales_ytd), max_sales = ~ max(sales_ytd)),
clusterOptions = markerClusterOptions(iconCreateFunction=JS(sum.formula))
) %>%
addLabelOnlyMarkers(
~long, ~lat,
options = markerOptions(mag = ~ sales_ytd),
label = ~scales::number(sales_ytd),
labelOptions = labelOptions(noHide = T, direction = 'center', textOnly = T),
clusterOptions = markerClusterOptions(iconCreateFunction=JS(sum.formula)))
})
}
shinyApp(ui, server)