@abi-software/simulationvuer 2.0.11-beta.0 → 2.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/App.vue +57 -31
- package/src/components/SimulationVuer.vue +67 -27
package/package.json
CHANGED
package/src/App.vue
CHANGED
|
@@ -2,14 +2,24 @@
|
|
|
2
2
|
<div id="app">
|
|
3
3
|
<div class="app">
|
|
4
4
|
<h1>SimulationVuer</h1>
|
|
5
|
-
<
|
|
6
|
-
|
|
7
|
-
<el-radio-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
<div v-if="datasetIds.length !== 0">
|
|
6
|
+
<h3>Dataset IDs (run on o²S²PARC):</h3>
|
|
7
|
+
<el-radio-group v-model="activeResource" size="small">
|
|
8
|
+
<el-radio-button :class="className(datasetId.id)" v-for="datasetId in datasetIds" v-bind:key="datasetId.id" :label="datasetId.label" :value="datasetId.id" />
|
|
9
|
+
</el-radio-group>
|
|
10
|
+
</div>
|
|
11
|
+
<div v-if="datasetUrls.length !== 0">
|
|
12
|
+
<h3>Dataset URLs (run in the browser):</h3>
|
|
13
|
+
<el-radio-group v-model="activeResource" size="small">
|
|
14
|
+
<el-radio-button :class="className(datasetUrl.id)" v-for="datasetUrl in datasetUrls" v-bind:key="datasetUrl.id" :label="datasetUrl.label" :value="datasetUrl.id" />
|
|
15
|
+
</el-radio-group>
|
|
16
|
+
</div>
|
|
17
|
+
<div v-if="pmrPaths.length !== 0">
|
|
18
|
+
<h3>PMR paths (run in the browser):</h3>
|
|
19
|
+
<el-radio-group v-model="activeResource" size="small">
|
|
20
|
+
<el-radio-button :class="className(pmrPath.id)" v-for="pmrPath in pmrPaths" v-bind:key="pmrPath.id" :label="pmrPath.label" :value="pmrPath.id" />
|
|
21
|
+
</el-radio-group>
|
|
22
|
+
</div>
|
|
13
23
|
<div ref="dropArea" class="drop-area" @dragenter.prevent="onDragEnter" @dragover.prevent @drop.prevent="onDrop" @dragleave.prevent="onDragLeave">
|
|
14
24
|
You can drag and drop a COMBINE archive here.
|
|
15
25
|
</div>
|
|
@@ -25,20 +35,20 @@
|
|
|
25
35
|
</el-dialog>
|
|
26
36
|
</div>
|
|
27
37
|
<hr />
|
|
28
|
-
<div v-for="
|
|
29
|
-
<div v-if="
|
|
30
|
-
<div v-if="typeof
|
|
38
|
+
<div v-for="resource in resources()" v-bind:key="resource.id">
|
|
39
|
+
<div v-if="isResourceInitialised(resource.id)" v-show="resource.id === activeResource">
|
|
40
|
+
<div v-if="typeof resource.id === 'number'">
|
|
31
41
|
<span>
|
|
32
|
-
<strong>Dataset <a :href="datasetUrl(
|
|
42
|
+
<strong>Dataset <a :href="datasetUrl(resource.id)" target="_blank">{{ resource.id }}</a>:</strong> {{ resource.description }}
|
|
33
43
|
</span>
|
|
34
44
|
<hr />
|
|
35
45
|
</div>
|
|
36
|
-
<SimulationVuer :apiLocation="apiLocation" :id="
|
|
46
|
+
<SimulationVuer :apiLocation="apiLocation" :id="resource.id" style="height: 640px;" />
|
|
37
47
|
</div>
|
|
38
48
|
</div>
|
|
39
|
-
<div v-if="
|
|
49
|
+
<div v-if="activeResource === -1">
|
|
40
50
|
<div v-for="combineArchive in combineArchives" v-bind:key="combineArchive">
|
|
41
|
-
<SimulationVuer :apiLocation="apiLocation" :
|
|
51
|
+
<SimulationVuer :apiLocation="apiLocation" :id="combineArchive" style="height: 640px;" />
|
|
42
52
|
</div>
|
|
43
53
|
</div>
|
|
44
54
|
<hr />
|
|
@@ -62,46 +72,58 @@ export default {
|
|
|
62
72
|
dropAreaCounter: 0,
|
|
63
73
|
dragAndDropWarningVisible: false,
|
|
64
74
|
combineArchives: [],
|
|
65
|
-
|
|
66
|
-
{ id: 0, label: "
|
|
75
|
+
datasetIds: [
|
|
76
|
+
{ id: 0, label: "Invalid", description: "Non-simulation dataset" },
|
|
67
77
|
{ id: 135, label: "135", description: "Computational analysis of the human sinus node action potential - Model development and effects of mutations" },
|
|
68
78
|
{ id: 157, label: "157", description: "Fabbri-based composite SAN model" },
|
|
69
79
|
{ id: 308, label: "308", description: "Kember Cardiac Nerve Model" },
|
|
70
80
|
{ id: 318, label: "318", description: "Multi-scale rabbit cardiac electrophysiology models" },
|
|
71
81
|
{ id: 320, label: "320", description: "Multi-scale human cardiac electrophysiology models" },
|
|
72
82
|
],
|
|
73
|
-
|
|
83
|
+
datasetUrls: [
|
|
84
|
+
{ id: "https://raw.githubusercontent.com/opencor/webapp/refs/heads/main/tests/models/ui/invalid.omex", label: "Invalid", description: "COMBINE archive" },
|
|
85
|
+
{ id: "https://raw.githubusercontent.com/opencor/webapp/refs/heads/main/tests/models/ui/135.omex", label: "135", description: "COMBINE archive" },
|
|
86
|
+
{ id: "https://raw.githubusercontent.com/opencor/webapp/refs/heads/main/tests/models/ui/157.omex", label: "157", description: "COMBINE archive" },
|
|
87
|
+
{ id: "https://raw.githubusercontent.com/opencor/webapp/refs/heads/main/tests/models/ui/lorenz.omex", label: "Lorenz", description: "COMBINE archive" },
|
|
88
|
+
{ id: "https://raw.githubusercontent.com/opencor/webapp/refs/heads/main/tests/models/ui/tt04.omex", label: "TT04", description: "COMBINE archive" },
|
|
89
|
+
{ id: "https://raw.githubusercontent.com/opencor/webapp/refs/heads/main/tests/models/ui/cvs.omex", label: "CVS", description: "COMBINE archive" },
|
|
90
|
+
],
|
|
91
|
+
pmrPaths: [
|
|
92
|
+
{ id: "workspace/b7c/rawfile/e0ae8d2d56aaaa091e23e1ee7e84cacbda1dfb6b/invalid.omex", label: "Invalid", description: "COMBINE archive from PMR" },
|
|
74
93
|
{ id: "workspace/b7c/rawfile/e0ae8d2d56aaaa091e23e1ee7e84cacbda1dfb6b/135.omex", label: "135", description: "COMBINE archive from PMR" },
|
|
75
94
|
{ id: "workspace/b7c/rawfile/e0ae8d2d56aaaa091e23e1ee7e84cacbda1dfb6b/157.omex", label: "157", description: "COMBINE archive from PMR" },
|
|
76
95
|
{ id: "workspace/b7c/rawfile/e0ae8d2d56aaaa091e23e1ee7e84cacbda1dfb6b/lorenz.omex", label: "Lorenz", description: "COMBINE archive from PMR" },
|
|
77
96
|
{ id: "workspace/b7c/rawfile/e0ae8d2d56aaaa091e23e1ee7e84cacbda1dfb6b/tt04.omex", label: "TT04", description: "COMBINE archive from PMR" },
|
|
78
|
-
{ id: "workspace/b7c/rawfile/e0ae8d2d56aaaa091e23e1ee7e84cacbda1dfb6b/Gee_whiz_Exported.omex", label: "GeeWhiz", description: "COMBINE archive from PMR" },
|
|
79
97
|
{ id: "workspace/b7c/rawfile/e0ae8d2d56aaaa091e23e1ee7e84cacbda1dfb6b/cvs.omex", label: "CVS", description: "COMBINE archive from PMR" },
|
|
80
98
|
],
|
|
81
|
-
|
|
82
|
-
|
|
99
|
+
activeResource: 0,
|
|
100
|
+
initialisedResources: [],
|
|
83
101
|
};
|
|
84
102
|
},
|
|
85
103
|
methods: {
|
|
86
104
|
className(id) {
|
|
87
|
-
return ((
|
|
105
|
+
return ( ((this.datasetIds.length !== 0) && (id === this.datasetIds[0].id))
|
|
106
|
+
|| ((this.datasetUrls.length !== 0) && (id === this.datasetUrls[0].id))
|
|
107
|
+
|| ((this.pmrPaths.length !== 0) && (id === this.pmrPaths[0].id))) ?
|
|
108
|
+
"first-resource" :
|
|
109
|
+
"not-first-resource";
|
|
88
110
|
},
|
|
89
|
-
|
|
90
|
-
return this.
|
|
111
|
+
resources() {
|
|
112
|
+
return this.datasetIds.concat(this.datasetUrls).concat(this.pmrPaths);
|
|
91
113
|
},
|
|
92
114
|
datasetUrl(id) {
|
|
93
115
|
return `https://sparc.science/datasets/${id}?type=dataset`;
|
|
94
116
|
},
|
|
95
|
-
|
|
96
|
-
if (this.
|
|
117
|
+
isResourceInitialised(resource) {
|
|
118
|
+
if (this.initialisedResources.includes(resource)) {
|
|
97
119
|
return true;
|
|
98
120
|
}
|
|
99
121
|
|
|
100
|
-
if (this.
|
|
101
|
-
this.
|
|
122
|
+
if (this.activeResource === resource) {
|
|
123
|
+
this.initialisedResources.push(resource);
|
|
102
124
|
}
|
|
103
125
|
|
|
104
|
-
return this.
|
|
126
|
+
return this.initialisedResources.includes(resource);
|
|
105
127
|
},
|
|
106
128
|
onDragEnter() {
|
|
107
129
|
this.dropAreaCounter += 1;
|
|
@@ -123,7 +145,7 @@ export default {
|
|
|
123
145
|
files[0]
|
|
124
146
|
.arrayBuffer()
|
|
125
147
|
.then((arrayBuffer) => {
|
|
126
|
-
this.
|
|
148
|
+
this.activeResource = -1;
|
|
127
149
|
this.combineArchives = [new Uint8Array(arrayBuffer)];
|
|
128
150
|
})
|
|
129
151
|
}
|
|
@@ -181,10 +203,14 @@ export default {
|
|
|
181
203
|
color: #8300bf;
|
|
182
204
|
}
|
|
183
205
|
|
|
184
|
-
.first-
|
|
206
|
+
.first-resource>.el-radio-button__inner {
|
|
185
207
|
border-left: 1px solid #8300bf !important;
|
|
186
208
|
}
|
|
187
209
|
|
|
210
|
+
.not-first-resource>.el-radio-button__inner {
|
|
211
|
+
border-left: 0 !important;
|
|
212
|
+
}
|
|
213
|
+
|
|
188
214
|
.el-radio-button__original-radio:checked+.el-radio-button__inner {
|
|
189
215
|
background-color: #8300bf !important;
|
|
190
216
|
border-color: #8300bf !important;
|
|
@@ -18,17 +18,17 @@
|
|
|
18
18
|
:stepValue="input.stepValue"
|
|
19
19
|
/>
|
|
20
20
|
</div>
|
|
21
|
-
<div class="primary-button">
|
|
22
|
-
<el-button type="primary" size="small" @click="startSimulation()"
|
|
21
|
+
<div class="primary-button" v-if="!libopencorSet">
|
|
22
|
+
<el-button type="primary" size="small" @click="startSimulation()">Run Simulation</el-button>
|
|
23
23
|
</div>
|
|
24
24
|
<div class="secondary-button" v-if="uuid">
|
|
25
25
|
<el-button size="small" @click="runOnOsparc()">Run on oSPARC</el-button>
|
|
26
26
|
</div>
|
|
27
|
-
<div class="secondary-button">
|
|
28
|
-
<el-button size="small" @click="viewDataset()"
|
|
27
|
+
<div class="secondary-button" v-if="!libopencorSet">
|
|
28
|
+
<el-button size="small" @click="viewDataset()">View Dataset</el-button>
|
|
29
29
|
</div>
|
|
30
|
-
<div class="secondary-button">
|
|
31
|
-
<el-button size="small" @click="viewWorkspace()"
|
|
30
|
+
<div class="secondary-button" v-if="libopencorSet && idType === 'pmr_path'">
|
|
31
|
+
<el-button size="small" @click="viewWorkspace()">View Workspace</el-button>
|
|
32
32
|
</div>
|
|
33
33
|
<p class="default note" v-if="uuid">Additional parameters are available on oSPARC</p>
|
|
34
34
|
</div>
|
|
@@ -66,6 +66,13 @@ const PMR_URL = "https://models.physiomeproject.org/";
|
|
|
66
66
|
|
|
67
67
|
const math = create(all, {});
|
|
68
68
|
|
|
69
|
+
const IdType = Object.freeze({
|
|
70
|
+
DATASET_ID: 'dataset_id',
|
|
71
|
+
DATASET_URL: 'dataset_url',
|
|
72
|
+
PMR_PATH: 'pmr_path',
|
|
73
|
+
RAW_COMBINE_ARCHIVE: 'raw_combine_archive',
|
|
74
|
+
});
|
|
75
|
+
|
|
69
76
|
/**
|
|
70
77
|
* SimulationVuer
|
|
71
78
|
*/
|
|
@@ -89,27 +96,35 @@ export default {
|
|
|
89
96
|
type: String,
|
|
90
97
|
},
|
|
91
98
|
/**
|
|
92
|
-
* The ID
|
|
93
|
-
*
|
|
99
|
+
* The ID for this simulation, i.e. either
|
|
100
|
+
* - the ID (as a number) of a SPARC dataset,
|
|
101
|
+
* - the URL (as a string) of a COMBINE archive located in a SPARC dataset,
|
|
102
|
+
* - the path (as a string) to a COMBINE archive located on PMR, or
|
|
103
|
+
* - a raw COMBINE archive (as a Uint8Array).
|
|
94
104
|
*/
|
|
95
105
|
id: {
|
|
96
|
-
required:
|
|
97
|
-
type: [Number, String],
|
|
98
|
-
default: 0,
|
|
99
|
-
},
|
|
100
|
-
/**
|
|
101
|
-
* A COMBINE archive that was passed directly.
|
|
102
|
-
*/
|
|
103
|
-
combineArchive: {
|
|
104
|
-
required: false,
|
|
105
|
-
type: Uint8Array,
|
|
106
|
-
default: undefined,
|
|
106
|
+
required: true,
|
|
107
|
+
type: [Number, String, Uint8Array],
|
|
107
108
|
},
|
|
108
109
|
},
|
|
109
110
|
data: function () {
|
|
111
|
+
// Determine the ID's type.
|
|
112
|
+
|
|
113
|
+
let idType;
|
|
114
|
+
|
|
115
|
+
if (typeof this.id === "number") {
|
|
116
|
+
idType = IdType.DATASET_ID;
|
|
117
|
+
} else if (this.id instanceof Uint8Array) {
|
|
118
|
+
idType = IdType.RAW_COMBINE_ARCHIVE;
|
|
119
|
+
} else if (this.id.startsWith("https://")) {
|
|
120
|
+
idType = IdType.DATASET_URL;
|
|
121
|
+
} else {
|
|
122
|
+
idType = IdType.PMR_PATH;
|
|
123
|
+
}
|
|
124
|
+
|
|
110
125
|
// Retrieve some information about the dataset.
|
|
111
126
|
|
|
112
|
-
if (
|
|
127
|
+
if (idType === IdType.DATASET_ID) {
|
|
113
128
|
const xmlhttp = new XMLHttpRequest();
|
|
114
129
|
|
|
115
130
|
xmlhttp.open("GET", this.apiLocation + "/sim/dataset/" + this.id);
|
|
@@ -131,6 +146,7 @@ export default {
|
|
|
131
146
|
fileManager: undefined,
|
|
132
147
|
hasFinalisedUi: false,
|
|
133
148
|
hasValidSimulationUiInfo: false,
|
|
149
|
+
idType: idType,
|
|
134
150
|
instance: undefined,
|
|
135
151
|
isMounted: false,
|
|
136
152
|
isSimulationValid: true,
|
|
@@ -657,7 +673,7 @@ export default {
|
|
|
657
673
|
created: function () {
|
|
658
674
|
// Try to retrieve the UI information.
|
|
659
675
|
|
|
660
|
-
if (this.
|
|
676
|
+
if (this.idType === IdType.DATASET_ID) {
|
|
661
677
|
this.userMessage = "Retrieving UI information...";
|
|
662
678
|
this.showUserMessage = true;
|
|
663
679
|
|
|
@@ -682,7 +698,33 @@ export default {
|
|
|
682
698
|
};
|
|
683
699
|
xmlhttp.send();
|
|
684
700
|
});
|
|
685
|
-
} else if (this.
|
|
701
|
+
} else if (this.idType === IdType.DATASET_URL) {
|
|
702
|
+
this.userMessage = "Retrieving COMBINE archive...";
|
|
703
|
+
this.showUserMessage = true;
|
|
704
|
+
|
|
705
|
+
// Retrieve the COMBINE archive, extract the simulation UI JSON file from
|
|
706
|
+
// it and then build the simulation UI.
|
|
707
|
+
|
|
708
|
+
this.$nextTick(() => {
|
|
709
|
+
const xmlhttp = new XMLHttpRequest();
|
|
710
|
+
|
|
711
|
+
xmlhttp.open("GET", this.id);
|
|
712
|
+
xmlhttp.responseType = "arraybuffer";
|
|
713
|
+
xmlhttp.onreadystatechange = () => {
|
|
714
|
+
if (xmlhttp.readyState === 4) {
|
|
715
|
+
if (xmlhttp.status === 200) {
|
|
716
|
+
libOpenCOR().then((libopencor) => {
|
|
717
|
+
this.extractAndBuildSimulationUi(libopencor, new Uint8Array(xmlhttp.response));
|
|
718
|
+
});
|
|
719
|
+
} else {
|
|
720
|
+
this.errorMessage = "the COMBINE archive could not be retrieved";
|
|
721
|
+
this.showUserMessage = false;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
};
|
|
725
|
+
xmlhttp.send();
|
|
726
|
+
});
|
|
727
|
+
} else if (this.idType === IdType.PMR_PATH) {
|
|
686
728
|
this.userMessage = "Retrieving COMBINE archive from PMR...";
|
|
687
729
|
this.showUserMessage = true;
|
|
688
730
|
|
|
@@ -701,14 +743,14 @@ export default {
|
|
|
701
743
|
this.extractAndBuildSimulationUi(libopencor, Uint8Array.from(atob(xmlhttp.response), (c) => c.charCodeAt(0)));
|
|
702
744
|
});
|
|
703
745
|
} else {
|
|
704
|
-
this.errorMessage = "the COMBINE archive chould not be retrieved";
|
|
746
|
+
this.errorMessage = "the COMBINE archive chould not be retrieved from PMR";
|
|
705
747
|
this.showUserMessage = false;
|
|
706
748
|
}
|
|
707
749
|
}
|
|
708
750
|
};
|
|
709
751
|
xmlhttp.send(JSON.stringify({ path: this.id }));
|
|
710
752
|
});
|
|
711
|
-
} else
|
|
753
|
+
} else {
|
|
712
754
|
// Extract the simulation UI JSON file from the COMBINE archive and build
|
|
713
755
|
// the simulation UI.
|
|
714
756
|
|
|
@@ -717,11 +759,9 @@ export default {
|
|
|
717
759
|
|
|
718
760
|
this.$nextTick(() => {
|
|
719
761
|
libOpenCOR().then((libopencor) => {
|
|
720
|
-
this.extractAndBuildSimulationUi(libopencor, this.
|
|
762
|
+
this.extractAndBuildSimulationUi(libopencor, this.id);
|
|
721
763
|
});
|
|
722
764
|
});
|
|
723
|
-
} else {
|
|
724
|
-
this.errorMessage = "an non-simulation dataset was provided";
|
|
725
765
|
}
|
|
726
766
|
},
|
|
727
767
|
mounted: function () {
|