Skip to content

Commit

Permalink
Improves statstics view
Browse files Browse the repository at this point in the history
  • Loading branch information
lyret committed Jul 15, 2024
1 parent 4c1dfc0 commit 598baaf
Showing 1 changed file with 81 additions and 35 deletions.
116 changes: 81 additions & 35 deletions src/stats.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,90 @@
import { Tabulator } from 'tabulator-tables';
import { TabulatorFull } from 'tabulator-tables';
import ExcelJS from 'exceljs';

/** Initializes the statistics page */
export const createStats = async () => {
// The URL to the API
const ENTITIES_URL = 'https://placement.freaks.se/api/v1/mapentities';
/** The URL to the API */
const ENTITIES_URL = 'https://placement.freaks.se/api/v1/mapentities';

/** Total memberships sold for 2024 */
const TOTAL_MEMBERSHIPS_SOLD = 4114;

/** Columns visible on the /stats url and in the excel export */
const COLUMNS: Array<{ title: String; field: keyof Entity; [key: string]: any }> = [
{
title: 'Location',
field: 'id',
formatter: 'link',
formatterParams: {
labelField: 'id',
urlPrefix: '/index.html?id=',
target: '_blank',
},
},
{ title: 'Name', field: 'name' },
{ title: 'Contact Info', field: 'contactInfo' },
{ title: 'Nr of People', field: 'nrOfPeople' },
{ title: 'Nr of Vechiles', field: 'nrOfVechiles' },
{ title: 'Color', field: 'color', formatter: 'color' },
{ title: 'Additional Square meters (m2)', field: 'additionalSqm' },
{ title: 'Amplified Sound (watts)', field: 'amplifiedSound' },
{ title: 'Power need (watts)', field: 'powerNeed' },
{ title: 'Revision', field: 'revision' },
{
title: 'Description',
field: 'description',
formatter: 'textarea',
resizable: true,
width: 600,
variableHeight: true,
},
];

type Entity = {
id: number;
name: string;
timeStamp: Date;
isDeleted: boolean;
additionalSqm: number;
amplifiedSound: number;
color: string;
contactInfo: string;
description: string;
nrOfPeople: number;
nrOfVechiles: number;
powerNeed: number;
revision: number;
supressWarnings: number;
};

// Total memberships sold for 2024
const TOTAL_MEMBERSHIPS_SOLD = 4114;
const createRowFromEntity = (row: Entity) => {
const newEntity = {};
for (const { field } of COLUMNS) {
newEntity[field] = row[field];
}
return newEntity;
};

/** Initializes the statistics page */
export const createStats = async () => {
// Fetch the data
const resp = await fetch(ENTITIES_URL);
const entries = await resp.json();

const rows = [];
const totalNrOfEntries = entries.length;
const parsedEntries = [];
const stats = {
nrOfMembershipsSold: { value: TOTAL_MEMBERSHIPS_SOLD, title: 'total nr. of memberships', unit: 'memberships' },
totalNrOfPeople: { value: 0, title: 'total nr. of campers', unit: 'persons' },
totalNrOfVechiles: { value: 0, title: 'total nr. of vechiles', unit: 'automobiles' },
totalPowerNeed: { value: 0, title: 'total power need of all camps', unit: 'watts' },
totalNrOfEntries: { value: entries.length, title: 'total nr. of shapes on the map', unit: 'shapes' },
};

for (const entry of entries) {
const { properties } = JSON.parse(entry.geoJson);
const row = {
//id: Number(entry.id),
const entity: Entity = {
id: Number(entry.id),
name: String(properties.name),
//timeStamp: new Date(entry.timeStamp),
//isDeleted: Boolean(entry.isDeleted),
timeStamp: new Date(entry.timeStamp),
isDeleted: Boolean(entry.isDeleted),
additionalSqm: Number(properties.additionalSqm),
amplifiedSound: Number(properties.amplifiedSound),
color: String(properties.color),
Expand All @@ -37,38 +94,26 @@ export const createStats = async () => {
nrOfVechiles: Number(properties.nrOfVechiles),
powerNeed: Number(properties.powerNeed),
revision: Number(entry.revision),
//supressWarnings: Number(properties.supressWarnings),
supressWarnings: Number(properties.supressWarnings),
};
stats.totalNrOfPeople.value += +row.nrOfPeople;
stats.totalNrOfVechiles.value += row.nrOfVechiles;
stats.totalPowerNeed.value += row.powerNeed;
//console.log(row);
rows.push(row);
stats.totalNrOfPeople.value += +entity.nrOfPeople;
stats.totalNrOfVechiles.value += entity.nrOfVechiles;
stats.totalPowerNeed.value += entity.powerNeed;
parsedEntries.push(entity);
}

// Create Tabulator view
new Tabulator('#stats', {
data: rows,
autoColumns: true,
new TabulatorFull('#stats', {
data: parsedEntries,
columns: COLUMNS,
});

// Create Excel export file
const workbook = new ExcelJS.Workbook();
workbook.creator = 'Borderland Community Cocreators';
const worksheet = workbook.addWorksheet('Camps');
worksheet.columns = [
{ header: 'Name', key: 'name' },
{ header: 'Revision', key: 'revision' },
{ header: 'AdditionalSqm', key: 'additionalSqm' },
{ header: 'AmplifiedSound', key: 'amplifiedSound' },
{ header: 'Color', key: 'color' },
{ header: 'ContactInfo', key: 'contactInfo' },
{ header: 'Description', key: 'description' },
{ header: 'NrOfPeople', key: 'nrOfPeople' },
{ header: 'NrOfVechiles', key: 'nrOfVechiles' },
{ header: 'PowerNeed', key: 'powerNeed' },
];
rows.forEach((row) => worksheet.addRow(row));
worksheet.columns = COLUMNS.map((column) => ({ header: column.title, key: column.field } as ExcelJS.Column));
parsedEntries.forEach((entity) => worksheet.addRow(createRowFromEntity(entity)));

// Create header title
const title = document.createElement('h1');
Expand All @@ -89,6 +134,7 @@ export const createStats = async () => {
const url = URL.createObjectURL(new Blob([buffer], { type: 'application/xlsx' }));
const link = document.createElement('a');
link.href = url;
link.download = 'camps.xlsx';
const btn = document.createElement('sl-button');
btn.innerHTML = 'Download XLSX File';
btn.setAttribute('variant', 'primary');
Expand Down

0 comments on commit 598baaf

Please sign in to comment.