linny-r 1.6.1 → 1.6.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/package.json +1 -1
- package/server.js +27 -6
- package/static/index.html +18 -0
- package/static/linny-r.css +39 -2
- package/static/scripts/linny-r-ctrl.js +8 -1
- package/static/scripts/linny-r-gui-chart-manager.js +80 -16
- package/static/scripts/linny-r-gui-controller.js +3 -3
- package/static/scripts/linny-r-gui-equation-manager.js +19 -0
- package/static/scripts/linny-r-gui-experiment-manager.js +14 -3
- package/static/scripts/linny-r-gui-expression-editor.js +1 -1
- package/static/scripts/linny-r-gui-monitor.js +1 -0
- package/static/scripts/linny-r-gui-paper.js +25 -23
- package/static/scripts/linny-r-model.js +134 -82
- package/static/scripts/linny-r-utils.js +15 -1
- package/static/scripts/linny-r-vm.js +248 -58
package/package.json
CHANGED
package/server.js
CHANGED
@@ -1521,7 +1521,7 @@ function connectionErrorText(msg) {
|
|
1521
1521
|
//
|
1522
1522
|
|
1523
1523
|
function commandLineSettings() {
|
1524
|
-
// Sets default settings, and then checks the command line arguments
|
1524
|
+
// Sets default settings, and then checks the command line arguments.
|
1525
1525
|
const settings = {
|
1526
1526
|
cli_name: (PLATFORM.startsWith('win') ? 'Command Prompt' : 'Terminal'),
|
1527
1527
|
inkscape: '',
|
@@ -1533,6 +1533,22 @@ function commandLineSettings() {
|
|
1533
1533
|
solver_path: '',
|
1534
1534
|
user_dir: path.join(WORKING_DIRECTORY, 'user')
|
1535
1535
|
};
|
1536
|
+
const
|
1537
|
+
cmd = process.argv[0],
|
1538
|
+
app = (cmd.endsWith('node.exe') ? 'node' : 'linny-r'),
|
1539
|
+
usage = `Usage: ${app} server [options]
|
1540
|
+
|
1541
|
+
Possible options are:
|
1542
|
+
dpi=[number] will make InkScape render SVGs in the specified resolution
|
1543
|
+
help will display these command line options
|
1544
|
+
launch will open the Linny-R GUI in a browser window
|
1545
|
+
port=[number] will listen at the specified port number
|
1546
|
+
(default is 5050; number must be unique for each server)
|
1547
|
+
solver=[name] will select solver [name], or warn if not found
|
1548
|
+
(name choices: Gurobi, CPLEX, SCIP or LP_solve)
|
1549
|
+
verbose will output solver messages to the console
|
1550
|
+
workspace=[path] will create workspace in [path] instead of (Linny-R)/user
|
1551
|
+
`;
|
1536
1552
|
for(let i = 2; i < process.argv.length; i++) {
|
1537
1553
|
const lca = process.argv[i].toLowerCase();
|
1538
1554
|
if(lca === 'launch') {
|
@@ -1541,7 +1557,7 @@ function commandLineSettings() {
|
|
1541
1557
|
const av = lca.split('=');
|
1542
1558
|
if(av.length === 1) av.push('');
|
1543
1559
|
if(av[0] === 'port') {
|
1544
|
-
// Accept any number greater than or equal to 1024
|
1560
|
+
// Accept any number greater than or equal to 1024.
|
1545
1561
|
const n = parseInt(av[1]);
|
1546
1562
|
if(isNaN(n) || n < 1024) {
|
1547
1563
|
console.log(`WARNING: Invalid port number ${av[1]}`);
|
@@ -1555,7 +1571,7 @@ function commandLineSettings() {
|
|
1555
1571
|
settings.preferred_solver = av[1];
|
1556
1572
|
}
|
1557
1573
|
} else if(av[0] === 'dpi') {
|
1558
|
-
// Accept any number greater than or equal to 1024
|
1574
|
+
// Accept any number greater than or equal to 1024.
|
1559
1575
|
const n = parseInt(av[1]);
|
1560
1576
|
if(isNaN(n) || n > 1200) {
|
1561
1577
|
console.log(`WARNING: Invalid resolution ${av[1]} (max. 1200 dpi)`);
|
@@ -1563,7 +1579,7 @@ function commandLineSettings() {
|
|
1563
1579
|
settings.dpi = n;
|
1564
1580
|
}
|
1565
1581
|
} else if(av[0] === 'workspace') {
|
1566
|
-
// User directory must be READ/WRITE-accessible
|
1582
|
+
// User directory must be READ/WRITE-accessible.
|
1567
1583
|
try {
|
1568
1584
|
fs.accessSync(av[1], fs.constants.R_OK | fs.constants.W_O);
|
1569
1585
|
} catch(err) {
|
@@ -1571,10 +1587,15 @@ function commandLineSettings() {
|
|
1571
1587
|
process.exit();
|
1572
1588
|
}
|
1573
1589
|
settings.user_dir = av[1];
|
1590
|
+
} else if(av[0] === 'help') {
|
1591
|
+
// Print command line options.
|
1592
|
+
console.log(usage);
|
1593
|
+
process.exit();
|
1574
1594
|
} else {
|
1575
|
-
// Terminate script
|
1595
|
+
// Terminate script.
|
1576
1596
|
console.log(
|
1577
|
-
`ERROR: Invalid command line argument "${process.argv[i]}"`);
|
1597
|
+
`ERROR: Invalid command line argument "${process.argv[i]}"\n`);
|
1598
|
+
console.log(usage);
|
1578
1599
|
process.exit();
|
1579
1600
|
}
|
1580
1601
|
}
|
package/static/index.html
CHANGED
@@ -1765,6 +1765,8 @@ NOTE: * and ? will be interpreted as wildcards"
|
|
1765
1765
|
<img id="eq-delete-btn" class="btn disab" src="images/delete.png"
|
1766
1766
|
title="Delete selected equation">
|
1767
1767
|
</div>
|
1768
|
+
<img id="equation-outcome" class="not-selected" src="images/outcome.png"
|
1769
|
+
title="Click to consider/ignore selected equation as experiment outcome">
|
1768
1770
|
<div id="equation-scroll-area">
|
1769
1771
|
<table id="equation-table">
|
1770
1772
|
</table>
|
@@ -2011,6 +2013,22 @@ NOTE: * and ? will be interpreted as wildcards"
|
|
2011
2013
|
</div>
|
2012
2014
|
</div>
|
2013
2015
|
|
2016
|
+
<!-- the ADD WILDCARD VARIABLES dialog allows selecting wildcard
|
2017
|
+
variables from a list to be added to the current chart -->
|
2018
|
+
<div id="add-wildcard-variables-modal" class="modal">
|
2019
|
+
<div id="add-wildcard-variables-dlg" class="inp-dlg">
|
2020
|
+
<div class="dlg-title">
|
2021
|
+
Add wildcard matches
|
2022
|
+
<img class="cancel-btn" src="images/cancel.png">
|
2023
|
+
<img class="ok-btn" src="images/ok.png">
|
2024
|
+
</div>
|
2025
|
+
<div id="add-wildcard-variables-scroll-area">
|
2026
|
+
<table id="add-wildcard-variables-table">
|
2027
|
+
</table>
|
2028
|
+
</div>
|
2029
|
+
</div>
|
2030
|
+
</div>
|
2031
|
+
|
2014
2032
|
<!-- the RENAME CHART dialog prompts for the new title for a chart -->
|
2015
2033
|
<div id="rename-chart-modal" class="modal">
|
2016
2034
|
<div id="rename-chart-dlg" class="inp-dlg">
|
package/static/linny-r.css
CHANGED
@@ -2161,7 +2161,8 @@ div.io-box {
|
|
2161
2161
|
cursor: pointer;
|
2162
2162
|
}
|
2163
2163
|
|
2164
|
-
#dataset-outcome.not-selected
|
2164
|
+
#dataset-outcome.not-selected,
|
2165
|
+
#equation-outcome.not-selected {
|
2165
2166
|
filter: saturate(0) contrast(50%) brightness(170%);
|
2166
2167
|
}
|
2167
2168
|
|
@@ -2273,10 +2274,12 @@ div.modif::before {
|
|
2273
2274
|
margin-right: 2px;
|
2274
2275
|
}
|
2275
2276
|
|
2276
|
-
div.outcome::before
|
2277
|
+
div.outcome::before,
|
2278
|
+
span.outcome::before {
|
2277
2279
|
content: ' \25C8';
|
2278
2280
|
color: #b00080;
|
2279
2281
|
margin-right: 1px;
|
2282
|
+
font-style: normal;
|
2280
2283
|
}
|
2281
2284
|
|
2282
2285
|
div.array::before {
|
@@ -2449,6 +2452,15 @@ td.equation-expression {
|
|
2449
2452
|
border-top: 1px solid Silver;
|
2450
2453
|
}
|
2451
2454
|
|
2455
|
+
#equation-outcome {
|
2456
|
+
position: absolute;
|
2457
|
+
top: 25px;
|
2458
|
+
right: 4px;
|
2459
|
+
width: 16px;
|
2460
|
+
height: 16px;
|
2461
|
+
cursor: pointer;
|
2462
|
+
}
|
2463
|
+
|
2452
2464
|
/* NOTE: Rename equation modal must be above Edit variable modal */
|
2453
2465
|
#rename-equation-modal {
|
2454
2466
|
z-index: 110;
|
@@ -3098,6 +3110,31 @@ img.v-disab {
|
|
3098
3110
|
width: calc(100% - 6px);
|
3099
3111
|
}
|
3100
3112
|
|
3113
|
+
#add-wildcard-variables-dlg {
|
3114
|
+
width: 250px;
|
3115
|
+
min-height: 42px;
|
3116
|
+
max-height: 50vh;
|
3117
|
+
}
|
3118
|
+
|
3119
|
+
#add-wildcard-variables-scroll-area {
|
3120
|
+
position: absolute;
|
3121
|
+
top: 22px;
|
3122
|
+
left: 2px;
|
3123
|
+
width: calc(100% - 4px);
|
3124
|
+
height: calc(100% - 26px);
|
3125
|
+
overflow-y: auto;
|
3126
|
+
border-top: 1px solid Silver;
|
3127
|
+
}
|
3128
|
+
|
3129
|
+
#add-wildcard-variables-table {
|
3130
|
+
width: 100%;
|
3131
|
+
border-collapse: collapse;
|
3132
|
+
line-height: 16px;
|
3133
|
+
background-color: white;
|
3134
|
+
border: 1px solid Silver;
|
3135
|
+
border-top: none;
|
3136
|
+
}
|
3137
|
+
|
3101
3138
|
/* the SENSITIVITY DIALOG displays the sensitivity analysis */
|
3102
3139
|
#sensitivity-dlg {
|
3103
3140
|
display: none;
|
@@ -834,12 +834,19 @@ class ChartManager {
|
|
834
834
|
}
|
835
835
|
|
836
836
|
resetChartVectors() {
|
837
|
-
// Reset vectors of all charts
|
837
|
+
// Reset vectors of all charts.
|
838
838
|
for(let i = 0; i < MODEL.charts.length; i++) {
|
839
839
|
MODEL.charts[i].resetVectors();
|
840
840
|
}
|
841
841
|
}
|
842
842
|
|
843
|
+
promptForWildcardIndices(chart, dsm) {
|
844
|
+
// No GUI dialog, so add *all* vectors for wildcard dataset modifier
|
845
|
+
// `dsm` as variables to `chart`.
|
846
|
+
const indices = Object.keys(dsm.expression.wildcard_vectors);
|
847
|
+
chart.addWildcardVariables(dsm, indices);
|
848
|
+
}
|
849
|
+
|
843
850
|
setRunsChart(show) {
|
844
851
|
// Indicate whether the chart manager should display a run result chart.
|
845
852
|
this.runs_chart = show;
|
@@ -131,7 +131,7 @@ class GUIChartManager extends ChartManager {
|
|
131
131
|
document.getElementById('chart-narrow-btn').addEventListener(
|
132
132
|
'click', () => CHART_MANAGER.stretchChart(-1));
|
133
133
|
|
134
|
-
// The Add variable modal
|
134
|
+
// The Add variable modal.
|
135
135
|
this.add_variable_modal = new ModalDialog('add-variable');
|
136
136
|
this.add_variable_modal.ok.addEventListener(
|
137
137
|
'click', () => CHART_MANAGER.addVariable());
|
@@ -143,7 +143,7 @@ class GUIChartManager extends ChartManager {
|
|
143
143
|
this.add_variable_modal.element('name').addEventListener(
|
144
144
|
'change', () => X_EDIT.updateAttributeSelector('add-'));
|
145
145
|
|
146
|
-
// The Edit variable modal
|
146
|
+
// The Edit variable modal.
|
147
147
|
this.variable_modal = new ModalDialog('variable');
|
148
148
|
this.variable_modal.ok.addEventListener(
|
149
149
|
'click', () => CHART_MANAGER.modifyVariable());
|
@@ -160,7 +160,7 @@ class GUIChartManager extends ChartManager {
|
|
160
160
|
'mouseleave', () => CHART_MANAGER.hidePasteColor());
|
161
161
|
document.getElementById('variable-color').addEventListener(
|
162
162
|
'click', (event) => CHART_MANAGER.copyPasteColor(event));
|
163
|
-
// NOTE:
|
163
|
+
// NOTE: Uses the color picker developed by James Daniel.
|
164
164
|
this.color_picker = new iro.ColorPicker("#color-picker", {
|
165
165
|
width: 92,
|
166
166
|
height: 92,
|
@@ -179,13 +179,20 @@ class GUIChartManager extends ChartManager {
|
|
179
179
|
CHART_MANAGER.color_picker.color.hexString;
|
180
180
|
});
|
181
181
|
|
182
|
-
// The Rename chart modal
|
182
|
+
// The Rename chart modal.
|
183
183
|
this.rename_chart_modal = new ModalDialog('rename-chart');
|
184
184
|
this.rename_chart_modal.ok.addEventListener(
|
185
185
|
'click', () => CHART_MANAGER.renameChart());
|
186
186
|
this.rename_chart_modal.cancel.addEventListener(
|
187
187
|
'click', () => CHART_MANAGER.rename_chart_modal.hide());
|
188
188
|
|
189
|
+
// The Add wildcard variables modal.
|
190
|
+
this.add_wildcard_modal = new ModalDialog('add-wildcard-variables');
|
191
|
+
this.add_wildcard_modal.ok.addEventListener(
|
192
|
+
'click', () => CHART_MANAGER.addSelectedWildcardVariables());
|
193
|
+
this.add_wildcard_modal.cancel.addEventListener(
|
194
|
+
'click', () => CHART_MANAGER.add_wildcard_modal.hide());
|
195
|
+
|
189
196
|
// Do not display the time step until cursor moves over chart
|
190
197
|
this.time_step.style.display = 'none';
|
191
198
|
document.getElementById('table-only-buttons').style.display = 'none';
|
@@ -326,16 +333,25 @@ class GUIChartManager extends ChartManager {
|
|
326
333
|
}
|
327
334
|
|
328
335
|
updateSelector() {
|
329
|
-
// Adds one option to the selector for each chart defined for the model
|
330
|
-
// NOTE:
|
336
|
+
// Adds one option to the selector for each chart defined for the model.
|
337
|
+
// NOTE: Add the "new chart" option if it is not in the list.
|
331
338
|
MODEL.addChart(this.new_chart_title);
|
332
339
|
if(this.chart_index < 0) this.chart_index = 0;
|
333
340
|
const ol = [];
|
334
341
|
for(let i = 0; i < MODEL.charts.length; i++) {
|
335
|
-
|
336
|
-
|
337
|
-
|
342
|
+
const t = MODEL.charts[i].title;
|
343
|
+
ol.push(['<option value="', i,
|
344
|
+
(i == this.chart_index ? '" selected="selected' : ''),
|
345
|
+
'">', t , '</option>'].join(''));
|
338
346
|
}
|
347
|
+
// Sort option list by chart title.
|
348
|
+
ol.sort((a, b) => {
|
349
|
+
const
|
350
|
+
re = /<option value="\d+"( selected="selected")?>(.+)<\/option>/,
|
351
|
+
ta = a.replace(re, '$2'),
|
352
|
+
tb = b.replace(re, '$2');
|
353
|
+
return UI.compareFullNames(ta, tb);
|
354
|
+
});
|
339
355
|
this.chart_selector.innerHTML = ol.join('');
|
340
356
|
}
|
341
357
|
|
@@ -379,6 +395,11 @@ class GUIChartManager extends ChartManager {
|
|
379
395
|
} else {
|
380
396
|
this.variable_index = -1;
|
381
397
|
}
|
398
|
+
// Just in case variable index has not been adjusted after some
|
399
|
+
// variables have been deleted
|
400
|
+
if(this.variable_index >= c.variables.length) {
|
401
|
+
this.variable_index = -1;
|
402
|
+
}
|
382
403
|
// Set the image of the sort type button.
|
383
404
|
if(this.variable_index >= 0) {
|
384
405
|
const
|
@@ -392,11 +413,6 @@ class GUIChartManager extends ChartManager {
|
|
392
413
|
u_btn = 'chart-variable-up ',
|
393
414
|
d_btn = 'chart-variable-down ',
|
394
415
|
ed_btns = 'chart-edit-variable chart-sort-variable chart-delete-variable ';
|
395
|
-
// Just in case variable index has not been adjusted after some
|
396
|
-
// variables have been deleted
|
397
|
-
if(this.variable_index >= c.variables.length) {
|
398
|
-
this.variable_index = -1;
|
399
|
-
}
|
400
416
|
if(this.variable_index < 0) {
|
401
417
|
UI.disableButtons(ed_btns + u_btn + d_btn);
|
402
418
|
} else {
|
@@ -713,15 +729,63 @@ class GUIChartManager extends ChartManager {
|
|
713
729
|
}
|
714
730
|
}
|
715
731
|
|
732
|
+
promptForWildcardIndices(chart, dsm) {
|
733
|
+
// Prompt modeler with list of vectors for wildcard dataset modifier
|
734
|
+
// `dsm` as variables to `chart`.
|
735
|
+
const
|
736
|
+
md = this.add_wildcard_modal,
|
737
|
+
indices = Object.keys(dsm.expression.wildcard_vectors);
|
738
|
+
// First hide the "Add variable" modal.
|
739
|
+
this.add_variable_modal.hide();
|
740
|
+
// Do not prompt for selection if there is only 1 match.
|
741
|
+
if(indices.length < 2) chart.addWildcardVariables(dsm, indices);
|
742
|
+
md.chart = chart;
|
743
|
+
md.modifier = dsm;
|
744
|
+
md.indices = indices;
|
745
|
+
const
|
746
|
+
tr = [],
|
747
|
+
dn = dsm.displayName,
|
748
|
+
tbl = md.element('table');
|
749
|
+
for(let i = 0; i < indices.length; i++) {
|
750
|
+
tr.push('<tr><td class="v-box"><div id="wcv-box-', indices[i],
|
751
|
+
'" class="box clear" onclick="UI.toggleBox(event);"></td>',
|
752
|
+
'<td class="vname">', dn.replace('??', indices[i]),
|
753
|
+
'</td></tr>');
|
754
|
+
tbl.innerHTML = tr.join('');
|
755
|
+
}
|
756
|
+
md.dialog.style.height = (22 + indices.length * 16) + 'px';
|
757
|
+
md.show();
|
758
|
+
}
|
759
|
+
|
760
|
+
addSelectedWildcardVariables() {
|
761
|
+
// Let the chart add selected wildcard matches (if any) as chart
|
762
|
+
// variables.
|
763
|
+
const
|
764
|
+
md = this.add_wildcard_modal,
|
765
|
+
c = md.chart,
|
766
|
+
dsm = md.modifier,
|
767
|
+
il = md.indices,
|
768
|
+
indices = [];
|
769
|
+
if(c && dsm && il) {
|
770
|
+
for(let i = 0; i < il.length; i++) {
|
771
|
+
if(UI.boxChecked('wcv-box-'+ il[i])) indices.push(il[i]);
|
772
|
+
}
|
773
|
+
}
|
774
|
+
if(indices.length) c.addWildcardVariables(dsm, indices);
|
775
|
+
// Always hide the dialog.
|
776
|
+
md.hide();
|
777
|
+
this.updateDialog();
|
778
|
+
}
|
779
|
+
|
716
780
|
selectVariable(vi) {
|
717
|
-
// Select variable, and edit it when double-clicked
|
781
|
+
// Select variable, and edit it when double-clicked.
|
718
782
|
const
|
719
783
|
now = Date.now(),
|
720
784
|
dt = now - this.last_time_selected;
|
721
785
|
if(vi >= 0 && this.chart_index >= 0) {
|
722
786
|
this.last_time_selected = now;
|
723
787
|
if(vi === this.variable_index) {
|
724
|
-
// Consider click to be "double" if it occurred less than 300 ms ago
|
788
|
+
// Consider click to be "double" if it occurred less than 300 ms ago.
|
725
789
|
if(dt < 300) {
|
726
790
|
this.last_time_selected = 0;
|
727
791
|
this.editVariable();
|
@@ -109,7 +109,7 @@ class GroupPropertiesDialog extends ModalDialog {
|
|
109
109
|
// input fields this means `onkeydown` events.
|
110
110
|
const fnc = (event) => {
|
111
111
|
const id = event.target.id.split('-').shift();
|
112
|
-
// NOTE:
|
112
|
+
// NOTE: Add a short delay to permit checkboxes to update their
|
113
113
|
// status first, before checking for change.
|
114
114
|
setTimeout(() => UI.modals[id].highlightModifiedFields(), 100);
|
115
115
|
};
|
@@ -819,8 +819,8 @@ class GUIController extends Controller {
|
|
819
819
|
|
820
820
|
// Add all draggable stay-on-top dialogs as controller properties.
|
821
821
|
|
822
|
-
// Make checkboxes respond to click
|
823
|
-
// NOTE:
|
822
|
+
// Make checkboxes respond to click.
|
823
|
+
// NOTE: Checkbox-specific events must be bound AFTER this general setting.
|
824
824
|
const
|
825
825
|
cbs = document.getElementsByClassName('box'),
|
826
826
|
cbf = (event) => UI.toggleBox(event);
|
@@ -54,6 +54,9 @@ class EquationManager {
|
|
54
54
|
'click', () => EQUATION_MANAGER.editEquation());
|
55
55
|
document.getElementById('eq-delete-btn').addEventListener(
|
56
56
|
'click', () => EQUATION_MANAGER.deleteEquation());
|
57
|
+
this.outcome_btn = document.getElementById('equation-outcome');
|
58
|
+
this.outcome_btn.addEventListener(
|
59
|
+
'click', () => EQUATION_MANAGER.toggleOutcome());
|
57
60
|
|
58
61
|
// Create modal dialogs
|
59
62
|
this.new_modal = new ModalDialog('new-equation');
|
@@ -134,6 +137,11 @@ class EquationManager {
|
|
134
137
|
ml = [],
|
135
138
|
msl = ed.selectorList,
|
136
139
|
sm = this.selected_modifier;
|
140
|
+
if(sm && sm.outcome_equation) {
|
141
|
+
this.outcome_btn.classList.remove('not-selected');
|
142
|
+
} else {
|
143
|
+
this.outcome_btn.classList.add('not-selected');
|
144
|
+
}
|
137
145
|
let smid = 'eqmtr';
|
138
146
|
for(let i = 0; i < msl.length; i++) {
|
139
147
|
const
|
@@ -155,6 +163,7 @@ class EquationManager {
|
|
155
163
|
(m.expression.noMethodObject ? ' no-object' : ''),
|
156
164
|
(m.expression.isStatic ? '' : ' it'), issue,
|
157
165
|
(wild ? ' wildcard' : ''), clk, ', false);"', mover, '>',
|
166
|
+
(m.outcome_equation ? '<span class="outcome"></span>' : ''),
|
158
167
|
(wild ? wildcardFormat(m.selector) : m.selector),
|
159
168
|
'</td><td class="equation-expression', issue,
|
160
169
|
(issue ? '"title="' +
|
@@ -201,6 +210,16 @@ class EquationManager {
|
|
201
210
|
this.updateDialog();
|
202
211
|
}
|
203
212
|
|
213
|
+
toggleOutcome() {
|
214
|
+
const m = this.selected_modifier;
|
215
|
+
// NOTE: Methods cannot be outcomes.
|
216
|
+
if(m && !m.selector.startsWith(':')) {
|
217
|
+
m.outcome_equation = !m.outcome_equation;
|
218
|
+
this.updateDialog();
|
219
|
+
if(!UI.hidden('experiment-dlg')) EXPERIMENT_MANAGER.updateDialog();
|
220
|
+
}
|
221
|
+
}
|
222
|
+
|
204
223
|
promptForEquation(add=false) {
|
205
224
|
this.add_to_chart = add;
|
206
225
|
this.new_modal.element('name').value = '';
|
@@ -356,7 +356,11 @@ class GUIExperimentManager extends ExperimentManager {
|
|
356
356
|
dim_count.innerHTML = pluralS(x.available_dimensions.length,
|
357
357
|
'more dimension');
|
358
358
|
x.inferActualDimensions();
|
359
|
+
for(let i = 0; i < x.actual_dimensions.length; i++) {
|
360
|
+
x.actual_dimensions[i].sort(compareSelectors);
|
361
|
+
}
|
359
362
|
x.inferCombinations();
|
363
|
+
//x.combinations.sort(compareCombinations);
|
360
364
|
combi_count.innerHTML = pluralS(x.combinations.length, 'combination');
|
361
365
|
if(x.combinations.length === 0) canview = false;
|
362
366
|
header.innerHTML = x.title;
|
@@ -850,6 +854,9 @@ class GUIExperimentManager extends ExperimentManager {
|
|
850
854
|
}
|
851
855
|
// Get the selected statistic for each run so as to get an array of numbers
|
852
856
|
const data = [];
|
857
|
+
// Set reference column indices so that values for the reference|
|
858
|
+
// configuration can be displayed in orange.
|
859
|
+
const ref_conf_indices = [];
|
853
860
|
for(let i = 0; i < x.runs.length; i++) {
|
854
861
|
const
|
855
862
|
r = x.runs[i],
|
@@ -878,7 +885,7 @@ class GUIExperimentManager extends ExperimentManager {
|
|
878
885
|
data.push(rr.last);
|
879
886
|
}
|
880
887
|
}
|
881
|
-
// Scale data as selected
|
888
|
+
// Scale data as selected.
|
882
889
|
const scaled = data.slice();
|
883
890
|
// NOTE: scale only after the experiment has been completed AND
|
884
891
|
// configurations have been defined (otherwise comparison is pointless)
|
@@ -896,7 +903,9 @@ class GUIExperimentManager extends ExperimentManager {
|
|
896
903
|
}
|
897
904
|
// Set difference for reference configuration itself to 0
|
898
905
|
for(let i = 0; i < n; i++) {
|
899
|
-
|
906
|
+
const index = rc * n + i;
|
907
|
+
scaled[index] = 0;
|
908
|
+
ref_conf_indices.push(index);
|
900
909
|
}
|
901
910
|
} else if(x.selected_scale === 'reg') {
|
902
911
|
// Compute regret: current config - high value config in same scenario
|
@@ -934,13 +943,15 @@ class GUIExperimentManager extends ExperimentManager {
|
|
934
943
|
formatted.push(VM.sig4Dig(scaled[i]));
|
935
944
|
}
|
936
945
|
uniformDecimals(formatted);
|
937
|
-
// Display formatted data in cells
|
946
|
+
// Display formatted data in cells.
|
938
947
|
for(let i = 0; i < x.combinations.length; i++) {
|
939
948
|
const cell = document.getElementById('xr' + i);
|
940
949
|
if(i < x.runs.length) {
|
941
950
|
cell.innerHTML = formatted[i];
|
942
951
|
cell.classList.remove('not-run');
|
943
952
|
cell.style.backgroundColor = this.color_scale.rgb(normalized[i]);
|
953
|
+
cell.style.color = (ref_conf_indices.indexOf(i) >= 0 ?
|
954
|
+
'orange' : 'black');
|
944
955
|
const
|
945
956
|
r = x.runs[i],
|
946
957
|
rr = r.results[rri],
|
@@ -377,7 +377,7 @@ NOTE: Grouping groups results in a single group, e.g., (1;2);(3;4;5) evaluates a
|
|
377
377
|
}
|
378
378
|
va.innerHTML = options.join('');
|
379
379
|
// NOTE: Chart Manager variable dialog is 60px wider
|
380
|
-
va.style.width = (prefix ? 'calc(100% -
|
380
|
+
va.style.width = (prefix ? 'calc(100% - 84px)' : 'calc(100% - 142px)');
|
381
381
|
return;
|
382
382
|
}
|
383
383
|
// Add "empty" as first and initial option, as it denotes "use default"
|