From f98bd2a0451df91cbf5f482269cb0bcff731b1ad Mon Sep 17 00:00:00 2001
From: Lucio Zambon <lucio.zambon@elettra.eu>
Date: Thu, 31 Oct 2024 03:06:09 +0000
Subject: [PATCH] Update panther2d.js

---
 panther2d.js | 94 +++++++++++++++++++++++++++++++++-------------------
 1 file changed, 60 insertions(+), 34 deletions(-)

diff --git a/panther2d.js b/panther2d.js
index 639dbd8..576ba2e 100644
--- a/panther2d.js
+++ b/panther2d.js
@@ -19,6 +19,7 @@
 	const alias = [];
 	let maxZoom = 230;
 	const status = [];
+	const compData = {};
 	const point = {x: 0, y: 0};
 	const pa = document.location.search.replace('?','').split('&');
 	const parameters = {};
@@ -286,7 +287,7 @@
 		obj.style.height = obj.contentWindow.document.documentElement.scrollHeight + 'px';
 	}
 	const latticeFile = document.location.href.split('?')[0].split('/').slice(0,-1).join('/')+'/'+machine+'_lattice.json';
-	const params = {machine: machineCaseSensitive.toLowerCase(), search: '', backgroundColor: '#333333'};
+	const menuParams = {machine: machineCaseSensitive.toLowerCase(), search: '', backgroundColor: '#333333'};
 	gui.title('PAnTHer - controls');
 	// if (navigator.userAgent.indexOf('Firefox/63')>-1) {$( "body" ).append('<button id="starter" style="align: center;height: 500px; width: 95%;background-color: #449944; font-size: 100px;" onClick="mystart()">START</button>');}
 	function mystart() {
@@ -337,17 +338,17 @@
 	function shrinkName(name) {
 		return name.replaceAll('FEL0', 'FEL').replaceAll('PS_', 'PS').replaceAll('SIP_', 'SIP').replaceAll('KG0', 'KG').replaceAll('BC0', 'BC').replaceAll('_L0', 'L').replaceAll('_F0', 'F').replaceAll('_0', '').replaceAll('_', '');
 	}
-	// if (navigator.userAgent.indexOf('Firefox/63')==-1) {gui.add(params, 'machine', conf.machineList).onChange(function() {toggleMachine(params.machine);});}
-	gui.add(params, 'machine', conf.machineList).onChange(function() {toggleMachine(params.machine);});
-	gui.add(params, 'search');
-	$('.controller.string:last').parent().append('<iframe id="talk" src="./speech/talk.php?background=black&token='+speechToken+'" frameborder="0" scrolling="no" onload="resizeIframe(this)"></iframe>');
-	gui.addColor(params, 'backgroundColor').onChange(function() {toggleParam('backgroundColor');});
-	params.vlv = document.location.search.indexOf('vlv')>-1;
-	gui.add(params, 'vlv').name('vlv & bst').onChange(function() {toggleParam('vlv');});
-	params.ps = document.location.search.indexOf('ps')>-1;
-	gui.add(params, 'ps').onChange(function() {toggleParam('ps');});
-	params.measurement = document.location.search.indexOf('measurement')>-1;
-	gui.add(params, 'measurement').onChange(function() {toggleParam('measurement');});
+	// if (navigator.userAgent.indexOf('Firefox/63')==-1) {gui.add(menuParams, 'machine', conf.machineList).onChange(function() {toggleMachine(menuParams.machine);});}
+	gui.add(menuParams, 'machine', conf.machineList).onChange(function() {toggleMachine(menuParams.machine);});
+	gui.add(menuParams, 'search');
+	$('.controller.string:last').parent().append('<iframe id="talk" style="height: 30px;" src="./speech/talk.php?background=black&token='+speechToken+'" frameborder="0" scrolling="no" onload="resizeIframe(this)"></iframe>');
+	gui.addColor(menuParams, 'backgroundColor').onChange(function() {toggleParam('backgroundColor');});
+	menuParams.vlv = document.location.search.indexOf('vlv')>-1;
+	gui.add(menuParams, 'vlv').name('vlv & bst').onChange(function() {toggleParam('vlv');});
+	menuParams.ps = document.location.search.indexOf('ps')>-1;
+	gui.add(menuParams, 'ps').onChange(function() {toggleParam('ps');});
+	menuParams.measurement = document.location.search.indexOf('measurement')>-1;
+	gui.add(menuParams, 'measurement').onChange(function() {toggleParam('measurement');});
 	const sstring = $('.controller.string').children().eq(1).children().eq(0);
 	sstring.attr('id', 'sname');
 	sstring.attr('name', 'sname');
@@ -405,7 +406,7 @@
 	$(function() {$(".sname").autocomplete({source: names, select: function(event, ui) {findComponent(ui.item.value); return false;}});});
 	function toggleParam(name) {
 		if (name=='measurement') { measurement = !measurement; measurementType = measurement; if (measurement) measurementEnable(); else  measurementDisable(); return;}
-		if (name=='backgroundColor') {$('body').css('backgroundColor', params.backgroundColor); return;}
+		if (name=='backgroundColor') {$('body').css('backgroundColor', menuParams.backgroundColor); return;}
 		const urlparam = {};
 		let search = document.location.search.replace('?', '').split('&');
 		if (search[0]=='') search.splice(0,1);
@@ -464,27 +465,24 @@
 		fetch(latticeFile).then((response) => {return response.json();}).then((flattice) => {
 			lattice = flattice;
 			if (Object.keys(lattice).length>0) {
-				gui.add(params, 'measurement button', {Left: 'left', Right: 'right'}).onChange(measurementFacility);
+				gui.add(menuParams, 'measurement button', {Left: 'left', Right: 'right'}).onChange(measurementFacility);
 				const measurementDevice = {'': ''};
 				for (let i in lattice) {if (i!='conf') facilities.push(i);}
 				for (let i in lattice) {
 					if (i == 'conf') continue;
-					params[i] = false;
+					menuParams[i] = false;
 					if (i != 'servicearea' && i != 'bl') measurementDevice[i] = i;
 					// logic XOR https://stackoverflow.com/questions/2335979/is-there-anyway-to-implement-xor-in-javascript
 					if ((document.location.search.indexOf('servicearea')==-1) != (i=='servicearea')) initLattice(lattice[i].sections, i); else {
 						if (document.location.search.indexOf('+servicearea')>-1) initLattice(lattice[i].sections, i); else initSearch(lattice[i].sections, i);
 					}
 				}
-				gui.add(params, 'measurement device', measurementDevice).onChange(measurementFacility);
+				gui.add(menuParams, 'measurement device', measurementDevice).onChange(measurementFacility);
 				if (document.location.search.indexOf('measurement')==-1) measurementToggle(false);
 				if (document.location.search.indexOf('servicearea')>-1) initSearch(lattice.servicearea.sections, 'servicearea');
-				if (typeof blm != 'undefined') blmMenu(lattice, facilities, params);
+				if (typeof blm != 'undefined') blmMenu(lattice, facilities, menuParams);
 				bpmInit(facilities); 
-				if (typeof bpmData != 'undefined') bpmMenu(lattice, facilities, params);
-				params.gotoAdmin = function() {document.location = './admin.php';};
-				gui.add(params, 'gotoAdmin').name('Admin');
-				params.goto3D =  function() {document.location = './panther.php?machine='+params.machine;}; gui.add(params, 'goto3D').name('3D');
+				if (typeof bpmData != 'undefined') bpmMenu(lattice, facilities, menuParams);
 				if (lattice.conf && lattice.conf.index) initIndex(lattice);
 			}
 			$('.scale').attr('transform', "scale(2)");
@@ -569,11 +567,15 @@
 				setInterval(updateVlv, 1000);
 			}
 			$("#sname").on("keydown", searchText);
-			if (lattice.conf.modules) {
+			if (lattice.conf && lattice.conf.modules) {
 				for (let i=0; i<lattice.conf.modules.length; i++) {
-					window[lattice.conf.modules[i]](lattice);
+					window[lattice.conf.modules[i]](lattice, menuParams, compData);
 				}
 			}
+			menuParams.gotoAdmin = function() {document.location = './admin.php';};
+			gui.add(menuParams, 'gotoAdmin').name('Admin');
+			menuParams.goto3D =  function() {document.location = './panther.php?machine='+menuParams.machine;}; 
+			gui.add(menuParams, 'goto3D').name('3D');
 		});
 	}
 	function showStatus(i, stat) {
@@ -603,12 +605,11 @@
 			const vlvVal = data.split(':')[1].split(';');
 			// console.log('updateVlv()', conf.vlvUrl, vlvVal, vlvs);
 			for (let i=0; i<vlvs.length; i++) {
-				if (vlvs[i].type=='vlv') $('#'+vlvs[i].name).css('fill', vlvVal[vlvs[i].vlvindex]=='CLOSED'? 'yellow': (vlvVal[vlvs[i].vlvindex]=='OPENED'? 'limegreen': 'grey'));
+				if (vlvs[i].type=='vlv') $('#'+vlvs[i].name).css('fill', vlvVal[vlvs[i].vlvindex]=='CLOSED'? 'red': (vlvVal[vlvs[i].vlvindex]=='OPENED'? 'limegreen': 'grey'));
 				if (vlvs[i].type=='bst') {
 					if (typeof vlvVal[vlvs[i].vlvindex] != 'string') continue;
 					const val = vlvVal[vlvs[i].vlvindex].split(',');
-					// console.log('updateVlv(): ', i, vlvs[i], vlvs[i].type, vlvs[i].vlvindex, vlvVal[vlvs[i].vlvindex], '#'+vlvs[i].name, vlvs[i].comp, val[0]=='true'? 'limegreen': (val[1]=='true'? 'yellow': 'grey'));
-					$('#'+vlvs[i].name).css('fill', val[0]=='true'? 'limegreen': (val[1]=='true'? 'yellow': 'grey'));
+					$('#'+vlvs[i].name).css('fill', val[0]=='true'? 'limegreen': (val[1]=='true'? 'red': 'grey'));
 				}
 			}
 		});
