Skip to content

Commit 6160f55

Browse files
committed
Improve visibility of elements
Added a toggle to not show the current memory index, allowing to fit memory more densely. (You can still see the index by hovering for a medium long time). To speed up page rendering, background color has been moved to outside of the single component, so that just the parent needs to be updated. Additionally to be able to see the different cells more easily, borders have been added. By default for better visibility elements will get wrapped to show as many on screen as possible, to easier identify hotspots.
1 parent f240780 commit 6160f55

10 files changed

Lines changed: 251 additions & 28 deletions

File tree

html/index.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,15 @@
33
<head>
44
<meta charset="utf-8" />
55
<meta name="viewport" content="width=device-width" />
6+
<title>Memory Visualization</title>
67
</head>
78
<body data-theme="skeleton">
9+
<noscript>
10+
<div class="noscript">
11+
<p>JavaScript is disabled. Please enable JavaScript to view this template output.</p>
12+
<p>Additionally, a modern browser is needed to support the used features.</p>
13+
</div>
14+
</noscript>
815
<script type="module" src="/src/main.ts"></script>
916
</body>
1017
</html>

html/src/App.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
// Additionally this leaves us an easy entry point which will not get simplified away (which normally a comment might be)
2424
2525
// But actually for development mode load in a file
26-
const MemoryData: OutputJSON = JSON.parse(import.meta.env.DEV ? dummyData : `//JS_TEMPLATE`);
26+
const MemoryData: OutputJSON = JSON.parse(import.meta.env.DEV ? dummyData : `// JS_TEMPLATE`);
2727
2828
const info = MemoryData.GlobalSettings;
2929

html/src/app.pcss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,9 @@ html:root {
1919
.high-contrast-text-shadow {
2020
text-shadow: 0px 0px 1px black;
2121
}
22+
23+
.noscript {
24+
width: 100%;
25+
text-align: center;
26+
font-size: 2rem;
27+
}

html/src/components/Layout.svelte

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
<script>
2-
import '@skeletonlabs/skeleton/themes/theme-skeleton.css';
2+
import '../theme.pcss';
33
import '@skeletonlabs/skeleton/styles/all.css';
44
import '../app.pcss';
55
import { AppShell, AppBar, Drawer, tooltip } from '@skeletonlabs/skeleton';
66
import Icon from '@iconify/svelte';
77
import baselineLightbulb from '@iconify/icons-ic/baseline-lightbulb';
88
import outlineSplitscreen from '@iconify/icons-ic/outline-splitscreen';
99
import outlineRectangle from '@iconify/icons-ic/outline-rectangle';
10+
import baselineMenu from '@iconify/icons-ic/baseline-menu';
11+
import baselineFormatListNumbered from '@iconify/icons-ic/baseline-format-list-numbered';
1012
import { pageState, drawerState } from '../lib/stores';
1113
</script>
1214

@@ -20,6 +22,21 @@
2022
<strong class="px-3">v1.0.0</strong>
2123
</svelte:fragment>
2224
<svelte:fragment slot="trail">
25+
<div
26+
class="cursor-pointer"
27+
on:click={() => ($pageState.showIndex = !$pageState.showIndex)}
28+
use:tooltip={{
29+
content: 'Toggle between showing the index of the memory',
30+
position: 'bottom'
31+
}}
32+
>
33+
<Icon
34+
class="drop-shadow-xl"
35+
height="32"
36+
icon={$pageState.showIndex ? baselineMenu : baselineFormatListNumbered}
37+
width="32"
38+
/>
39+
</div>
2340
<div
2441
class="cursor-pointer"
2542
on:click={() => ($drawerState.showSingleAccessTable = !$drawerState.showSingleAccessTable)}
@@ -42,7 +59,7 @@
4259
>
4360
<Icon
4461
class="drop-shadow-xl"
45-
color={$pageState.backGroundContrastBlack ? 'black' : 'white'}
62+
color={!$pageState.backGroundContrastBlack ? 'black' : 'white'}
4663
height="32"
4764
icon={baselineLightbulb}
4865
width="32"

html/src/components/MemoryRegionBlock.svelte

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
<script lang="ts">
22
import { drawerState } from '../lib/stores';
33
import { MemoryRegionManager } from '../lib/types';
4-
import { drawerStore } from '@skeletonlabs/skeleton';
4+
import { drawerStore, tooltip } from '@skeletonlabs/skeleton';
55
import { pageState } from '../lib/stores';
6+
import type { ArgsTooltip } from '@skeletonlabs/skeleton/utilities/Tooltip/tooltip';
67
78
export let MemoryRegion: MemoryRegionManager;
89
export let index: number;
@@ -30,15 +31,13 @@
3031
}
3132
</script>
3233

