Portrait Table
This commit is contained in:
parent
39f813bec3
commit
5768a15876
7 changed files with 169 additions and 55 deletions
|
@ -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;
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,22 +64,23 @@
|
|||
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) => {
|
||||
const newEthicsData: {
|
||||
machine: boolean;
|
||||
displayName: string;
|
||||
regular: number;
|
||||
fanatic: number;
|
||||
} = {
|
||||
machine: ethic.machine,
|
||||
displayName: ethic.displayName,
|
||||
regular: 0,
|
||||
fanatic: 0
|
||||
};
|
||||
machine: boolean;
|
||||
displayName: string;
|
||||
regular: number;
|
||||
fanatic: number;
|
||||
} = {
|
||||
machine: ethic.machine,
|
||||
displayName: ethic.displayName,
|
||||
regular: 0,
|
||||
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>
|
||||
<div class="text-column">
|
||||
<div class="row">
|
||||
<p>Portrait 1</p>
|
||||
<p>Portrait 2</p>
|
||||
<p>Portrait 3</p>
|
||||
<section>
|
||||
<div class="text-column">
|
||||
<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>
|
||||
<div class="row">
|
||||
<p>Portrait 1</p>
|
||||
<p>Portrait 2</p>
|
||||
<p>Portrait 3</p>
|
||||
</div>
|
||||
</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>
|
||||
|
|
|
@ -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 '';
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Reference in a new issue