IntervalSelection.js
9.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
// Define a constant for the layout style of the form
const LAYOUT_STYLE = {
type: 'vbox', // vertical box layout
pack: 'start', // controls the vertical alignment of child items
align: 'stretch' // each child item is stretched to fill the width of the container
};
// Width of button
const width = 100;
// Define the parent class for all classes to use time interval selection.
Ext.define('amdaPlotComp.intervalSelection.IntervalSelection', {
extend: 'Ext.window.Window', // This class extends from Ext.window.Window
// Window configurations
x: 0, y: 0, // The initial position of the window
title: 'Interval Selection', // The title of the window
constrain: true, // Constrains the window to within the boundaries of its containing element
collapsible: true, // Allows the window to be collapsed
resizable: false, // Prevents the window from being resizable
ghost: false, // Disables "ghosting" (semi-transparent representation of the window body) when moving or resizing
form: null, // a panel which contains all components
hostCmp: null, // The host component from which this class is instantiated.
interactiveId: '',
panelId: -1,
// Attributes of this class
config: {
field1Type: 'datefield', // The xtype of field1. By default is datefield because we are working with time series.
field1Label: 'Start Time', // The label of field1.
field1Format: 'Y/m/d H:i:s.u',
field2Type: 'datefield', // The xtype of field2. By default is datefield.
field2Label: 'Stop Time', // The label of field2.
field2Format: 'Y/m/d H:i:s.u',
buttonApply: 'Apply'
},
// Define the itemIds as constants
// These will be used to reference the fields later in the code
FIELD1_ITEM_ID: 'field1',
FIELD2_ITEM_ID: 'field2',
buttonUseTime: 'button-use-time',
initComponent: function () {
const self = this; // Reference to this instance for use in event handlers
this.form = new Ext.form.FormPanel({ // Create a new FormPanel instance and assign it to form
frame: true, // Display a frame around the panel
width: 255, // Set the width of the panel
layout: LAYOUT_STYLE, // Set the layout style of the panel
fieldDefaults: {
labelWidth: 60 // Set default label width for fields in this panel
},
items: [{
xtype: 'fieldset', // Create a new FieldSet to group related fields together
title: 'Interval Selection',
name: 'interval-selection-fieldset',
collapsible: false,
layout: LAYOUT_STYLE,
items: [{
xtype: this.field1Type,
fieldLabel: this.field1Label,
itemId: this.FIELD1_ITEM_ID,
format: this.field1Format,
listeners: {
change: function (field, newValue) {
if (newValue === null || newValue === undefined || newValue === '') return;
var field2 = self._getField2();
// Check if field2 is not empty
const value2 = field2.getValue();
if (value2 !== null && value2 !== undefined && value2 !== '') {
if (newValue > value2) {
// Update both field1 and field2 to the new values
field2.suspendEvents();
field2.setValue(newValue);
field.setValue(value2);
field2.resumeEvents();
}
}
}
}
},
{
xtype: this.field2Type,
fieldLabel: this.field2Label,
itemId: this.FIELD2_ITEM_ID,
format: this.field2Format,
listeners: {
change: function (field, newValue) {
if (newValue === null || newValue === undefined || newValue === '') return;
var field1 = self._getField1();
// Check if field1 is not empty
const value1 = field1.getValue();
if (value1 !== null && value1 !== undefined && value1 !== '') {
if (newValue < value1) {
// Update both field1 and field2 to the new values
field1.suspendEvents();
field1.setValue(newValue);
field.setValue(value1);
field1.resumeEvents();
}
}
}
}
}, {
xtype: 'button',
text: 'Reset',
width: width,
handler: function () {
self.reset();
}
},
{
xtype: 'button',
text: 'Use in Time Selection',
itemId: this.buttonUseTime,
handler: function () {
self._setTimeInterval();
}
}]
}],
fbar: [
{
xtype: 'button',
width: width,
text: this.buttonApply,
handler: function () {
self._apply();
}
}
]
})
Ext.apply(this, {
items: this.form
});
this.setTitle(this.title + " - Panel Id : " + this.panelId);
this.callParent(arguments);
},
/**
* Resets the time interval selection in the host component.
* This function calls the resetZoom method on the panelImage of the host component,
* effectively resetting any zoom applied to the image.
*/
_resetHostCmpSelection: function () {
this.hostCmp.panelImage.resetZoom();
},
/**
* Abstract method that must be implemented by subclasses.
* Throws an error if not overridden.
*/
_apply: function () {
throw new Error('_apply() method must be implemented by subclass');
},
/**
* Checks if the values of field1 and field2 are valid and if the form is valid.
* Returns true if any of these conditions are not met.
*/
_notValidValues: function () {
return !this.getField1Value() || !this.getField2Value() || !this.form.getForm().isValid();
},
/**
* Retrieves the component associated with FIELD1_ITEM_ID in the form.
* Returns the component if found, null otherwise.
*/
_getField1: function () {
return this.form.down('#' + this.FIELD1_ITEM_ID);
},
/**
* Retrieves the component associated with FIELD2_ITEM_ID in the form.
* Returns the component if found, null otherwise.
*/
_getField2: function () {
return this.form.down('#' + this.FIELD2_ITEM_ID);
},
/**
* Sets the time interval of the plot based on the values of the fields.
* This method is triggered when the buttonUseTime is clicked.
* It creates a new time object with start, stop, and interactiveId properties,
* and then calls the setTimeInterval method on the plot module with this object.
*/
_setTimeInterval: function () {
const timeObj = new Object();
timeObj.start = this.getField1Value();
timeObj.stop = this.getField2Value();
timeObj.interactiveId = this.interactiveId;
const plotModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id);
plotModule.setTimeInterval(timeObj);
},
/**
* Hides the buttonUseTime when it's not needed.
* For example, when we call Zoom on y-left axis we should not see this button.
* It finds the button by its ID and then calls the hide method on it.
*/
_removeUseTimeButton: function () {
const buttonToHide = this.form.down('#' + this.buttonUseTime);
buttonToHide.hide();
},
/**
* Retrieves the value of field1 from the form.
*/
getField1Value: function () {
return this._getField1().getValue();
},
/**
* Retrieves the value of field2 from the form.
*/
getField2Value: function () {
return this._getField2().getValue();
},
/**
* Sets a new value for field1 in the form.
*/
setField1Value: function (value) {
this._getField1().setValue(value);
},
/**
* Sets a new value for field2 in the form.
*/
setField2Value: function (value) {
this._getField2().setValue(value);
},
/**
* Resets the values of fields and host component selection.
* It calls the reset method on field1 and field2, and then calls _resetHostCmpSelection.
*/
reset: function () {
this._getField1().reset();
this._getField2().reset();
this._resetHostCmpSelection();
}
});