syd 1.1.0__py3-none-any.whl → 1.2.0__py3-none-any.whl
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.
- syd/__init__.py +2 -1
- syd/flask_deployment/deployer.py +107 -23
- syd/flask_deployment/static/css/styles.css +77 -62
- syd/flask_deployment/static/css/viewer.css +0 -42
- syd/flask_deployment/static/js/modules/api.js +89 -0
- syd/flask_deployment/static/js/modules/config.js +22 -0
- syd/flask_deployment/static/js/modules/plot.js +75 -0
- syd/flask_deployment/static/js/modules/state.js +89 -0
- syd/flask_deployment/static/js/modules/system_controls.js +191 -0
- syd/flask_deployment/static/js/modules/ui_controls.js +812 -0
- syd/flask_deployment/static/js/modules/utils.js +49 -0
- syd/flask_deployment/static/js/old_viewer.js +1195 -0
- syd/flask_deployment/static/js/viewer.js +40 -1177
- syd/flask_deployment/templates/index.html +1 -1
- syd/support.py +25 -0
- syd/viewer.py +4 -0
- {syd-1.1.0.dist-info → syd-1.2.0.dist-info}/METADATA +18 -5
- syd-1.2.0.dist-info/RECORD +28 -0
- syd-1.1.0.dist-info/RECORD +0 -20
- {syd-1.1.0.dist-info → syd-1.2.0.dist-info}/WHEEL +0 -0
- {syd-1.1.0.dist-info → syd-1.2.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { updateControlValue } from './ui_controls.js';
|
|
2
|
+
import { updatePlot } from './plot.js';
|
|
3
|
+
import { updateParameterOnServer } from './api.js';
|
|
4
|
+
import { updateStatus } from './utils.js';
|
|
5
|
+
|
|
6
|
+
export let state = {};
|
|
7
|
+
export let paramInfo = {};
|
|
8
|
+
export let paramOrder = [];
|
|
9
|
+
let isUpdating = false;
|
|
10
|
+
|
|
11
|
+
// Function to initialize state (called after fetching initial data)
|
|
12
|
+
export function initializeState(initialData) {
|
|
13
|
+
paramInfo = initialData.params;
|
|
14
|
+
paramOrder = initialData.param_order;
|
|
15
|
+
// Initialize state from parameter info
|
|
16
|
+
for (const [name, param] of Object.entries(paramInfo)) {
|
|
17
|
+
state[name] = param.value;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Update a parameter value and send to server
|
|
23
|
+
*/
|
|
24
|
+
export function updateParameter(name, value) {
|
|
25
|
+
// Prevent recursive updates
|
|
26
|
+
if (isUpdating) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
// Indicate status update
|
|
30
|
+
updateStatus('Updating ' + name + '...');
|
|
31
|
+
|
|
32
|
+
// Update local state
|
|
33
|
+
state[name] = value;
|
|
34
|
+
|
|
35
|
+
// Send update to server (from api.js)
|
|
36
|
+
updateParameterOnServer(name, value)
|
|
37
|
+
.then(data => {
|
|
38
|
+
if (data.error) {
|
|
39
|
+
console.error('Error:', data.error);
|
|
40
|
+
} else {
|
|
41
|
+
// Update state with any changes from callbacks
|
|
42
|
+
updateStateFromServer(data.state, data.params);
|
|
43
|
+
// Update plot
|
|
44
|
+
updatePlot();
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
.catch(error => {
|
|
48
|
+
console.error('Error:', error);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// Indicate status update
|
|
52
|
+
updateStatus('Ready!');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Update local state from server response
|
|
57
|
+
*/
|
|
58
|
+
export function updateStateFromServer(serverState, serverParamInfo) {
|
|
59
|
+
// Set updating flag to prevent recursive updates
|
|
60
|
+
isUpdating = true;
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
// Update global paramInfo first if it changed
|
|
64
|
+
if (serverParamInfo) {
|
|
65
|
+
// Basic check: update if stringified versions differ. Might need deeper comparison.
|
|
66
|
+
if(JSON.stringify(paramInfo) !== JSON.stringify(serverParamInfo)) {
|
|
67
|
+
paramInfo = serverParamInfo;
|
|
68
|
+
// TODO: Potentially re-create controls if param info structure changed significantly?
|
|
69
|
+
// For now, we only update values below.
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Update any parameters that changed due to callbacks
|
|
74
|
+
for (const [name, value] of Object.entries(serverState)) {
|
|
75
|
+
// Check if state value changed OR if paramInfo for this specific param changed
|
|
76
|
+
const currentParamInfoStr = paramInfo[name] ? JSON.stringify(paramInfo[name]) : undefined;
|
|
77
|
+
const serverParamInfoStr = serverParamInfo && serverParamInfo[name] ? JSON.stringify(serverParamInfo[name]) : undefined;
|
|
78
|
+
|
|
79
|
+
if (JSON.stringify(state[name]) !== JSON.stringify(value) || currentParamInfoStr !== serverParamInfoStr) {
|
|
80
|
+
state[name] = value;
|
|
81
|
+
// Pass the potentially updated paramInfo for this specific control
|
|
82
|
+
updateControlValue(name, value, serverParamInfo ? serverParamInfo[name] : paramInfo[name]);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
} finally {
|
|
86
|
+
// Clear updating flag
|
|
87
|
+
isUpdating = false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { config, updateThreshold, setUpdateThreshold, setConfigValue } from './config.js';
|
|
2
|
+
// Import createFloatController - we assume it will be exported from ui_controls.js
|
|
3
|
+
import { createFloatController } from './ui_controls.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Create system controls (width, threshold, margin)
|
|
7
|
+
* @param {HTMLElement} container - The DOM element to append controls to.
|
|
8
|
+
*/
|
|
9
|
+
export function createSystemControls(container) {
|
|
10
|
+
// Create controls width slider
|
|
11
|
+
const widthControl = createFloatController('controls_width', {
|
|
12
|
+
type: 'float',
|
|
13
|
+
value: config.controlsWidthPercent,
|
|
14
|
+
min: 10,
|
|
15
|
+
max: 50,
|
|
16
|
+
step: 1
|
|
17
|
+
});
|
|
18
|
+
widthControl.className = 'numeric-control system-control';
|
|
19
|
+
|
|
20
|
+
// Add label for width control
|
|
21
|
+
const widthLabel = document.createElement('span');
|
|
22
|
+
widthLabel.className = 'control-label';
|
|
23
|
+
widthLabel.textContent = 'Controls Width %';
|
|
24
|
+
|
|
25
|
+
const widthGroup = document.createElement('div');
|
|
26
|
+
widthGroup.className = 'control-group';
|
|
27
|
+
widthGroup.appendChild(widthLabel);
|
|
28
|
+
widthGroup.appendChild(widthControl);
|
|
29
|
+
|
|
30
|
+
// Create update threshold slider
|
|
31
|
+
const thresholdControl = createFloatController('update_threshold', {
|
|
32
|
+
type: 'float',
|
|
33
|
+
value: updateThreshold,
|
|
34
|
+
min: 0.1,
|
|
35
|
+
max: 10.0,
|
|
36
|
+
step: 0.1
|
|
37
|
+
});
|
|
38
|
+
thresholdControl.className = 'numeric-control system-control';
|
|
39
|
+
|
|
40
|
+
// Add label for threshold control
|
|
41
|
+
const thresholdLabel = document.createElement('span');
|
|
42
|
+
thresholdLabel.className = 'control-label';
|
|
43
|
+
thresholdLabel.textContent = 'Update Threshold';
|
|
44
|
+
|
|
45
|
+
const thresholdGroup = document.createElement('div');
|
|
46
|
+
thresholdGroup.className = 'control-group';
|
|
47
|
+
thresholdGroup.appendChild(thresholdLabel);
|
|
48
|
+
thresholdGroup.appendChild(thresholdControl);
|
|
49
|
+
|
|
50
|
+
// Create plot margin slider
|
|
51
|
+
const plotMarginControl = createFloatController('plot_margin', {
|
|
52
|
+
type: 'float',
|
|
53
|
+
value: config.plotMarginPercent,
|
|
54
|
+
min: 0,
|
|
55
|
+
max: 50,
|
|
56
|
+
step: 1
|
|
57
|
+
});
|
|
58
|
+
plotMarginControl.className = 'numeric-control system-control';
|
|
59
|
+
|
|
60
|
+
// Add label for margin control
|
|
61
|
+
const marginLabel = document.createElement('span');
|
|
62
|
+
marginLabel.className = 'control-label';
|
|
63
|
+
marginLabel.textContent = 'Plot Margin %';
|
|
64
|
+
|
|
65
|
+
const marginGroup = document.createElement('div');
|
|
66
|
+
marginGroup.className = 'control-group';
|
|
67
|
+
marginGroup.appendChild(marginLabel);
|
|
68
|
+
marginGroup.appendChild(plotMarginControl);
|
|
69
|
+
|
|
70
|
+
// Add custom event listeners
|
|
71
|
+
// Width Control Listeners
|
|
72
|
+
function updateControlsWidth(width) {
|
|
73
|
+
setConfigValue('controlsWidthPercent', width); // Use setter from config.js
|
|
74
|
+
|
|
75
|
+
// Update the root containers using querySelector for classes
|
|
76
|
+
const rootContainer = document.querySelector('.viewer-container');
|
|
77
|
+
const controlsContainer = document.querySelector('.controls-container'); // Select the outer div by class
|
|
78
|
+
const plotContainer = document.querySelector('.plot-container');
|
|
79
|
+
|
|
80
|
+
if (rootContainer && controlsContainer && plotContainer) {
|
|
81
|
+
if (config.controlsPosition === 'left' || config.controlsPosition === 'right') {
|
|
82
|
+
controlsContainer.style.width = `${width}%`;
|
|
83
|
+
plotContainer.style.width = `${100 - width}%`;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Ensure slider/input values match
|
|
88
|
+
widthSlider.value = width;
|
|
89
|
+
widthInput.value = width;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const widthSlider = widthControl.querySelector('input[type="range"]');
|
|
93
|
+
const widthInput = widthControl.querySelector('input[type="number"]');
|
|
94
|
+
|
|
95
|
+
widthSlider.addEventListener('input', function() { // Real-time update for number input
|
|
96
|
+
updateControlsWidth(this.value);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
widthInput.addEventListener('change', function() {
|
|
100
|
+
updateControlsWidth(this.value);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Threshold Control Listeners
|
|
104
|
+
const thresholdSlider = thresholdControl.querySelector('input[type="range"]');
|
|
105
|
+
const thresholdInput = thresholdControl.querySelector('input[type="number"]');
|
|
106
|
+
|
|
107
|
+
thresholdSlider.addEventListener('input', function() { // Real-time update for number input
|
|
108
|
+
thresholdInput.value = this.value;
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
thresholdSlider.addEventListener('change', function() {
|
|
112
|
+
const newThreshold = parseFloat(this.value);
|
|
113
|
+
setUpdateThreshold(newThreshold); // Use setter from config.js
|
|
114
|
+
thresholdInput.value = newThreshold; // Ensure input matches final value
|
|
115
|
+
thresholdSlider.value = newThreshold; // Ensure slider matches final value
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// Plot Margin Control Listeners
|
|
119
|
+
const marginSlider = plotMarginControl.querySelector('input[type="range"]');
|
|
120
|
+
const marginInput = plotMarginControl.querySelector('input[type="number"]');
|
|
121
|
+
const plotContainer = document.querySelector('.plot-container');
|
|
122
|
+
|
|
123
|
+
// Function to apply margin and adjust size of the plot image
|
|
124
|
+
function applyPlotMargin(marginPercent) {
|
|
125
|
+
const plotImage = document.getElementById('plot-image'); // Get the image element
|
|
126
|
+
if (plotImage) {
|
|
127
|
+
const effectiveMargin = parseFloat(marginPercent); // Ensure it's a number
|
|
128
|
+
// Apply margin to the image
|
|
129
|
+
plotImage.style.margin = `${effectiveMargin}%`;
|
|
130
|
+
// Adjust width and height to account for the margin
|
|
131
|
+
plotImage.style.width = `calc(100% - ${2 * effectiveMargin}%)`;
|
|
132
|
+
plotImage.style.height = `calc(100% - ${2 * effectiveMargin}%)`;
|
|
133
|
+
// Reset container padding just in case
|
|
134
|
+
if (plotContainer) {
|
|
135
|
+
plotContainer.style.padding = '0';
|
|
136
|
+
}
|
|
137
|
+
setConfigValue('plotMarginPercent', effectiveMargin); // Update config using setter
|
|
138
|
+
} else {
|
|
139
|
+
console.warn('Plot image element not found when applying margin.');
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
marginSlider.addEventListener('input', function() { // Real-time update for number input
|
|
144
|
+
marginInput.value = this.value;
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
marginSlider.addEventListener('change', function() {
|
|
148
|
+
const margin = parseFloat(this.value);
|
|
149
|
+
marginInput.value = margin; // Ensure input matches final value
|
|
150
|
+
marginSlider.value = margin; // Ensure slider matches final value
|
|
151
|
+
applyPlotMargin(margin);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// Add wheel event listener to plot container for margin control
|
|
155
|
+
if (plotContainer) {
|
|
156
|
+
plotContainer.addEventListener('wheel', function(event) {
|
|
157
|
+
event.preventDefault(); // Prevent page scrolling
|
|
158
|
+
|
|
159
|
+
const currentValue = parseFloat(marginSlider.value);
|
|
160
|
+
const step = parseFloat(marginSlider.step) || 1;
|
|
161
|
+
const min = parseFloat(marginSlider.min);
|
|
162
|
+
const max = parseFloat(marginSlider.max);
|
|
163
|
+
|
|
164
|
+
let newValue;
|
|
165
|
+
if (event.deltaY < 0) {
|
|
166
|
+
// Scrolling up (or zoom in) -> decrease margin
|
|
167
|
+
newValue = currentValue - step;
|
|
168
|
+
} else {
|
|
169
|
+
// Scrolling down (or zoom out) -> increase margin
|
|
170
|
+
newValue = currentValue + step;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Clamp the value within min/max bounds
|
|
174
|
+
newValue = Math.max(min, Math.min(max, newValue));
|
|
175
|
+
|
|
176
|
+
// Only update if the value actually changed
|
|
177
|
+
if (newValue !== currentValue) {
|
|
178
|
+
marginSlider.value = newValue;
|
|
179
|
+
marginInput.value = newValue;
|
|
180
|
+
applyPlotMargin(newValue);
|
|
181
|
+
}
|
|
182
|
+
}, { passive: false }); // Need passive: false to call preventDefault()
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Apply initial margin
|
|
186
|
+
applyPlotMargin(config.plotMarginPercent);
|
|
187
|
+
|
|
188
|
+
container.appendChild(widthGroup);
|
|
189
|
+
container.appendChild(thresholdGroup);
|
|
190
|
+
container.appendChild(marginGroup);
|
|
191
|
+
}
|