Skip to content
Snippets Groups Projects
LoadFile.ts 32.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • //dichiarazione interfacce e variabili globali
    interface coordinates{
      xp: number;
      yp: number;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    }
    var a: number = 3.36275; //costante moltiplicativa per la calibrazione
    var b: number = 58.2353; //costante additiva per la calibrazione
    
    var pixelDim: number; //dimensione dei pixel responsive
    var maxAbsolute: number; //massimo conteggio della matrice nOfCounts
    var globalxMinRange: number = 0, globalxMaxRange: number = 55;
    var xDim: number = 0, yDim: number = 0; //numero di pixel nelle due dimensioni
    var DataMatrix: number[][][], nOfCounts: number[][]; //matrici con i dati
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    var rePrint: boolean = false; //variabile per ricolorare con il max relativo
    var newOrigin: coordinates; //nuovo origine nel caso di zoom
    var zPixel1: coordinates = {xp: 0, yp: 0}; //pixel1 dello zoom
    var zPixel2: coordinates = {xp: 0, yp: 0}; //pixel2 dello zoom
    
    var dataCompleteChart: string = "Channel,Counts\n";
    var dataCompleteChartCalibrated: string = "Energy,Counts\n";
    var calibrated: boolean = false; //variabile per il controllo sulla calibrazione
    
    //INIZIO DELLO SCRIPT
    $(document).ready( function() {
    
      //creazione dell'albero e gestione barre laterali
      setImportFile();
      compressingSidenavSettings();
      compressingSidenavFS();
    
      //abilitazione drag&drop
      var droppableArea: any = document.querySelector('.droppable');
      makeDroppable(droppableArea, callback);
    
    }); 
    
    //funzione che definisce tutti gli elementi responsabili dell'apertura di un file.
    //Sono definiti quindi l'albero e il bottone per l'importazione da locale
    function setImportFile(){
    
    
      //genero e leggo il contenuto della directory "filesystem"
      var jsonResponse: any;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
      var xmlListingFile: any = new XMLHttpRequest();
    
      xmlListingFile.open("GET", "https://baltig.infn.it/api/v4/projects/819/repository/tree?recursive=1&path=XRF-File-System", false);
    
    Laura Cappelli's avatar
    Laura Cappelli committed
      xmlListingFile.onreadystatechange = function(){
        if(xmlListingFile.readyState === 4){
          if(xmlListingFile.status === 200){
    
            jsonResponse = JSON.parse(xmlListingFile.responseText);
    
    Laura Cappelli's avatar
    Laura Cappelli committed
          }
        }
      }
      xmlListingFile.send(null);
    
    
      //ora genero l'albero e definisco l'evento in caso di selezione di un nodo
    
      $('#FileTreeview').treeview({data: generateTree(jsonResponse)});
    
      $('#FileTreeview').on('nodeSelected', function(e, node){
        if(node['url'] != undefined){
    
          openFileFromServer(node['url']);
    
    
      //bottone per l'importazione locale
      var fileInputButton: any = document.getElementById('myImport'); 
      fileInputButton.onchange = function(){
        var fileName: string = fileInputButton.files[0];
        var readerObject: any = new FileReader();
        readerObject.readAsBinaryString(fileName);  
        readerObject.onload = function() {
          var fileString: string = readerObject.result; 
          readData(fileString);
        }
      }
    
    
    
    //funzione che genera automaticamente l'albero
    
    function generateTree(jsonDoc){
    
      var tree: any = [ {
        text:"XRF-File-System",
        nodes: [ ]
      }];
    
      //scorro ogni elemento dell'albero
      for (var i: number = 0; i < jsonDoc.length; i++) {
    
        if(jsonDoc[i].type == "tree"){ //è una cartella      
    
          var Folder = {  //definisco l'oggetto Folder
    
            text: jsonDoc[i].name,
    
            relativePath: jsonDoc[i].path, 
    
            nodes: []
    
          insertOBJinFS(Folder, 0, tree);
    
        } else { //è un file
    
          var File = { //definisco l'oggetto File
            text: jsonDoc[i].name,
            relativePath: jsonDoc[i].path,
    
            icon: "glyphicon glyphicon-file",
            selectedIcon: "glyphicon glyphicon-file",
    
          //inserisco il file nella giusta posizione
          insertOBJinFS(File, 1, tree);
    
    //funzione che posiziona l'oggetto passato in input nell'albero
    
    function insertOBJinFS(objfs, type, tree){
    
      //tree[0].nodes.push(objfs);
    
      var parentPath: string = objfs.relativePath.slice(0, objfs.relativePath.lastIndexOf("/"));
      if(parentPath == tree[0].text){
        tree[0].nodes.push(objfs);
      }
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
    //funzione che dato l'url di un file, lo apre e lo legge passandone il contenuto
    //alla funzione readData(). Questa funzione è invocata quando viene selezionato
    //un file dall'albero
    function openFileFromServer(url){
    
      
      console.log("Try to open " + url.slice(url.lastIndexOf("/"), url.length-1) + " ...");
      url = encodeURIComponent(url).slice(2, url.length-1);
    
      url = "https://baltig.infn.it/api/v4/projects/819/repository/files/ " + 
    
        url + "?ref=master";
    
      var txtFile: any = new XMLHttpRequest();
      txtFile.open("GET", url, true);
      txtFile.onreadystatechange = function(){
        if(txtFile.readyState === 4){
          if(txtFile.status === 200){
    
    Laura Cappelli's avatar
    Laura Cappelli committed
            readData((txtFile.responseText));
    
      txtFile.send(null);    
    
    }
    
    //funzione per la compressione della sidenav dx
    function compressingSidenavSettings(){
    
    
      var setLabel: any = $('.btn-settings');
      var isClosedSettings: boolean = false;
      setLabel.click(function () { setLabel_cross(); });
    
      function setLabel_cross() {
        if (isClosedSettings == true) {
          isClosedSettings = false;
    
          $('#mySidenavSet').css('width', "0");
          $('#wrapper').css('marginRight', "0");
          $('#setbtn').css('marginRight', "-2px");
    
        } else {
          isClosedSettings = true;
    
          $('#mySidenavSet').css('width', "250px");
          $('#wrapper').css('marginRight', "250px");
          $('#setbtn').css('marginRight', "248px");
    
    }
    
    //funzione per la compressione della sidenav sx
    function compressingSidenavFS(){
    
    
      var fsLabel: any = $('.fs-label');
      var isClosedfs: boolean = false;
      fsLabel.click(function () { fsLabel_cross(); });
    
      function fsLabel_cross() {
        if (isClosedfs == true) {
          isClosedfs = false;
          fsLabel.removeClass('is-open');
          fsLabel.addClass('is-closed');
    
          $('#mySidenavfs').css('width', "0");
          $('#wrapper').css('marginLeft', "0");
          $('#fsbtn').css('marginLeft', "-2px");
    
        } else {
          isClosedfs = true;
          fsLabel.removeClass('is-closed');
          fsLabel.addClass('is-open');
    
          $('#mySidenavfs').css('width', "250px");
          $('#wrapper').css('marginLeft', "250px");
          $('#fsbtn').css('marginLeft', "248px");
    
    //funzione che definisce l'area su cui si può eseguire il drag&drop
    function makeDroppable(droppableArea, callback) {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      //creo l'elemento "input type file" non visibile e lo aggiungo a "droppableArea"
      var input: any = document.createElement('input');
    
    Laura Cappelli's avatar
    Laura Cappelli committed
      input.setAttribute('type', 'file');
      input.setAttribute('multiple', true);
      input.style.display = 'none';
    
      droppableArea.appendChild(input);
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
      //questo evento è chiamato quando i file sono trascinati ma non ancora lasciati
    
      droppableArea.addEventListener('dragover', function(e) {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        e.preventDefault(); //impediamo l'apertura del file
        e.stopPropagation();
        e.dataTransfer.dropEffect = 'copy';
    
        droppableArea.classList.add('dragover');
    
    Laura Cappelli's avatar
    Laura Cappelli committed
      });
    
      //l'evento è chiamato quando un file lascia la zona predefinita per il drag&drop
    
      droppableArea.addEventListener('dragleave', function(e) {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        e.preventDefault();
        e.stopPropagation();
    
        droppableArea.classList.remove('dragover');
    
    Laura Cappelli's avatar
    Laura Cappelli committed
      });
    
      //questo evento si innesca quando il drop è effettivamente avvenuto
    
      droppableArea.addEventListener('drop', function(e) {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        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) {
    
      console.log("Try to open " + files[files.length-1].name + " ...");
      var readerObject: any = new FileReader();
      readerObject.readAsBinaryString(files[files.length-1]);  
      readerObject.onload = function() {
        var fileString: string = readerObject.result; 
        readData(fileString);
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
    //la funzione prepara i dati per il grafico completo
    function setDataForCompleteChart(){
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      //per ogni pixel sommo i conteggi di tutti i canali rilevati
      var dataForChart: number[] = new Array(16384);
      for(var i: number = 0; i < 16384; i++){
       dataForChart[i] = 0;
      }
      for(var i: number = 0; i < xDim; i++){
        for(var j: number = 0; j < yDim; j++){
          for(var k: number = 0; k < 16384; k++){
            dataForChart[k] += DataMatrix[i][j][k];
          }
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        }
    
      }
      //riempio le stringhe con i dati per il grafico
      for(var i: number = 0; i < 16348; i++){
        dataCompleteChart += (i+1) + "," + dataForChart[i] + "\n";
        dataCompleteChartCalibrated+=round3(((i+1)*a-b)/1000)+","+dataForChart[i]+"\n";
      }
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
    //La funzione riceve in input un vettore di cui somma gli elementi compresi tra 
    //gli indici from e to 
    function sumVect(vect: number[], from: number, to: number){
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      var sum: number = 0;
      for(var i: number = from; i < to; i++){ sum += vect[i]; }
      return sum;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
    //La funzione riceve in input la matrice e gli estremi della sottomatrice di cui
    //calcola il massimo
    function findMax(matrix: number[][], pixel1: coordinates, pixel2:coordinates){
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      var max: number = 0;
      for(var i: number = pixel1.xp; i <= pixel2.xp; i++){
        for(var j: number = pixel1.yp; j <= pixel2.yp; j++){
          if(matrix[i][j] > max){
              max = matrix[i][j];
          }
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        }
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
    //Funzione per arrotondare il numero in input alla terza cifra decimale
    function round3(val: number){
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      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: any, pixel: coordinates){
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      var scrollTOP: number = (document.documentElement.scrollTop) ? 
        document.documentElement.scrollTop : document.body.scrollTop;
      var scrollLEFT: number = (document.documentElement.scrollLeft) ? 
        document.documentElement.scrollLeft : document.body.scrollLeft;
      var allX: number = event.clientX+scrollLEFT;
      var allY: number = event.clientY+scrollTOP;
      var elParent: any = document.getElementById('myCanvas');
      var objX: number = 0, objY: number = 0;
      while (elParent){
        objX += elParent.offsetLeft;
        objY += elParent.offsetTop;
        elParent = elParent.offsetParent;
      }
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      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: any){
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      findPosition(event, zPixel1);
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
    }
     
    //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: any){
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      findPosition(event, zPixel2);
      var tmp: number;
      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
      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 readData() prende in ingresso il file di input memorizzato nella 
    // stringa "fileString". La funzione riempie la matrice "DataMatrix" con i dati
    // in modo che essi siano memorizzati in un formato più leggibile. Sono ricavate
    // anche altre variabili necessarie per il resto del codice.
    function readData(fileString){
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      newOrigin = {xp: 0, yp: 0};  //origine nel caso di zoom
      var passo: number = 0; //dimensione di un pixel in micorn
      var readMode: string; //direzione di lettura
      //coordinate minime e massime in entrambe le dimensioni
      var xMin: number = 0, yMin: number = 0, xMax: number = 0, yMax: number = 0;  
      //array con il contenuto del file di input suddiviso per righe
      var fileStringArray: any = fileString.split("\n");
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        
    
      //scorro l'array soffermandomi solo sulle righe "intestazione delle x". Devo
      //determinare ascisse e cordinate minime e massime, il passo e la direzione di
      //scansione
      for(var i: number = 0; i < fileStringArray.length; i++){
        if(parseInt(fileStringArray[i]) > 17000 && fileStringArray[i][0] =='5'){      
          if(xMin == 0){ //se sono alla prima intestazione salvo la x e la y
            xMin = parseInt(fileStringArray[i]);
            yMin = parseInt(fileStringArray[i+1]);
            i++;
          } else { //definisco passo e direzione di scansione dalla seconda intestazione
            if(parseInt(fileStringArray[i]) == xMin){
              readMode = 'c';
              passo = Math.abs(yMin - fileStringArray[i+1]);
              //se sto leggendo per colonne determino xMax leggendo dalla fine
              for(var j: number = fileStringArray.length; j > i; j--){
                //se la riga è "intestazione x" memorizzo xMax e lo confronto con xMin
                if(parseInt(fileStringArray[j]) > 17000 && fileStringArray[j][0] =='5'){
                  xMax = parseInt(fileStringArray[j]);
                  if(xMax < xMin){ var t: number = xMax; xMax = xMin; xMin = t; }
                  break;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
                }
    
    Laura Cappelli's avatar
    Laura Cappelli committed
            } else {
    
              readMode = 'r';
              passo = Math.abs(xMin - fileStringArray[i]);
              //se sto leggendo per righe determino yMax leggendo dalla fine
              for(var j: number = fileStringArray.length; j > i; j--){
                //se la riga è "intestazione y" memorizzo yMax e lo confronto con yMin
                if(parseInt(fileStringArray[j]) > 17000 && fileStringArray[j][0] =='6'){
                  yMax = parseInt(fileStringArray[j]);
                  if(yMax < yMin){ var t: number = yMax; yMax = yMin; yMin = t; }
                  break;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
                }
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        }
    
      } //alert(xMin + " " + xMax + " " + yMin + " " + yMax + " " + passo);
        
      //A seconda della direzione di lettura determino o yMin e yMax, o xMin e xMax    
      for(var i: number = 2; i < fileStringArray.length; i++){
        if(readMode == 'c'){ //se leggo per colonne devo deterinare yMin e yMax
          //mi soffermo sulle righe "intestazione y"
          if (parseInt(fileStringArray[i]) > 17000 && fileStringArray[i][0] == '6') {
            if (yMin > parseInt(fileStringArray[i])){
              yMin = parseInt(fileStringArray[i]);
    
    Laura Cappelli's avatar
    Laura Cappelli committed
            }
    
            if(yMax < parseInt(fileStringArray[i])){
              yMax = parseInt(fileStringArray[i]);
    
          }
          //alla terza colonna posso uscire perché ho già tutte le informazioni
          if (parseInt(fileStringArray[i]) == xMin + (passo * 2)) { break; }
        } else { //se leggo per righe devo deterinare xMin e xMax 
          //mi soffermo sulle righe "intestazione x"
          if (parseInt(fileStringArray[i]) > 17000 && fileStringArray[i][0] == '5') {
            if (xMin > parseInt(fileStringArray[i])){
              xMin = parseInt(fileStringArray[i]);
    
            if(xMax < parseInt(fileStringArray[i])){
              xMax = parseInt(fileStringArray[i]);
            }
          }
          //alla terza colonna posso uscire perché ho già tutte le informazioni
          if (parseInt(fileStringArray[i]) == yMin + 2000) { break; }
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        }
    
      } //alert(xMin + " " + xMax + " " + yMin + " " + yMax + " " + passo);
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      //Risolvo gli shift
      for(var i: number = 0; i < fileStringArray.length; i++){
        //se leggo per colonne allora aggiungo 1 alle y di tutte le colonne dispari
        if(readMode == 'c' && parseInt(fileStringArray[i]) > 17000 &&
          fileStringArray[i][0]=='5' && (parseInt(fileStringArray[i])/1000)%2 != 0){
          
          fileStringArray[i+1] = (parseInt(fileStringArray[i+1]) + passo).toString();
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        }
    
        //se leggo per righe allora aggiungo 1 alle x di tutte le righe dispari
        else if(readMode == 'r' && parseInt(fileStringArray[i]) > 17000 &&
          fileStringArray[i][0]=='5' && (parseInt(fileStringArray[i+1])/1000)%2 != 0){
    
          fileStringArray[i] = (parseInt(fileStringArray[i]) + passo).toString();
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        }
    
      }
    
      //Definisco le dimensioni della matrice DataMatrix e la inizializzo
      if(readMode == 'c'){
        xDim = (xMax - xMin)/passo + 1;
        yDim = (yMax - yMin)/passo - 2;
      } else {
        xDim = (xMax - xMin)/passo - 2;
        yDim = (yMax - yMin)/passo + 1;
      }
      //alert(xDim + " " + yDim);
      DataMatrix = new Array(xDim);
      for(var i: number = 0; i < xDim; i++){
        DataMatrix[i] = new Array(yDim);
        for(var j: number = 0; j < yDim; j++){
          DataMatrix[i][j] = new Array(16384);
          for(var k: number = 0; k < 16384; k++){
            DataMatrix[i][j][k] = 0;
          }
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        }
    
      }
        
      //riempio la matrice DataMatrix eliminando i bordi
      for(var i: number = 0; i < fileStringArray.length; i++){
        var x: number, y: number, write: boolean;
        //riga "intestazione x": memorizzo le x e le y del punto e avanzo al conteggio
        if(parseInt(fileStringArray[i]) > 17000 && fileStringArray[i][0] == '5'){
          x = (parseInt(fileStringArray[i]) - xMin);
          y = (parseInt(fileStringArray[i+1]) - yMin);
          if(x != 0){ x /= passo; }
          if(y != 0){ y /= passo; }
          i++;
    
          //non è un pixel del bordo e sto leggendo per colonne: i successivi valori
          //sono da considerare
          if(readMode == 'c' && y != 0 && y != 1 && y != (yMax - yMin)/passo &&
            y != (yMax - yMin)/passo + 1){
            write = true;
            y -= 2; //aggiorno la y con i bordi tagliati
          }
          //non è un pixel del bordo e sto leggendo per righe: i successivi valori
          //sono da considerare
          else if(readMode == 'r' && x != 0 && x != 1 && x != (xMax - xMin)/passo && 
            x != (xMax - xMin)/passo + 1){
            write = true;
            x -= 2; //aggiorno la x con i bordi tagliati
          }
          //pixel del bordo: i valori successivi sono da ignorare
          else{ write = false; }
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        
    
        //conteggio da considerare (non del bordo) 
        } else if (parseInt(fileStringArray[i]) < 17000 && write == true){
          //inserisco il conteggio nella matrice (occhio all'orientamento)
          DataMatrix[xDim-x-1][yDim-y-1][parseInt(fileStringArray[i])] += 1;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        }
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      //calcolo il numero di conteggi per pixel e li salvo nella matrice nOfCounts
      nOfCounts = new Array(xDim);
      for(var i: number = 0; i < xDim; i++){
        nOfCounts[i] = new Array(yDim);
        for(var j: number = 0; j < yDim; j++){
          nOfCounts[i][j] = sumVect(DataMatrix[i][j], 0, DataMatrix[i][j].length);
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        }
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      //calcolo il conteggio massimo della matrice
      maxAbsolute = findMax(nOfCounts, {xp: 0, yp: 0}, {xp: xDim-1, yp: yDim-1});
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      //definisco i dati per il grafico completo
      setDataForCompleteChart();
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      console.log("File open with succes");
      drawImg({xp: 0, yp: 0}, {xp: xDim - 1, yp: yDim - 1}, 0, 55);
      drawChart({xp: 0, yp: 0}, {xp: xDim - 1, yp: yDim - 1}, 0, 55);
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
    //la funzione drawImg disegna il canvas con l'immagine desiderata ed è responsabile
    //della gestione di tutti gli eventi ad essa associati
    function drawImg(pixel1: coordinates, pixel2:coordinates, xMinRange: number, xMaxRange: number){
    
      //dimensioni pixel
      var nPixelX: number = pixel2.xp - pixel1.xp + 1;
      var nPixelY: number = pixel2.yp - pixel1.yp + 1;
      var mappaPannelDim: any = document.querySelector ('#mappa-pannel').getBoundingClientRect();
      var mappaWidth: number = mappaPannelDim.right - mappaPannelDim.left - 20;
      var mappaHeigth: number = mappaPannelDim.bottom - mappaPannelDim.top - 50; 
      var dimPixelx: number = Math.floor(mappaWidth/nPixelX);
      var dimPixely: number = Math.floor(mappaHeigth/nPixelY);
      pixelDim = (dimPixelx < dimPixely) ? dimPixelx : dimPixely;
      document.getElementById("myCanvas").height = nPixelY * pixelDim;
      document.getElementById("myCanvas").width = nPixelX * pixelDim;
      var ctx = document.getElementById('myCanvas').getContext('2d'); //contesto del canvas
    
      if(xMaxRange - xMinRange >= 55){ //range completo
        var max: number; //massimo relativo o assoluto
        if (rePrint) max = findMax(nOfCounts, pixel1, pixel2);
        else max = maxAbsolute;
        max = (max * document.getElementById("SaturationSlider").value)/100 ; //saturazione
        drawCanvas(nOfCounts, max); //disegno
    
      } else { //range parziale (solo alcuni canali)
        var xMinRangeCh: number = Math.floor((((xMinRange*1000)+b)/a)-1); //16
        var xMaxRangeCh: number = Math.floor((((xMaxRange*1000)+b)/a)-1); //16371
        //calcolo il numero di conteggi solo dei canali selezionati
        var nOfCountsRelative: number[][];
        nOfCountsRelative = new Array(xDim);
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        for(var i: number = 0; i < xDim; i++){
    
          nOfCountsRelative[i] = new Array(yDim);
          for(var j: number = 0; j < yDim; j++){
            nOfCountsRelative[i][j] = sumVect(DataMatrix[i][j], xMinRangeCh, xMaxRangeCh);
          }
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        }
    
        //calcolo il massimo
        var max: number;
        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 ; //saturazione
        drawCanvas(nOfCountsRelative, max); //disegno
      }
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      //La funzione, ricevuti dati e massimo, disegna la mappa nel canvas
      function drawCanvas(noc, max){
    
        //controllo il valore della trasparenza
        var setTrsp: number = 1-document.getElementById("TrasparencySlider").value/100;
    
        //scorro tutti i pixel: ne determino il colore e li disegno      
        var color:string = "";
        for (var i: number = pixel1.xp; i <= pixel2.xp; i++) {
          for (var j: number = pixel1.yp; j <= pixel2.yp; j++) {
            var intensity: number = noc[i][j] / max;
            if(intensity < 1/5) //blu
              color = "rgba(0, 0, "+Math.floor(intensity*5*255)+","+setTrsp+")";
            else if (1/5 <= intensity && intensity < 2/5) //blu+verde
              color="rgba(0, "+Math.floor((intensity-1/5)*5*255)+",255, "+setTrsp+")"; 
            else if (2/5 <= intensity && intensity < 3/5) // verde-blu
              color="rgba(0, 255, "+(255-Math.floor((intensity-2/5)*5*255))+", "+setTrsp+")"; 
            else if (3/5 <= intensity && intensity < 4/5) //verde + rosso 
              color="rgba("+Math.floor((intensity-3/5)*5*255)+",255,0,"+setTrsp+")"; 
            else //rosso -verde
              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);
          }
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        }
    
        rePrint = false; //annullo rePrint
      }
      
      $("#SaturationSlider").mouseup(function(){ //Slider della saturazione
        drawImg(pixel1, pixel2, xMinRange, xMaxRange);
      });
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      $("#rePlot").click(function(){ //bottone per colorare con il max relativo
        rePrint = true;
        document.getElementById("SaturationSlider").value = "100";
        drawImg(pixel1, pixel2, xMinRange, xMaxRange);
      });
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      $("#TrasparencySlider").mouseup(function(){ //Slider della trasparenza
        drawImg(pixel1, pixel2, xMinRange, xMaxRange);
      });
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      $("#reset").click(function(){ //bottone per il reset dell'applicazione
        newOrigin = {xp: 0, yp: 0};
        rePrint = false;
        calibrated = false;
        globalxMinRange = 0;
        globalxMaxRange = 55;
        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, 55);
        drawChart({xp: 0, yp: 0}, {xp: xDim - 1, yp: yDim - 1}, 0, 55);
      });
    
      $("#ExportImage").click(function(){ //esportazione immagine
        var img = document.getElementById("myCanvas").toDataURL("image/png");
        $("#ExportImage").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: coordinates, pixel2:coordinates, xMinRange: number, xMaxRange: number){
        
      //definisco la variabile "grafico", i bottoni relativi al grafico, il tag
      //select e le due spinbox con il relativo botton
      var g: any;
      var box1 = <HTMLElement>document.getElementById("spinBoxMin");
      var box2 = <HTMLElement>document.getElementById("spinBoxMax");
    
      //disegno il grafico completo
      if(pixel1.xp == 0 && pixel1.yp == 0 && pixel2.xp == xDim-1 && pixel2.yp == yDim-1){
        if(!calibrated){ //canali
          var chartTitle: string = "Chart from (0, 0) to ("+(xDim-1)+", "+(yDim-1)+")";
          g = setChart(dataCompleteChart, chartTitle);
        } else { //energie
          var chartTitle: string = "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: number[] = new Array(16384);
        for(var i: number = 0; i < 16384; i++){
          dataForChart[i] = 0;
        }
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        for(var i: number = pixel1.xp; i <= pixel2.xp; i++){
    
          for(var j: number = pixel1.yp; j <= pixel2.yp; j++){
            for(var k: number = 0; k < 16384; k++){
              dataForChart[k] += DataMatrix[i][j][k];
    
    Laura Cappelli's avatar
    Laura Cappelli committed
            }
    
          }
        }
        
        if(!calibrated){ //disegno in canali
          var dataChart: string = "Channel,Counts\n";
          for(var i: number = 0; i < 16348; i++){
            dataChart += i + "," + dataForChart[i] + "\n";
          }
          if(pixel1.xp == pixel2.xp && pixel1.yp == pixel2.yp){
            var chartTitle: string = "Chart pixel (" + pixel1.xp + ", " + (yDim - pixel1.yp - 1) + ")";
          } else {
            var chartTitle: string = "Chart from (" + pixel1.xp + "," + pixel2.xp + ") to (" +
              (yDim - pixel1.yp - 1) + ", " + (yDim - pixel2.yp - 1) + ")";
          }
          g = setChart(dataChart, chartTitle);
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
        } else { //disegno in energie
          var dataChartCalibrated: string = "Energy,Counts\n";
          for(var i: number = 0; i < 16348; i++){
            dataChartCalibrated += round3(((i+1)*a-b)/1000) + "," + dataForChart[i] + "\n";
          }
          if(pixel1.xp == pixel2.xp && pixel1.yp == pixel2.yp){
            var chartTitle: string = "Calibrated chart pixel ("+pixel1.xp+", "+(yDim-pixel1.yp-1)+")";
          } else {
            var chartTitle: string = "Calibrated chart from (" + pixel1.xp + ", " + pixel2.xp +
             ") to ("+ (yDim - pixel1.yp - 1) + ", " + (yDim - pixel2.yp - 1) + ")";
          }
          g = setChart(dataChartCalibrated, chartTitle);
        }     
      }
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      $('#setlinearButton').on('click', function() { //selezione scala lineare
        g.updateOptions( {logscale: false} );
      });
      $('#setlogButton').on('click', function() { //selezione scala logaritmica
        g.updateOptions( {logscale: true} );
      });
      $('#setEnergyButton').on('click', function() { //selezione energie
        calibrated = true;
        drawChart(pixel1, pixel2, 0, 55);
        box1.setAttribute("value", "0");
        box2.setAttribute("value", "55");
      });
      $('#setChannelsButton').on('click', function() { //selezione canali
        calibrated = false;
        drawChart(pixel1, pixel2, 0, 55);
        box1.setAttribute("value", "-");
        box2.setAttribute("value", "-");
      });
      $('#ExportGraph').on('click', function() { //esportazione grafico
        var img = document.getElementById("chartToImg");
        Dygraph.Export.asPNG(g, img);
        document.getElementById("ExportGraph").href = img.src.replace('image/png','image/octet-stream');
      });
      $('#readSpinbox').on('click', function() { //esportazione grafico
        peackSelection(0, 0);
      });
      $('#chart').on('click', function() { //zoom manuale sul grafico
        var r: number[];
        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]);
      });
      $('#elementSelect').on('change', function() { //selezione elemento
        var element: string = 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, 55);
            box1.setAttribute("value", "0");
            box2.setAttribute("value", "55");
            break;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        }
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      //la funzione setChart riceve in input i dati e il titolo del grafico da disegnare
      //il quale è restituito il output
      function setChart(dataString: string, charTitle: string){
    
        var xArrayRange: number[]; //estremi asse x da visualizzare
        var xLab: string;
        if(!calibrated){
          xArrayRange = [0, 16383];
          xLab = "ADC Channel";
        }else{
          xArrayRange = [xMinRange, xMaxRange];
          xLab = "Energy (keV)";
        }
    
        //dimensioni grafico
        var chartDim: any = document.querySelector('#chart-pannel').getBoundingClientRect();
        var chartWidth = chartDim.right - chartDim.left - 50;
        $('#chart').css('width', chartWidth);
        var chartHeight: number = chartDim.bottom - chartDim.top - 100; 
        $('#chart').css('height', chartHeight);
    
        //disegno il grafico
        var graphs: any = new Dygraph(document.getElementById("chart"), dataString, {
          title: charTitle,
          ylabel: 'Counts',
          xlabel: xLab,
          //legend: 'always',
          labelsDivStyles: { 'textAlign': 'right' },
          dateWindow: xArrayRange,
          showRangeSelector: true,
          logscale: false
        });
    
        //dimensioni responsive alle sideNav
        $('#fsbtn').on('click', function() { 
          setTimeout(function(){
            g = setChart(dataString, charTitle);
            drawImg(pixel1, pixel2, xMinRange, xMaxRange);
          }, 400);
        });
        $('#setbtn').on('click', function() {
          setTimeout(function(){
            g = setChart(dataString, charTitle);
            drawImg(pixel1, pixel2, xMinRange, xMaxRange);
          }, 400);
        });
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      //la funzione, dati gli estremi dell'intervallo da rappresentare, aggiorna mappa e grafico
      function peackSelection(xMinRange: number, xMaxRange: number){
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
        //se l'intervallo è [0, 0] devo leggere dalle i valori dalle spinbox
        if(xMinRange == 0 && xMaxRange == 0){
          xMinRange = box1.value;
          xMaxRange = box2.value;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        }
    
    
        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);
    
      }
    
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    }