Skip to content

Commit

Permalink
Add data tables to UI, needs styling
Browse files Browse the repository at this point in the history
  • Loading branch information
JakeWags committed Apr 4, 2024
1 parent 867f015 commit a267e8c
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 11 deletions.
84 changes: 76 additions & 8 deletions web/shapeworks/src/components/DeepSSM/DeepSSMTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@ import {
spawnJob,
spawnJobProgressPoll,
abort,
deepSSMResult
deepSSMDataTab,
deepSSMResult,
deepSSMAugShowOrgData,
deepSSMAugShowGenData,
} from '@/store';
import { Ref, computed, onMounted, ref, watch } from 'vue';
import { parseCSVFromURL } from '@/helper';
export default {
Expand Down Expand Up @@ -37,7 +41,6 @@ export default {
const openExpansionPanel = ref<number>(0);
const controlsTabs = ref();
const dataTabs = ref();
const showAbortConfirmation = ref(false);
const prepData = {
Expand Down Expand Up @@ -65,6 +68,25 @@ export default {
ftLearningRate: ref<number>(0.001),
}
// headers are assigned from the parseCSV function's output
const dataTables = {
aug_table: ref<any>(undefined),
aug_headers: ref<any>(undefined),
training_table: ref<any>(undefined),
training_headers: ref<any>([
{text: "Training Stage", value: '0'},
{text: "Epoch", value: '1'},
{text: "LR", value: '2'},
{text: "Train_Err", value: '3'},
{text: "Train_Rel_Err", value: '4'},
{text: "Val_Err", value: '5'},
{text: "Val_Rel_Err", value: '6'},
{text: "Sec", value: '7'},
]),
testing_table: ref<any>(undefined),
testing_headers: ref<any>([{text: "Name", value: '0'}, {text: "Distance", value: '1'}]),
}
/**
* Converts an object of reactive properties to a plain object for use in api formData fields.
*/
Expand Down Expand Up @@ -98,16 +120,40 @@ export default {
return taskId;
}
async function getCSVDataFromURL(url: string) {
return await parseCSVFromURL(url);
}
onMounted(async () => {
if (!deepSSMResult.value && selectedProject.value) {
await loadDeepSSMDataForProject();
}
if (deepSSMResult.value) {
try {
Promise.all([
await getCSVDataFromURL(deepSSMResult.value.result.aug_total_data),
await getCSVDataFromURL(deepSSMResult.value.result.training_data_table),
await getCSVDataFromURL(deepSSMResult.value.result.testing_distances),
]).then((res) => {
dataTables.aug_table.value = res[0];
dataTables.training_table.value = res[1];
dataTables.testing_table.value = res[2];
// Augmentation data table doesn't have headers, only a numbered list
dataTables.aug_headers.value = dataTables.aug_table.value.map((_: string, index: number) => {
return {text: index+1, value: `${index}`, align:'start'}
});
});
}
catch (e) {
console.error(e);
}
}
})
return {
openExpansionPanel,
controlsTabs,
dataTabs,
prepData,
augmentationData,
trainingData,
Expand All @@ -117,7 +163,11 @@ export default {
taskData,
abort,
showAbortConfirmation,
deepSSMDataTab,
deepSSMResult,
deepSSMAugShowOrgData,
deepSSMAugShowGenData,
dataTables,
}
},
}
Expand Down Expand Up @@ -237,25 +287,38 @@ export default {
<v-expansion-panel v-if="deepSSMResult">
<v-expansion-panel-header>Data</v-expansion-panel-header>
<v-expansion-panel-content>
<v-tabs v-model="dataTabs">
<v-tab>Prep</v-tab>
<v-tabs v-model="deepSSMDataTab">
<v-tab>Augmentation</v-tab>
<v-tab>Training</v-tab>
<v-tab>Testing</v-tab>
</v-tabs>
<v-tabs-items v-model="dataTabs">
<v-tabs-items v-model="deepSSMDataTab">
<v-tab-item>
<div>
<div class="aug-data-checkboxes">
<v-checkbox v-model="deepSSMAugShowOrgData" label="Original Data"></v-checkbox>
<v-checkbox v-model="deepSSMAugShowGenData" label="Generated Data"></v-checkbox>
</div>
<!-- table -->
total
<!-- TODO: CLEAN STYLING -->
<v-data-table
:items="dataTables.aug_table.value"
:headers="dataTables.aug_headers.value"
></v-data-table>
<!-- violin plot -->
<h4>Violin Plot</h4>
<v-img :src="deepSSMResult.result?.aug_visualization" alt="Augmented Data Violin Plot" />
</div>
</v-tab-item>
<v-tab-item>
<div>
<!-- training data -->
<!-- table -->
<!-- TODO: CLEAN STYLING -->
<v-data-table
:items="dataTables.training_table.value"
:headers="dataTables.training_headers.value"
></v-data-table>
<!-- epoch plots -->
Training Plot
<v-img :src="deepSSMResult.result?.training_visualization" alt="Training Plot" />
Expand All @@ -269,6 +332,11 @@ export default {
<div>
<!-- testing data -->
<!-- distance table -->
<!-- TODO: CLEAN STYLING -->
<v-data-table
:items="dataTables.testing_table.value"
:headers="dataTables.testing_headers.value"
></v-data-table>
</div>
</v-tab-item>
</v-tabs-items>
Expand Down Expand Up @@ -300,7 +368,7 @@ input[type=number] {
margin: 0 10px;
}
.image-spacing {
.image-spacing, .aug-data-checkboxes {
display: flex;
flex-direction: row;
justify-content: space-between;
Expand Down
54 changes: 53 additions & 1 deletion web/shapeworks/src/helper.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,44 @@
// Helper functions that may come in handy in component or view files

/**
* Groups an array of objects by a specified key.
* @param xs The array of objects to be grouped.
* @param key The key to group the objects by.
* @returns An object where the keys are unique values of the specified key, and the values are arrays of objects with that key value.
*/
export function groupBy(xs: any[], key: string) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
}

/**
* Returns the short date string from a given date string.
* @param date The date string.
* @returns The short date string.
*/
export function shortDateString(date: string) {
return date.split('T')[0]
}

/**
* Returns the short file name from a given file path.
* @param file The file path.
* @returns The short file name.
*/
export function shortFileName(file: string) {
const split = file.split('?')[0].split('/')
return split[split.length-1]
}

/**
* Calculates the Euclidean distance between two points in n-dimensional space.
* @param one The coordinates of the first point.
* @param two The coordinates of the second point.
* @param signed (Optional) Whether to return a signed distance. Defaults to false.
* @returns The Euclidean distance between the two points.
*/
export function getDistance(
one: number[], two: number[], signed=false
){
Expand All @@ -32,7 +55,11 @@ export function getDistance(
return Math.sqrt(squaredDimSum);
}

// from https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
/**
* Converts a hexadecimal color code to an RGB array.
* @param hex The hexadecimal color code.
* @returns The RGB array representation of the color.
*/
export function hexToRgb(hex: string) {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? [
Expand All @@ -53,3 +80,28 @@ export function rgbToHex(rgb) {
export function distance(a, b){
return Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2) + Math.pow(a.z - b.z, 2);
}

/**
* Parses a CSV file from the specified URL and returns the data as an array of objects.
* @param url - The URL of the CSV file to parse.
* @returns A promise that resolves to an array of objects representing the CSV data.
*/
export async function parseCSVFromURL(url: string) {
return fetch(url)
.then(response => response.text())
.then(text => {
// last value of the substring is blank, so we remove it
const splitstring = text.split('\n').slice(0, -1);

const data: {[x: string]: any} = [];
for (let i = 0; i < splitstring.length; i++) {
const d = {};
const row = splitstring[i].split(',');
for (let j = 0; j < row.length; j++) {
d[j] = row[j];
}
data.push(d);
}
return data;
})
}
8 changes: 7 additions & 1 deletion web/shapeworks/src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,10 @@ export const imageViewLevel = ref<number>(0);

export const imageViewLevelRange = ref<number[]>([0, 1]);

export const deepSSMResult = ref<Record<string, any>>();
export const deepSSMResult = ref<Record<string, any>>();

export const deepSSMDataTab = ref<number>(0);

export const deepSSMAugShowOrgData = ref<boolean>(true);

export const deepSSMAugShowGenData = ref<boolean>(false);
1 change: 0 additions & 1 deletion web/shapeworks/src/store/methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,6 @@ export const loadDeepSSMDataForProject = async () => {
training_images: results[2],
test_images: results[3]
}
console.log(deepSSMResult.value)
}
}

Expand Down

0 comments on commit a267e8c

Please sign in to comment.