@@ -635,12 +636,21 @@
 			hideTimeout = setTimeout(hideTooltip, 120000);
 			const id = evalId(this.id);
 			let buttons = '<button onClick="compLink(\''+conf.compdb + id+'\')">'+id+'</button> ';
+			let rack = '';
 			if (typeof this.dataset.embedded != 'undefined') {
 				const emb = this.dataset.embedded.split(',');
 				for (let e=0; e<emb.length; e++) {
 					buttons = buttons + '<button onClick="compLink(\''+evalId(emb[e])+'\')">'+evalId(emb[e])+'</button> ';
 				}
 			}
+			else {
+				for (let i=0; i<lattice.servicearea.sections.length; i++) {
+					if (lattice.servicearea.sections[i].components) for (let j=0; j<lattice.servicearea.sections[i].components.length; j++) {
+						if (lattice.servicearea.sections[i].components[j].embedded && lattice.servicearea.sections[i].components[j].embedded.indexOf('PS'+id)>-1) rack = 'rack <button onClick="compLink(\'https://puma-01.elettra.eu/spa/index.html?s='+lattice.servicearea.sections[i].components[j].name.split('_')[0].toLowerCase()+'&param='+lattice.servicearea.sections[i].components[j].name+'\')">'+lattice.servicearea.sections[i].components[j].name+'</button> ';
+					}
+				}
+			}
+			buttons = buttons + rack;
 			document.getElementById('compdb').innerHTML = buttons;
 			document.getElementById('compdb').style.display = (type.indexOf('rv')==0 || type.indexOf('rc')==0 || type.indexOf('rid')==0 || type.indexOf('rd')==0 || type.indexOf('rps')==0 || type.indexOf('plc')==0)? 'none': 'block';
 			if (document.getElementById('compname')) document.getElementById('compname').innerHTML = id;
