Portrait Table

This commit is contained in:
Neshura 2023-08-21 00:48:23 +02:00
parent 39f813bec3
commit 5768a15876
Signed by: Neshura
GPG key ID: B6983AAA6B9A7A6C
7 changed files with 169 additions and 55 deletions

View file

@ -1,10 +1,7 @@
import { writable, type Writable } from "svelte/store"; import { writable, type Writable } from "svelte/store";
import type { ChellarisInfo } from '../types/chellaris'; import type { ChellarisInfo } from '../types/chellaris';
import { createChellarisInfo } from '../types/chellaris';
const ChellarisDataStore: Writable<ChellarisInfo> = writable({ const ChellarisDataStore: Writable<ChellarisInfo> = writable(createChellarisInfo());
games: new Map(),
ethics: [],
portraits: []
});
export default ChellarisDataStore; export default ChellarisDataStore;

View file

@ -1,8 +1,8 @@
import type { Ethic } from './stellaris'; import type { Ethic, Species } from './stellaris';
export interface ChellarisInfo { export interface ChellarisInfo {
games: Map<number, ChellarisGame>, // Key is Game Id games: Map<number, ChellarisGame>, // Key is Game Id
ethics: Map<number, Ethic>, // TODO implement ethics: Map<number, Ethic>, // Key is Ethic Id
portraits: Array<null>, // TODO implement species: Map<number, Species>, // Key is Species Group Id
} }
export type ChellarisGame = { export type ChellarisGame = {
@ -29,7 +29,7 @@ export const createChellarisInfo = (): ChellarisInfo => {
const newChellarisInfo = { const newChellarisInfo = {
games: new Map(), games: new Map(),
ethics: new Map(), ethics: new Map(),
portraits: [] species: new Map(),
}; };
return newChellarisInfo; return newChellarisInfo;

View file

@ -1,4 +1,4 @@
export enum Species { export enum SpeciesLegacy {
Humanoid = 0, Humanoid = 0,
Mammalian = 1, Mammalian = 1,
Reptilian = 2, Reptilian = 2,
@ -31,13 +31,7 @@ export enum LegacyEthics {
Industrialist = 13, Industrialist = 13,
} }
export type Ethic = { export enum LegacyEthicsScale {
displayName: string,
machine: boolean
fanatic?: boolean,
}
export enum Scale {
normal = 1, normal = 1,
fanatic = 2, fanatic = 2,
} }
@ -47,8 +41,8 @@ export class EthicsDataLegacy {
private data: Array<number> = [0] private data: Array<number> = [0]
constructor(data: Array<number>) { constructor(data: Array<number>) {
this.data[Scale.normal] = data[0], this.data[LegacyEthicsScale.normal] = data[0],
this.data[Scale.fanatic] = data[1] this.data[LegacyEthicsScale.fanatic] = data[1]
} }
sum(weigthed: boolean): number { sum(weigthed: boolean): number {
@ -66,6 +60,22 @@ export class EthicsDataLegacy {
} }
sumRegular(): number { sumRegular(): number {
return this.data[Scale.normal]; return this.data[LegacyEthicsScale.normal];
} }
} }
export type Ethic = {
displayName: string,
machine: boolean,
fanatic?: boolean,
}
export type Species = {
displayName: string,
portraits: Map<number, Portrait>, // Key is Portrait Id
}
export type Portrait = {
imageLink: string,
}

View file

@ -85,6 +85,36 @@ export const load: LayoutLoad = async () => {
empireData.ethics.set(empireEthic.ethics_id, tmpEthic); empireData.ethics.set(empireEthic.ethics_id, tmpEthic);
} }
} }
});
const portraitGroups: {
id: number,
name: string
}[] = await (await fetch(apiBaseUrl + '/portrait_groups')).json();
portraitGroups.sort((a, b) => (a.id < b.id ? -1 : 1));
portraitGroups.forEach(portraitGroup => {
const newPortraitGroup = { displayName: portraitGroup.name, portraits: new Map() };
chellarisData.species.set(portraitGroup.id, newPortraitGroup);
});
const portraits: {
id: number,
href: string,
group_id: number
}[] = await (await fetch(apiBaseUrl + '/portraits')).json();
portraits.sort((a, b) => (a.id < b.id ? -1 : 1));
portraits.forEach(portrait => {
const portraitGroupData = chellarisData.species.get(portrait.group_id);
if (typeof portraitGroupData !== "undefined") {
const newPortraitData = { imageLink: portrait.href };
portraitGroupData.portraits.set(portrait.id, newPortraitData);
}
}) })
ChellarisDataStore.set(chellarisData); ChellarisDataStore.set(chellarisData);

