Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
"@vue/eslint-config-typescript": "^11.0.2",
"d3": "^7.8.0",
"eslint-import-resolver-alias": "^1.1.2",
"multinet": "^0.21.4",
"multinet-components": "^0.0.2",
"multinet": "^0.21.7",
"multinet-components": "^0.0.4",
"pinia": "^2.0.28",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
122 changes: 80 additions & 42 deletions src/components/AlertBanner.vue
Original file line number Diff line number Diff line change
@@ -1,48 +1,7 @@
<script setup lang="ts">
import { ref, watchEffect } from 'vue';
import { useStore } from '@/store';
import api from '@/api';
import { storeToRefs } from 'pinia';

const store = useStore();
const { loadError } = storeToRefs(store);

// Vars to store the selected choices in
const workspace = ref<string | null>(null);
const network = ref<string | null>(null);

// Compute the workspace/network options
const workspaceOptions = ref<string[]>([]);
watchEffect(async () => {
workspaceOptions.value = (await api.workspaces()).results.map((workspaceObj) => workspaceObj.name);
});

const networkOptions = ref<string[]>([]);
watchEffect(async () => {
if (workspace.value !== null) {
networkOptions.value = (await api.networks(workspace.value)).results.map((networkObj) => networkObj.name);
}
});

const buttonHref = ref(loadError.value.href);
const buttonText = ref('');
watchEffect(async () => {
if (workspace.value !== null) {
buttonHref.value = `./?workspace=${workspace.value}&network=${network.value}`;
buttonText.value = 'Go To Network';
} else if (loadError.value.message === 'There was a network issue when getting data') {
buttonHref.value = loadError.value.href;
buttonText.value = 'Refresh the page';
} else {
buttonHref.value = loadError.value.href;
buttonText.value = 'Back to MultiNet';
}
});
</script>

