@abi-software/simulationvuer 0.4.5 → 0.5.1
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 +970 -352
- package/dist/simulationvuer.common.js.map +1 -1
- package/dist/simulationvuer.css +1 -1
- package/dist/simulationvuer.umd.js +970 -352
- 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 +3 -2
- package/src/.DS_Store +0 -0
- package/src/App.vue +16 -12
- package/src/components/SimulationVuer.vue +161 -271
- package/src/components/SimulationVuerInput.vue +150 -0
- package/src/components/common.js +29 -0
- package/src/components/json.js +376 -0
- package/src/components/ui.js +80 -0
|
@@ -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>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
function doEvaluateValue(value, from, to) {
|
|
2
|
+
if (from !== undefined) {
|
|
3
|
+
let re = new RegExp(`\\b${ from }\\b`, 'g');
|
|
4
|
+
|
|
5
|
+
value = value.replace(re, to);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function evaluateValue(parent, value) {
|
|
12
|
+
let index = -1;
|
|
13
|
+
|
|
14
|
+
parent.simulationUiInformation.input.forEach((input) => {
|
|
15
|
+
++index;
|
|
16
|
+
|
|
17
|
+
value = doEvaluateValue(value, input.id, parent.$children[index].vModel);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
return Function("return " + value + ";")();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function evaluateSimulationValue(parent, results, value, i) {
|
|
24
|
+
parent.simulationUiInformation.output.data.forEach((data) => {
|
|
25
|
+
value = doEvaluateValue(value, data.id, results[parent.simulationDataId[data.id]][i]);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
return Function("return " + value + ";")();
|
|
29
|
+
}
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
import { Validator } from "jsonschema";
|
|
2
|
+
|
|
3
|
+
export function validJson(json) {
|
|
4
|
+
// Check the JSON against our schema.
|
|
5
|
+
|
|
6
|
+
let validator = new Validator();
|
|
7
|
+
let schema = {
|
|
8
|
+
additionalProperties: false,
|
|
9
|
+
properties: {
|
|
10
|
+
input: {
|
|
11
|
+
items: {
|
|
12
|
+
oneOf: [
|
|
13
|
+
{
|
|
14
|
+
additionalProperties: false,
|
|
15
|
+
properties: {
|
|
16
|
+
defaultValue: {
|
|
17
|
+
required: true,
|
|
18
|
+
type: "number",
|
|
19
|
+
},
|
|
20
|
+
enabled: {
|
|
21
|
+
type: "string",
|
|
22
|
+
},
|
|
23
|
+
id: {
|
|
24
|
+
type: "string",
|
|
25
|
+
},
|
|
26
|
+
name: {
|
|
27
|
+
required: true,
|
|
28
|
+
type: "string",
|
|
29
|
+
},
|
|
30
|
+
possibleValues: {
|
|
31
|
+
items: {
|
|
32
|
+
additionalProperties: false,
|
|
33
|
+
properties: {
|
|
34
|
+
name: {
|
|
35
|
+
required: true,
|
|
36
|
+
type: "string",
|
|
37
|
+
},
|
|
38
|
+
value: {
|
|
39
|
+
required: true,
|
|
40
|
+
type: "number",
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
type: "object",
|
|
44
|
+
},
|
|
45
|
+
minItems: 1,
|
|
46
|
+
required: true,
|
|
47
|
+
type: "array",
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
additionalProperties: false,
|
|
53
|
+
properties: {
|
|
54
|
+
defaultValue: {
|
|
55
|
+
required: true,
|
|
56
|
+
type: "number",
|
|
57
|
+
},
|
|
58
|
+
enabled: {
|
|
59
|
+
type: "string",
|
|
60
|
+
},
|
|
61
|
+
id: {
|
|
62
|
+
type: "string",
|
|
63
|
+
},
|
|
64
|
+
maximumValue: {
|
|
65
|
+
required: true,
|
|
66
|
+
type: "number",
|
|
67
|
+
},
|
|
68
|
+
minimumValue: {
|
|
69
|
+
required: true,
|
|
70
|
+
type: "number",
|
|
71
|
+
},
|
|
72
|
+
name: {
|
|
73
|
+
required: true,
|
|
74
|
+
type: "string",
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
type: "object",
|
|
80
|
+
},
|
|
81
|
+
minItems: 1,
|
|
82
|
+
type: "array",
|
|
83
|
+
},
|
|
84
|
+
output: {
|
|
85
|
+
additionalProperties: false,
|
|
86
|
+
properties: {
|
|
87
|
+
data: {
|
|
88
|
+
items: {
|
|
89
|
+
additionalProperties: false,
|
|
90
|
+
properties: {
|
|
91
|
+
id: {
|
|
92
|
+
type: "string",
|
|
93
|
+
},
|
|
94
|
+
name: {
|
|
95
|
+
required: true,
|
|
96
|
+
type: "string",
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
type: "object",
|
|
100
|
+
},
|
|
101
|
+
type: "array",
|
|
102
|
+
},
|
|
103
|
+
plots: {
|
|
104
|
+
items: {
|
|
105
|
+
additionalProperties: false,
|
|
106
|
+
properties: {
|
|
107
|
+
xAxisTitle: {
|
|
108
|
+
required: true,
|
|
109
|
+
type: "string",
|
|
110
|
+
},
|
|
111
|
+
xValue: {
|
|
112
|
+
required: true,
|
|
113
|
+
type: "string",
|
|
114
|
+
},
|
|
115
|
+
yAxisTitle: {
|
|
116
|
+
required: true,
|
|
117
|
+
type: "string",
|
|
118
|
+
},
|
|
119
|
+
yValue: {
|
|
120
|
+
required: true,
|
|
121
|
+
type: "string",
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
type: "object",
|
|
125
|
+
},
|
|
126
|
+
maxItems: 9,
|
|
127
|
+
minItems: 1,
|
|
128
|
+
required: true,
|
|
129
|
+
type: "array",
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
required: true,
|
|
133
|
+
type: "object",
|
|
134
|
+
},
|
|
135
|
+
parameters: {
|
|
136
|
+
items: {
|
|
137
|
+
additionalProperties: false,
|
|
138
|
+
properties: {
|
|
139
|
+
name: {
|
|
140
|
+
required: true,
|
|
141
|
+
type: "string",
|
|
142
|
+
},
|
|
143
|
+
value: {
|
|
144
|
+
required: true,
|
|
145
|
+
type: "string",
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
type: "object",
|
|
149
|
+
},
|
|
150
|
+
type: "array",
|
|
151
|
+
},
|
|
152
|
+
simulation: {
|
|
153
|
+
additionalProperties: false,
|
|
154
|
+
properties: {
|
|
155
|
+
endingPoint: {
|
|
156
|
+
required: true,
|
|
157
|
+
type: "number",
|
|
158
|
+
},
|
|
159
|
+
pointInterval: {
|
|
160
|
+
required: true,
|
|
161
|
+
type: "number",
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
type: "object",
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
type: "object",
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
let result = validator.validate(json, schema, { nestedErrors: true });
|
|
171
|
+
|
|
172
|
+
if (!result.valid) {
|
|
173
|
+
console.warn(result.toString());
|
|
174
|
+
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Make sure that the input information makes sense.
|
|
179
|
+
|
|
180
|
+
let inputIdUsed = [];
|
|
181
|
+
let inputValid = json.input.every((input) => {
|
|
182
|
+
if (input.id !== undefined) {
|
|
183
|
+
if (input.id === "") {
|
|
184
|
+
console.warn("JSON: an input id must not be empty.");
|
|
185
|
+
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (inputIdUsed[input.id]) {
|
|
190
|
+
console.warn("JSON: an input id must be unique (" + input.id + " is used more than once).");
|
|
191
|
+
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
inputIdUsed[input.id] = true;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (input.name === "") {
|
|
199
|
+
console.warn("JSON: an input name must not be empty.");
|
|
200
|
+
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (input.possibleValues !== undefined) {
|
|
205
|
+
if (!input.possibleValues.every((possibleValue) => {
|
|
206
|
+
if (possibleValue.name === "") {
|
|
207
|
+
console.warn("JSON: an input possible value must not have an empty name.");
|
|
208
|
+
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return true;
|
|
213
|
+
})) {
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
let values = input.possibleValues.map((value) => {
|
|
218
|
+
return value.value;
|
|
219
|
+
});
|
|
220
|
+
let valueUsed = [];
|
|
221
|
+
|
|
222
|
+
if (!values.every((value) => {
|
|
223
|
+
if (valueUsed[value]) {
|
|
224
|
+
console.warn("JSON: an input possible value must have a unique value (" + value + " is used more than once).");
|
|
225
|
+
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
valueUsed[value] = true;
|
|
230
|
+
|
|
231
|
+
return true;
|
|
232
|
+
})) {
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (!values.includes(input.defaultValue)) {
|
|
237
|
+
console.warn("JSON: the input default value (" + input.defaultValue + ") must be one of the possible values (" + values.join(", ") + ").");
|
|
238
|
+
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (input.enabled !== undefined) {
|
|
244
|
+
if (input.enabled === "") {
|
|
245
|
+
console.warn("JSON: an input enabled must not be empty.");
|
|
246
|
+
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if ((input.minimumValue !== undefined) && (input.maximumValue !== undefined)) {
|
|
252
|
+
if (input.minimumValue >= input.maximumValue) {
|
|
253
|
+
console.warn("JSON: the input minimum value (" + input.minimumValue + ") must be lower than the maximum value (" + input.maximumValue + ").");
|
|
254
|
+
|
|
255
|
+
return false;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
if ((input.defaultValue < input.minimumValue) || (input.defaultValue > input.maximumValue)) {
|
|
259
|
+
console.warn("JSON: the input default value (" + input.defaultValue + ") must be greater or equal to the minimum value (" + input.minimumValue + ") and lower or equal to the maximum value (" + input.maximumValue + ").");
|
|
260
|
+
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return true;
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
if (!inputValid) {
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Make sure that the output information makes sense.
|
|
273
|
+
|
|
274
|
+
let outputIdUsed = [];
|
|
275
|
+
let outputDataValid = json.output.data.every((outputData) => {
|
|
276
|
+
if (outputData.id !== undefined) {
|
|
277
|
+
if (outputData.id === "") {
|
|
278
|
+
console.warn("JSON: an output data id must not be empty.");
|
|
279
|
+
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (outputIdUsed[outputData.id]) {
|
|
284
|
+
console.warn("JSON: an output data id must be unique (" + outputData.id + " is used more than once).");
|
|
285
|
+
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
outputIdUsed[outputData.id] = true;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if (outputData.name === "") {
|
|
293
|
+
console.warn("JSON: an output data name must not be empty.");
|
|
294
|
+
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return true;
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
if (!outputDataValid) {
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
let outputPlotsValid = json.output.plots.every((outputPlot) => {
|
|
306
|
+
if (outputPlot.xAxisTitle === "") {
|
|
307
|
+
console.warn("JSON: an output plot X axis title must not be empty.");
|
|
308
|
+
|
|
309
|
+
return false;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (outputPlot.xValue === "") {
|
|
313
|
+
console.warn("JSON: an output plot X value must not be empty.");
|
|
314
|
+
|
|
315
|
+
return false;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
if (outputPlot.yAxisTitle === "") {
|
|
319
|
+
console.warn("JSON: an output plot Y axis title must not be empty.");
|
|
320
|
+
|
|
321
|
+
return false;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (outputPlot.yValue === "") {
|
|
325
|
+
console.warn("JSON: an output plot Y value must not be empty.");
|
|
326
|
+
|
|
327
|
+
return false;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
return true;
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
if (!outputPlotsValid) {
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Make sure that the parameters information makes sense.
|
|
338
|
+
|
|
339
|
+
let parametersValid = json.parameters.every((parameter) => {
|
|
340
|
+
if (parameter.name === "") {
|
|
341
|
+
console.warn("JSON: a parameter name must not be empty.");
|
|
342
|
+
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
if (parameter.value === "") {
|
|
347
|
+
console.warn("JSON: a parameter value must not be empty.");
|
|
348
|
+
|
|
349
|
+
return false;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
return true;
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
if (!parametersValid) {
|
|
356
|
+
return false;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// Make sure that the simulation information makes sense.
|
|
360
|
+
|
|
361
|
+
if (json.simulation !== undefined) {
|
|
362
|
+
if (json.simulation.endingPoint <= 0.0) {
|
|
363
|
+
console.warn("JSON: a simulation ending point must be greater than zero.");
|
|
364
|
+
|
|
365
|
+
return false;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if (json.simulation.pointInterval <= 0.0) {
|
|
369
|
+
console.warn("JSON: a simulation point interval must be greater than zero.");
|
|
370
|
+
|
|
371
|
+
return false;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
return true;
|
|
376
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { evaluateValue } from "./common.js";
|
|
2
|
+
|
|
3
|
+
export function initialiseUi(parent) {
|
|
4
|
+
// Initialise some input-related data.
|
|
5
|
+
|
|
6
|
+
let index = -1;
|
|
7
|
+
let isPreviousDiscrete = true;
|
|
8
|
+
|
|
9
|
+
parent.simulationUiInformation.input.forEach((input) => {
|
|
10
|
+
let isDiscrete = input.possibleValues !== undefined;
|
|
11
|
+
|
|
12
|
+
parent.firstScalarInput[++index] = !isDiscrete && isPreviousDiscrete;
|
|
13
|
+
|
|
14
|
+
isPreviousDiscrete = isDiscrete;
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
// Initialise some output-related data.
|
|
18
|
+
|
|
19
|
+
parent.simulationUiInformation.output.data.forEach((data) => {
|
|
20
|
+
parent.simulationDataId[data.id] = data.name;
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
index = -1;
|
|
24
|
+
|
|
25
|
+
parent.simulationUiInformation.output.plots.forEach((outputPlot) => {
|
|
26
|
+
++index;
|
|
27
|
+
|
|
28
|
+
parent.layout[index] = {
|
|
29
|
+
xaxis: {
|
|
30
|
+
title: {
|
|
31
|
+
text: outputPlot.xAxisTitle,
|
|
32
|
+
font: {
|
|
33
|
+
size: 10,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
yaxis: {
|
|
38
|
+
title: {
|
|
39
|
+
text: outputPlot.yAxisTitle,
|
|
40
|
+
font: {
|
|
41
|
+
size: 10,
|
|
42
|
+
},
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
parent.simulationData[index] = [{}];
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function finaliseUi(parent) {
|
|
52
|
+
// Finalise our UI, but only if we haven't already done so, we are mounted,
|
|
53
|
+
// and we have some valid simulation UI information.
|
|
54
|
+
|
|
55
|
+
if (!parent.hasFinalisedUi && parent.isMounted && parent.hasValidSimulationUiInformation) {
|
|
56
|
+
// Configure the PlotVuer's.
|
|
57
|
+
|
|
58
|
+
parent.$refs.output.classList.add("x" + parent.simulationUiInformation.output.plots.length);
|
|
59
|
+
|
|
60
|
+
// Make sure that our UI is up to date.
|
|
61
|
+
|
|
62
|
+
updateUi(parent);
|
|
63
|
+
|
|
64
|
+
parent.hasFinalisedUi = true;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function updateUi(parent) {
|
|
69
|
+
// Enable/disable all the elements.
|
|
70
|
+
// Note: we do this using $nextTick() to be ensure that the UI has been fully
|
|
71
|
+
// mounted.
|
|
72
|
+
|
|
73
|
+
parent.$nextTick(() => {
|
|
74
|
+
let index = -1;
|
|
75
|
+
|
|
76
|
+
parent.simulationUiInformation.input.forEach((input) => {
|
|
77
|
+
parent.$children[++index].enabled = (input.enabled === undefined)?true:evaluateValue(parent, input.enabled);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
}
|