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.
148 lines
3.9 KiB
R
148 lines
3.9 KiB
R
1 year ago
|
#!/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()
|
||
|
|
||
|
|
||
|
}
|