<template>
<div>
<v-alert
v-if="loadError.message !== 'The network you are loading is too large'"
type="warning"
border="left"
prominent
Expand Down Expand Up @@ -98,9 +57,88 @@ watchEffect(async () => {
</v-col>
</v-row>
</v-alert>

<network-subsetter
v-if="loadError.message === 'The network you are loading is too large' && edgeTableName !== null"
:workspace-name="workspaceName"
:min-subset-size="10"
:max-subset-size="100"
:node-table-names="nodeTableNames"
:edge-table-name="edgeTableName"
:load-error="loadError"
:set-load-error="setLoadError"
:network-name="networkName"
:api="api"
@networkUpdated="replaceNetworkWithSubset"
/>
</div>
</template>

<script setup lang="ts">
import { ref, watchEffect } from 'vue';
import { useStore } from '@/store';
import api from '@/api';
import { storeToRefs } from 'pinia';
import { LoadError, Network } from '@/types';
import { NetworkSubsetter } from 'multinet-components';

const store = useStore();
const {
loadError,
networkName,
nodeTableNames,
edgeTableName,
workspaceName,
} = storeToRefs(store);

// Vars to store the selected choices in
const workspace = ref<string | null>(null);
const network = ref<string | null>(null);

// Compute the workspace/network options
const workspaceOptions = ref<string[]>([]);
watchEffect(async () => {
workspaceOptions.value = (await api.workspaces()).results.map((workspaceObj) => workspaceObj.name);
});

const networkOptions = ref<string[]>([]);
watchEffect(async () => {
if (workspace.value !== null) {
networkOptions.value = (await api.networks(workspace.value)).results.map((networkObj) => networkObj.name);
}
});

const buttonHref = ref(loadError.value.href);
const buttonText = ref('');
watchEffect(async () => {
if (workspace.value !== null) {
buttonHref.value = `./?workspace=${workspace.value}&network=${network.value}`;
buttonText.value = 'Go To Network';
} else if (loadError.value.message === 'There was a network issue when getting data') {
buttonHref.value = loadError.value.href;
buttonText.value = 'Refresh the page';
} else {
buttonHref.value = loadError.value.href;
buttonText.value = 'Back to MultiNet';
}
});

function replaceNetworkWithSubset(newNetwork: Network) {
if (newNetwork.nodes.length !== 0) {
// Update state with new network
store.network = newNetwork;
store.loadError = {
message: '',
href: '',
};
}
}

function setLoadError(newError: LoadError) {
loadError.value = newError;
}
</script>

<style>
html {
scrollbar-width: none;
Expand Down
50 changes: 31 additions & 19 deletions src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import { defineStore, storeToRefs } from 'pinia';
import {
forceCollide, Simulation, scaleLinear, scaleOrdinal, scaleSequential, interpolateBlues, interpolateReds, schemeCategory10,
} from 'd3';
import { ColumnTypes, NetworkSpec, UserSpec } from 'multinet';
import {
ColumnTypes, NetworkSpec, Table, UserSpec,
} from 'multinet';
import api from '@/api';
import {
Edge, Node, NestedVariables, AttributeRanges, LoadError, Network, SimulationEdge, AttributeRange,
Expand Down Expand Up @@ -58,6 +60,14 @@ export const useStore = defineStore('store', () => {
height: 0,
width: 0,
});
const networkTables = ref<Table[]>([]);

const nodeTableNames = computed(() => networkTables.value.filter((table) => !table.edge).map((table) => table.name));
const edgeTableName = computed(() => {
const edgeTable = networkTables.value.find((table) => table.edge);

return edgeTable !== undefined ? edgeTable.name : undefined;
});

const nodeColorScale = computed(() => {
if (columnTypes.value !== null && Object.keys(columnTypes.value).length > 0 && columnTypes.value[nodeColorVariable.value] === 'number') {
Expand Down Expand Up @@ -179,6 +189,24 @@ export const useStore = defineStore('store', () => {
};
}

networkTables.value = await api.networkTables(workspaceName.value, networkName.value);
// Get the network metadata promises
const metadataPromises: Promise<ColumnTypes>[] = [];
networkTables.value.forEach((table) => {
metadataPromises.push(api.columnTypes(workspaceName.value, table.name));
});

// Resolve network metadata promises
const resolvedMetadataPromises = await Promise.all(metadataPromises);

// Combine all network metadata
const columnTypesFromRequests: ColumnTypes = {};
resolvedMetadataPromises.forEach((types) => {
Object.assign(columnTypesFromRequests, types);
});

columnTypes.value = columnTypesFromRequests;

if (loadError.value.message !== '') {
return;
}
Expand All @@ -196,24 +224,6 @@ export const useStore = defineStore('store', () => {
};
network.value = networkElements;

const networkTables = await api.networkTables(workspaceName.value, networkName.value);
// Get the network metadata promises
const metadataPromises: Promise<ColumnTypes>[] = [];
networkTables.forEach((table) => {
metadataPromises.push(api.columnTypes(workspaceName.value, table.name));
});

// Resolve network metadata promises
const resolvedMetadataPromises = await Promise.all(metadataPromises);

// Combine all network metadata
const columnTypesFromRequests: ColumnTypes = {};
resolvedMetadataPromises.forEach((types) => {
Object.assign(columnTypesFromRequests, types);
});

columnTypes.value = columnTypesFromRequests;

// Guess the best label variable and set it
const allVars: Set<string> = new Set();
networkElements.nodes.map((node: Node) => Object.keys(node).forEach((key) => allVars.add(key)));
Expand Down Expand Up @@ -366,5 +376,7 @@ export const useStore = defineStore('store', () => {
setEdgeLength,
guessLabel,
applyVariableLayout,
nodeTableNames,
edgeTableName,
};
});
18 changes: 9 additions & 9 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3037,15 +3037,15 @@ ms@^2.1.1:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==

multinet-components@^0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/multinet-components/-/multinet-components-0.0.2.tgz#172d6e68217c3089add1e2066a9eccfd5b73cf3e"
integrity sha512-D7OsIxzIjQEAEEb4asN9/8GD9NX/uck3w4wAJAkJrrmc46pB58dw3LnwPP4F4OyqHfwRfHdaX5iGYWPBukicJg==

multinet@^0.21.4:
version "0.21.4"
resolved "https://registry.yarnpkg.com/multinet/-/multinet-0.21.4.tgz#9b9015fdeebd245800833db21b8f8e6d81aa351d"
integrity sha512-lYdj11yi5PJblDMg+T1fTih/2RMgIljYoWhpKElUNOdwPCHmc4Z1wFAd7Yo3nf1qKic2qlx0ac45XTcswnl05g==
multinet-components@^0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/multinet-components/-/multinet-components-0.0.4.tgz#26c519733ce72145f5ebf81de1333b294903ee4b"
integrity sha512-T3r/UsB4r4OLZXFx8uIbgYKls1CQ2q8yerySCWQHEbJ0Jga57g2sIyHEpdecXo4Rf3yH/9ZcvhAqBIrV1hnF6A==

multinet@^0.21.7:
version "0.21.8"
resolved "https://registry.yarnpkg.com/multinet/-/multinet-0.21.8.tgz#a8f6d08480c64a1c38e4874922e82f5e707f1518"
integrity sha512-9rXHDUa0B6XKjcwJnAijNTPyvxmm3ZaMgdRxYmSt9fMOKboVBG85JGX65sCpSNA64mJ/6ocplIJhcqOgdHRv1Q==
dependencies:
axios "^0.21.1"
django-s3-file-field "^0.1.2"
Expand Down