3 JSROOT.define([], () => {
7 if (typeof GO4 !=
"object") {
8 let e1 =
new Error(
"condition.js requires GO4 to be already loaded");
9 e1.source =
"condition.js";
15 class ConditionEditor
extends JSROOT.BasePainter {
17 constructor(dom, cond) {
20 this.changes = [
"dummy",
"init"];
25 return ((this.cond._typename ==
"TGo4PolyCond") || (
this.cond._typename ==
"TGo4ShapedCond"));
29 return (this.cond._typename ==
"TGo4ShapedCond");
35 for (let index = 0; index < this.changes.length; index++) {
36 if (this.changes[index]== key)
return;
38 this.changes.push(key);
39 console.log(
"Mark changed :%s", key);
40 this.selectDom().select(
".buttonChangeLabel").style(
"display", null);
45 for (let index = 0; index < this.changes.length ; index++) {
46 let removed = this.changes.pop();
47 console.log(
"Clear changes removed :%s", removed);
49 this.selectDom().select(
".buttonChangeLabel").style(
"display",
"none");
53 evaluateChanges(optionstring) {
54 let dom = this.selectDom(),
55 len = this.changes.length;
56 for (let index = 0; index < len ; index++) {
58 let key = this.changes[index];
64 let xmin = dom.select(
".cond_xmin").property(
"value"),
65 xmax = dom.select(
".cond_xmax").property(
"value");
66 optionstring += `&xmin=${xmin}&xmax=${xmax}`;
67 this.cond.fLow1 = xmin;
68 this.cond.fUp1 = xmax;
69 if (this.cond.fiDim == 2) {
70 let ymin = dom.select(
".cond_ymin").property(
"value"),
71 ymax = dom.select(
".cond_ymax").property(
"value");
72 this.cond.fLow2 = ymin;
73 this.cond.fUp2 = ymax;
74 optionstring += `&ymin=${ymin}&ymax=${ymax}`;
76 }
else if (key ==
"polygon") {
77 let npoints = dom.select(
".cut_points").property(
"value");
78 optionstring +=
"&npolygon="+npoints;
79 let values = dom.selectAll(
".cut_values input").nodes();
81 if (values.length != npoints*2)
82 return console.error(
'mismatch', values.length, npoints*2);
85 values[npoints*2-2].value = values[0].value;
86 values[npoints*2-1].value = values[1].value;
88 for(let i = 0; i < npoints; ++i) {
89 let x = values[i*2].value,
90 y = values[i*2+1].value;
91 optionstring += `&x${i}=${x}&y${i}=${y}`;
93 }
else if (key ==
"ellinpts") {
94 let val = dom.select(
".cond_ellipse_points").property(
"value");
95 optionstring += `&${key}=${val}`;
96 }
else if (key ==
"ellicx") {
97 let val = dom.select(
".cond_ellipse_cx").property(
"value");
98 optionstring += `&${key}=${val}`;
99 }
else if (key ==
"ellicy") {
100 let val = dom.select(
".cond_ellipse_cy").property(
"value");
101 optionstring += `&${key}=${val}`;
102 }
else if (key ==
"ellia1") {
103 let val = dom.select(
".cond_ellipse_a1").property(
"value");
104 optionstring += `&${key}=${val}`;
105 }
else if (key ==
"ellia2") {
106 let val = dom.select(
".cond_ellipse_a2").property(
"value");
107 optionstring += `&${key}=${val}`;
108 }
else if (key ==
"ellishape") {
109 let val = dom.select(
".cond_ellipse_iscircle").property(
"value");
110 optionstring += `&${key}=${val}`;
111 }
else if (key ==
"ellith") {
112 let val = dom.select(
".cond_ellipse_theta").property(
"value");
113 optionstring += `&${key}=${val}`;
114 }
else if (key ==
"resultmode") {
115 let val = dom.select(
".cond_execmode").property(
"value");
116 optionstring += `&${key}=${val}`;
117 }
else if (key ==
"invertmode") {
118 let val = dom.select(
".cond_invertmode").property(
"value");
119 optionstring += `&${key}=${val}`;
120 }
else if (key ==
"visible") {
121 let arg = dom.select(
".cond_visible").property(
"checked") ? 1 : 0;
122 optionstring += `&${key}=${arg}`;
123 }
else if (key ==
"labeldraw") {
124 let arg = dom.select(
".cond_label").property(
"checked") ? 1 : 0;
125 this.cond.fbLabelDraw = arg;
126 optionstring += `&${key}=${arg}`;
127 }
else if (key ==
"limitsdraw"){
128 let arg = dom.select(
".cond_limits").property(
"checked") ? 1 : 0;
129 this.cond.fbLimitsDraw = arg;
130 optionstring += `&${key}=${arg}`;
131 }
else if (key ==
"intdraw") {
132 let arg = dom.select(
".cond_integr").property(
"checked") ? 1 : 0;
133 this.cond.fbIntDraw = arg;
134 optionstring += `&${key}=${arg}`;
135 }
else if (key ==
"xmeandraw") {
136 let arg = dom.select(
".cond_xmean").property(
"checked") ? 1 : 0;
137 this.cond.fbXMeanDraw = arg;
138 optionstring += `&${key}=${arg}`;
139 }
else if (key ==
"xrmsdraw") {
140 let arg = dom.select(
".cond_xrms").property(
"checked") ? 1 : 0;
141 this.cond.fbXRMSDraw = arg;
142 optionstring += `&${key}=${arg}`;
143 }
else if (key ==
"ymeandraw") {
144 let arg = dom.select(
".cond_ymean").property(
"checked") ? 1 : 0;
145 this.cond.fbYMeanDraw = arg;
146 optionstring += `&${key}=${arg}`;
147 }
else if (key ==
"yrmsdraw") {
148 let arg = dom.select(
".cond_yrms").property(
"checked") ? 1 : 0;
149 this.cond.fbYRMSDraw = arg;
150 optionstring += `&${key}=${arg}`;
151 }
else if (key ==
"xmaxdraw") {
152 let arg = dom.select(
".cond_maxx").property(
"checked") ? 1 : 0;
153 this.cond.fbXMaxDraw = arg;
154 optionstring += `&${key}=${arg}`;
155 }
else if (key==
"ymaxdraw") {
156 let arg = dom.select(
".cond_maxy").property(
"checked") ? 1 : 0;
157 this.cond.fbYMaxDraw = arg;
158 optionstring += `&${key}=${arg}`;
159 }
else if (key==
"cmaxdraw") {
160 let arg = dom.select(
".cond_max").property(
"checked") ? 1 : 0;
161 this.cond.fbCMaxDraw = arg;
162 optionstring += `&${key}=${arg}`;
164 console.log(`Warning: evaluateChanges found unknown key: ${key}`);
167 console.log(`Resulting option
string: ${optionstring}`);
177 changePolygonDimension() {
178 if(!this.isPolyCond())
return;
180 let dom = this.selectDom(),
181 oldpoints = this.cond.fxCut.fNpoints,
182 npoints = dom.select(
".cut_points").property(
"value");
185 if (this.cond.fxCut) {
186 let body = dom.select(
".cut_values tbody").html(
"");
187 if (npoints > oldpoints) {
190 for (let i = 0; i < oldpoints - 1; i++) {
191 let x = this.cond.fxCut.fX[i], y = this.cond.fxCut.fY[i];
192 body.append(
"tr").html(`<td><input type=
"text" value=
"${x}"/></td><td><input type=
"text" value=
"${y}"/></td>`);
195 let insx = this.cond.fxCut.fX[oldpoints - 2],
196 insy = this.cond.fxCut.fY[oldpoints - 2];
197 for (let i = oldpoints - 1; i < npoints - 1; i++)
198 body.append(
"tr").html(`<td><input type=
"text" value=
"${insx}"/></td><td><input type=
"text" value=
"${insy}"/></td>`);
201 let lastx = this.cond.fxCut.fX[oldpoints - 1],
202 lasty = this.cond.fxCut.fY[oldpoints - 1];
203 body.append(
"tr").html(`<td><input type=
"text" value=
"${lastx}" disabled/></td><td><input type=
"text" value=
"${lasty}" disabled/></td>`);
206 for (let i = 0; i < npoints - 1; i++) {
207 let x = this.cond.fxCut.fX[i], y = this.cond.fxCut.fY[i];
208 body.append(
"tr").html(`<td><input type=
"text" value=
"${x}"/></td><td><input type=
"text" value=
"${y}"/></td>`);
212 let lastx = this.cond.fxCut.fX[oldpoints - 1],
213 lasty = this.cond.fxCut.fY[oldpoints - 1];
214 body.append(
"tr").html(`<td><input type=
"text" value=
"${lastx}" disabled/></td><td><input type=
"text" value=
"${lasty}" disabled/> </td>`);
217 this.markChanged(
"polygon");
221 changeTab(action, indx) {
223 let dom = this.selectDom(),
224 btns = dom.select(
'.cond_tabs_header').selectAll(
"button").nodes(),
225 tabs = dom.selectAll(
'.tabs_body>div').nodes();
227 if (btns.length != tabs.length)
228 return console.error(
'mismatch in tabs sizes', btns.length, tabs.length);
230 d3.select(btns[indx]).attr(
'disabled', (action==
"enable") ? null :
"true");
233 if ((action ==
"disable") && d3.select(btns[indx]).classed(
"active_btn")) {
235 btns.forEach((btn,k) => {
236 if (!d3.select(btn).attr(
'disabled') && (k != indx) && (best < 0)) best = k;
240 d3.select(tabs[indx]).style(
"display",
"none");
241 d3.select(tabs[best]).style(
"display", null);
242 d3.select(btns[indx]).classed(
"active_btn",
false);
243 d3.select(btns[best]).classed(
"active_btn",
true);
252 dom = this.selectDom();
254 dom.select(
".cond_name").text(cond.fName);
255 dom.select(
".cond_type").text(cond._typename);
257 dom.select(
".cond_execmode").node().value = cond.fbEnabled ? 0 : (cond.fbResult ? 1 : 2);
259 dom.select(
".cond_invertmode").node().value = cond.fbTrue ? 0 : 1;
261 dom.select(
".cond_xmin").property(
"value", cond.fLow1).on(
"change", () => this.markChanged(
"limits"));
262 dom.select(
".cond_xmax").property(
"value", cond.fUp1).on(
"change", () => this.markChanged(
"limits"));
264 dom.select(
".cond_ymin").property(
"value", cond.fLow2).on(
"change", () => this.markChanged(
"limits"));
265 dom.select(
".cond_ymax").property(
"value", cond.fUp2).on(
"change", () => this.markChanged(
"limits"));
267 dom.select(
".cond_ymin").attr(
'disabled',
true);
268 dom.select(
".cond_ymax").attr(
'disabled',
true);
271 if(this.isPolyCond()) {
272 this.changeTab(
"enable", 1);
273 this.changeTab(
"disable", 0);
274 if (this.cond.fxCut) {
275 let numpoints = this.cond.fxCut.fNpoints;
276 dom.select(
".cut_points").property(
"value", numpoints);
277 let body = dom.select(
".cut_values tbody").html(
"").on(
"change", () => editor.markChanged(
"polygon"));
279 for(let i = 0; i < numpoints; i++) {
280 let x = this.cond.fxCut.fX[i];
281 let y = this.cond.fxCut.fY[i];
282 let row = body.append(
"tr").html(`<td><input type=
"text" value=
"${x}"/></td><td><input type=
"text" value=
"${y}"/> </td>`);
283 if ((i == numpoints-1) && (numpoints > 1)) row.selectAll(
"input").property(
"disabled",
true);
286 if(this.isEllipseCond()) {
287 this.changeTab(
"enable", 2 );
288 let numpoints = this.cond.fiResolution;
289 dom.select(
".cond_ellipse_points").property(
"value", numpoints);
290 dom.select(
".cond_ellipse_cx").property(
"value", cond.fdCenterX).on(
"change", () => this.markChanged(
"ellicx"));
291 dom.select(
".cond_ellipse_cy").property(
"value", cond.fdCenterY).on(
"change", () => this.markChanged(
"ellicy"));
292 dom.select(
".cond_ellipse_a1").property(
"value", cond.fdRadius1).on(
"change", () => this.markChanged(
"ellia1"));
293 dom.select(
".cond_ellipse_a2").property(
"value", cond.fdRadius2).property(
'disabled', cond.fbIsCircle).on(
"change", () => this.markChanged(
"ellia2"));
294 dom.select(
".cond_ellipse_theta").property(
"value", cond.fdTheta).property(
'disabled', cond.fbIsCircle).on(
"change", () => {
295 this.markChanged(
"ellith");
296 dom.select(
".cond_ellipse_theta_slider").property(
"value", dom.select(
".cond_ellipse_theta").property(
"value") % 360);
299 let options = dom.select(
".cond_ellipse_iscircle").node().options;
300 for (let i = 0; i < options.length; i++)
301 options[i].selected = (options[i].value == cond.fiShapeType);
303 dom.select(
".cond_ellipse_theta_slider")
304 .property(
"value",cond.fdTheta)
305 .attr(
"disbaled", cond.fbIsCircle)
306 .on(
"change", () => {
307 this.markChanged(
"ellith");
308 dom.select(
".cond_ellipse_theta").property(
"value", dom.select(
".cond_ellipse_theta_slider").property(
"value"));
313 this.changeTab(
"enable", 0 );
314 this.changeTab(
"disable", 1 );
315 this.changeTab(
"disable", 2 );
318 dom.select(
".cond_counts").text(cond.fiCounts);
319 dom.select(
".cond_true").text(cond.fiTrueCounts);
320 dom.select(
".cond_percent").text((cond.fiCounts > 0 ? 100. * cond.fiTrueCounts / cond.fiCounts : 0.).toFixed(2) +
"%");
325 dom.select(
".cond_visible")
326 .property(
'checked', cond.fbVisible)
327 .on(
"click",
function() { cond.fbVisible = this.checked; editor.markChanged(
"visible")});
329 dom.select(
".cond_limits")
330 .property(
'checked', cond.fbLimitsDraw)
331 .on(
"click",
function() { cond.fbLimitsDraw = this.checked; editor.markChanged(
"limitsdraw")});
333 dom.select(
".cond_label")
334 .property(
'checked', cond.fbLabelDraw)
335 .on(
"click",
function() { cond.fbLabelDraw = this.checked; editor.markChanged(
"labeldraw")});
337 dom.select(
".cond_integr")
338 .property(
'checked', cond.fbIntDraw)
339 .on(
"click",
function() { cond.fbIntDraw = this.checked; editor.markChanged(
"intdraw")});
341 dom.select(
".cond_maxx")
342 .property(
'checked', cond.fbXMaxDraw)
343 .on(
"click",
function() { cond.fbXMaxDraw = this.checked; editor.markChanged(
"xmaxdraw")});
345 dom.select(
".cond_max")
346 .property(
'checked', cond.fbCMaxDraw)
347 .on(
"click",
function() { cond.fbCMaxDraw = this.checked; editor.markChanged(
"cmaxdraw")});
349 dom.select(
".cond_maxy")
350 .property(
'checked', cond.fbYMaxDraw)
351 .on(
"click",
function() { cond.fbYMaxDraw = this.checked; editor.markChanged(
"ymaxdraw")});
353 dom.select(
".cond_xmean")
354 .property(
'checked', cond.fbXMeanDraw)
355 .on(
"click",
function() { cond.fbXMeanDraw = this.checked; editor.markChanged(
"xmeandraw")});
357 dom.select(
".cond_xrms")
358 .property(
'checked', cond.fbXRMSDraw)
359 .on(
"click",
function() { cond.fbXRMSDraw = this.checked; editor.markChanged(
"xrmsdraw")});
361 dom.select(
".cond_ymean")
362 .property(
'checked', cond.fbYMeanDraw)
363 .on(
"click",
function() { cond.fbYMeanDraw = this.checked; editor.markChanged(
"ymeandraw")});
365 dom.select(
".cond_yrms")
366 .property(
'checked', cond.fbYRMSDraw)
367 .on(
"click",
function() { cond.fbYRMSDraw = this.checked; editor.markChanged(
"yrmsdraw")});
369 editor.clearChanges();
374 this.setTopPainter();
378 dom = this.selectDom();
381 dom.select(
'.cond_tabs_header').selectAll(
"button").on(
"click",
function() {
382 let btn = d3.select(
this);
384 dom.select(
'.cond_tabs_header').selectAll(
"button").each(
function() {
385 d3.select(
this).classed(
"active_btn",
false);
388 btn.classed(
"active_btn",
true);
390 dom.selectAll(
'.tabs_body>div').each(
function() {
391 let tab = d3.select(
this);
392 tab.style(
'display', tab.attr(
'id') == btn.attr(
"for") ? null :
"none");
397 dom.select(
'.cond_tabs_header').select(
"button").classed(
"active_btn",
true);
399 dom.select(
".cond_execmode").on(
"change", () => this.markChanged(
"resultmode"));
401 dom.select(
".cond_invertmode").on(
"change", () => this.markChanged(
"invertmode"));
403 if(this.isEllipseCond()) {
404 dom.select(
".cond_ellipse_iscircle").on(
"change", () => {
405 cond.fiShapeType = parseInt(dom.select(
".cond_ellipse_iscircle").property(
"value"));
407 switch(cond.fiShapeType) {
408 case 2: flags = [
true,
true,
true, null];
break;
409 case 3: flags = [null, null, null, null];
break;
410 case 4: flags = [null, null, null,
true];
break;
411 default: flags = [
true,
true,
true, null];
413 dom.select(
".cond_ellipse_a2").attr(
'disabled', flags[0]);
414 dom.select(
".cond_ellipse_theta").attr(
'disabled', flags[1]);
415 dom.select(
".cond_ellipse_theta_slider").attr(
'disabled', flags[2]);
416 dom.select(
".cond_ellipse_points").attr(
'disabled', flags[3]);
417 this.markChanged(
"ellishape");
421 dom.select(
".buttonGetCondition")
422 .style(
'background-image',
"url(" + GO4.source_dir +
"icons/right.png)")
424 if (JSROOT.hpainter) JSROOT.hpainter.display(
this.getItemName());
425 else console.log(
"hierarhy painter object not found!");
428 dom.select(
".buttonSetCondition")
429 .style(
'background-image',
"url(" + GO4.source_dir +
"icons/left.png)")
431 let options = this.evaluateChanges(
"");
432 console.log(
"set condition " + this.getItemName() +
", options="+options);
433 GO4.ExecuteMethod(
this,
"UpdateFromUrl",options)
435 console.log(
"set condition done.");
438 console.log(
"set condition FAILED.", err);
442 dom.select(
".buttonChangeLabel")
443 .style(
'background-image',
"url(" + GO4.source_dir +
"icons/info1.png)");
445 dom.select(
".buttonDrawCondition")
446 .style(
'background-image',
"url(" + GO4.source_dir +
"icons/chart.png)")
450 if (JSROOT.hpainter) {
451 this.evaluateChanges(
"");
453 if (JSROOT.hpainter.updateOnOtherFrames(this, this.cond)) return;
455 JSROOT.hpainter.drawOnSuitableHistogram(this, this.cond, editor.cond.fiDim==2);
460 let baseurl = editor.getItemName() +
"/",
461 drawurl = baseurl +
"draw.htm";
463 console.log(
"draw condition to next window with url="+drawurl);
465 window.open(drawurl,
'_blank');
469 dom.select(
".buttonClearCondition")
470 .style(
'background-image',
"url(" + GO4.source_dir +
"icons/clear.png)")
472 GO4.ExecuteMethod(
this,
"UpdateFromUrl",
"&resetcounters=1")
474 console.log(
"reset condition counters done.");
475 if(JSROOT.hpainter) JSROOT.hpainter.display(editor.getItemName());
477 console.log(
"reset condition counters FAILED.", err);
481 dom.select(
".cut_points").on(
"change", () => this.changePolygonDimension());
483 dom.select(
".cond_ellipse_points").on(
"change", () => this.markChanged(
"ellinpts"));
485 this.refreshEditor();
489 return JSROOT.httpRequest(GO4.source_dir +
"html/condeditor.htm",
"text").then(src => {
490 this.selectDom().html(src);
497 if (obj._typename !=
this.cond._typename)
return false;
498 this.cond = JSROOT.clone(obj);
499 this.refreshEditor();
504 GO4.ConditionEditor = ConditionEditor;