"use strict"; // Copyright 2017 Istituto Nazionale di Fisica Nucleare // // Licensed under the EUPL exports.__esModule = true; var jquery_1 = require("jquery"); var a = 3.36275; //costante moltiplicativa per la calibrazione var b = 58.2353; //costante additiva per la calibrazione var pixelDim; //dimensione dei pixel responsive var maxAbsolute; //massimo conteggio della matrice nOfCounts var xDim = 0, yDim = 0; //numero di pixel nelle due dimensioni var DataMatrix, nOfCounts; //matrici con i dati var rePrint = false; //variabile per ricolorare con il max relativo var newOrigin; //nuovo origine nel caso di zoom var zPixel1; //pixel1 dello zoom var zPixel2; //pixel2 dello zoom var dataCompleteChart = "Channel,Counts\n"; var dataCompleteChartCalibrated = "Energy,Counts\n"; var calibrated = false; //variabile per il controllo sulla calibrazione var depth = 8000; //profondità massima della matrice var channelDepth = round3(((depth + 1) * a - b) / 1000); //profondità massima in canali var globalxMinRange = 0, globalxMaxRange = channelDepth; //INIZIO DELLO SCRIPT jquery_1["default"](document).ready(function () { //abilito tooltip jquery_1["default"]('[data-toggle="tooltip"]').tooltip(); //creazione dell'albero e gestione barre laterali setImportFile(); compressingSidenav(); //abilitazione drag&drop var droppableArea = document.querySelector('.droppable'); makeDroppable(droppableArea, callback); //inizializzazione variabili zPixel1 = { xp: 0, yp: 0 }; zPixel2 = { xp: 0, yp: 0 }; }); //funzione per la compressione della sidenav sx function compressingSidenav() { var fsLabel = jquery_1["default"]('.sidebar-label'); var isClosedfs = false; fsLabel.click(function () { fsLabel_cross(); }); function fsLabel_cross() { if (isClosedfs == true) { isClosedfs = false; jquery_1["default"]('.w3-bar-block').css('width', "65px"); jquery_1["default"]('.text-sidenav').css('display', 'none'); jquery_1["default"]('#collapse-symbol').attr('title', 'Open Sidebar'); jquery_1["default"]("#collapse-symbol").removeClass("fa-angle-double-left"); jquery_1["default"]("#collapse-symbol").addClass("fa-angle-double-right"); } else { isClosedfs = true; jquery_1["default"]('.w3-bar-block').css('width', "200px"); jquery_1["default"]('.text-sidenav').css('display', 'inline'); jquery_1["default"]('#collapse-symbol').attr('title', 'Close Sidebar'); jquery_1["default"]("#collapse-symbol").removeClass("fa-angle-double-right"); jquery_1["default"]("#collapse-symbol").addClass("fa-angle-double-left"); } } } //funzione che definisce l'area su cui si può eseguire il drag&drop function makeDroppable(droppableArea, callback) { //creo l'elemento "input type file" non visibile e lo aggiungo a "droppableArea" var input = document.createElement('input'); input.setAttribute('type', 'file'); input.setAttribute('multiple', true); input.style.display = 'none'; droppableArea.appendChild(input); //questo evento è chiamato quando i file sono trascinati ma non ancora lasciati droppableArea.addEventListener('dragover', function (e) { e.preventDefault(); //impediamo l'apertura del file e.stopPropagation(); e.dataTransfer.dropEffect = 'copy'; droppableArea.classList.add('dragover'); }); //l'evento è chiamato quando un file lascia la zona predefinita per il drag&drop droppableArea.addEventListener('dragleave', function (e) { e.preventDefault(); e.stopPropagation(); droppableArea.classList.remove('dragover'); }); //questo evento si innesca quando il drop è effettivamente avvenuto droppableArea.addEventListener('drop', function (e) { e.preventDefault(); e.stopPropagation(); droppableArea.classList.remove('dragover'); callback.call(null, e.dataTransfer.files); }); } //funzione chiamata in caso di drag&drop responsabile dell'apertura del file droppato, //della sua lettura e del passaggio del suo contenuto alla funzione readData() function callback(files) { jquery_1["default"]("#load-spinner").css("display", "inline"); console.log("Try to open " + files[files.length - 1].name + " ..."); var readerObject = new FileReader(); readerObject.readAsBinaryString(files[files.length - 1]); readerObject.onload = function () { var fileString = readerObject.result; readData(fileString); }; } //la funzione prepara i dati per il grafico completo function setDataForCompleteChart() { //per ogni pixel sommo i conteggi di tutti i canali rilevati var dataForChart = new Array(depth); for (var i = 0; i < depth; i++) { dataForChart[i] = 0; } for (var i = 0; i < xDim; i++) { for (var j = 0; j < yDim; j++) { for (var k = 0; k < depth; k++) { dataForChart[k] += DataMatrix[i][j][k]; } } } //riempio le stringhe con i dati per il grafico for (var i = 0; i < depth; i++) { dataCompleteChart += (i + 1) + "," + dataForChart[i] + "\n"; dataCompleteChartCalibrated += round3(((i + 1) * a - b) / 1000) + "," + dataForChart[i] + "\n"; } } //La funzione riceve in input un vettore di cui somma gli elementi compresi tra //gli indici from e to function sumVect(vect, from, to) { var sum = 0; for (var i = from; i < to; i++) { sum += vect[i]; } return sum; } //La funzione riceve in input la matrice e gli estremi della sottomatrice di cui //calcola il massimo function findMax(matrix, pixel1, pixel2) { var max = 0; for (var i = pixel1.xp; i <= pixel2.xp; i++) { for (var j = pixel1.yp; j <= pixel2.yp; j++) { if (matrix[i][j] > max) { max = matrix[i][j]; } } } return max; } //Funzione per arrotondare il numero in input alla terza cifra decimale function round3(val) { return (Math.round(val * Math.pow(10, 3)) / Math.pow(10, 3)); } //la funzione findPosition definisce la posizione del cursore del mouse //relativa al canvas nel momento in cui avviene l'evento passato in input function findPosition(event, pixel) { var scrollTOP = (document.documentElement.scrollTop) ? document.documentElement.scrollTop : document.body.scrollTop; var scrollLEFT = (document.documentElement.scrollLeft) ? document.documentElement.scrollLeft : document.body.scrollLeft; var allX = event.clientX + scrollLEFT; var allY = event.clientY + scrollTOP; var elParent = document.getElementById('myCanvas'); var objX = 0, objY = 0; while (elParent) { objX += elParent.offsetLeft; objY += elParent.offsetTop; elParent = elParent.offsetParent; } pixel.xp = Math.floor((allX - objX - 1) / pixelDim) + newOrigin.xp; pixel.yp = Math.floor((allY - objY - 1) / pixelDim) + newOrigin.yp; } //la funzione findPosDown memorizza la posizione del pixel cliccato function findPosDown(event) { findPosition(event, zPixel1); } //la funzione findPosUp memorizza la posizione del pixel quando il mouse viene //rilasciato, ordina le coordinate, aggiorna l'origine e la pagina. function findPosUp(event) { findPosition(event, zPixel2); var tmp; if (zPixel1.xp > zPixel2.xp) { tmp = zPixel1.xp; zPixel1.xp = zPixel2.xp; zPixel2.xp = tmp; } if (zPixel1.yp > zPixel2.yp) { tmp = zPixel1.yp; zPixel1.yp = zPixel2.yp; zPixel2.yp = tmp; } //se è stato cliccato un punto disegno il grafico, altrimenti disegno anche il //canvas e aggiorno l'origine //alert(zPixel1.xp + ", " + zPixel1.yp + " - " + zPixel2.xp + ", " + zPixel2.yp); if (zPixel1.xp != zPixel2.xp || zPixel1.yp != zPixel2.yp) { newOrigin = { xp: zPixel1.xp, yp: zPixel1.yp }; drawImg(zPixel1, zPixel2, globalxMinRange, globalxMaxRange); } drawChart(zPixel1, zPixel2, globalxMinRange, globalxMaxRange); } //la funzione disegna il rettangolo durante la selezione di un'area della mappa function zoomRect() { var selectCanvas = document.getElementById("selectionCanvas"); var ctx = selectCanvas.getContext("2d"); // style the context ctx.fillStyle = "rgba(0, 110, 255, 0.25)"; // this flage is true when the user is dragging the mouse var isDown = false; // these vars will hold the starting mouse position var startX; var startY; var mouseX; var mouseY; // these vars will hold the starting mouse position function handleMouseDown(e) { e.preventDefault(); e.stopPropagation(); //calculate mouse position var scrollTOP = (document.documentElement.scrollTop) ? document.documentElement.scrollTop : document.body.scrollTop; var scrollLEFT = (document.documentElement.scrollLeft) ? document.documentElement.scrollLeft : document.body.scrollLeft; var allX = e.clientX + scrollLEFT; var allY = e.clientY + scrollTOP; var elParent = document.getElementById('myCanvas'); var objX = 0, objY = 0; while (elParent) { objX += elParent.offsetLeft; objY += elParent.offsetTop; elParent = elParent.offsetParent; } startX = allX - objX; startY = allY - objY; // set a flag indicating the drag has begun isDown = true; } function handleMouseUp(e) { e.preventDefault(); e.stopPropagation(); // the drag is over, clear the dragging flag isDown = false; ctx.clearRect(0, 0, selectCanvas.width, selectCanvas.height); } function handleMouseOut(e) { e.preventDefault(); e.stopPropagation(); // the drag is over, clear the dragging flag isDown = false; ctx.clearRect(0, 0, selectCanvas.width, selectCanvas.height); } function handleMouseMove(e) { e.preventDefault(); e.stopPropagation(); // if we're not dragging, just return if (!isDown) { return; } //calculate mouse position var scrollTOP = (document.documentElement.scrollTop) ? document.documentElement.scrollTop : document.body.scrollTop; var scrollLEFT = (document.documentElement.scrollLeft) ? document.documentElement.scrollLeft : document.body.scrollLeft; var allX = e.clientX + scrollLEFT; var allY = e.clientY + scrollTOP; var elParent = document.getElementById('myCanvas'); var objX = 0, objY = 0; while (elParent) { objX += elParent.offsetLeft; objY += elParent.offsetTop; elParent = elParent.offsetParent; } mouseX = allX - objX; mouseY = allY - objY; // Put your mousemove stuff here // clear the canvas ctx.clearRect(0, 0, selectCanvas.width, selectCanvas.height); // calculate the rectangle width/height based // on starting vs current mouse position var width = mouseX - startX; var height = mouseY - startY; // draw a new rect from the start position // to the current mouse position ctx.fillRect(startX, startY, width, height); } // listen for mouse events jquery_1["default"]("#selectionCanvas").mousedown(function (e) { handleMouseDown(e); }); jquery_1["default"]("#selectionCanvas").mousemove(function (e) { handleMouseMove(e); }); jquery_1["default"]("#selectionCanvas").mouseup(function (e) { handleMouseUp(e); }); jquery_1["default"]("#selectionCanvas").mouseout(function (e) { handleMouseOut(e); }); } //la funzione drawImg disegna il canvas con l'immagine desiderata ed è responsabile //della gestione di tutti gli eventi ad essa associati function drawImg(pixel1, pixel2, xMinRange, xMaxRange) { //alert("disegno in corso"); //numero di pixel per dimensione var nPixelX = pixel2.xp - pixel1.xp + 1; var nPixelY = pixel2.yp - pixel1.yp + 1; //dimensione dei canvas var mappaPannelDim = document.querySelector('#mappa-pannel').getBoundingClientRect(); var mappaWidth = mappaPannelDim.right - mappaPannelDim.left - 40; var mappaHeigth = 400; //dimensione reale dei pixel var dimPixelx = Math.floor(mappaWidth / nPixelX); var dimPixely = Math.floor(mappaHeigth / nPixelY); pixelDim = (dimPixelx < dimPixely) ? dimPixelx : dimPixely; //dimensioni esatte dei canvas document.getElementById("myCanvas").height = nPixelY * pixelDim; document.getElementById("myCanvas").width = nPixelX * pixelDim; document.getElementById("selectionCanvas").height = nPixelY * pixelDim; document.getElementById("selectionCanvas").width = nPixelX * pixelDim; var ctx = document.getElementById('myCanvas').getContext('2d'); //contesto del canvas if (xMaxRange - xMinRange >= channelDepth) { var max = void 0; //massimo relativo o assoluto if (rePrint) max = findMax(nOfCounts, pixel1, pixel2); else max = maxAbsolute; max = (max * document.getElementById("SaturationSlider").value) / 100; //max = (max * parseInt($("#SaturationSlider").attr("value")))/100 ; //saturazione drawCanvas(nOfCounts, max); //disegno } else { var xMinRangeCh = Math.floor((((xMinRange * 1000) + b) / a) - 1); //16 var xMaxRangeCh = Math.floor((((xMaxRange * 1000) + b) / a) - 1); //16371 //calcolo il numero di conteggi solo dei canali selezionati var nOfCountsRelative = void 0; nOfCountsRelative = new Array(xDim); for (var i = 0; i < xDim; i++) { nOfCountsRelative[i] = new Array(yDim); for (var j = 0; j < yDim; j++) { nOfCountsRelative[i][j] = sumVect(DataMatrix[i][j], xMinRangeCh, xMaxRangeCh); } } //calcolo il massimo var max = void 0; if (rePrint) { max = findMax(nOfCountsRelative, pixel1, pixel2); } else { max = findMax(nOfCountsRelative, { xp: 0, yp: 0 }, { xp: xDim - 1, yp: yDim - 1 }); } max = (max * document.getElementById("SaturationSlider").value) / 100; //max = (max * parseInt($("#SaturationSlider").attr("value")))/100 ; //saturazione drawCanvas(nOfCountsRelative, max); //disegno } //La funzione, ricevuti dati e massimo, disegna la mappa nel canvas function drawCanvas(noc, max) { //controllo il valore della trasparenza var setTrsp = 1 - (document.getElementById("TrasparencySlider").value / 100); //let setTrsp: number = 1-(parseInt($("#TrasparencySlider").attr("value"))/100); //scorro tutti i pixel: ne determino il colore e li disegno var color = ""; for (var i = pixel1.xp; i <= pixel2.xp; i++) { for (var j = pixel1.yp; j <= pixel2.yp; j++) { var intensity = noc[i][j] / max; if (intensity < 1 / 5) color = "rgba(0, 0, " + Math.floor(intensity * 5 * 255) + "," + setTrsp + ")"; else if (1 / 5 <= intensity && intensity < 2 / 5) color = "rgba(0, " + Math.floor((intensity - 1 / 5) * 5 * 255) + ",255, " + setTrsp + ")"; else if (2 / 5 <= intensity && intensity < 3 / 5) color = "rgba(0, 255, " + (255 - Math.floor((intensity - 2 / 5) * 5 * 255)) + ", " + setTrsp + ")"; else if (3 / 5 <= intensity && intensity < 4 / 5) color = "rgba(" + Math.floor((intensity - 3 / 5) * 5 * 255) + ",255,0," + setTrsp + ")"; else color = "rgba(255," + (255 - Math.floor((intensity - 4 / 5) * 5 * 255)) + ", 0, " + setTrsp + ")"; ctx.fillStyle = color; ctx.fillRect((i - pixel1.xp) * pixelDim, (j - pixel1.yp) * pixelDim, pixelDim, pixelDim); } } rePrint = false; //annullo rePrint zoomRect(); } jquery_1["default"]("#SaturationSlider").mouseup(function () { drawImg(pixel1, pixel2, xMinRange, xMaxRange); }); jquery_1["default"]("#rePlot").click(function () { rePrint = true; document.getElementById("SaturationSlider").value = "100"; drawImg(pixel1, pixel2, xMinRange, xMaxRange); }); jquery_1["default"]("#TrasparencySlider").mouseup(function () { drawImg(pixel1, pixel2, xMinRange, xMaxRange); }); jquery_1["default"]("#reset").click(function () { newOrigin = { xp: 0, yp: 0 }; rePrint = false; calibrated = false; globalxMinRange = 0; globalxMaxRange = channelDepth; document.getElementById("SaturationSlider").value = "100"; document.getElementById("TrasparencySlider").value = "0"; document.getElementById("spinBoxMin").setAttribute("value", "-"); document.getElementById("spinBoxMax").setAttribute("value", "-"); drawImg({ xp: 0, yp: 0 }, { xp: xDim - 1, yp: yDim - 1 }, 0, channelDepth); drawChart({ xp: 0, yp: 0 }, { xp: xDim - 1, yp: yDim - 1 }, 0, channelDepth); }); jquery_1["default"]("#ExportImage").click(function () { var img = document.getElementById("myCanvas").toDataURL("image/png"); jquery_1["default"]("#ExportLink").attr("href", img); //document.write('<img src="'+img+'"/>'); }); } //la funzione drawChart (input: estremi dell'immagine, estremi dell'intervallo) //disegna il grafico richiesto relativo alla mappa visualizzata function drawChart(pixel1, pixel2, xMinRange, xMaxRange) { //definisco la variabile "grafico", i bottoni relativi al grafico, il tag //select e le due spinbox con il relativo botton var g; var box1 = document.getElementById("spinBoxMin"); var box2 = document.getElementById("spinBoxMax"); //disegno il grafico completo if (pixel1.xp == 0 && pixel1.yp == 0 && pixel2.xp == xDim - 1 && pixel2.yp == yDim - 1) { if (!calibrated) { var chartTitle = "Chart from (0, 0) to (" + (xDim - 1) + ", " + (yDim - 1) + ")"; g = setChart(dataCompleteChart, chartTitle); } else { var chartTitle = "Calibrated chart from (0, 0) to (" + (xDim - 1) + ", " + (yDim - 1) + ")"; g = setChart(dataCompleteChartCalibrated, chartTitle); } //disegno il grafico parzialmente } else { //determino i conteggi dei pixel da disegnare var dataForChart = new Array(depth); for (var i = 0; i < depth; i++) { dataForChart[i] = 0; } for (var i = pixel1.xp; i <= pixel2.xp; i++) { for (var j = pixel1.yp; j <= pixel2.yp; j++) { for (var k = 0; k < depth; k++) { dataForChart[k] += DataMatrix[i][j][k]; } } } if (!calibrated) { var dataChart = "Channel,Counts\n"; for (var i = 0; i < depth; i++) { dataChart += i + "," + dataForChart[i] + "\n"; } if (pixel1.xp == pixel2.xp && pixel1.yp == pixel2.yp) { var chartTitle = "Chart pixel (" + pixel1.xp + ", " + (yDim - pixel1.yp - 1) + ")"; } else { var chartTitle = "Chart from (" + pixel1.xp + "," + pixel2.xp + ") to (" + (yDim - pixel1.yp - 1) + ", " + (yDim - pixel2.yp - 1) + ")"; } g = setChart(dataChart, chartTitle); } else { var dataChartCalibrated = "Energy,Counts\n"; for (var i = 0; i < depth; i++) { dataChartCalibrated += round3(((i + 1) * a - b) / 1000) + "," + dataForChart[i] + "\n"; } if (pixel1.xp == pixel2.xp && pixel1.yp == pixel2.yp) { var chartTitle = "Calibrated chart pixel (" + pixel1.xp + ", " + (yDim - pixel1.yp - 1) + ")"; } else { var chartTitle = "Calibrated chart from (" + pixel1.xp + ", " + pixel2.xp + ") to (" + (yDim - pixel1.yp - 1) + ", " + (yDim - pixel2.yp - 1) + ")"; } g = setChart(dataChartCalibrated, chartTitle); } } jquery_1["default"]('#setlinearButton').on('click', function () { g.updateOptions({ logscale: false }); }); jquery_1["default"]('#setlogButton').on('click', function () { g.updateOptions({ logscale: true }); }); jquery_1["default"]('#setEnergyButton').on('click', function () { calibrated = true; drawChart(pixel1, pixel2, 0, channelDepth); box1.setAttribute("value", "0"); box2.setAttribute("value", "channelDepth"); }); jquery_1["default"]('#setChannelsButton').on('click', function () { calibrated = false; drawChart(pixel1, pixel2, 0, channelDepth); box1.setAttribute("value", "-"); box2.setAttribute("value", "-"); }); jquery_1["default"]('#ExportGraph').on('click', function () { var img = document.getElementById("chartToImg"); Dygraph.Export.asPNG(g, img); jquery_1["default"]("#ExportGraph").attr("href", img.src.replace('image/png', 'image/octet-stream')); }); jquery_1["default"]('#readSpinbox').on('click', function () { peackSelection(0, 0); }); jquery_1["default"]('#chart').on('click', function () { var r; r = g.xAxisRange(); if (!calibrated) { r[0] = Math.floor((((r[0] + 1) * a) - b) / 1000); r[1] = Math.floor((((r[1] + 1) * a) - b) / 1000); } else { r[0] = round3(r[0]); r[1] = round3(r[1]); box1.setAttribute("value", r[0].toString()); box2.setAttribute("value", r[1].toString()); } globalxMinRange = r[0]; globalxMaxRange = r[1]; drawImg(pixel1, pixel2, r[0], r[1]); }); jquery_1["default"]('#elementSelect').on('change', function () { var element = document.getElementById("elementSelect").value; switch (element) { case "1"://Ca peackSelection(3.6, 3.8); box1.setAttribute("value", "3.60"); box2.setAttribute("value", "3.80"); break; case "2"://Pb peackSelection(10.4, 10.7); box1.setAttribute("value", "10.40"); box2.setAttribute("value", "10.70"); break; case "3"://Hg peackSelection(9.8, 10.15); box1.setAttribute("value", "9.80"); box2.setAttribute("value", "10.15"); break; case "4"://Fe peackSelection(6.3, 6.5); box1.setAttribute("value", "6.30"); box2.setAttribute("value", "6.50"); break; case "5"://Cu peackSelection(7.85, 8.2); box1.setAttribute("value", "7.85"); box2.setAttribute("value", "8.20"); break; case "6"://Zn peackSelection(8.5, 8.72); box1.setAttribute("value", "8.50"); box2.setAttribute("value", "8.72"); break; case "7"://Ti peackSelection(4.35, 4.65); box1.setAttribute("value", "4.35"); box2.setAttribute("value", "4.65"); break; case "8"://K peackSelection(3.2, 3.42); box1.setAttribute("value", "3.20"); box2.setAttribute("value", "3.42"); break; case "9"://Co peackSelection(6.8, 7.05); box1.setAttribute("value", "6.80"); box2.setAttribute("value", "7.05"); break; default: peackSelection(0, channelDepth); box1.setAttribute("value", "0"); box2.setAttribute("value", "channelDepth"); break; } }); //la funzione setChart riceve in input i dati e il titolo del grafico da disegnare //il quale è restituito il output function setChart(dataString, charTitle) { var xArrayRange; //estremi asse x da visualizzare var xLab; if (!calibrated) { xArrayRange = [0, depth]; xLab = "ADC Channel"; } else { xArrayRange = [xMinRange, xMaxRange]; xLab = "Energy (keV)"; } //dimensioni grafico var chartDim = document.querySelector('#chart-pannel').getBoundingClientRect(); var chartWidth = chartDim.right - chartDim.left - 50; jquery_1["default"]('#chart').css('width', chartWidth); jquery_1["default"]('#chart').css('height', "400"); //disegno il grafico var graphs = new Dygraph(document.getElementById("chart"), dataString, { title: charTitle, ylabel: 'Counts', xlabel: xLab, //legend: 'always', labelsDivStyles: { 'textAlign': 'right' }, dateWindow: xArrayRange, showRangeSelector: true, logscale: false }); return graphs; } //la funzione, dati gli estremi dell'intervallo da rappresentare, aggiorna mappa e grafico function peackSelection(xMinRange, xMaxRange) { //se l'intervallo è [0, 0] devo leggere dalle i valori dalle spinbox if (xMinRange == 0 && xMaxRange == 0) { xMinRange = parseInt(box1.value); xMaxRange = parseInt(box2.value); } globalxMinRange = xMinRange; globalxMaxRange = xMaxRange; newOrigin = { xp: 0, yp: 0 }; rePrint = false; calibrated = true; drawImg({ xp: 0, yp: 0 }, { xp: xDim - 1, yp: yDim - 1 }, globalxMinRange, globalxMaxRange); drawChart({ xp: 0, yp: 0 }, { xp: xDim - 1, yp: yDim - 1 }, globalxMinRange, globalxMaxRange); } }