@@ -697,7 +707,8 @@
 		for (let i in attrib) {
 			jelem.attr(i, attrib[i]);
 		}
-		$(appendTo.replace('.','_').replace(' ','_')).append(jelem);
+		const hook = appendTo.indexOf('.')==0? appendTo.replace(' ','_'): appendTo.replace('.','_').replace(' ','_');
+		$(hook).append(jelem);
 	}
 	function appendSearch(component, facility) {
 		// mylog('appendSearch()',component, facility);
@@ -729,8 +740,9 @@
 		if ((beta+3600)%360 <180 && typeof labelReverse != 'object') labelReverse = [-90, -250, -100];
 		appendSvg("text", {
 			id: (id+suffix).replace(' ','_'), 
+			filter: "url(#solid)",
 			class: labelclass, 
-			x:0, y:0, style:"display: "+display, fill:"white", stroke:"#101020","stroke-width":5, "font-family":"Arial", "font-size":100*fontSize, "font-weight":"900",
+			x:0, y:0, style:"display: "+display, fill:"white", stroke:"#101020","stroke-width":0, "font-family":"Arial", "font-size":100*fontSize, "font-weight":"700",
 			"text-anchor": (labelReverse? "end": "start"),
 			transform: transformLabel(x, y, beta, labelReverse)
 		}, false, id, false, appendTo);
@@ -745,9 +757,10 @@
 		}
 		else if ((beta+3600)%360 < 180 && typeof labelReverse != 'object') labelReverse = [-90, -250, -100];
 		appendSvg("text", {
-			id: id+suffix, 
+			id: id+suffix,
+			// filter: "url(#solid)",
 			class: labelclass, 
-			x:0, y:0, style:"display: block", fill:"red", stroke:"pink","stroke-width":5, "font-family":"Arial", "font-size":fontsize, "font-weight":"900", 
+			x:0, y:0, style:"display: block", fill:"red", stroke:"pink","stroke-width":5, "font-family":"Arial", "font-size":fontsize, "font-weight":"700", 
 			"text-anchor": (labelReverse? "end": "start"),
 			transform: transformLabel(x, y, beta, labelReverse)
 		}, false, id);
