Skip to content

Commit e55d644

Browse files
committed
Implement own version of fingerprint visualization from TFlow
1 parent e0ccd81 commit e55d644

File tree

15 files changed

+150
-70
lines changed

15 files changed

+150
-70
lines changed

features.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@
66
"liveGraphInputValues": true,
77
"recordingScrubberValues": true,
88
"modelValidation": true,
9-
"modelSettings": true
9+
"modelSettings": true,
10+
"fingerprint": true
1011
}

src/__tests__/archtest/default-build-config.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,9 @@ describe('Default build config test', () => {
3131
expect(windiContent.includes("secondary: '#2CCAC0'"), message).toBeFalsy();
3232
expect(features.title, message).toBe('Learning tool');
3333
});
34+
35+
test("deleteme pls", () => {
36+
// TODO: Remember to add feature flag for fingerprint!
37+
expect(true).toBeFalsy();
38+
});
3439
});

src/__viteBuildVariants__/ml-machine-simple/features.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@
66
"liveGraphInputValues": false,
77
"recordingScrubberValues": false,
88
"modelValidation": false,
9-
"modelSettings": false
9+
"modelSettings": false,
10+
"fingerprint": false
1011
}

src/__viteBuildVariants__/ml-machine/features.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@
66
"liveGraphInputValues": true,
77
"recordingScrubberValues": true,
88
"modelValidation": true,
9-
"modelSettings": true
9+
"modelSettings": true,
10+
"fingerprint": true
1011
}

src/__viteBuildVariants__/unbranded/features.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@
66
"liveGraphInputValues": true,
77
"recordingScrubberValues": true,
88
"modelValidation": true,
9-
"modelSettings": true
9+
"modelSettings": true,
10+
"fingerprint": true
1011
}

src/assets/messages/ui.da.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
"content.data.noData.exampleName.shake": "Ryste",
5151
"content.data.noData.exampleName.still": "Stille",
5252
"content.data.noData.exampleName.circle": "Cirkel",
53+
"content.data.tooltip.remove": "Fjern",
5354
"content.trainer.failure.header": "Træning mislykkedes",
5455
"content.trainer.failure.body": "Træningen resulterede ikke i en brugbar model. Grunden til dette ligger sandsynligvis i dataet. Hvis dataet i forskellige klasser minder for meget om hinanden, kan dette resultere i nogle forskellige problemer i træningsprocessen, der ikke gør det muligt at træne modellen ordentligt.",
5556
"content.trainer.failure.todo": "Gå tilbage til datasiden og ændr i din data.",

src/assets/messages/ui.de.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
"content.data.noData.exampleName.shake": "Schütteln",
5151
"content.data.noData.exampleName.still": "Still",
5252
"content.data.noData.exampleName.circle": "Kreis",
53+
"content.data.tooltip.remove": "Entfernen",
5354
"content.trainer.failure.header": "Training fehlgeschlagen",
5455
"content.trainer.failure.body": "Das Training führte nicht zu einem brauchbaren Modell. Der Grund dafür sind höchstwahrscheinlich die für das Training verwendeten Daten. Wenn die Daten für verschiedene Klassen zu ähnlich sind, kann dies zu Problemen im Trainingsprozess führen.",
5556
"content.trainer.failure.todo": "Gehe zur Datenseite zurück und ändere die Daten.",

src/assets/messages/ui.en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
"content.data.noData.exampleName.shake": "Shake",
5151
"content.data.noData.exampleName.still": "Still",
5252
"content.data.noData.exampleName.circle": "Circle",
53+
"content.data.tooltip.remove": "Remove",
5354
"content.trainer.failure.header": "Training Failed",
5455
"content.trainer.failure.body": "The training did not result in a usable model. The reason for this is most likely the data used for training. If the data for different classes are too similar, this can result in issues in the training process.",
5556
"content.trainer.failure.todo": "Return to the data page and change your data.",

src/components/features/bottom/BottomPanel.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
class="absolute right-0 cursor-pointer w-45 hover:bg-secondary hover:bg-opacity-10 transition"
8484
on:click={() => (isLive3DOpen = true)}>
8585
<div class="flex flex-row">
86-
<div class="absolute">
86+
<div class="absolute h-full">
8787
<LiveDataFingerprint gestureName="Live" />
8888
</div>
8989
<View3DLive width={160} height={160} freeze={isLive3DOpen} />

src/components/features/bottom/LiveDataFingerprint.svelte

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,50 @@
44
SPDX-License-Identifier: MIT
55
-->
66
<script lang="ts">
7+
import { onMount } from 'svelte';
8+
import { ClassifierInput } from '../../../lib/domain/ClassifierInput';
79
import { stores } from '../../../lib/stores/Stores';
10+
import StaticConfiguration from '../../../StaticConfiguration';
11+
import StandardButton from '../../ui/buttons/StandardButton.svelte';
812
import Fingerprint from '../../ui/recording/Fingerprint.svelte';
913
1014
export let gestureName: string;
1115
const classifier = stores.getClassifier();
1216
const filters = classifier.getFilters();
17+
const highlightedAxes = stores.getHighlightedAxes();
18+
$: liveData = $stores.liveData;
19+
let filteredNormalizedInput: null | number[] = null;
1320
1421
$: filtersLabels = $filters.flatMap(filter => {
1522
const filterName = filter.getName();
1623
return [`${filterName} - x`, `${filterName} - y`, `${filterName} - z`];
1724
});
18-
$: fingerprint = $classifier.filteredInput.normalized.getValue();
25+
// $: fingerprint = $classifier.filteredInput.normalized.getValue();
26+
onMount(() => {
27+
return liveData?.subscribe(() => {
28+
try {
29+
if (liveData) {
30+
const bufferedData = liveData
31+
.getBuffer()
32+
.getSeries(
33+
StaticConfiguration.pollingPredictionSampleDuration,
34+
StaticConfiguration.pollingPredictionSampleSize,
35+
);
36+
filteredNormalizedInput = ClassifierInput.getInputForAxes(
37+
bufferedData.map(e => e.value),
38+
$highlightedAxes,
39+
).getNormalizedInput(filters);
40+
}
41+
} catch (error) {}
42+
});
43+
});
1944
</script>
2045

21-
<div class="w-7 overflow-hidden">
22-
<div style="margin-left: -8px;margin-bottom: -7px">
46+
<div class="w-7 h-full">
47+
{#if !!filteredNormalizedInput}
2348
<Fingerprint
24-
height={166}
25-
width={100}
2649
filterLabels={filtersLabels}
2750
title={gestureName}
28-
{fingerprint} />
29-
</div>
51+
fingerprint={filteredNormalizedInput} />
52+
{/if}
3053
</div>

0 commit comments

Comments
 (0)