@abi-software/simulationvuer 0.4.6 → 0.5.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/dist/simulationvuer.common.js +1052 -229
- package/dist/simulationvuer.common.js.map +1 -1
- package/dist/simulationvuer.css +1 -1
- package/dist/simulationvuer.umd.js +1052 -229
- 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 -1
- package/src/.DS_Store +0 -0
- package/src/App.vue +6 -4
- package/src/components/SimulationVuer.vue +130 -184
- package/src/components/common.js +29 -0
- package/src/components/configuration.js +139 -0
- package/src/components/json.js +373 -0
- package/src/components/ui.js +273 -0
- package/vue.config.js +2 -1
|
@@ -0,0 +1,373 @@
|
|
|
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
|
+
id: {
|
|
21
|
+
type: "string",
|
|
22
|
+
},
|
|
23
|
+
name: {
|
|
24
|
+
required: true,
|
|
25
|
+
type: "string",
|
|
26
|
+
},
|
|
27
|
+
possibleValues: {
|
|
28
|
+
items: {
|
|
29
|
+
additionalProperties: false,
|
|
30
|
+
properties: {
|
|
31
|
+
name: {
|
|
32
|
+
required: true,
|
|
33
|
+
type: "string",
|
|
34
|
+
},
|
|
35
|
+
value: {
|
|
36
|
+
required: true,
|
|
37
|
+
type: "number",
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
type: "object",
|
|
41
|
+
},
|
|
42
|
+
minItems: 1,
|
|
43
|
+
required: true,
|
|
44
|
+
type: "array",
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
additionalProperties: false,
|
|
50
|
+
properties: {
|
|
51
|
+
defaultValue: {
|
|
52
|
+
required: true,
|
|
53
|
+
type: "number",
|
|
54
|
+
},
|
|
55
|
+
enabled: {
|
|
56
|
+
type: "string",
|
|
57
|
+
},
|
|
58
|
+
id: {
|
|
59
|
+
type: "string",
|
|
60
|
+
},
|
|
61
|
+
maximumValue: {
|
|
62
|
+
required: true,
|
|
63
|
+
type: "number",
|
|
64
|
+
},
|
|
65
|
+
minimumValue: {
|
|
66
|
+
required: true,
|
|
67
|
+
type: "number",
|
|
68
|
+
},
|
|
69
|
+
name: {
|
|
70
|
+
required: true,
|
|
71
|
+
type: "string",
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
type: "object",
|
|
77
|
+
},
|
|
78
|
+
minItems: 1,
|
|
79
|
+
type: "array",
|
|
80
|
+
},
|
|
81
|
+
output: {
|
|
82
|
+
additionalProperties: false,
|
|
83
|
+
properties: {
|
|
84
|
+
data: {
|
|
85
|
+
items: {
|
|
86
|
+
additionalProperties: false,
|
|
87
|
+
properties: {
|
|
88
|
+
id: {
|
|
89
|
+
type: "string",
|
|
90
|
+
},
|
|
91
|
+
name: {
|
|
92
|
+
required: true,
|
|
93
|
+
type: "string",
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
type: "object",
|
|
97
|
+
},
|
|
98
|
+
type: "array",
|
|
99
|
+
},
|
|
100
|
+
plots: {
|
|
101
|
+
items: {
|
|
102
|
+
additionalProperties: false,
|
|
103
|
+
properties: {
|
|
104
|
+
xAxisTitle: {
|
|
105
|
+
required: true,
|
|
106
|
+
type: "string",
|
|
107
|
+
},
|
|
108
|
+
xValue: {
|
|
109
|
+
required: true,
|
|
110
|
+
type: "string",
|
|
111
|
+
},
|
|
112
|
+
yAxisTitle: {
|
|
113
|
+
required: true,
|
|
114
|
+
type: "string",
|
|
115
|
+
},
|
|
116
|
+
yValue: {
|
|
117
|
+
required: true,
|
|
118
|
+
type: "string",
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
type: "object",
|
|
122
|
+
},
|
|
123
|
+
maxItems: 9,
|
|
124
|
+
minItems: 1,
|
|
125
|
+
required: true,
|
|
126
|
+
type: "array",
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
required: true,
|
|
130
|
+
type: "object",
|
|
131
|
+
},
|
|
132
|
+
parameters: {
|
|
133
|
+
items: {
|
|
134
|
+
additionalProperties: false,
|
|
135
|
+
properties: {
|
|
136
|
+
name: {
|
|
137
|
+
required: true,
|
|
138
|
+
type: "string",
|
|
139
|
+
},
|
|
140
|
+
value: {
|
|
141
|
+
required: true,
|
|
142
|
+
type: "string",
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
type: "object",
|
|
146
|
+
},
|
|
147
|
+
type: "array",
|
|
148
|
+
},
|
|
149
|
+
simulation: {
|
|
150
|
+
additionalProperties: false,
|
|
151
|
+
properties: {
|
|
152
|
+
endingPoint: {
|
|
153
|
+
required: true,
|
|
154
|
+
type: "number",
|
|
155
|
+
},
|
|
156
|
+
pointInterval: {
|
|
157
|
+
required: true,
|
|
158
|
+
type: "number",
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
type: "object",
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
type: "object",
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
let result = validator.validate(json, schema, { nestedErrors: true });
|
|
168
|
+
|
|
169
|
+
if (!result.valid) {
|
|
170
|
+
console.warn(result.toString());
|
|
171
|
+
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Make sure that the input information makes sense.
|
|
176
|
+
|
|
177
|
+
let inputIdUsed = [];
|
|
178
|
+
let inputValid = json.input.every((input) => {
|
|
179
|
+
if (input.id !== undefined) {
|
|
180
|
+
if (input.id === "") {
|
|
181
|
+
console.warn("JSON: an input id must not be empty.");
|
|
182
|
+
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (inputIdUsed[input.id]) {
|
|
187
|
+
console.warn("JSON: an input id must be unique (" + input.id + " is used more than once).");
|
|
188
|
+
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
inputIdUsed[input.id] = true;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (input.name === "") {
|
|
196
|
+
console.warn("JSON: an input name must not be empty.");
|
|
197
|
+
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (input.possibleValues !== undefined) {
|
|
202
|
+
if (!input.possibleValues.every((possibleValue) => {
|
|
203
|
+
if (possibleValue.name === "") {
|
|
204
|
+
console.warn("JSON: an input possible value must not have an empty name.");
|
|
205
|
+
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return true;
|
|
210
|
+
})) {
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
let values = input.possibleValues.map((value) => {
|
|
215
|
+
return value.value;
|
|
216
|
+
});
|
|
217
|
+
let valueUsed = [];
|
|
218
|
+
|
|
219
|
+
if (!values.every((value) => {
|
|
220
|
+
if (valueUsed[value]) {
|
|
221
|
+
console.warn("JSON: an input possible value must have a unique value (" + value + " is used more than once).");
|
|
222
|
+
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
valueUsed[value] = true;
|
|
227
|
+
|
|
228
|
+
return true;
|
|
229
|
+
})) {
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (!values.includes(input.defaultValue)) {
|
|
234
|
+
console.warn("JSON: the input default value (" + input.defaultValue + ") must be one of the possible values (" + values.join(", ") + ").");
|
|
235
|
+
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (input.enabled !== undefined) {
|
|
241
|
+
if (input.enabled === "") {
|
|
242
|
+
console.warn("JSON: an input enabled must not be empty.");
|
|
243
|
+
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if ((input.minimumValue !== undefined) && (input.maximumValue !== undefined)) {
|
|
249
|
+
if (input.minimumValue >= input.maximumValue) {
|
|
250
|
+
console.warn("JSON: the input minimum value (" + input.minimumValue + ") must be lower than the maximum value (" + input.maximumValue + ").");
|
|
251
|
+
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if ((input.defaultValue < input.minimumValue) || (input.defaultValue > input.maximumValue)) {
|
|
256
|
+
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 + ").");
|
|
257
|
+
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return true;
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
if (!inputValid) {
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Make sure that the output information makes sense.
|
|
270
|
+
|
|
271
|
+
let outputIdUsed = [];
|
|
272
|
+
let outputDataValid = json.output.data.every((outputData) => {
|
|
273
|
+
if (outputData.id !== undefined) {
|
|
274
|
+
if (outputData.id === "") {
|
|
275
|
+
console.warn("JSON: an output data id must not be empty.");
|
|
276
|
+
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (outputIdUsed[outputData.id]) {
|
|
281
|
+
console.warn("JSON: an output data id must be unique (" + outputData.id + " is used more than once).");
|
|
282
|
+
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
outputIdUsed[outputData.id] = true;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (outputData.name === "") {
|
|
290
|
+
console.warn("JSON: an output data name must not be empty.");
|
|
291
|
+
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
return true;
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
if (!outputDataValid) {
|
|
299
|
+
return false;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
let outputPlotsValid = json.output.plots.every((outputPlot) => {
|
|
303
|
+
if (outputPlot.xAxisTitle === "") {
|
|
304
|
+
console.warn("JSON: an output plot X axis title must not be empty.");
|
|
305
|
+
|
|
306
|
+
return false;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if (outputPlot.xValue === "") {
|
|
310
|
+
console.warn("JSON: an output plot X value must not be empty.");
|
|
311
|
+
|
|
312
|
+
return false;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if (outputPlot.yAxisTitle === "") {
|
|
316
|
+
console.warn("JSON: an output plot Y axis title must not be empty.");
|
|
317
|
+
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (outputPlot.yValue === "") {
|
|
322
|
+
console.warn("JSON: an output plot Y value must not be empty.");
|
|
323
|
+
|
|
324
|
+
return false;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return true;
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
if (!outputPlotsValid) {
|
|
331
|
+
return false;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Make sure that the parameters information makes sense.
|
|
335
|
+
|
|
336
|
+
let parametersValid = json.parameters.every((parameter) => {
|
|
337
|
+
if (parameter.name === "") {
|
|
338
|
+
console.warn("JSON: a parameter name must not be empty.");
|
|
339
|
+
|
|
340
|
+
return false;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
if (parameter.value === "") {
|
|
344
|
+
console.warn("JSON: a parameter value must not be empty.");
|
|
345
|
+
|
|
346
|
+
return false;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
return true;
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
if (!parametersValid) {
|
|
353
|
+
return false;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Make sure that the simulation information makes sense.
|
|
357
|
+
|
|
358
|
+
if (json.simulation !== undefined) {
|
|
359
|
+
if (json.simulation.endingPoint <= 0.0) {
|
|
360
|
+
console.warn("JSON: a simulation ending point must be greater than zero.");
|
|
361
|
+
|
|
362
|
+
return false;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (json.simulation.pointInterval <= 0.0) {
|
|
366
|
+
console.warn("JSON: a simulation point interval must be greater than zero.");
|
|
367
|
+
|
|
368
|
+
return false;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return true;
|
|
373
|
+
}
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import Vue from "vue";
|
|
2
|
+
import { evaluateValue } from "./common.js";
|
|
3
|
+
|
|
4
|
+
export function prepareForUi(parent) {
|
|
5
|
+
let index = -1;
|
|
6
|
+
|
|
7
|
+
parent.json.output.data.forEach((data) => {
|
|
8
|
+
parent.simulationDataId[data.id] = data.name;
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
parent.json.output.plots.forEach((outputPlot) => {
|
|
12
|
+
++index;
|
|
13
|
+
|
|
14
|
+
parent.layout[index] = {
|
|
15
|
+
xaxis: {
|
|
16
|
+
title: {
|
|
17
|
+
text: outputPlot.xAxisTitle,
|
|
18
|
+
font: {
|
|
19
|
+
size: 10,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
yaxis: {
|
|
24
|
+
title: {
|
|
25
|
+
text: outputPlot.yAxisTitle,
|
|
26
|
+
font: {
|
|
27
|
+
size: 10,
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
parent.simulationData[index] = [{}];
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const VueContainer = Vue.extend({
|
|
38
|
+
template: `
|
|
39
|
+
<div class="sliders-and-fields"/>
|
|
40
|
+
`,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const VueInputNumber = Vue.extend({
|
|
44
|
+
methods: {
|
|
45
|
+
emitSynchroniseSliderAndInputNumber: function(value) {
|
|
46
|
+
this.$emit("synchroniseSliderAndInputNumber", this.index, value);
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
props: {
|
|
50
|
+
disabled: Boolean,
|
|
51
|
+
index: Number,
|
|
52
|
+
maximumValue: Number,
|
|
53
|
+
minimumValue: Number,
|
|
54
|
+
parent: Object,
|
|
55
|
+
vModel: Number,
|
|
56
|
+
},
|
|
57
|
+
template: `
|
|
58
|
+
<el-input-number class="scalar" size="mini" v-model="vModel" :controls="false" :disabled="disabled" :max="maximumValue" :min="minimumValue" @change="emitSynchroniseSliderAndInputNumber" />
|
|
59
|
+
`,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const VueLabel = Vue.extend({
|
|
63
|
+
props: {
|
|
64
|
+
classes: String,
|
|
65
|
+
label: String,
|
|
66
|
+
},
|
|
67
|
+
template: `
|
|
68
|
+
<p :class="classes">{{ label }}</p>
|
|
69
|
+
`,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const VueSelect = Vue.extend({
|
|
73
|
+
methods: {
|
|
74
|
+
emitSelectionChanged: function(value) {
|
|
75
|
+
this.$emit("selectionChanged", this.index, value);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
props: {
|
|
79
|
+
index: Number,
|
|
80
|
+
parent: Object,
|
|
81
|
+
possibleValues: Array,
|
|
82
|
+
vModel: Number,
|
|
83
|
+
},
|
|
84
|
+
template: `
|
|
85
|
+
<el-select class="discrete" popper-class="discrete-popper" size="mini" v-model="vModel" :popper-append-to-body="false" @change="emitSelectionChanged">
|
|
86
|
+
<el-option v-for="possibleValue in possibleValues" :key="possibleValue.value" :label="possibleValue.name" :value="possibleValue.value" />
|
|
87
|
+
</el-select>
|
|
88
|
+
`,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const VueSlider = Vue.extend({
|
|
92
|
+
methods: {
|
|
93
|
+
emitSynchroniseSliderAndInputNumber: function(value) {
|
|
94
|
+
this.$emit("synchroniseSliderAndInputNumber", this.index, value);
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
props: {
|
|
98
|
+
disabled: Boolean,
|
|
99
|
+
index: Number,
|
|
100
|
+
maximumValue: Number,
|
|
101
|
+
parent: Object,
|
|
102
|
+
vModel: Number,
|
|
103
|
+
},
|
|
104
|
+
template: `
|
|
105
|
+
<el-slider v-model="vModel" :disabled="disabled" :max="maximumValue" :show-input="false" :show-tooltip="false" @input="emitSynchroniseSliderAndInputNumber" />
|
|
106
|
+
`,
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
export default class Ui {
|
|
110
|
+
discreteElements = [];
|
|
111
|
+
scalarElements = [];
|
|
112
|
+
|
|
113
|
+
setVueAttributes(root, element) {
|
|
114
|
+
root.attributes.forEach((attribute) => {
|
|
115
|
+
element.setAttribute(attribute.nodeName, attribute.nodeValue);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
element.children.forEach((childElement) => {
|
|
119
|
+
this.setVueAttributes(root, childElement);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
addVueElement(root, parent, element) {
|
|
124
|
+
element.$mount();
|
|
125
|
+
|
|
126
|
+
this.setVueAttributes(root, element.$el);
|
|
127
|
+
|
|
128
|
+
parent.appendChild(element.$el);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
selectionChanged() {
|
|
132
|
+
// Enable/disable all the scalar elements.
|
|
133
|
+
|
|
134
|
+
let ui = (this instanceof Ui)?this:this.parent;
|
|
135
|
+
|
|
136
|
+
ui.scalarElements.forEach((scalarElement) => {
|
|
137
|
+
let enabled = scalarElement.enabled;
|
|
138
|
+
|
|
139
|
+
if (enabled !== undefined) {
|
|
140
|
+
let disabled = !evaluateValue(ui, enabled);
|
|
141
|
+
|
|
142
|
+
scalarElement.slider.disabled = disabled;
|
|
143
|
+
scalarElement.input_number.disabled = disabled;
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
synchroniseSliderAndInputNumber(index, value) {
|
|
149
|
+
// Make sure that both a slider and its corresponding input number have
|
|
150
|
+
// the same value.
|
|
151
|
+
|
|
152
|
+
this.parent.scalarElements[index].slider.vModel = value;
|
|
153
|
+
this.parent.scalarElements[index].input_number.vModel = value;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
constructor(parent) {
|
|
157
|
+
// Generate the UI for the input fields.
|
|
158
|
+
|
|
159
|
+
let inputRoot = parent.$refs.input;
|
|
160
|
+
let isPreviousDiscrete = true;
|
|
161
|
+
let slidersAndFieldsContainer = undefined;
|
|
162
|
+
let firstScalarInput = true;
|
|
163
|
+
let discreteElementIndex = -1;
|
|
164
|
+
let scalarElementIndex = -1;
|
|
165
|
+
|
|
166
|
+
parent.json.input.forEach((input) => {
|
|
167
|
+
// Determine whether we are dealing with a discrete or a scalar input.
|
|
168
|
+
|
|
169
|
+
let isDiscrete = input.possibleValues !== undefined;
|
|
170
|
+
|
|
171
|
+
// Determine our element mode and create a container for our sliders and
|
|
172
|
+
// input numbers, if needed.
|
|
173
|
+
|
|
174
|
+
if (!isDiscrete && isPreviousDiscrete) {
|
|
175
|
+
slidersAndFieldsContainer = new VueContainer();
|
|
176
|
+
|
|
177
|
+
this.addVueElement(inputRoot, inputRoot, slidersAndFieldsContainer);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
isPreviousDiscrete = isDiscrete;
|
|
181
|
+
|
|
182
|
+
// Add the Label.
|
|
183
|
+
|
|
184
|
+
let label = new VueLabel({
|
|
185
|
+
propsData: {
|
|
186
|
+
classes: "default " + (isDiscrete?"discrete":firstScalarInput?"first-scalar":"scalar"),
|
|
187
|
+
label: input.name,
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
this.addVueElement(inputRoot, isDiscrete?inputRoot:slidersAndFieldsContainer.$el, label);
|
|
192
|
+
|
|
193
|
+
firstScalarInput = isDiscrete;
|
|
194
|
+
|
|
195
|
+
// Add a drop-down list or a slider and a text box depending on whether
|
|
196
|
+
// we are dealing with a discrete or a scalar input.
|
|
197
|
+
|
|
198
|
+
if (isDiscrete) {
|
|
199
|
+
// Add the drop-down list.
|
|
200
|
+
|
|
201
|
+
++discreteElementIndex;
|
|
202
|
+
|
|
203
|
+
let select = new VueSelect({
|
|
204
|
+
propsData: {
|
|
205
|
+
index: discreteElementIndex,
|
|
206
|
+
parent: this,
|
|
207
|
+
possibleValues: input.possibleValues,
|
|
208
|
+
vModel: input.defaultValue,
|
|
209
|
+
},
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
this.addVueElement(inputRoot, inputRoot, select);
|
|
213
|
+
|
|
214
|
+
select.$on("selectionChanged", this.selectionChanged);
|
|
215
|
+
|
|
216
|
+
// Keep track of the select and its id.
|
|
217
|
+
|
|
218
|
+
this.discreteElements[discreteElementIndex] = {
|
|
219
|
+
id: input.id,
|
|
220
|
+
select: select,
|
|
221
|
+
};
|
|
222
|
+
} else {
|
|
223
|
+
// Add the slider and input number.
|
|
224
|
+
|
|
225
|
+
++scalarElementIndex;
|
|
226
|
+
|
|
227
|
+
let slider = new VueSlider({
|
|
228
|
+
propsData: {
|
|
229
|
+
index: scalarElementIndex,
|
|
230
|
+
maximumValue: input.maximumValue,
|
|
231
|
+
parent: this,
|
|
232
|
+
vModel: input.defaultValue,
|
|
233
|
+
},
|
|
234
|
+
});
|
|
235
|
+
let inputNumber = new VueInputNumber({
|
|
236
|
+
propsData: {
|
|
237
|
+
index: scalarElementIndex,
|
|
238
|
+
maximumValue: input.maximumValue,
|
|
239
|
+
minimumValue: input.minimumValue,
|
|
240
|
+
parent: this,
|
|
241
|
+
vModel: input.defaultValue,
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
this.addVueElement(inputRoot, slidersAndFieldsContainer.$el, slider);
|
|
246
|
+
this.addVueElement(inputRoot, slidersAndFieldsContainer.$el, inputNumber);
|
|
247
|
+
|
|
248
|
+
slider.$on("synchroniseSliderAndInputNumber", this.synchroniseSliderAndInputNumber);
|
|
249
|
+
inputNumber.$on("synchroniseSliderAndInputNumber", this.synchroniseSliderAndInputNumber);
|
|
250
|
+
|
|
251
|
+
// Keep track of the slider and input number.
|
|
252
|
+
|
|
253
|
+
this.scalarElements[scalarElementIndex] = {
|
|
254
|
+
enabled: input.enabled,
|
|
255
|
+
id: input.id,
|
|
256
|
+
input_number: inputNumber,
|
|
257
|
+
slider: slider,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
// Configure the PlotVuer's.
|
|
263
|
+
// Note: the PlotVuer's are created in SimulationVuer.vue since we can't
|
|
264
|
+
// create them dynamically. So, all we need to do here is to configure
|
|
265
|
+
// them.
|
|
266
|
+
|
|
267
|
+
parent.$refs.output.classList.add("x" + parent.json.output.plots.length);
|
|
268
|
+
|
|
269
|
+
// Enable/disable all the elements by pretending that a selection changed.
|
|
270
|
+
|
|
271
|
+
this.selectionChanged();
|
|
272
|
+
}
|
|
273
|
+
}
|