Responds to a /graphroles slash command, then displays a sorted graph of how many people have each role percentagewise. When registering your command in the command builder, it must have at least 2 and no more than 9 options with type "role".
const lib = require('lib')({token: process.env.STDLIB_SECRET_TOKEN});
const maxInputs = 9;
let totalPlayers = 0;
const guild_id = `${context.params.event.guild_id}`
let members = await lib.discord.guilds['@0.1.0'].members.list({ guild_id, limit: 1000 });
// Get all members then filter down to those with the given role ID
// Note: Only works for up to 1000 members
function roleCount(role_id)
{
let membersWithRoleCount = 0;
let membersWithRole = members.filter(m => !!m.roles.find(r => r === role_id));
totalPlayers += membersWithRole.length;
membersWithRoleCount = membersWithRole.length;
return `${membersWithRoleCount}`
}
//role id's to display on the graph
try {
var role = []
var gameCount = []
for (let a = 0; a < maxInputs; a++)
{
role[a] = context.params.event.data.options[a].value; //role IDs array
gameCount[a] = roleCount(`${role[a]}`) //count members of each role
}
console.log(`${role}\n`)
console.log('gameCount: ', gameCount)
console.log('totalPlayers: ', totalPlayers)
}
catch (e) {}//console.log(e)}
let rolePercents = [];
let totalPercent = 0;
let coloredSquares = [':red_square:',':orange_square:',':yellow_square:',
':green_square:',':blue_square:',':purple_square:',
':brown_square:',':black_large_square:',':white_large_square:'];
let printString = []; //array of coloredSquares
for (let i = 0; i < gameCount.length; i++)
{
rolePercents[i] = gameCount[i]/totalPlayers*100.0;
totalPercent += Math.floor(rolePercents[i]);
}
//1) combine the arrays:
var list = [];
for (var j = 0; j < role.length; j++)
list.push({'role': role[j], 'percentage': rolePercents[j]});
//2) sort by decimals:
list.sort((a, b) =>
(b.percentage - Math.floor(b.percentage)) - (a.percentage - Math.floor(a.percentage)));
//3) round up and down
let remainingPercent = 100 - totalPercent;
for (let i = 0; i < list.length; i++)
{
if (i < remainingPercent) { list[i].percentage = Math.ceil(list[i].percentage); }
else { list[i].percentage = Math.floor(list[i].percentage); }
}
//4) sort by values
list.sort((a, b) => b.percentage - a.percentage);
//5) separate them back out:
for (var k = 0; k < list.length; k++) {
role[k] = list[k].role;
rolePercents[k] = list[k].percentage;
}
console.log(`rolePercents: ${rolePercents}`);
//console.log(`totalPercent ${totalPercent}`);
//j = 0 sequential position of grid 0-99
let color = 0 //0-->5, changes the sequence's color
let num = 0 //also sequential position of grid 0-99 but doesn't affect j loop
//Assign colors to each array index on the grid
for (let j = 0; j < rolePercents.length; j++) //0 < 6
{
for (let k = 0; k < Math.round(rolePercents[color]); k++)
{
if (num >= 110)
{
break
}
if (num % 11 != 0) //11 because its 10x10 grid plus newline
{
printString[num] = `${coloredSquares[color]}`
num++
}
else
{
printString[num] = ('\n')
num++
printString[num] = `${coloredSquares[color]}`
num++
}
}
color++
}
//Fill missing percents with filler emoji
for (let L = num; L < 110; L++)
{ //YOU SHOULD NEVER SEE THIS
printString[L] = '<:flushedsquare:852568798850449428>'
}
//remove commas from Discord message
printString = printString.join('');
//Create dynamically sized array for fields
function feeldz()
{
let output = []
for (let x = 0; x < role.length; x++)
{
output[x] = {name: coloredSquares[x],
value: `<@&${role[x]}> ${Math.round(rolePercents[x])}%`,
inline: true}
}
return output
}
await lib.discord.channels['@0.1.2'].messages.create
({
channel_id: `${context.params.event.channel_id}`,
content: `${printString}`,
embeds:
[
{
description: '**Color Key**',
color: 0x33669a,
fields: feeldz(role.length - 1)
}
]
});