@@ -780,6 +793,9 @@
 				corr[facility].dir.push(beta);
 				corr[facility].pos.push([x, y]);
 			}
+			compData[facility].obj.push(components[i].name);
+			compData[facility].dir.push(beta);
+			compData[facility].pos.push([rescale(x), rescale(y)]);
 			if ($('#'+comp)[0]) {
 				// mylog('components['+i+']',components[i]);
 				const id = extractId(components[i].name);
@@ -869,8 +885,9 @@
 	}
 	function initLattice(sections, facility) { 
 		initSearch(sections, facility);
-		if (document.location.search.indexOf('facility=')>-1 && facility!=document.location.search.split('facility=')[1].split('&')[0]) return;
+		if (document.location.search.indexOf('facility=')>-1 && document.location.search.split('facility=')[1].split('&')[0].split(',').indexOf(facility)==-1) return;
 		if (typeof bpmData != 'undefined') {
+			compData[facility] = {obj: [], dir: [], pos: [], index: []};
 			bpmData[facility] = {obj: [], dir: [], pos: []};
 			corr[facility] = {obj: [], dir: [], pos: []};
 		}
@@ -878,15 +895,24 @@
 		let d = '';
 		let m = true;
 		let wall = false;
+		let w = 20;
 		for (let i=0; i<sections.length; i++) {
 			d = d + (m? 'M ': ' L ')+rescale(sections[i].start.x)+' '+rescale(sections[i].start.z);
-			if (i<sections.length-1 && typeof sections[i+1].chamber == 'undefined') {m = true;} else if (i<sections.length-1 && sections[i+1].chamber.type=="chamber") {m = false;}
-			if (i<sections.length-1 && typeof sections[i+1].chamber != 'undefined' && sections[i+1].chamber.type=="wall") wall = true;
+			if (i<sections.length-1 && typeof sections[i+1].chamber == 'undefined') {m = true;} else if (i<sections.length-1 && (sections[i+1].chamber.type=="chamber" || sections[i+1].chamber.type.indexOf("wall")>-1)) {m = false;}
+			if (i<sections.length-1 && typeof sections[i+1].chamber != 'undefined' && sections[i+1].chamber.type.indexOf("wall")>-1) {
+				if (sections[i+1].chamber.type.indexOf('_')>-1) w = sections[i+1].chamber.type.split('_')[1]-0;
+				wall = true;
+			}
 		}
 		if (sections[0].chamber && sections[0].chamber.type=='chamber') d = d + ' Z';
 		if (facility=='sr') console.log('sections', sections, 'd', d);
 		if (d!='') {
-			if (wall) appendSvg("path", {d: d, fill: "none", stroke: "#990000", "stroke-dasharray": "200 200", "stroke-width": 50, id:"wall"+facility});
+			if (wall) {
+				console.log('w', w, sections, d);
+				//appendSvg("path", {d: d, fill: "none", stroke: "#990000", "stroke-dasharray": "200 200", "stroke-width": 50, id:"wall"+facility});
+				appendSvg("path", {d: d, fill: "none", stroke: "#f0fff0", "stroke-width": w+20, id:"chamber"+facility});
+				appendSvg("path", {d: d, fill: "none", stroke: "#ff0000", "stroke-width": w, id:"chamber"+facility});
+			}
 			else appendSvg("path", {d: d, fill: "none", stroke: "#999999", "stroke-width": 20, id:"chamber"+facility});
 		}
 		// bending
-- 
GitLab