@abi-software/simulationvuer 0.5.0 → 0.5.3
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/dist/simulationvuer.common.js +462 -662
- package/dist/simulationvuer.common.js.map +1 -1
- package/dist/simulationvuer.css +1 -1
- package/dist/simulationvuer.umd.js +462 -662
- package/dist/simulationvuer.umd.js.map +1 -1
- package/dist/simulationvuer.umd.min.js +1 -1
- package/dist/simulationvuer.umd.min.js.map +1 -1
- package/package.json +2 -2
- package/src/.DS_Store +0 -0
- package/src/App.vue +10 -8
- package/src/components/SimulationVuer.vue +85 -141
- package/src/components/SimulationVuerInput.vue +150 -0
- package/src/components/common.js +7 -7
- package/src/components/json.js +8 -0
- package/src/components/ui.js +37 -230
- package/vue.config.js +1 -2
- package/src/components/configuration.js +0 -139
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="simulation-vuer" v-loading="
|
|
3
|
-
<p v-if="!
|
|
4
|
-
<div class="main" v-if="
|
|
2
|
+
<div class="simulation-vuer" v-loading="showUserMessage" :element-loading-text="userMessage">
|
|
3
|
+
<p v-if="!hasValidSimulationUiInformation && !showUserMessage" class="default error"><span class="error">Error:</span> an unknown or invalid model was provided.</p>
|
|
4
|
+
<div class="main" v-if="hasValidSimulationUiInformation">
|
|
5
5
|
<div class="main-left">
|
|
6
6
|
<p class="default title">{{title}}</p>
|
|
7
7
|
<el-divider></el-divider>
|
|
8
8
|
<p class="default input-parameters">Input parameters</p>
|
|
9
|
+
<div>
|
|
10
|
+
<SimulationVuerInput v-for="(input, index) in simulationUiInformation.input" :defaultValue="input.defaultValue" :firstScalarInput="firstScalarInput[index]" :key="`input-${index}`" :name="input.name" :maximumValue="input.maximumValue" :minimumValue="input.minimumValue" :possibleValues="input.possibleValues" />
|
|
11
|
+
</div>
|
|
9
12
|
<div ref="input" />
|
|
10
13
|
<div class="primary-button">
|
|
11
14
|
<el-button type="primary" size="mini" @click="runSimulation()">Run simulation</el-button>
|
|
@@ -18,10 +21,10 @@
|
|
|
18
21
|
</div>
|
|
19
22
|
<p class="default note">Additional parameters are available on oSPARC</p>
|
|
20
23
|
</div>
|
|
21
|
-
<div class="main-right" ref="output" v-show="
|
|
22
|
-
<PlotVuer v-for="(outputPlot, index) in
|
|
24
|
+
<div class="main-right" ref="output" v-show="isSimulationValid">
|
|
25
|
+
<PlotVuer v-for="(outputPlot, index) in simulationUiInformation.output.plots" :key="`output-${index}`" :layout-input="layout[index]" :dataInput="simulationData[index]" :plotType="'plotly-only'" />
|
|
23
26
|
</div>
|
|
24
|
-
<div class="main-right" v-show="!
|
|
27
|
+
<div class="main-right" v-show="!isSimulationValid">
|
|
25
28
|
<p class="default error"><span class="error">Error:</span> <span v-html="errorMessage"></span>.</p>
|
|
26
29
|
</div>
|
|
27
30
|
</div>
|
|
@@ -32,28 +35,21 @@
|
|
|
32
35
|
import Vue from "vue";
|
|
33
36
|
import { PlotVuer } from "@abi-software/plotvuer";
|
|
34
37
|
import "@abi-software/plotvuer/dist/plotvuer.css";
|
|
35
|
-
import
|
|
36
|
-
import {
|
|
38
|
+
import SimulationVuerInput from "./SimulationVuerInput.vue";
|
|
39
|
+
import { Button, Divider, Loading } from "element-ui";
|
|
37
40
|
import { evaluateValue, evaluateSimulationValue } from "./common.js";
|
|
38
41
|
import { validJson } from "./json.js";
|
|
39
|
-
import
|
|
40
|
-
import { prepareForUi } from "./ui.js";
|
|
42
|
+
import { initialiseUi, finaliseUi } from "./ui.js";
|
|
41
43
|
|
|
42
|
-
Vue.use(Aside);
|
|
43
44
|
Vue.use(Button);
|
|
44
|
-
Vue.use(Container);
|
|
45
45
|
Vue.use(Divider);
|
|
46
|
-
Vue.use(InputNumber);
|
|
47
46
|
Vue.use(Loading);
|
|
48
|
-
Vue.use(Main);
|
|
49
|
-
Vue.use(Option);
|
|
50
|
-
Vue.use(Select);
|
|
51
|
-
Vue.use(Slider);
|
|
52
47
|
|
|
53
48
|
export default {
|
|
54
49
|
name: "SimulationVuer",
|
|
55
50
|
components: {
|
|
56
51
|
PlotVuer,
|
|
52
|
+
SimulationVuerInput,
|
|
57
53
|
},
|
|
58
54
|
props: {
|
|
59
55
|
apiLocation: {
|
|
@@ -67,15 +63,18 @@ export default {
|
|
|
67
63
|
},
|
|
68
64
|
data: function() {
|
|
69
65
|
return {
|
|
70
|
-
mode: 0, //---GRY--- TO BE DELETED!
|
|
71
|
-
json: {},
|
|
72
|
-
hasValidJson: true,
|
|
73
66
|
errorMessage: "",
|
|
67
|
+
firstScalarInput: [],
|
|
68
|
+
hasFinalisedUi: false,
|
|
69
|
+
hasValidSimulationUiInformation: false,
|
|
70
|
+
isMounted: false,
|
|
71
|
+
isSimulationValid: true,
|
|
74
72
|
layout: [],
|
|
73
|
+
showUserMessage: false,
|
|
75
74
|
simulationData: [],
|
|
76
75
|
simulationDataId: {},
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
simulationUiInformation: {},
|
|
77
|
+
userMessage: "",
|
|
79
78
|
title: (this.entry !== undefined)?this.entry.name:"",
|
|
80
79
|
ui: null,
|
|
81
80
|
};
|
|
@@ -88,41 +87,42 @@ export default {
|
|
|
88
87
|
window.open(this.entry.dataset, "_blank");
|
|
89
88
|
},
|
|
90
89
|
runSimulation() {
|
|
91
|
-
this.
|
|
90
|
+
this.userMessage = "Loading simulation results...";
|
|
91
|
+
this.showUserMessage = true;
|
|
92
92
|
|
|
93
93
|
let request = {
|
|
94
94
|
model_url: this.entry.resource,
|
|
95
95
|
json_config: {},
|
|
96
96
|
};
|
|
97
97
|
|
|
98
|
-
// Specify the ending point and point interval
|
|
99
|
-
//
|
|
98
|
+
// Specify the ending point and point interval, if we have some simulation
|
|
99
|
+
// data.
|
|
100
100
|
|
|
101
|
-
if (this.
|
|
101
|
+
if (this.simulationUiInformation.simulation !== undefined) {
|
|
102
102
|
request.json_config.simulation = {
|
|
103
|
-
"Ending point": this.
|
|
104
|
-
"Point interval": this.
|
|
103
|
+
"Ending point": this.simulationUiInformation.simulation.endingPoint,
|
|
104
|
+
"Point interval": this.simulationUiInformation.simulation.pointInterval,
|
|
105
105
|
};
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
// Specify the simulation parameters.
|
|
109
109
|
|
|
110
|
-
if (this.
|
|
110
|
+
if (this.simulationUiInformation.parameters != undefined) {
|
|
111
111
|
request.json_config.parameters = {};
|
|
112
112
|
|
|
113
|
-
this.
|
|
114
|
-
request.json_config.parameters[parameter.name] = evaluateValue(this
|
|
113
|
+
this.simulationUiInformation.parameters.forEach((parameter) => {
|
|
114
|
+
request.json_config.parameters[parameter.name] = evaluateValue(this, parameter.value);
|
|
115
115
|
});
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
// Specify what we want to retrieve.
|
|
119
119
|
|
|
120
|
-
if (this.
|
|
120
|
+
if (this.simulationUiInformation.output.data !== undefined) {
|
|
121
121
|
let index = -1;
|
|
122
122
|
|
|
123
123
|
request.json_config.output = [];
|
|
124
124
|
|
|
125
|
-
this.
|
|
125
|
+
this.simulationUiInformation.output.data.forEach((outputData) => {
|
|
126
126
|
request.json_config.output[++index] = outputData.name;
|
|
127
127
|
});
|
|
128
128
|
}
|
|
@@ -135,20 +135,20 @@ export default {
|
|
|
135
135
|
xmlhttp.setRequestHeader("Content-type", "application/json");
|
|
136
136
|
xmlhttp.onreadystatechange = () => {
|
|
137
137
|
if (xmlhttp.readyState === 4) {
|
|
138
|
-
this.
|
|
138
|
+
this.showUserMessage = false;
|
|
139
139
|
|
|
140
140
|
if (xmlhttp.status === 200) {
|
|
141
141
|
let response = JSON.parse(xmlhttp.responseText);
|
|
142
142
|
|
|
143
|
-
this.
|
|
143
|
+
this.isSimulationValid = response.status === "ok";
|
|
144
144
|
|
|
145
|
-
if (this.
|
|
145
|
+
if (this.isSimulationValid) {
|
|
146
146
|
// Retrieve and post-process the simulation data.
|
|
147
147
|
|
|
148
148
|
let index = -1;
|
|
149
149
|
let iMax = response.results[this.simulationDataId[Object.keys(this.simulationDataId)[0]]].length;
|
|
150
150
|
|
|
151
|
-
this.
|
|
151
|
+
this.simulationUiInformation.output.plots.forEach((outputPlot) => {
|
|
152
152
|
let xValue = [];
|
|
153
153
|
let yValue = [];
|
|
154
154
|
|
|
@@ -168,7 +168,7 @@ export default {
|
|
|
168
168
|
this.errorMessage = response.description;
|
|
169
169
|
}
|
|
170
170
|
} else {
|
|
171
|
-
this.
|
|
171
|
+
this.isSimulationValid = false;
|
|
172
172
|
|
|
173
173
|
this.errorMessage = xmlhttp.statusText.toLowerCase() + " (<a href='https://httpstatuses.com/" + xmlhttp.status + "/' target='_blank'>" + xmlhttp.status + "</a>)";
|
|
174
174
|
}
|
|
@@ -178,39 +178,58 @@ export default {
|
|
|
178
178
|
},
|
|
179
179
|
},
|
|
180
180
|
created: function() {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
if (this.entry.resource === "https://models.physiomeproject.org/workspace/486/rawfile/55879cbc485e2d4c41f3dc6d60424b849f94c4ee/HumanSAN_Fabbri_Fantini_Wilders_Severi_2017.cellml") {
|
|
188
|
-
this.mode = 0;
|
|
189
|
-
this.json = jsonForNormalModel();
|
|
190
|
-
} else if (this.entry.resource === "https://models.physiomeproject.org/workspace/698/rawfile/f3fc911063ac72ed44e84c0c5af28df41c25d452/fabbri_et_al_based_composite_SAN_model.sedml") {
|
|
191
|
-
this.mode = 1;
|
|
192
|
-
this.json = jsonForCompositeModel();
|
|
193
|
-
}
|
|
194
|
-
}
|
|
181
|
+
this.userMessage = "Retrieving UI information...";
|
|
182
|
+
this.showUserMessage = true;
|
|
183
|
+
|
|
184
|
+
// Retrieve the simulation UI file for the given dataset.
|
|
185
|
+
|
|
186
|
+
let xmlhttp = new XMLHttpRequest();
|
|
195
187
|
|
|
196
|
-
|
|
188
|
+
xmlhttp.open("GET", this.apiLocation + "/simulation_ui_file/" + this.entry.datasetId, true);
|
|
189
|
+
xmlhttp.setRequestHeader("Content-type", "application/json");
|
|
190
|
+
xmlhttp.onreadystatechange = () => {
|
|
191
|
+
if (xmlhttp.readyState === 4) {
|
|
192
|
+
// Keep track of the simulation UI information.
|
|
197
193
|
|
|
198
|
-
|
|
194
|
+
this.simulationUiInformation = JSON.parse(xmlhttp.responseText);
|
|
199
195
|
|
|
200
|
-
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
196
|
+
// Make sure that the simulation UI information is valid.
|
|
203
197
|
|
|
204
|
-
|
|
198
|
+
this.hasValidSimulationUiInformation = validJson(this.simulationUiInformation);
|
|
199
|
+
|
|
200
|
+
if (!this.hasValidSimulationUiInformation) {
|
|
201
|
+
this.showUserMessage = false;
|
|
202
|
+
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
205
|
|
|
206
|
-
|
|
206
|
+
// Initialise our UI.
|
|
207
|
+
|
|
208
|
+
initialiseUi(this);
|
|
209
|
+
|
|
210
|
+
// Finalise our UI.
|
|
211
|
+
// Note: we try both here and in the mounded() function since we have no
|
|
212
|
+
// idea how long it's going to take to retrieve the simulation UI
|
|
213
|
+
// information.
|
|
214
|
+
|
|
215
|
+
this.$nextTick(() => {
|
|
216
|
+
finaliseUi(this);
|
|
217
|
+
|
|
218
|
+
this.showUserMessage = false;
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
xmlhttp.send();
|
|
207
223
|
},
|
|
208
224
|
mounted: function() {
|
|
209
|
-
//
|
|
225
|
+
// Finalise our UI.
|
|
226
|
+
// Note: we try both here and in the created() function since we have no
|
|
227
|
+
// idea how long it's going to take to retrieve the simulation UI
|
|
228
|
+
// information.
|
|
229
|
+
|
|
230
|
+
this.isMounted = true;
|
|
210
231
|
|
|
211
|
-
|
|
212
|
-
this.ui = new Ui(this);
|
|
213
|
-
}
|
|
232
|
+
finaliseUi(this);
|
|
214
233
|
},
|
|
215
234
|
};
|
|
216
235
|
</script>
|
|
@@ -222,51 +241,9 @@ export default {
|
|
|
222
241
|
box-shadow: -3px 2px 4px #00000040;
|
|
223
242
|
}
|
|
224
243
|
>>> .el-divider {
|
|
225
|
-
margin: -8px 0 8px 0;
|
|
244
|
+
margin: -8px 0 8px 0 !important;
|
|
226
245
|
width: 191px;
|
|
227
246
|
}
|
|
228
|
-
>>> .el-input-number.scalar {
|
|
229
|
-
margin-top: -8px;
|
|
230
|
-
width: 0;
|
|
231
|
-
height: 0;
|
|
232
|
-
}
|
|
233
|
-
>>> .el-input-number.scalar .el-input {
|
|
234
|
-
width: 60px;
|
|
235
|
-
}
|
|
236
|
-
>>> .el-input-number.scalar .el-input__inner:focus {
|
|
237
|
-
border-color: #8300bf;
|
|
238
|
-
}
|
|
239
|
-
>>> .el-select.discrete {
|
|
240
|
-
margin-bottom: 16px;
|
|
241
|
-
}
|
|
242
|
-
>>> .el-slider {
|
|
243
|
-
width: 108px;
|
|
244
|
-
margin-top: -12px;
|
|
245
|
-
margin-left: 8px;
|
|
246
|
-
}
|
|
247
|
-
>>> .el-slider__bar {
|
|
248
|
-
background-color: #8300bf;
|
|
249
|
-
}
|
|
250
|
-
>>> .el-slider__button {
|
|
251
|
-
border-color: #8300bf;
|
|
252
|
-
}
|
|
253
|
-
.discrete {
|
|
254
|
-
margin-left: 8px;
|
|
255
|
-
}
|
|
256
|
-
.discrete >>> .el-input__inner {
|
|
257
|
-
font-family: Asap, sans-serif;
|
|
258
|
-
}
|
|
259
|
-
.discrete >>> .el-input__inner:focus,
|
|
260
|
-
.discrete >>> .el-input.is-focus .el-input__inner {
|
|
261
|
-
border-color: #8300bf;
|
|
262
|
-
}
|
|
263
|
-
.discrete-popper .el-select-dropdown__item {
|
|
264
|
-
font-family: Asap, sans-serif;
|
|
265
|
-
}
|
|
266
|
-
.discrete-popper .el-select-dropdown__item.selected {
|
|
267
|
-
font-weight: normal;
|
|
268
|
-
color: #8300bf;
|
|
269
|
-
}
|
|
270
247
|
div.main {
|
|
271
248
|
display: grid;
|
|
272
249
|
--mainLeftWidth: 224px;
|
|
@@ -309,10 +286,6 @@ div.main-right.x9 {
|
|
|
309
286
|
>>> div.main-right div.controls {
|
|
310
287
|
height: 0;
|
|
311
288
|
}
|
|
312
|
-
div.plot-vuer {
|
|
313
|
-
display: grid;
|
|
314
|
-
width: 100%;
|
|
315
|
-
}
|
|
316
289
|
div.primary-button,
|
|
317
290
|
div.secondary-button {
|
|
318
291
|
display: flex;
|
|
@@ -344,11 +317,6 @@ div.secondary-button .el-button:hover {
|
|
|
344
317
|
div.simulation-vuer {
|
|
345
318
|
height: 100%;
|
|
346
319
|
}
|
|
347
|
-
div.sliders-and-fields {
|
|
348
|
-
display: grid;
|
|
349
|
-
grid-template-columns: 132px auto;
|
|
350
|
-
width: 191px;
|
|
351
|
-
}
|
|
352
320
|
p.default {
|
|
353
321
|
font-family: Asap, sans-serif;
|
|
354
322
|
letter-spacing: 0;
|
|
@@ -358,12 +326,6 @@ p.default {
|
|
|
358
326
|
p.error {
|
|
359
327
|
margin-left: 16px;
|
|
360
328
|
}
|
|
361
|
-
p.first-scalar,
|
|
362
|
-
p.scalar {
|
|
363
|
-
grid-column-start: 1;
|
|
364
|
-
grid-column-end: 3;
|
|
365
|
-
margin-bottom: 8px;
|
|
366
|
-
}
|
|
367
329
|
p.note {
|
|
368
330
|
font-size: 12px;
|
|
369
331
|
line-height: 16px;
|
|
@@ -376,31 +338,13 @@ p.input-parameters {
|
|
|
376
338
|
p.title {
|
|
377
339
|
line-height: 20px;
|
|
378
340
|
}
|
|
379
|
-
p.discrete {
|
|
380
|
-
margin-top: 0;
|
|
381
|
-
margin-bottom: 4px;
|
|
382
|
-
}
|
|
383
|
-
p.first-scalar {
|
|
384
|
-
margin-top: 0;
|
|
385
|
-
}
|
|
386
|
-
p.scalar {
|
|
387
|
-
margin-top: 6px;
|
|
388
|
-
}
|
|
389
341
|
span.error {
|
|
390
342
|
font-weight: 500 /* Medium */;
|
|
391
343
|
}
|
|
392
344
|
</style>
|
|
393
|
-
<style scoped src="../styles/purple/aside.css">
|
|
394
|
-
</style>
|
|
395
345
|
<style scoped src="../styles/purple/button.css">
|
|
396
346
|
</style>
|
|
397
|
-
<style scoped src="../styles/purple/
|
|
398
|
-
</style>
|
|
399
|
-
<style scoped src="../styles/purple/input-number.css">
|
|
400
|
-
</style>
|
|
401
|
-
<style scoped src="../styles/purple/option.css">
|
|
402
|
-
</style>
|
|
403
|
-
<style scoped src="../styles/purple/select.css">
|
|
347
|
+
<style scoped src="../styles/purple/divider.css">
|
|
404
348
|
</style>
|
|
405
|
-
<style scoped src="../styles/purple/
|
|
349
|
+
<style scoped src="../styles/purple/loading.css">
|
|
406
350
|
</style>
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<p :class="labelClasses">{{ name }}</p>
|
|
4
|
+
<el-select class="discrete" popper-class="discrete-popper" size="mini" v-if="isDiscrete" v-model="vModel" :disabled="!enabled" :popper-append-to-body="false" @change="updateUi()">
|
|
5
|
+
<el-option v-for="possibleValue in possibleValues" :key="possibleValue.value" :label="possibleValue.name" :value="possibleValue.value" />
|
|
6
|
+
</el-select>
|
|
7
|
+
<div class="sliders-and-fields" v-if="!isDiscrete">
|
|
8
|
+
<el-slider v-model="vModel" :disabled="!enabled" :max="maximumValue" :min="minimumValue" :show-input="false" :show-tooltip="false" @change="updateUi()" />
|
|
9
|
+
<el-input-number class="scalar" size="mini" v-model="vModel" :controls="false" :disabled="!enabled" :max="maximumValue" :min="minimumValue" @input="updateUi()" />
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script>
|
|
15
|
+
import Vue from "vue";
|
|
16
|
+
import { InputNumber, Option, Select, Slider } from "element-ui";
|
|
17
|
+
import { updateUi } from "./ui.js";
|
|
18
|
+
|
|
19
|
+
Vue.use(InputNumber);
|
|
20
|
+
Vue.use(Option);
|
|
21
|
+
Vue.use(Select);
|
|
22
|
+
Vue.use(Slider);
|
|
23
|
+
|
|
24
|
+
export default {
|
|
25
|
+
name: "SimulationVuerInput",
|
|
26
|
+
props: {
|
|
27
|
+
defaultValue: {
|
|
28
|
+
required: true,
|
|
29
|
+
type: Number,
|
|
30
|
+
},
|
|
31
|
+
firstScalarInput: {
|
|
32
|
+
type: Boolean,
|
|
33
|
+
},
|
|
34
|
+
maximumValue: {
|
|
35
|
+
type: Number,
|
|
36
|
+
},
|
|
37
|
+
minimumValue: {
|
|
38
|
+
type: Number,
|
|
39
|
+
},
|
|
40
|
+
name: {
|
|
41
|
+
required: true,
|
|
42
|
+
type: String,
|
|
43
|
+
},
|
|
44
|
+
possibleValues: {
|
|
45
|
+
type: Array,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
data: function() {
|
|
49
|
+
return {
|
|
50
|
+
enabled: true,
|
|
51
|
+
isDiscrete: this.possibleValues !== undefined,
|
|
52
|
+
labelClasses: "default " + ((this.possibleValues !== undefined)?"discrete":this.firstScalarInput?"first-scalar":"scalar"),
|
|
53
|
+
vModel: this.defaultValue,
|
|
54
|
+
};
|
|
55
|
+
},
|
|
56
|
+
methods: {
|
|
57
|
+
updateUi: function() {
|
|
58
|
+
updateUi(this.$parent);
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
</script>
|
|
63
|
+
|
|
64
|
+
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
65
|
+
<style scoped>
|
|
66
|
+
@import url("//unpkg.com/element-ui@2.14.1/lib/theme-chalk/index.css");
|
|
67
|
+
>>> .el-input-number.scalar {
|
|
68
|
+
margin-top: -8px;
|
|
69
|
+
width: 0;
|
|
70
|
+
}
|
|
71
|
+
>>> .el-input-number.scalar .el-input {
|
|
72
|
+
width: 60px;
|
|
73
|
+
}
|
|
74
|
+
>>> .el-input-number.scalar .el-input__inner:focus {
|
|
75
|
+
border-color: #8300bf;
|
|
76
|
+
}
|
|
77
|
+
>>> .el-select.discrete {
|
|
78
|
+
margin-bottom: 16px;
|
|
79
|
+
}
|
|
80
|
+
>>> .el-slider {
|
|
81
|
+
width: 108px;
|
|
82
|
+
margin-top: -12px;
|
|
83
|
+
margin-left: 8px;
|
|
84
|
+
}
|
|
85
|
+
>>> .el-slider__bar {
|
|
86
|
+
background-color: #8300bf;
|
|
87
|
+
}
|
|
88
|
+
>>> .el-slider__button {
|
|
89
|
+
border-color: #8300bf;
|
|
90
|
+
}
|
|
91
|
+
.discrete {
|
|
92
|
+
margin-left: 8px;
|
|
93
|
+
}
|
|
94
|
+
.discrete >>> .el-input__inner {
|
|
95
|
+
font-family: Asap, sans-serif;
|
|
96
|
+
}
|
|
97
|
+
.discrete >>> .el-input__inner:focus,
|
|
98
|
+
.discrete >>> .el-input.is-focus .el-input__inner {
|
|
99
|
+
border-color: #8300bf;
|
|
100
|
+
}
|
|
101
|
+
.discrete-popper .el-select-dropdown__item {
|
|
102
|
+
font-family: Asap, sans-serif;
|
|
103
|
+
}
|
|
104
|
+
.discrete-popper .el-select-dropdown__item.selected {
|
|
105
|
+
font-weight: normal;
|
|
106
|
+
color: #8300bf;
|
|
107
|
+
}
|
|
108
|
+
.scalar >>> .el-input__inner {
|
|
109
|
+
text-align: center;
|
|
110
|
+
}
|
|
111
|
+
div.simulation-vuer {
|
|
112
|
+
height: 100%;
|
|
113
|
+
}
|
|
114
|
+
div.sliders-and-fields {
|
|
115
|
+
display: grid;
|
|
116
|
+
grid-template-columns: 132px auto;
|
|
117
|
+
width: 191px;
|
|
118
|
+
height: 26px;
|
|
119
|
+
}
|
|
120
|
+
p.default {
|
|
121
|
+
font-family: Asap, sans-serif;
|
|
122
|
+
letter-spacing: 0;
|
|
123
|
+
margin: 16px 0;
|
|
124
|
+
text-align: start;
|
|
125
|
+
}
|
|
126
|
+
p.first-scalar,
|
|
127
|
+
p.scalar {
|
|
128
|
+
grid-column-start: 1;
|
|
129
|
+
grid-column-end: 3;
|
|
130
|
+
margin-bottom: 8px;
|
|
131
|
+
}
|
|
132
|
+
p.discrete {
|
|
133
|
+
margin-top: 0;
|
|
134
|
+
margin-bottom: 4px;
|
|
135
|
+
}
|
|
136
|
+
p.first-scalar {
|
|
137
|
+
margin-top: 0;
|
|
138
|
+
}
|
|
139
|
+
p.scalar {
|
|
140
|
+
margin-top: 6px;
|
|
141
|
+
}
|
|
142
|
+
</style>
|
|
143
|
+
<style scoped src="../styles/purple/input-number.css">
|
|
144
|
+
</style>
|
|
145
|
+
<style scoped src="../styles/purple/option.css">
|
|
146
|
+
</style>
|
|
147
|
+
<style scoped src="../styles/purple/select.css">
|
|
148
|
+
</style>
|
|
149
|
+
<style scoped src="../styles/purple/slider.css">
|
|
150
|
+
</style>
|
package/src/components/common.js
CHANGED
|
@@ -8,20 +8,20 @@ function doEvaluateValue(value, from, to) {
|
|
|
8
8
|
return value;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
export function evaluateValue(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
export function evaluateValue(parent, value) {
|
|
12
|
+
let index = -1;
|
|
13
|
+
|
|
14
|
+
parent.simulationUiInformation.input.forEach((input) => {
|
|
15
|
+
++index;
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
value = doEvaluateValue(value, scalarElement.id, scalarElement.input_number.vModel);
|
|
17
|
+
value = doEvaluateValue(value, input.id, parent.$children[index].vModel);
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
return Function("return " + value + ";")();
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
export function evaluateSimulationValue(parent, results, value, i) {
|
|
24
|
-
parent.
|
|
24
|
+
parent.simulationUiInformation.output.data.forEach((data) => {
|
|
25
25
|
value = doEvaluateValue(value, data.id, results[parent.simulationDataId[data.id]][i]);
|
|
26
26
|
});
|
|
27
27
|
|
package/src/components/json.js
CHANGED
|
@@ -17,6 +17,9 @@ export function validJson(json) {
|
|
|
17
17
|
required: true,
|
|
18
18
|
type: "number",
|
|
19
19
|
},
|
|
20
|
+
enabled: {
|
|
21
|
+
type: "string",
|
|
22
|
+
},
|
|
20
23
|
id: {
|
|
21
24
|
type: "string",
|
|
22
25
|
},
|
|
@@ -76,16 +79,19 @@ export function validJson(json) {
|
|
|
76
79
|
type: "object",
|
|
77
80
|
},
|
|
78
81
|
minItems: 1,
|
|
82
|
+
required: true,
|
|
79
83
|
type: "array",
|
|
80
84
|
},
|
|
81
85
|
output: {
|
|
82
86
|
additionalProperties: false,
|
|
87
|
+
minItems: 1,
|
|
83
88
|
properties: {
|
|
84
89
|
data: {
|
|
85
90
|
items: {
|
|
86
91
|
additionalProperties: false,
|
|
87
92
|
properties: {
|
|
88
93
|
id: {
|
|
94
|
+
required: true,
|
|
89
95
|
type: "string",
|
|
90
96
|
},
|
|
91
97
|
name: {
|
|
@@ -95,6 +101,8 @@ export function validJson(json) {
|
|
|
95
101
|
},
|
|
96
102
|
type: "object",
|
|
97
103
|
},
|
|
104
|
+
minItems: 1,
|
|
105
|
+
required: true,
|
|
98
106
|
type: "array",
|
|
99
107
|
},
|
|
100
108
|
plots: {
|