- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对分组标记和以小饼图形式按组显示计数的解决方案很着迷https://stackoverflow.com/a/60525137/3480717
我只是R,不知道JS。我希望代码对每个数据点的值求和而不是计数(每个单独的数据点可能已经代表一个计数)。而且我想根据值控制更多气泡的大小。
你能帮我看看如何更改 js 代码,以便它对数据点的值求和,以及如何增加/控制气泡的大小吗?
这里有一个对非饼标记求和而不是计数的理想解决方案:How to display the value (sum) rather than count of markers in a dc.leaflet.js
这里有一个也可以控制气泡大小的解决方案:Clustered leaflet markers with sum (not count) totals: how to get consistent round red shape and label format like in unclustered markers
原码是https://stackoverflow.com/users/2711712/danielbonnery @DanielBonnery
library(leaflet)
library(dplyr)
#Creates data
data("breweries91",package="leaflet")
#set.seed(1);
breweries91$goodbear<-sample(as.factor(c("terrific","marvelous","culparterretaping")),nrow(breweries91),replace=T)
#Colors
joliepalette<-c("red","green","blue")[1:nlevels(breweries91$goodbear)]
getColor <- function(breweries91) {joliepalette[breweries91$goodbear]}
icons <- awesomeIcons(
icon = 'ios-close',
iconColor = 'black',
library = 'ion',
markerColor = getColor(breweries91)
)
#Generate the javascript
jsscript3<-
paste0(
"function(cluster) {
const groups= [",paste("'",levels(breweries91$goodbear),"'",sep="",collapse=","),"];
const colors= {
groups: [",paste("'",joliepalette,"'",sep="",collapse=","),"],
center:'#ddd',
text:'black'
};
const markers= cluster.getAllChildMarkers();
const proportions= groups.map(group => markers.filter(marker => marker.options.group === group).length / markers.length);
function sum(arr, first= 0, last) {
return arr.slice(first, last).reduce((total, curr) => total+curr, 0);
}
const cumulativeProportions= proportions.map((val, i, arr) => sum(arr, 0, i+1));
cumulativeProportions.unshift(0);
const width = 2*Math.sqrt(markers.length);
const radius= 15+width/2;
const arcs= cumulativeProportions.map((prop, i) => { return {
x : radius*Math.sin(2*Math.PI*prop),
y : -radius*Math.cos(2*Math.PI*prop),
long: proportions[i-1] >.5 ? 1 : 0
}});
const paths= proportions.map((prop, i) => {
if (prop === 0) return '';
else if (prop === 1) return `<circle cx='0' cy='0' r='${radius}' fill='none' stroke='${colors.groups[i]}' stroke-width='${width}' stroke-alignment='center' stroke-linecap='butt' />`;
else return `<path d='M ${arcs[i].x} ${arcs[i].y} A ${radius} ${radius} 0 ${arcs[i+1].long} 1 ${arcs[i+1].x} ${arcs[i+1].y}' fill='none' stroke='${colors.groups[i]}' stroke-width='${width}' stroke-alignment='center' stroke-linecap='butt' />`
});
return new L.DivIcon({
html: `
<svg width='60' height='60' viewBox='-30 -30 60 60' style='width: 60px; height: 60px; position: relative; top: -24px; left: -24px;' >
<circle cx='0' cy='0' r='15' stroke='none' fill='${colors.center}' />
<text x='0' y='0' dominant-baseline='central' text-anchor='middle' fill='${colors.text}' font-size='15'>${markers.length}</text>
${paths.join('')}
</svg>
`,
className: 'marker-cluster'
});
}")
# Generates the map.
leaflet() %>%
addTiles() %>%
addAwesomeMarkers(data=breweries91,
group=~goodbear,
icon = icons,
clusterOptions = markerClusterOptions(
iconCreateFunction =
JS(jsscript3)))
最佳答案
I would like the code to sum values from each data point and not count.
markerOptions()
将数据/统计信息传递给标记。
leaflet() %>%
addTiles() %>%
addMarkers(
options = markerOptions(score = getScore(breweries91)),
...
)
然后在 JavaScript 中使用
marker.options.score
检索它。
And I would like to control more the size of the bubbles dependent on the value.
let width = 4 + 2*Math.sqrt(grandTotal/1.5);
玩它来调整气泡半径。
... count for non-pie markers
makeIcon
,
awesomeIcons
, 和
icons
强制您创建和使用自定义图像。而且没有办法绕过它。
addCircleMarkers
看起来对我们的目的很有用,但它不允许您设置文本。
singleMarkerMode
在集群选项中。使用它,我们可以使单个标记成为大小为 1 的簇,并使用我们已经编码的
iconCreateFunction
渲染它们JavaScript 代码:
leaflet() %>%
addTiles() %>%
addMarkers(
...
clusterOptions = markerClusterOptions(
singleMarkerMode = TRUE,
iconCreateFunction = JS(jsscript3)
)
)
getScore
函数,对于分值:
terrific => 3
marvelous => 2
culparterretaping => 1
使用
summarytools 添加带有摘要的图例.
# Title: R Leaflet custom summing marker demo
# Load packages ##################
install.packages("pacman")
require(pacman)
pacman::p_load(pacman, dplyr, leaflet, summarytools)
# Creates data ##################
data("breweries91",package="leaflet")
cat('\014') # ctrl+L
#head(breweries91, 2L)
breweries91$goodbeer<-sample(as.factor(c("terrific","marvelous","culparterretaping")),nrow(breweries91),replace=T)
names(breweries91)
# Colors
joliepalette<-c("darkviolet","orangered","lime")[1:nlevels(breweries91$goodbeer)]
getColor <- function(breweries91) {joliepalette[breweries91$goodbeer]}
# Score
jolieValue<-c(1L,2L,3L)[1:nlevels(breweries91$goodbeer)]
getScore <- function(breweries91) {jolieValue[breweries91$goodbeer]}
# iconCreateFunction Javascript
jsscript3<-paste0(
"function(cluster) {
const groups= [",paste("'",levels(breweries91$goodbeer),"'",sep="",collapse=","),"];
const colors= {
groups: [",paste("'",joliepalette,"'",sep="",collapse=","),"],
center:'#ddd',
text:'black'
};
const markers= cluster.getAllChildMarkers();
let grandTotal = markers.reduce((a,b)=> +a + +b.options.score, 0);
const proportions= groups.map(group => markers
.filter(marker => marker.options.group === group)
.reduce((a,b)=> +a + +b.options.score, 0) / grandTotal);
function sum(arr, first= 0, last) {
return arr.slice(first, last).reduce((total, curr) => total+curr, 0);
}
const cumulativeProportions= proportions.map((val, i, arr) => sum(arr, 0, i+1));
cumulativeProportions.unshift(0);
let width = 4 + 2*Math.sqrt(grandTotal/1.5);
width = width > 16? 16: width;
let radius= 10 + (width/2);
radius += (grandTotal < 40)? grandTotal/10 : 4;
const arcs= cumulativeProportions.map((prop, i) => { return {
x : radius*Math.sin(2*Math.PI*prop),
y : -radius*Math.cos(2*Math.PI*prop),
long: proportions[i-1] >.5 ? 1 : 0
}});
const paths= proportions.map((prop, i) => {
if (prop === 0) return '';
else if (prop === 1) return `<circle cx='0' cy='0' r='${radius-2}' fill-opacity='0.3' stroke-opacity fill='${colors.groups[i]}' stroke='${colors.groups[i]}' stroke-width='${width}' stroke-alignment='center' stroke-linecap='butt' />`;
else return `<path d='M ${arcs[i].x} ${arcs[i].y} A ${radius} ${radius} 0 ${arcs[i+1].long} 1 ${arcs[i+1].x} ${arcs[i+1].y}' fill='none' stroke='${colors.groups[i]}' stroke-width='${width}' stroke-alignment='center' stroke-linecap='butt' />`
});
return new L.DivIcon({
html: `
<svg width='60' height='60' viewBox='-30 -30 60 60' style='width: 60px; height: 60px; position: relative; top: -24px; left: -24px;' >
<circle cx='0' cy='0' r='15' stroke='none' fill='${colors.center}' />
${paths.join('')}
<text x='0' y='0' dominant-baseline='central' text-anchor='middle' fill='${colors.text}' font-size='16'>${grandTotal}</text>
</svg>
`,
className: 'marker-cluster'
});
}")
# gather stats for legend
myStat <- freq(breweries91$goodbeer, report.nas = FALSE, cumul = FALSE)
s1 <- paste("3 - terrific(",myStat[3,1],")")
s2 <- paste("2 - marvelous(",myStat[2,1],")")
s3 <- paste("1 - culparterretaping(", myStat[1,1],")")
# generates the map.
leaflet() %>%
addTiles() %>%
addLegend("topright",
colors = c("lime", "orangered", "darkviolet"),
labels = c(s1, s2,s3),
title = "Beer goodness:",
opacity = 1) %>%
addMarkers(data = breweries91,
group = ~goodbeer,
options = markerOptions(score = getScore(breweries91)),
clusterOptions = markerClusterOptions(
singleMarkerMode = TRUE,
iconCreateFunction = JS(jsscript3)
)
)
# print stats
freq(breweries91$goodbeer, report.nas = FALSE, cumul = FALSE)
print(paste("Grand Score: ", myStat[1,1]*1 + myStat[2,1]*2 + myStat[3,1]*3))
iconCreateFunction
.
# Title: R Leaflet custom summing marker demo
# Load packages ##################
install.packages("pacman")
require(pacman)
pacman::p_load(pacman, dplyr, leaflet, summarytools)
# Creates data ##################
data("breweries91",package="leaflet")
cat('\014') # ctrl+L
#head(breweries91, 2L)
breweries91$goodbeer<-sample(as.factor(c("terrific","marvelous","culparterretaping")),nrow(breweries91),replace=T)
names(breweries91)
# Colors
joliepalette<-c("darkviolet","orangered","limegreen")[1:nlevels(breweries91$goodbeer)]
getColor <- function(breweries91) {joliepalette[breweries91$goodbeer]}
# Score
jolieValue<-c(1L,2L,3L)[1:nlevels(breweries91$goodbeer)]
getScore <- function(breweries91) {jolieValue[breweries91$goodbeer]}
# iconCreateFunction Javascript
jsscript3<-paste0(
"function(cluster) {
const groups= [",paste("'",levels(breweries91$goodbeer),"'",sep="",collapse=","),"];
const colors= {
groups: [",paste("'",joliepalette,"'",sep="",collapse=","),"],
center:'#ddd',
text:'black'
};
const markers= cluster.getAllChildMarkers();
let grandTotal = markers.reduce((a,b)=> +a + +b.options.score, 0);
const proportions= groups.map(group => markers
.filter(marker => marker.options.group === group)
.reduce((a,b)=> +a + +b.options.score, 0) / grandTotal);
function sum(arr, first= 0, last) {
return arr.slice(first, last).reduce((total, curr) => total+curr, 0);
}
const cumulativeProportions= proportions.map((val, i, arr) => sum(arr, 0, i+1));
cumulativeProportions.unshift(0);
let width = 4 + 2*Math.sqrt(grandTotal/1.5);
width = width > 16? 16: width;
let radius= 10 + (width/2);
radius += (grandTotal < 40)? grandTotal/10 : 4;
const arcs= cumulativeProportions.map((prop, i) => { return {
x : radius*Math.sin(2*Math.PI*prop),
y : -radius*Math.cos(2*Math.PI*prop),
long: proportions[i-1] >.5 ? 1 : 0
}});
const paths= proportions.map((prop, i) => {
if (prop === 0) return '';
else if (prop === 1) return `<circle cx='0' cy='0' r='${radius-2}' fill-opacity='0.3' stroke-opacity fill='${colors.groups[i]}' stroke='${colors.groups[i]}' stroke-width='${width}' stroke-alignment='center' stroke-linecap='butt' />`;
else return `<path d='M ${arcs[i].x} ${arcs[i].y} A ${radius} ${radius} 0 ${arcs[i+1].long} 1 ${arcs[i+1].x} ${arcs[i+1].y}' fill='none' stroke='${colors.groups[i]}' stroke-width='${width}' stroke-alignment='center' stroke-linecap='butt' />`
});
let icon = new L.DivIcon({
html: `
<svg width='60' height='60' viewBox='-30 -30 60 60' style='width: 60px; height: 60px; position: relative; top: -24px; left: -24px;' >
<circle cx='0' cy='0' r='15' stroke='none' fill='${colors.center}' />
${paths.join('')}
<text x='0' y='0' dominant-baseline='central' text-anchor='middle' fill='${colors.text}' font-size='16'>${grandTotal}</text>
</svg>
`,
className: 'marker-cluster'
});
// make custom popup for the cluster
if(cluster._map){
let counts = groups.map(group => markers
.filter(marker => marker.options.group === group).length);
let content = `<span style='color:limegreen'>${groups[2]}</span> <span>(${counts[2]})</span><br>`;
content += `<span style='color:orangered'>${groups[1]}</span> <span>(${counts[1]})</span><br>`;
content += `<span style='color:darkviolet'>${groups[0]}</span> <span>(${counts[0]})</span><br>`;
content = `<div style='font-size:13px;font-weight:bold'>` + content + `</div>`;
cluster.on('click', function (a) {
let tt = L.tooltip({permanent:false, direction:'top', offset: L.point(0, -width*2)});
tt.setContent( content );
tt.setLatLng(cluster.getLatLng());
tt.addTo(cluster._map);
});
}
return icon;
}")
# gather stats for legend
myStat <- freq(breweries91$goodbeer, report.nas = FALSE, cumul = FALSE)
s1 <- paste("3 - terrific(",myStat[3,1],")")
s2 <- paste("2 - marvelous(",myStat[2,1],")")
s3 <- paste("1 - culparterretaping(", myStat[1,1],")")
# generates the map.
leaflet() %>%
addTiles() %>%
addLegend("topright",
colors = c("limegreen", "orangered", "darkviolet"),
labels = c(s1, s2,s3),
title = "Beer goodness:",
opacity = 1) %>%
addMarkers(data = breweries91,
group = ~goodbeer,
popup = paste("", breweries91$goodbeer),
popupOptions = popupOptions(maxWidth = 1000, closeOnClick = TRUE),
options = markerOptions(score = getScore(breweries91)),
clusterOptions = markerClusterOptions(
singleMarkerMode = TRUE,
zoomToBoundsOnClick = FALSE,
iconCreateFunction = JS(jsscript3)
)
)
# print stats
cat('\014') # ctrl+L
freq(breweries91$goodbeer, report.nas = FALSE, cumul = FALSE)
print(paste("Grand Score: ", myStat[1,1]*1 + myStat[2,1]*2 + myStat[3,1]*3))
leaflet() %>%
addTiles() %>%
addMarkers(data = breweries91,
popup = paste("", breweries91$goodbeer),
popupOptions = popupOptions(maxWidth = 1000, closeOnClick = TRUE),
...)
在
iconCreateFunction
中完成的特殊处理仅用于集群标记。
cluster._map
属性(property)。或者您可以将数据附加到 javascript
window
对象并通过 javascript 代码在任何地方访问它。
options = markerOptions(row_data = setNames(split(breweries91,
seq(nrow(breweries91))),
rownames(breweries91)))
有了这个,我们现在可以在弹出窗口中有很多东西,包括坐标:
# Title: R Leaflet custom summing marker demo
# Load packages ##################
install.packages("pacman")
require(pacman)
pacman::p_load(pacman, dplyr, leaflet, summarytools)
# Creates data ##################
data("breweries91",package="leaflet")
cat('\014') # ctrl+L
#head(breweries91, 2L)
breweries91$goodbeer<-sample(as.factor(c("terrific","marvelous","culparterretaping")),nrow(breweries91),replace=T)
breweries91$score<-ifelse(breweries91$goodbeer == "terrific",3L,
ifelse(breweries91$goodbeer == "marvelous",2L,
ifelse(breweries91$goodbeer == "culparterretaping",1L,0L)))
names(breweries91)
# Colors
joliepalette<-c("darkviolet","orangered","limegreen")[1:nlevels(breweries91$goodbeer)]
getColor <- function(breweries91) {joliepalette[breweries91$goodbeer]}
# iconCreateFunction Javascript
jsscript3<-paste0(
"function(cluster) {
const groups= [",paste("'",levels(breweries91$goodbeer),"'",sep="",collapse=","),"];
const colors= {
groups: [",paste("'",joliepalette,"'",sep="",collapse=","),"],
center:'#ddd',
text:'black'
};
const markers= cluster.getAllChildMarkers();
//console.log(markers[0]);
let grandTotal = markers.reduce((a,b)=> +a + +b.options.row_data.data.score, 0);
const proportions= groups.map(group => markers
.filter(marker => marker.options.group === group)
.reduce((a,b)=> +a + +b.options.row_data.data.score, 0) / grandTotal);
function sum(arr, first= 0, last) {
return arr.slice(first, last).reduce((total, curr) => total+curr, 0);
}
const cumulativeProportions= proportions.map((val, i, arr) => sum(arr, 0, i+1));
cumulativeProportions.unshift(0);
let width = 4 + 2*Math.sqrt(grandTotal/1.5);
width = width > 16? 16: width;
let radius= 10 + (width/2);
radius += (grandTotal < 40)? grandTotal/10 : 4;
const arcs= cumulativeProportions.map((prop, i) => { return {
x : radius*Math.sin(2*Math.PI*prop),
y : -radius*Math.cos(2*Math.PI*prop),
long: proportions[i-1] >.5 ? 1 : 0
}});
const paths= proportions.map((prop, i) => {
if (prop === 0) return '';
else if (prop === 1) return `<circle cx='0' cy='0' r='${radius-2}' fill-opacity='0.3' stroke-opacity fill='${colors.groups[i]}' stroke='${colors.groups[i]}' stroke-width='${width}' stroke-alignment='center' stroke-linecap='butt' />`;
else return `<path d='M ${arcs[i].x} ${arcs[i].y} A ${radius} ${radius} 0 ${arcs[i+1].long} 1 ${arcs[i+1].x} ${arcs[i+1].y}' fill='none' stroke='${colors.groups[i]}' stroke-width='${width}' stroke-alignment='center' stroke-linecap='butt' />`
});
let icon = new L.DivIcon({
html: `
<svg width='60' height='60' viewBox='-30 -30 60 60' style='width: 60px; height: 60px; position: relative; top: -24px; left: -24px;' >
<circle cx='0' cy='0' r='15' stroke='none' fill='${colors.center}' />
${paths.join('')}
<text x='0' y='0' dominant-baseline='central' text-anchor='middle' fill='${colors.text}' font-size='16'>${grandTotal}</text>
</svg>
`,
className: 'marker-cluster'
});
// make custom popup for the cluster
let content ='popup';
if(cluster._map){ //if it's cluster
//console.log(cluster);
let counts = groups.map(group => markers
.filter(marker => marker.options.group === group).length);
content = `<span style='color:limegreen'>${groups[2]}</span> <span>(${counts[2]})</span><br>`;
content += `<span style='color:orangered'>${groups[1]}</span> <span>(${counts[1]})</span><br>`;
content += `<span style='color:darkviolet'>${groups[0]}</span> <span>(${counts[0]})</span><br>`;
content = `<div style='font-size:13px;font-weight:bold'>` + content + `</div>`;
} else{ //if it's single marker
//console.log(cluster.getAllChildMarkers());
cluster = cluster.getAllChildMarkers()[0];
//console.log(cluster);
let r = cluster.options.row_data;
let loc = r.coords;
r = r.data;
let address = r.address;
let name = `${r.brewery} (${r.founded})`;
content = `<span><strong>${name}</strong></span><br>`;
content += `<span style='margin-bottom:10px'>[${loc}]</span><hr>`;
content += `<span>${address}, ${r.village}, ${r.zipcode}</span><br>`;
content += `<span>Goodness: ${r.goodbeer}</span>`;
}
cluster.on('click', function (a) {
let tt = L.tooltip({permanent:false, direction:'top', offset: L.point(0, -width*2)});
tt.setContent( content );
tt.setLatLng(cluster.getLatLng());
tt.addTo(cluster._map);
});
return icon;
}")
# gather stats for legend
myStat <- freq(breweries91$goodbeer, report.nas = FALSE, cumul = FALSE)
s1 <- paste("3 - terrific(",myStat[3,1],")")
s2 <- paste("2 - marvelous(",myStat[2,1],")")
s3 <- paste("1 - culparterretaping(", myStat[1,1],")")
# generates the map.
leaflet() %>%
addTiles() %>%
addLegend("topright",
colors = c("limegreen", "orangered", "darkviolet"),
labels = c(s1, s2,s3),
title = "Beer goodness:",
opacity = 1) %>%
addMarkers(data = breweries91,
group = ~goodbeer,
popupOptions = popupOptions(maxWidth = 1000, closeOnClick = TRUE),
options = markerOptions(row_data = setNames(split(breweries91, seq(nrow(breweries91))), rownames(breweries91))),
clusterOptions = markerClusterOptions(
singleMarkerMode = TRUE,
zoomToBoundsOnClick = FALSE,
iconCreateFunction = JS(jsscript3)
)
)
# print stats
cat('\014') # ctrl+L
freq(breweries91$goodbeer, report.nas = FALSE, cumul = FALSE)
print(paste("Grand Score: ", myStat[1,1]*1 + myStat[2,1]*2 + myStat[3,1]*3))
关于javascript - R传单中的饼图,将计数变为总和并控制更多大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69880307/
有人可以帮我理解为什么我的饼图百分比计算不正确吗?看截图: 根据我的计算,如 RHS 上所示,支出百分比应为 24.73%。传递给 Highcharts 的值如下:- 花费:204827099.36-
我正在制作圆环饼图。 我设置数据的颜色并获取钻取(它是保存外部切片的数据和配置的对象)切片的颜色为同一组颜色。我想设置要在向下钻取对象中使用的不同颜色数组。请参阅附图(外层切片有两种颜色:橙色和透明)
我是一名优秀的程序员,十分优秀!