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 type { ChellarisInfo } from '../types/chellaris';
import { createChellarisInfo } from '../types/chellaris';
const ChellarisDataStore: Writable<ChellarisInfo> = writable({
games: new Map(),
ethics: [],
portraits: []
});
const ChellarisDataStore: Writable<ChellarisInfo> = writable(createChellarisInfo());
export default ChellarisDataStore;

View file

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

View file

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

View file

@ -34,10 +34,12 @@
fanatic: number;
}
>;
takenPortraits: Map<number, Map<number, number>>;
} = {
empireCount: 0,
gestaltCount: { total: 0, machines: 0 },
ethicsData: new Map()
ethicsData: new Map(),
takenPortraits: new Map(),
};
// Save Tab to Store
@ -62,6 +64,7 @@
if (typeof tmpGameData !== 'undefined') {
const groupEmpires: Map<number, ChellarisEmpire> = new Map();
pageData.ethicsData = new Map();
pageData.takenPortraits = new Map();
pageData.gestaltCount = { total: 0, machines: 0 };
chellarisData.ethics.forEach((ethic, id) => {
@ -77,7 +80,7 @@
fanatic: 0
};
pageData.ethicsData.set(id, newEthicsData);
})
});
tmpGameData.empires.forEach((empire, index) => {
if (selectedGameGroups.includes(empire.group)) {
@ -87,7 +90,7 @@
pageData.gestaltCount.total = pageData.gestaltCount.total + 1;
let machine = false;
empire.ethics.forEach(ethic => {
empire.ethics.forEach((ethic) => {
if (ethic.machine) {
machine = true;
}
@ -132,6 +135,25 @@
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;
@ -230,25 +252,34 @@
</table>
</div>
</section>
<section>
<div class="text-column">
<div class="row">
<p>Portrait 1</p>
<p>Portrait 2</p>
<p>Portrait 3</p>
</div>
<div class="row">
<p>Portrait 1</p>
<p>Portrait 2</p>
<p>Portrait 3</p>
</div>
<table>
<tr>
<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>
</section>
</div>
<style>
table {
border: 1px solid var(--color-text);
}
th,
td {
padding: 0.3rem 0.5rem;
@ -275,8 +306,52 @@
.ethics-column {
min-width: fit-content;
}
.row {
display: flex;
flex-direction: row;
.image-box input {
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>

View file

@ -1,6 +1,6 @@
<script lang="ts">
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 ChartDataLabels from 'chartjs-plugin-datalabels';
@ -15,7 +15,7 @@
const chart_data = {
labels: data.popsData.map((_elem: any, idx: number) => {
return Species[idx];
return SpeciesLegacy[idx];
}),
datasets: [
{
@ -66,7 +66,7 @@
datalabels: {
formatter: (value: number, context: any) => {
if (value > 0) {
return Species[context.dataIndex];
return SpeciesLegacy[context.dataIndex];
} else {
return '';
}

View file

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