33-
<div
34-
class="flex m-0"
35-
class:bg-black={$pageState.backGroundContrastBlack}
36-
class:bg-white={!$pageState.backGroundContrastBlack}
37-
>
38-
<div class="py-1 flex-1 m-auto high-contrast-stroke font-black">
39-
{index}
40-
</div>
41-
<div class="flex flex-col flex-1" class:text-black={!$pageState.backGroundContrastBlack}>
34+
<div class="flex m-0 border-gray-600 border-[1px] cell-container">
35+
{#if $pageState.showIndex}
36+
<div class="py-1 flex-1 m-auto high-contrast-stroke font-black index-cell">
37+
{index}
38+
</div>
39+
{/if}
40+
<div class="flex flex-col flex-1" title={'Index: ' + index}>
4241
{#if $drawerState.showSingleAccessTable}
4342
<div
4443
class="flex-1 flex justify-center items-center bg-access-all high-contrast-text-shadow"
@@ -56,7 +55,7 @@
5655
</div>
5756
{:else}
5857
<div
59-
class="flex-1 bg-access-read high-contrast-text-shadow"
58+
class="flex-1 bg-access-read high-contrast-text-shadow content-cell"
6059
style="--tw-bg-opacity: {readOpacity}"
6160
on:click={() => {
6261
drawerStore.open({
@@ -71,7 +70,7 @@
7170
{readCount}
7271
</div>
7372
<div
74-
class="flex-1 bg-access-write high-contrast-text-shadow"
73+
class="flex-1 bg-access-write high-contrast-text-shadow content-cell"
7574
style="--tw-bg-opacity: {writeOpacity}"
7675
on:click={() => {
7776
drawerStore.open({
@@ -88,3 +87,19 @@
8887
{/if}
8988
</div>
9089
</div>
90+
91+
<style>
92+
.index-cell {
93+
border-right: 2px solid gray;
94+
min-width: var(--cell-index-width);
95+
}
96+
97+
.content-cell {
98+
min-width: var(--cell-content-width);
99+
color: var(--cell-text-color);
100+
}
101+
102+
.cell-container {
103+
background-color: var(--cell-background-color);
104+
}
105+
</style>
Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script lang="ts">
22
import { MemoryRegionManager } from '../lib/types';
33
import MemoryRegionBlock from './MemoryRegionBlock.svelte';
4+
import { pageState } from '../lib/stores';
45
56
export let MemoryRegion: MemoryRegionManager;
67
@@ -9,30 +10,65 @@
910
1011
MemoryRegion.displaySettings.using1DSparseRepresentation = false;
1112
13+
let highestIndexWidth = MemoryRegion.getHighestIndex().toString().length + 1.5 + 'ch';
14+
let highestValueWidth = MemoryRegion.highestTotalCount.toString().length + 1.5 + 'ch';
15+
1216
$: {
1317
if (MemoryRegion.displaySettings.using1DSparseRepresentation) {
1418
addressObject = MemoryRegion.getSparse1DMemoryLocations();
19+
console.log(addressObject);
1520
} else {
1621
addressObject = { length: MemoryRegion.getHighestIndex() + 1 };
1722
}
1823
}
1924
</script>
2025

21-
<div class="space-y-0.5 text-center flex flex-col m-3">
26+
<div class="text-center m-3 w-full">
2227
<div class="badge">
2328
{MemoryRegion.name}
2429
</div>
25-
{#each addressObject as address, index}
26-
<!-- Check if the address is a valid object, if not we are not using a sparse array but show every element instead, so we need to use the index -->
27-
{#if address == undefined}
28-
<MemoryRegionBlock {MemoryRegion} {index} />
29-
{:else}
30-
<!-- Now check if we have a number or an array, if we have a number, this is our index, if it is an array, we actually have items left out and just symbolize that with three dots -->
31-
{#if typeof address == 'number'}
32-
<MemoryRegionBlock {MemoryRegion} index={address} />
30+
<div
31+
class="screen-grid w-full"
32+
style={'--cell-index-width: ' +
33+
highestIndexWidth +
34+
'; --cell-content-width: ' +
35+
highestValueWidth +
36+
'; --cell-background-color: ' +
37+
($pageState.backGroundContrastBlack ? 'black' : 'white') +
38+
'; --cell-text-color: ' +
39+
($pageState.backGroundContrastBlack ? 'white;' : 'black;')}
40+
>
41+
{#each addressObject as address, index}
42+
<!-- Check if the address is a valid object, if not we are not using a sparse array but show every element instead, so we need to use the index -->
43+
{#if address == undefined}
44+
<MemoryRegionBlock {MemoryRegion} {index} />
3345
{:else}
34-
<div>...</div>
46+
<!-- Now check if we have a number or an array, if we have a number, this is our index, if it is an array, we actually have items left out and just symbolize that with three dots -->
47+
{#if typeof address == 'number'}
48+
<MemoryRegionBlock {MemoryRegion} index={address} />
49+
{:else}
50+
<div>...</div>
51+
{/if}
3552
{/if}
36-
{/if}
37-
{/each}
53+
{/each}
54+
</div>
3855
</div>
56+
57+
<style>
58+
:root {
59+
--minimum-grid-width: 60px;
60+
--cell-index-width: 32px;
61+
--cell-content-width: 32px;
62+
--cell-background-color: black;
63+
--cell-text-color: white;
64+
}
65+
66+
.screen-grid {
67+
display: flex;
68+
flex-wrap: wrap;
69+
align-items: center;
70+
align-content: center;
71+
flex-direction: row;
72+
gap: 4px 0px;
73+
}
74+
</style>

html/src/theme.pcss

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
:root {
2+
/* =~= Theme Properties =~= */
3+
--theme-font-family-base: system-ui;
4+
--theme-font-family-heading: system-ui;
5+
--theme-font-color-base: 0 0 0;
6+
--theme-font-color-dark: 255 255 255;
7+
--theme-rounded-base: 9999px;
8+
--theme-rounded-container: 12px;
9+
--theme-border-base: 2px;
10+
/* =~= Theme On-X Colors =~= */
11+
--on-primary: 0 0 0;
12+
--on-secondary: 255 255 255;
13+
--on-tertiary: 255 255 255;
14+
--on-success: 0 0 0;
15+
--on-warning: 0 0 0;
16+
--on-error: 255 255 255;
17+
--on-surface: 255 255 255;
18+
/* =~= Theme Colors =~= */
19+
/* primary | #22d3c7 */
20+
--color-primary-50: 222 248 247; /* ⬅ #def8f7 */
21+
--color-primary-100: 211 246 244; /* ⬅ #d3f6f4 */
22+
--color-primary-200: 200 244 241; /* ⬅ #c8f4f1 */
23+
--color-primary-300: 167 237 233; /* ⬅ #a7ede9 */
24+
--color-primary-400: 100 224 216; /* ⬅ #64e0d8 */
25+
--color-primary-500: 34 211 199; /* ⬅ #22d3c7 */
26+
--color-primary-600: 31 190 179; /* ⬅ #1fbeb3 */
27+
--color-primary-700: 26 158 149; /* ⬅ #1a9e95 */
28+
--color-primary-800: 20 127 119; /* ⬅ #147f77 */
29+
--color-primary-900: 17 103 98; /* ⬅ #116762 */
30+
/* secondary | #532fb6 */
31+
--color-secondary-50: 229 224 244; /* ⬅ #e5e0f4 */
32+
--color-secondary-100: 221 213 240; /* ⬅ #ddd5f0 */
33+
--color-secondary-200: 212 203 237; /* ⬅ #d4cbed */
34+
--color-secondary-300: 186 172 226; /* ⬅ #baace2 */
35+
--color-secondary-400: 135 109 204; /* ⬅ #876dcc */
36+
--color-secondary-500: 83 47 182; /* ⬅ #532fb6 */
37+
--color-secondary-600: 75 42 164; /* ⬅ #4b2aa4 */
38+
--color-secondary-700: 62 35 137; /* ⬅ #3e2389 */
39+
--color-secondary-800: 50 28 109; /* ⬅ #321c6d */
40+
--color-secondary-900: 41 23 89; /* ⬅ #291759 */
41+
/* tertiary | #453375 */
42+
--color-tertiary-50: 227 224 234; /* ⬅ #e3e0ea */
43+
--color-tertiary-100: 218 214 227; /* ⬅ #dad6e3 */
44+
--color-tertiary-200: 209 204 221; /* ⬅ #d1ccdd */
45+
--color-tertiary-300: 181 173 200; /* ⬅ #b5adc8 */
46+
--color-tertiary-400: 125 112 158; /* ⬅ #7d709e */
47+
--color-tertiary-500: 69 51 117; /* ⬅ #453375 */
48+
--color-tertiary-600: 62 46 105; /* ⬅ #3e2e69 */
49+
--color-tertiary-700: 52 38 88; /* ⬅ #342658 */
50+
--color-tertiary-800: 41 31 70; /* ⬅ #291f46 */
51+
--color-tertiary-900: 34 25 57; /* ⬅ #221939 */
52+
/* success | #8ff15b */
53+
--color-success-50: 238 253 230; /* ⬅ #eefde6 */
54+
--color-success-100: 233 252 222; /* ⬅ #e9fcde */
55+
--color-success-200: 227 252 214; /* ⬅ #e3fcd6 */
56+
--color-success-300: 210 249 189; /* ⬅ #d2f9bd */
57+
--color-success-400: 177 245 140; /* ⬅ #b1f58c */
58+
--color-success-500: 143 241 91; /* ⬅ #8ff15b */
59+
--color-success-600: 129 217 82; /* ⬅ #81d952 */
60+
--color-success-700: 107 181 68; /* ⬅ #6bb544 */
61+
--color-success-800: 86 145 55; /* ⬅ #569137 */
62+
--color-success-900: 70 118 45; /* ⬅ #46762d */
63+
/* warning | #e7a636 */
64+
--color-warning-50: 251 242 225; /* ⬅ #fbf2e1 */
65+
--color-warning-100: 250 237 215; /* ⬅ #faedd7 */
66+
--color-warning-200: 249 233 205; /* ⬅ #f9e9cd */
67+
--color-warning-300: 245 219 175; /* ⬅ #f5dbaf */
68+
--color-warning-400: 238 193 114; /* ⬅ #eec172 */
69+
--color-warning-500: 231 166 54; /* ⬅ #e7a636 */
70+
--color-warning-600: 208 149 49; /* ⬅ #d09531 */
71+
--color-warning-700: 173 125 41; /* ⬅ #ad7d29 */
72+
--color-warning-800: 139 100 32; /* ⬅ #8b6420 */
73+
--color-warning-900: 113 81 26; /* ⬅ #71511a */
74+
/* error | #8e1010 */
75+
--color-error-50: 238 219 219; /* ⬅ #eedbdb */
76+
--color-error-100: 232 207 207; /* ⬅ #e8cfcf */
77+
--color-error-200: 227 195 195; /* ⬅ #e3c3c3 */
78+
--color-error-300: 210 159 159; /* ⬅ #d29f9f */
79+
--color-error-400: 176 88 88; /* ⬅ #b05858 */
80+
--color-error-500: 142 16 16; /* ⬅ #8e1010 */
81+
--color-error-600: 128 14 14; /* ⬅ #800e0e */
82+
--color-error-700: 107 12 12; /* ⬅ #6b0c0c */
83+
--color-error-800: 85 10 10; /* ⬅ #550a0a */
84+
--color-error-900: 70 8 8; /* ⬅ #460808 */
85+
/* surface | #414358 */
86+
--color-surface-50: 227 227 230; /* ⬅ #e3e3e6 */
87+
--color-surface-100: 217 217 222; /* ⬅ #d9d9de */
88+
--color-surface-200: 208 208 213; /* ⬅ #d0d0d5 */
89+
--color-surface-300: 179 180 188; /* ⬅ #b3b4bc */
90+
--color-surface-400: 122 123 138; /* ⬅ #7a7b8a */
91+
--color-surface-500: 65 67 88; /* ⬅ #414358 */
92+
--color-surface-600: 59 60 79; /* ⬅ #3b3c4f */
93+
--color-surface-700: 49 50 66; /* ⬅ #313242 */
94+
--color-surface-800: 39 40 53; /* ⬅ #272835 */
95+
--color-surface-900: 32 33 43; /* ⬅ #20212b */
96+
97+
}
98+
99+
[data-theme='skeleton'] {
100+
background-image:
101+
radial-gradient(at 48% 41%, hsla(222,100%,28%,0.12) 0px, transparent 50%),
102+
radial-gradient(at 7% 8%, hsla(188,100%,28%,0.1) 0px, transparent 50%),
103+
radial-gradient(at 93% 8%, hsla(272,100%,28%,0.18) 0px, transparent 50%),
104+
radial-gradient(at 16% 74%, hsla(245,100%,28%,0.29) 0px, transparent 50%),
105+
radial-gradient(at 86% 80%, hsla(239,100%,28%,0.34) 0px, transparent 50%);
106+
}

html/tools/postBuild.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import type { Plugin } from 'vite';
2+
import type { OutputAsset, OutputChunk } from 'rollup';
3+
4+
const warnNotInlined = (filename: string) => console.warn(`WARNING: asset not inlined: ${filename}`);
5+
6+
export function vitePostBuildFix(): Plugin {
7+
return {
8+
name: 'vite:postBuildFix',
9+
enforce: 'post',
10+
generateBundle: (_, bundle) => {
11+
// Check if bundle has index.html
12+
if (!bundle['index.html']) {
13+
return;
14+
}
15+
16+
// Check if the source of index.html is a string and available
17+
if ('source' in bundle['index.html'] && typeof bundle['index.html'].source === 'string') {
18+
const indexHtml: OutputAsset = bundle['index.html'] as OutputAsset;
19+
20+
if (typeof indexHtml.source !== 'string') {
21+
return;
22+
}
23+
24+
// Now replace the placeholder with the correct quotes
25+
const source = indexHtml.source.replace(/"\/\/ JS_TEMPLATE"|'\/\/ JS_TEMPLATE'/g, '`// JS_TEMPLATE`');
26+
27+
// Log it to console that we replaced the incorrect quotes
28+
console.log('Post Build Fix: Replaced incorrect quotes in index.html');
29+
30+
indexHtml.source = source;
31+
}
32+
}
33+
};
34+
}

html/tsconfig.node.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
"module": "ESNext",
55
"moduleResolution": "Node"
66
},
7-
"include": ["vite.config.ts"]
7+
"include": ["vite.config.ts", "tools/postBuild.ts"]
88
}

0 commit comments

Comments
 (0)