You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sessioncommunities.online/etc/plot-staff.r

148 lines
3.9 KiB
R

#!/bin/env Rscript
library('jsonlite')
library('purrr')
library('RcppColors')
dummy <- function(x) { x }
srcdir <- getSrcDirectory(dummy)[1]
if (is.na(srcdir)) {
args <- commandArgs()
selfarg <- args[startsWith(args, "--file=")]
srcdir <- dirname(sub('^--file=', '', selfarg))
}
setwd(srcdir)
rooms <- read_json('rooms.json', simplifyVector = TRUE)
rooms <- rooms[rooms$write, ]
rooms <- rooms[rooms$read, ]
servers <- unique(data.frame(id=rooms$server_id,base_url=rooms$base_url))
servers$hostname <- sub('^https?://', '', servers$base_url)
servers$pch = rep_len(seq(15, 18), nrow(servers))
servers$col = rep_len(c("orange",2,3,4,5,6,8), nrow(servers))
rooms$staff = map_vec(rooms$moderators, length) + map_vec(rooms$admins, length)
dir.exists("plots") || dir.create("plots")
for (i in 1:nrow(servers)) {
server <- servers[i, ]
rooms.current <- rooms[rooms$server_id == server$id, ]
rooms.current <- rooms.current[order(rooms.current$active_users), ]
rooms.current$pch = rep_len(seq(15, 18), nrow(rooms.current))
rooms.current$col = rep_len(c(3,4,5,6,8), nrow(rooms.current))
rooms.space = min(10,nrow(rooms.current))
minwau <- min(rooms.current$active_users)
maxwau <- max(rooms.current$active_users)
maxstaff <- max(rooms.current$staff)
maxstaff.shown <- max(1, maxstaff*1.05^rooms.space * 1.3)
png(
filename=paste("plots/", server$hostname, ".plot.png", sep=""),
width=1080, height=1080, pointsize=30
)
if (maxwau-minwau < 10) {
xlim <- c(minwau*0.95, maxwau*1.05)
x.smol <- TRUE
} else {
xlim <- c(minwau, maxwau)
x.smol <- FALSE
}
#e <- exp(1)
# nice to have
#line <- function(x) 2 + floor(log(x, base=7)^1.1)
line <- function(x) ceiling(pmax(2,x^0.25))
# low bar (higher base)
line2 <- function(x) 1 + pmax(1,round((0.38*log(x))^1.15))
plot(
function(x) line(pmax(1,x)),
main=server$hostname,
sub=paste("black: ", deparse(body(line)), "; red: ", deparse(body(line2)), sep=""),
xlim=xlim,
log=ifelse(minwau==0,"","x"),
ylab="# of visible staff",
xlab="# of weekly readers",
ylim=c(0,maxstaff.shown),
yaxt="n",
cex.sub=0.8
)
plot(
function(x) line2(pmax(1,x)),
xlim=xlim, col="red", add=TRUE, lwd=2
)
wau.ceil.log <- ceiling(max(0, log10(maxwau)))
maxstaff.ceil.log <- ceiling(max(0, log10(maxstaff)))
grid.col <- "#777777"
grid.col.extra <- "#BBBBBB"
if (x.smol) {
vlines <- seq(floor(0.9*minwau),ceiling(1.1*maxwau),1)
} else {
vlines <- as.vector(outer(c(1,2,3,5), 10 ^ seq(0, wau.ceil.log)))
vlines.extra <- as.vector(outer(c(1.2,1.4,1.6,1.8,2.25,2.5,2.75,3.5,4,4.5,6,7,8,9), 10 ^ seq(0, wau.ceil.log)))
vlines.extra <- vlines.extra[vlines.extra == floor(vlines.extra)]
abline(v=vlines.extra, col=grid.col.extra, lty="dotted")
}
abline(v=vlines, col=grid.col, lty="dotted")
hlab.gap=ceiling(maxstaff.shown/5)
hlab.gap.logwise.floor = 10^floor(log10(hlab.gap))
hlines.extra <- c()
if (hlab.gap.logwise.floor * 5 < hlab.gap * 1.75) {
hlab.gap <- hlab.gap.logwise.floor * 5
hlines.extra <- seq(1,maxstaff.shown,hlab.gap/5)
} else {
hlab.gap <- hlab.gap.logwise.floor
if(hlab.gap %% 10 == 0) {
hlines.extra <- seq(hlab.gap/2,maxstaff.shown,hlab.gap)
}
}
hlab=seq(0, maxstaff * 1.5, hlab.gap)
axis(2, at=hlab)
hlines=seq(0,maxstaff.shown,hlab.gap)
abline(h=seq(0, maxstaff.shown, hlab.gap), col=grid.col, lty="dotted")
abline(h=hlines.extra, col=grid.col.extra, lty="dotted")
# pch = servers[match(rooms.current$server_id, servers$id), 'pch']
points(
rooms.current$active_users,
pmin(rooms.current$staff,maxstaff),
pch=rooms.current$pch,
# col=servers[match(rooms.current$server_id, servers$id), 'col'],
col=rooms.current$col,
cex=ifelse(rooms.current$pch==18,1.7,1.5)
)
for (i in 0:2) {
chunk <- rooms.current[((i*10)+1):((i+1)*10), ]
chunk <- chunk[!is.na(chunk$token), ]
if (nrow(chunk) == 0) {
break
}
legend(
x=(c("topleft","top","topright")[i+1]),
legend = chunk$token,
pch=chunk$pch,
col=chunk$col,
cex=0.99^rooms.space,
pt.cex = ifelse(chunk$pch==18,1.2,1)
)
}
dev.off()
}