atlas/web/_js/main/stats.js

238 lines
4.9 KiB
JavaScript
Raw Normal View History

/*!
* The 2022 r/place Atlas
* Copyright (c) 2017 Roland Rytz <roland@draemm.li>
* Copyright (c) 2022 Place Atlas Initiative and contributors
* Licensed under AGPL-3.0 (https://2022.place-atlas.stefanocoding.me/license.txt)
*/
2017-04-12 15:02:24 +02:00
2022-05-06 09:41:22 +02:00
let areasSum = 0
const areas = []
2017-04-12 15:02:24 +02:00
2023-04-07 11:44:33 +02:00
for (const entry of atlas) {
2017-04-12 15:02:24 +02:00
2023-04-07 11:44:33 +02:00
const path = entry.path
2017-04-12 15:02:24 +02:00
let area = 0,
2017-04-12 15:02:24 +02:00
i,
j,
point1,
2022-05-06 09:41:22 +02:00
point2
2017-04-12 15:02:24 +02:00
for (i = 0, j = path.length - 1; i < path.length; j = i, i++) {
2022-05-06 09:41:22 +02:00
point1 = path[i]
point2 = path[j]
area += point1[0] * point2[1]
area -= point1[1] * point2[0]
2017-04-12 15:02:24 +02:00
}
2022-05-06 09:41:22 +02:00
area = Math.abs(area / 2)
2017-04-12 15:02:24 +02:00
2022-05-06 09:41:22 +02:00
areasSum += area
areas.push(area)
2023-04-07 11:44:33 +02:00
entry.area = area
2017-04-12 15:02:24 +02:00
}
2023-04-07 11:44:33 +02:00
areas.sort((a, b) => a - b)
2017-04-12 15:02:24 +02:00
2023-04-07 11:44:33 +02:00
atlas.sort((a, b) => a.area - b.area)
2022-05-06 09:41:22 +02:00
const el = document.createElement("canvas")
el.style.position = "absolute"
el.style.top = "0px"
el.style.zIndex = "10000"
const ctx = el.getContext("2d")
el.width = 1600
el.height = 500
const steps = 150
const max = 1500
2017-04-12 15:02:24 +02:00
let largerThanMax = areas.reduce((total, area) => total + (area > max), 0)
2017-04-12 15:02:24 +02:00
2022-05-06 09:41:22 +02:00
console.info("There are " + largerThanMax + " entries larger than " + max + ", accounting for " + (largerThanMax / areas.length * 100) + "% of all entries.")
console.info("The largest entry has an area of " + areas[areas.length - 1] + " pixels.")
2017-04-12 15:02:24 +02:00
2022-05-06 09:41:22 +02:00
const counts = [0]
const brackets = [max / steps]
2017-04-12 15:02:24 +02:00
2022-05-06 09:41:22 +02:00
let bracket = 0
2017-04-12 15:02:24 +02:00
2022-05-06 09:41:22 +02:00
let mostCounts = 0
2017-04-12 15:02:24 +02:00
for (const area of areas) {
if (area > (bracket + 1) * (max / steps)) {
2022-05-06 09:41:22 +02:00
mostCounts = Math.max(mostCounts, counts[bracket])
bracket++
2023-04-07 11:44:33 +02:00
if (bracket >= steps) break
2022-05-06 09:41:22 +02:00
counts[bracket] = 0
brackets[bracket] = (bracket + 1) * (max / steps)
2017-04-12 15:02:24 +02:00
}
2022-05-06 09:41:22 +02:00
counts[bracket]++
2017-04-12 15:02:24 +02:00
}
2022-05-06 09:41:22 +02:00
//console.log(counts)
//console.log(brackets)
//console.log(mostCounts)
2017-04-12 15:02:24 +02:00
2022-05-06 09:41:22 +02:00
ctx.fillStyle = "#FFFFFF"
ctx.fillRect(0, 0, el.width, el.height)
ctx.strokeStyle = "#F5F5F5"
2017-04-12 15:02:24 +02:00
2022-05-06 09:41:22 +02:00
ctx.fillStyle = "#333333"
ctx.font = "15px sans"
ctx.textAlign = "right"
ctx.textBaseline = "middle"
2017-04-12 15:02:24 +02:00
2022-05-06 09:41:22 +02:00
let linesDistance = 1
for (let i = 0; i <= Math.ceil((mostCounts / linesDistance) / 5) * 5; i++) {
2022-05-06 09:41:22 +02:00
ctx.beginPath()
ctx.moveTo(
2023-03-19 07:10:21 +01:00
50,
~~(el.height - 50 - i * (linesDistance / mostCounts) * (el.height - 100)) + 0.5
2022-05-06 09:41:22 +02:00
)
ctx.lineTo(
2023-03-19 07:10:21 +01:00
el.width - 25,
~~(el.height - 50 - i * (linesDistance / mostCounts) * (el.height - 100)) + 0.5
2022-05-06 09:41:22 +02:00
)
ctx.stroke()
}
2022-05-06 09:41:22 +02:00
ctx.strokeStyle = "#333333"
linesDistance = 5
2017-04-12 15:02:24 +02:00
for (let i = 0; i <= Math.ceil(mostCounts / linesDistance); i++) {
2022-05-06 09:41:22 +02:00
ctx.beginPath()
2017-04-12 15:02:24 +02:00
ctx.moveTo(
2023-03-19 07:10:21 +01:00
50,
~~(el.height - 50 - i * (linesDistance / mostCounts) * (el.height - 100)) + 0.5
2022-05-06 09:41:22 +02:00
)
2017-04-12 15:02:24 +02:00
ctx.lineTo(
2023-03-19 07:10:21 +01:00
el.width - 25,
~~(el.height - 50 - i * (linesDistance / mostCounts) * (el.height - 100)) + 0.5
2022-05-06 09:41:22 +02:00
)
ctx.stroke()
2017-04-12 15:02:24 +02:00
ctx.fillText(
2023-03-19 07:10:21 +01:00
i * linesDistance,
40,
~~(el.height - 50 - i * (linesDistance / mostCounts) * (el.height - 100)) + 0.5
2022-05-06 09:41:22 +02:00
)
2017-04-12 15:02:24 +02:00
}
2022-05-06 09:41:22 +02:00
const skip = 2
2017-04-12 15:02:24 +02:00
2022-05-06 09:41:22 +02:00
ctx.textAlign = "center"
ctx.textBaseline = "hanging"
ctx.font = "10px sans"
2017-04-12 15:02:24 +02:00
2022-05-06 09:41:22 +02:00
let a = 0
for (let i = 0; i <= counts.length; i++) {
2023-03-17 18:30:33 +01:00
if (i % skip === 0) {
2022-05-06 09:41:22 +02:00
let y = 0
2023-03-17 18:30:33 +01:00
if (a % 2 === 0) {
2022-05-06 09:41:22 +02:00
y = ~~(el.height - 30) + 0.5
2017-04-12 15:02:24 +02:00
} else {
2022-05-06 09:41:22 +02:00
y = ~~(el.height - 45) + 0.5
2017-04-12 15:02:24 +02:00
}
2022-05-06 09:41:22 +02:00
a++
ctx.beginPath()
2017-04-12 15:02:24 +02:00
ctx.moveTo(
2023-03-19 07:10:21 +01:00
~~(((i) / steps) * (el.width - 125) + 75) + 0.5,
~~(el.height - 50) + 0.5
2022-05-06 09:41:22 +02:00
)
2017-04-12 15:02:24 +02:00
ctx.lineTo(
2023-03-19 07:10:21 +01:00
~~(((i) / steps) * (el.width - 125) + 75) + 0.5,
y
2022-05-06 09:41:22 +02:00
)
ctx.stroke()
2017-04-12 15:02:24 +02:00
ctx.fillText(
2023-03-19 07:10:21 +01:00
(i) * (max / steps),
~~(((i) / steps) * (el.width - 125) + 75) - 0.5,
y + 5
2022-05-06 09:41:22 +02:00
)
2017-04-12 15:02:24 +02:00
}
}
2022-05-06 09:41:22 +02:00
ctx.fillStyle = "#FF0000"
ctx.strokeStyle = "#CC0000"
2017-04-12 15:02:24 +02:00
for (let i = 0; i < counts.length; i++) {
2023-04-07 11:44:33 +02:00
if (i % 2) ctx.fillStyle = "#DD0000"
else ctx.fillStyle = "#FF0000"
2017-04-12 15:02:24 +02:00
ctx.fillRect(
2023-03-19 07:10:21 +01:00
~~((i / steps) * (el.width - 125) + 75),
el.height - 50,
Math.ceil(1 / steps * (el.width - 125)),
~~(-(counts[i] / mostCounts) * (el.height - 100))
2022-05-06 09:41:22 +02:00
)
2017-04-12 15:02:24 +02:00
2022-05-06 09:41:22 +02:00
/*ctx.beginPath()
2017-04-12 15:02:24 +02:00
ctx.moveTo(
~~((i/steps)*(el.width-125)+75)+0.5
,~~(el.height - 50)
2022-05-06 09:41:22 +02:00
)
2017-04-12 15:02:24 +02:00
ctx.lineTo(
~~((i/steps)*(el.width-125)+75)+0.5
,~~(el.height-(counts[i]/mostCounts)*(el.height-100))-50+0.5
2022-05-06 09:41:22 +02:00
)
2017-04-12 15:02:24 +02:00
ctx.lineTo(
~~(((i+1)/steps)*(el.width-125)+75)+0.5
,~~(el.height-(counts[i]/mostCounts)*(el.height-100))-50+0.5
2022-05-06 09:41:22 +02:00
)
2017-04-12 15:02:24 +02:00
ctx.lineTo(
~~(((i+1)/steps)*(el.width-125)+75)+0.5
,~~(el.height - 50)
2022-05-06 09:41:22 +02:00
)
2017-04-12 15:02:24 +02:00
ctx.stroke();*/
}
2022-05-06 09:41:22 +02:00
document.getElementById("wrapper").appendChild(el)
2017-04-12 15:02:24 +02:00
2022-05-06 09:41:22 +02:00
//console.log(areas)
2017-04-12 15:02:24 +02:00
2022-05-06 09:41:22 +02:00
console.info("Median area: " + areas[~~(areas.length / 2)])
2017-04-12 15:02:24 +02:00
2022-05-06 09:41:22 +02:00
console.info("Average area: " + (areasSum / atlas.length))
2017-04-12 15:02:24 +02:00
2022-05-06 09:41:22 +02:00
const topCount = 50
console.info("The " + topCount + " largest entries:")
2017-04-12 15:02:24 +02:00
2022-05-06 09:41:22 +02:00
let outstring = ""
for (let i = 0; i < topCount; i++) {
outstring += ((i + 1) + "|[" + atlas[atlas.length - i - 1].name + "](http://2023.place-atlas.stefanocoding.me/?id=" + atlas[atlas.length - i - 1].id + ")|" + ~~atlas[atlas.length - i - 1].area + "|" + Math.round(atlas[atlas.length - i - 1].area / 100) / 100 + "%\n")
}
2017-04-12 15:02:24 +02:00
2022-05-06 09:41:22 +02:00
console.info(outstring)
2017-04-12 15:02:24 +02:00
atlas.sort((a, b) => a.center[0] - b.center[0])
2022-05-06 09:41:22 +02:00
console.info("Median x: " + atlas[~~(atlas.length / 2)].center[0])
atlas.sort((a, b) => a.center[1] - b.center[1])
2022-05-06 09:41:22 +02:00
console.info("Median y: " + atlas[~~(atlas.length / 2)].center[1])
2017-04-12 15:02:24 +02:00