@abi-software/simulationvuer 2.0.20 → 3.0.0

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abi-software/simulationvuer",
3
- "version": "2.0.20",
3
+ "version": "3.0.0",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "vite serve --host --force",
@@ -18,9 +18,9 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "@abi-software/plotvuer": "1.0.7",
21
+ "@opencor/opencor": "^0.20251112.0",
21
22
  "element-plus": "2.8.4",
22
23
  "jsonschema": "^1.4.0",
23
- "mathjs": "^13.0.2",
24
24
  "unplugin-vue-components": "^0.26.0",
25
25
  "vue": "^3.4.21"
26
26
  },
package/src/App.vue CHANGED
@@ -174,7 +174,6 @@ export default {
174
174
  top: 8px;
175
175
  right: 8px;
176
176
  width: 192px;
177
- height: 48px;
178
177
  border: 2px dashed #8300bf;
179
178
  background-color: #f9f2fc;
180
179
  color: #8300bf;
@@ -227,6 +226,7 @@ a {
227
226
 
228
227
  div.app {
229
228
  text-align: center;
229
+ margin-bottom: 8px;
230
230
  }
231
231
 
232
232
  h3 {
@@ -1,53 +1,58 @@
1
1
  <template>
2
2
  <div class="simulation-vuer" v-loading="showUserMessage" :element-loading-text="userMessage">
3
- <p v-if="!hasValidSimulationUiInfo && !showUserMessage" class="default error"><span class="error">Error:</span> {{ errorMessage }}.</p>
4
- <div class="main" v-if="hasValidSimulationUiInfo">
5
- <div class="main-left" :class="{'with-buttons': !libopencorSet || uuid}">
6
- <p class="default name" v-if="!libopencorSet">{{ name }}</p>
7
- <el-divider v-if="!libopencorSet"></el-divider>
8
- <p class="default input-parameters">Input parameters</p>
9
- <div class="input scrollbar">
10
- <SimulationVuerInput v-for="(input, index) in simulationUiInfo.input"
11
- ref="simInput"
12
- :defaultValue="input.defaultValue"
13
- :key="`input-${index}`"
14
- :name="input.name"
15
- :maximumValue="input.maximumValue"
16
- :minimumValue="input.minimumValue"
17
- :possibleValues="input.possibleValues"
18
- :stepValue="input.stepValue"
19
- />
20
- </div>
21
- <div class="buttons-container">
22
- <div class="primary-button" v-if="!libopencorSet">
23
- <el-button type="primary" size="small" @click="startSimulation()">Run Simulation</el-button>
24
- </div>
25
- <div class="secondary-button" v-if="uuid">
26
- <el-button size="small" @click="runOnOsparc()">Run on oSPARC</el-button>
3
+ <div class="container" v-if="opencorOmexFile === null">
4
+ <p v-if="!hasValidSimulationUiInfo && !showUserMessage" class="default error"><span class="error">Error:</span> {{ errorMessage }}.</p>
5
+ <div class="main" v-if="hasValidSimulationUiInfo">
6
+ <div class="main-left" :class="{'with-buttons': !libopencorSet || uuid}">
7
+ <p class="default name" v-if="!libopencorSet">{{ name }}</p>
8
+ <el-divider v-if="!libopencorSet"></el-divider>
9
+ <p class="default input-parameters">Input parameters</p>
10
+ <div class="input scrollbar">
11
+ <SimulationVuerInput v-for="(input, index) in simulationUiInfo.input"
12
+ ref="simInput"
13
+ :defaultValue="input.defaultValue"
14
+ :key="`input-${index}`"
15
+ :name="input.name"
16
+ :maximumValue="input.maximumValue"
17
+ :minimumValue="input.minimumValue"
18
+ :possibleValues="input.possibleValues"
19
+ :stepValue="input.stepValue"
20
+ />
27
21
  </div>
28
- <div class="secondary-button" v-if="!libopencorSet">
29
- <el-button size="small" @click="viewDataset()">View Dataset</el-button>
22
+ <div class="buttons-container">
23
+ <div class="primary-button" v-if="!libopencorSet">
24
+ <el-button type="primary" size="small" @click="startSimulation()">Run Simulation</el-button>
25
+ </div>
26
+ <div class="secondary-button" v-if="uuid">
27
+ <el-button size="small" @click="runOnOsparc()">Run on oSPARC</el-button>
28
+ </div>
29
+ <div class="secondary-button" v-if="!libopencorSet">
30
+ <el-button size="small" @click="viewDataset()">View Dataset</el-button>
31
+ </div>
32
+ <div class="secondary-button" v-if="libopencorSet && idType === 'pmr_path'">
33
+ <el-button size="small" @click="viewWorkspace()">View Workspace</el-button>
34
+ </div>
35
+ <p class="default note" v-if="uuid">Additional parameters are available on oSPARC</p>
30
36
  </div>
31
- <div class="secondary-button" v-if="libopencorSet && idType === 'pmr_path'">
32
- <el-button size="small" @click="viewWorkspace()">View Workspace</el-button>
33
- </div>
34
- <p class="default note" v-if="uuid">Additional parameters are available on oSPARC</p>
35
37
  </div>
36
- </div>
37
- <div class="main-right" ref="output" v-show="isSimulationValid">
38
- <PlotVuer v-for="(_outputPlot, index) in simulationUiInfo.output.plots"
39
- :key="`output-${index}`"
40
- :metadata="plotMetadata(index)"
41
- :data-source="{ data: simulationResults[index] }"
42
- :plotLayout="layout[index]"
43
- :plotType="'plotly-only'"
44
- :selectorUi="false"
45
- />
46
- </div>
47
- <div class="main-right" v-show="!isSimulationValid">
48
- <p class="default error"><span class="error">Error:</span> <span v-html="errorMessage"></span>.</p>
38
+ <div class="main-right" ref="output" v-show="isSimulationValid">
39
+ <PlotVuer v-for="(_outputPlot, index) in simulationUiInfo.output.plots"
40
+ :key="`output-${index}`"
41
+ :metadata="plotMetadata(index)"
42
+ :data-source="{ data: simulationResults[index] }"
43
+ :plotLayout="layout[index]"
44
+ :plotType="'plotly-only'"
45
+ :selectorUi="false"
46
+ />
47
+ </div>
48
+ <div class="main-right" v-show="!isSimulationValid">
49
+ <p class="default error"><span class="error">Error:</span> <span v-html="errorMessage"></span>.</p>
50
+ </div>
49
51
  </div>
50
52
  </div>
53
+ <div v-else class="opencor">
54
+ <OpenCOR :omex="opencorOmexFile" theme="light" />
55
+ </div>
51
56
  </div>
52
57
  </template>
53
58
 
@@ -61,9 +66,9 @@ import { validJson } from "./json.js";
61
66
  import libOpenCOR from "https://mapcore-demo.org/current/opencor-wasm/0.0.3/libopencor.js";
62
67
  import { markRaw } from "vue";
63
68
  import { create, all } from "mathjs";
69
+ import OpenCOR from '@opencor/opencor';
70
+ import '@opencor/opencor/style.css';
64
71
 
65
- const LIBOPENCOR_SOLVER = "libOpenCOR";
66
- const OSPARC_SOLVER = "oSPARC";
67
72
  const PMR_URL = "https://models.physiomeproject.org/";
68
73
 
69
74
  const math = create(all, {});
@@ -79,8 +84,6 @@ const IdType = Object.freeze({
79
84
  * SimulationVuer
80
85
  */
81
86
  export default {
82
- LIBOPENCOR_SOLVER: LIBOPENCOR_SOLVER,
83
- OSPARC_SOLVER: OSPARC_SOLVER,
84
87
  name: "SimulationVuer",
85
88
  components: {
86
89
  PlotVuer,
@@ -88,6 +91,7 @@ export default {
88
91
  ElButton,
89
92
  ElDivider,
90
93
  ElLoading,
94
+ OpenCOR,
91
95
  },
92
96
  props: {
93
97
  /**
@@ -158,6 +162,7 @@ export default {
158
162
  model: undefined,
159
163
  name: null,
160
164
  opencorBasedSimulation: true,
165
+ opencorOmexFile: null,
161
166
  output: undefined,
162
167
  perfectScollbarOptions: {
163
168
  suppressScrollX: true,
@@ -741,57 +746,9 @@ export default {
741
746
  xmlhttp.send();
742
747
  });
743
748
  } else if (this.idType === IdType.DATASET_URL) {
744
- this.userMessage = "Retrieving COMBINE archive...";
745
- this.showUserMessage = true;
746
-
747
- // Retrieve the COMBINE archive, extract the simulation UI JSON file from
748
- // it and then build the simulation UI.
749
-
750
- this.$nextTick(() => {
751
- const xmlhttp = new XMLHttpRequest();
752
-
753
- xmlhttp.open("GET", this.id);
754
- xmlhttp.responseType = "arraybuffer";
755
- xmlhttp.onreadystatechange = () => {
756
- if (xmlhttp.readyState === 4) {
757
- if (xmlhttp.status === 200) {
758
- libOpenCOR().then((libopencor) => {
759
- this.extractAndBuildSimulationUi(libopencor, new Uint8Array(xmlhttp.response));
760
- });
761
- } else {
762
- this.errorMessage = "the COMBINE archive could not be retrieved";
763
- this.showUserMessage = false;
764
- }
765
- }
766
- };
767
- xmlhttp.send();
768
- });
749
+ this.opencorOmexFile = this.id;
769
750
  } else if (this.idType === IdType.PMR_PATH) {
770
- this.userMessage = "Retrieving COMBINE archive from PMR...";
771
- this.showUserMessage = true;
772
-
773
- // Retrieve the COMBINE archive, extract the simulation UI JSON file from
774
- // it and then build the simulation UI.
775
-
776
- this.$nextTick(() => {
777
- const xmlhttp = new XMLHttpRequest();
778
-
779
- xmlhttp.open("POST", this.apiLocation + "/pmr_file");
780
- xmlhttp.setRequestHeader("Content-type", "application/json");
781
- xmlhttp.onreadystatechange = () => {
782
- if (xmlhttp.readyState === 4) {
783
- if (xmlhttp.status === 200) {
784
- libOpenCOR().then((libopencor) => {
785
- this.extractAndBuildSimulationUi(libopencor, Uint8Array.from(atob(xmlhttp.response), (c) => c.charCodeAt(0)));
786
- });
787
- } else {
788
- this.errorMessage = "the COMBINE archive chould not be retrieved from PMR";
789
- this.showUserMessage = false;
790
- }
791
- }
792
- };
793
- xmlhttp.send(JSON.stringify({ path: this.id }));
794
- });
751
+ this.opencorOmexFile = PMR_URL + this.id;
795
752
  } else {
796
753
  // Extract the simulation UI JSON file from the COMBINE archive and build
797
754
  // the simulation UI.
@@ -848,6 +805,22 @@ export default {
848
805
  }
849
806
  }
850
807
 
808
+ :deep(.p-floatlabel:has(input:focus)) label, :deep(.p-floatlabel:has(input:-webkit-autofill)) label, :deep(.p-floatlabel:has(textarea:focus)) label, :deep(.p-floatlabel:has(.p-inputwrapper-focus)) label {
809
+ color: #8300BF;
810
+ }
811
+
812
+ :deep(.p-inputtext:enabled:focus) {
813
+ border-color: #8300BF;
814
+ }
815
+
816
+ :deep(.p-select:not(.p-disabled).p-focus) {
817
+ border-color: #8300BF;
818
+ }
819
+
820
+ :deep(.p-slider-range) {
821
+ background-color: #8300BF;
822
+ }
823
+
851
824
  div.input {
852
825
  display: flex;
853
826
  flex-direction: column;
@@ -866,6 +839,10 @@ div.input {
866
839
  flex-shrink: 0;
867
840
  }
868
841
 
842
+ div.container {
843
+ height: 100%;
844
+ }
845
+
869
846
  div.main {
870
847
  display: grid;
871
848
  --mainLeftWidth: 243px;
@@ -929,6 +906,10 @@ div.main-right.x9 > .plotvuer_parent {
929
906
  height: 0;
930
907
  }
931
908
 
909
+ div.opencor {
910
+ height: 100%;
911
+ }
912
+
932
913
  div.primary-button,
933
914
  div.secondary-button {
934
915
  display: flex;
@@ -1035,3 +1016,21 @@ span.error {
1035
1016
  }
1036
1017
  }
1037
1018
  </style>
1019
+
1020
+ <style>
1021
+ /* Note: not sure why, but the following rules need to be global!? */
1022
+
1023
+ .p-select-option:not(.p-select-option-selected):not(.p-disabled).p-focus {
1024
+ background: #F5F7FA;
1025
+ }
1026
+
1027
+ .p-select-option.p-select-option-selected.p-focus {
1028
+ background: #F5F7FA;
1029
+ color: #8300BF;
1030
+ }
1031
+
1032
+ .p-select-option.p-select-option-selected {
1033
+ background: white;
1034
+ color: #8300BF;
1035
+ }
1036
+ </style>