View file

@ -34,10 +34,12 @@
fanatic: number; fanatic: number;
} }
>; >;
takenPortraits: Map<number, Map<number, number>>;
} = { } = {
empireCount: 0, empireCount: 0,
gestaltCount: { total: 0, machines: 0 }, gestaltCount: { total: 0, machines: 0 },
ethicsData: new Map() ethicsData: new Map(),
takenPortraits: new Map(),
}; };
// Save Tab to Store // Save Tab to Store
@ -62,22 +64,23 @@
if (typeof tmpGameData !== 'undefined') { if (typeof tmpGameData !== 'undefined') {
const groupEmpires: Map<number, ChellarisEmpire> = new Map(); const groupEmpires: Map<number, ChellarisEmpire> = new Map();
pageData.ethicsData = new Map(); pageData.ethicsData = new Map();
pageData.takenPortraits = new Map();
pageData.gestaltCount = { total: 0, machines: 0 }; pageData.gestaltCount = { total: 0, machines: 0 };
chellarisData.ethics.forEach((ethic, id) => { chellarisData.ethics.forEach((ethic, id) => {
const newEthicsData: { const newEthicsData: {
machine: boolean; machine: boolean;
displayName: string; displayName: string;
regular: number; regular: number;
fanatic: number; fanatic: number;
} = { } = {
machine: ethic.machine, machine: ethic.machine,
displayName: ethic.displayName, displayName: ethic.displayName,
regular: 0, regular: 0,
fanatic: 0 fanatic: 0
}; };
pageData.ethicsData.set(id, newEthicsData); pageData.ethicsData.set(id, newEthicsData);
}) });
tmpGameData.empires.forEach((empire, index) => { tmpGameData.empires.forEach((empire, index) => {
if (selectedGameGroups.includes(empire.group)) { if (selectedGameGroups.includes(empire.group)) {
@ -87,7 +90,7 @@
pageData.gestaltCount.total = pageData.gestaltCount.total + 1; pageData.gestaltCount.total = pageData.gestaltCount.total + 1;
let machine = false; let machine = false;
empire.ethics.forEach(ethic => { empire.ethics.forEach((ethic) => {
if (ethic.machine) { if (ethic.machine) {
machine = true; machine = true;
} }
@ -132,6 +135,25 @@
pageData.ethicsData.set(id, newEthicsData); pageData.ethicsData.set(id, newEthicsData);
} }
}); });
if (!pageData.takenPortraits.has(empire.empire_portrait_group)) {
pageData.takenPortraits.set(empire.empire_portrait_group, new Map());
}
const portraitGroupData = pageData.takenPortraits.get(empire.empire_portrait_group);
if (typeof portraitGroupData !== "undefined") {
if (!portraitGroupData.has(empire.empire_portrait)) {
portraitGroupData.set(empire.empire_portrait, 0);
}
let portraitData = portraitGroupData.get(empire.empire_portrait);
if (typeof portraitData !== "undefined") {
portraitData = portraitData + 1;
portraitGroupData.set(empire.empire_portrait, portraitData);
pageData.takenPortraits.set(empire.empire_portrait_group, portraitGroupData);
}
}
} }
}); });
pageData.empireCount = groupEmpires.size; pageData.empireCount = groupEmpires.size;
@ -230,25 +252,34 @@
</table> </table>
</div> </div>
</section> </section>
<div class="text-column"> <section>
<div class="row"> <div class="text-column">
<p>Portrait 1</p> <table>
<p>Portrait 2</p> <tr>
<p>Portrait 3</p> <th>Species</th>
{#each Array(18) as _, index (index)}
<th>{index + 1}</th>
{/each}
</tr>
{#each chellarisData.species as portraitGroup}
<tr>
<td>{portraitGroup[1].displayName}</td>
{#each portraitGroup[1].portraits as portrait}
<td class="image-box" style="--color-hovered-portrait: {
(gameGroups.size - 1) - (pageData.takenPortraits.get(portraitGroup[0])?.get(portrait[0]) || 0) == 0 ? "var(--color-warn-2)" :
(gameGroups.size - 1) - (pageData.takenPortraits.get(portraitGroup[0])?.get(portrait[0]) || 0) != (gameGroups.size - 1) ? "var(--color-warn-1)" : "var(--color-bg)"}">
<input id={portraitGroup[0] + "-" + portrait[0]} type="image" src={portrait[1].imageLink} alt={portraitGroup[1].displayName + "-" + portrait[0]}>
<label for={portraitGroup[0] + "-" + portrait[0]}>{pageData.takenPortraits.get(portraitGroup[0])?.get(portrait[0]) || 0}/{gameGroups.size - 1}</label>
</td>
{/each}
</tr>
{/each}
</table>
</div> </div>
<div class="row"> </section>
<p>Portrait 1</p>
<p>Portrait 2</p>
<p>Portrait 3</p>
</div>
</div>
</div> </div>
<style> <style>
table {
border: 1px solid var(--color-text);
}
th, th,
td { td {
padding: 0.3rem 0.5rem; padding: 0.3rem 0.5rem;
@ -275,8 +306,52 @@
.ethics-column { .ethics-column {
min-width: fit-content; min-width: fit-content;
} }
.row {
display: flex; .image-box input {
flex-direction: row; padding-top: 0.3rem;
display: block;
position: absolute;
object-fit: contain;
top: 0px;
left: -0.25rem;
width: 2.5rem;
height: 2.2rem;
} }
.image-box label {
position: relative;
top: 25%;
cursor: pointer;
text-shadow: 0 0 2px var(--color-bg), 0 0 0px var(--color-text);
font-size: medium;
font-weight: 100;
}
.image-box {
padding: 0;
position: relative;
background-color: var(--color-hovered-portrait);
border: 1px solid var(--color-text);
min-width: 2rem;
height: 2rem;
overflow: hidden;
}
.image-box:hover {
z-index: 100;
transform: scale(170%);
transition-property: transform border-color;
transition-duration: 0.1s;
transition-timing-function: linear;
}
.image-box:hover label {
font-size: small;
font-weight: 100;
top: 20%;
transition-property: font-size top color;
transition-duration: 0.1s;
transition-timing-function: linear;
}
</style> </style>

View file

@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import { Pie } from 'svelte-chartjs'; import { Pie } from 'svelte-chartjs';
import { Species } from '$lib/types/stellaris'; import { SpeciesLegacy } from '$lib/types/stellaris';
import { Chart as ChartJS, registerables } from 'chart.js'; import { Chart as ChartJS, registerables } from 'chart.js';
import ChartDataLabels from 'chartjs-plugin-datalabels'; import ChartDataLabels from 'chartjs-plugin-datalabels';
@ -15,7 +15,7 @@
const chart_data = { const chart_data = {
labels: data.popsData.map((_elem: any, idx: number) => { labels: data.popsData.map((_elem: any, idx: number) => {
return Species[idx]; return SpeciesLegacy[idx];
}), }),
datasets: [ datasets: [
{ {
@ -66,7 +66,7 @@
datalabels: { datalabels: {
formatter: (value: number, context: any) => { formatter: (value: number, context: any) => {
if (value > 0) { if (value > 0) {
return Species[context.dataIndex]; return SpeciesLegacy[context.dataIndex];
} else { } else {
return ''; return '';
} }

View file

@ -7,6 +7,8 @@
--color-bg: #1a1a1a; --color-bg: #1a1a1a;
--color-active-1: #00c4a3; --color-active-1: #00c4a3;
--color-active-2: #4075a6; --color-active-2: #4075a6;
--color-warn-1: #FF9900;
--color-warn-2: #EA4335;
--color-text: rgba(255, 255, 255, 0.7); --color-text: rgba(255, 255, 255, 0.7);
--column-width: 42rem; --column-width: 42rem;
--column-margin-top: 4rem; --column-margin-top: 4rem;