Skip to content
Snippets Groups Projects
LoadFile.ts 49.7 KiB
Newer Older
Laura Cappelli's avatar
Laura Cappelli committed
interface coordinates{ //tipo delle variabili "pixel"
    xp: number;
    yp: number;
}
var DataMatrix: number[][][]; //matrice 3D con tutti i dati letti dal file
var nOfCounts: number[][]; //numero di conteggi per ogni pixel
var pixelDim: number; //dimensione di un pixel in pt
var maxAbsolute: number; //massimo conteggio della matrice nOfCounts
var dataCompleteChart: string; //dati del grafico completo
var dataCompleteChartCalibrated: string; //dati del grafico calibrato completo
var a: number = 3.36275; //costante moltiplicativa per la calibrazione
var b: number = 58.2353; //costante additiva per la calibrazione
var rePrint: boolean = false; //variabile per ricolorare con il max relativo
var calibrated: boolean = false; //variabile per il controllo sulla calibrazione
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 canvasMaxWidth: number = 450; //dim massima della canvas in pt - asse x
//var canvasMaxHeight: number = 500; //dim massima della canvas in pt - asse y
var xDim: number = 0; //numero di pixel dell'immagine sull'asse x
var yDim: number = 0; //numero di pixel dell'immagine sull'asse y
var passo: number = 0; //dimensione di un pixel in micorn
var globalxMinRange: number = 0; //estremo sinistro del range dell'asse x
var globalxMaxRange: number = 55; //estremo destra del range dell'asse x
var realPixelDim: number; //dimensione dei pixel responsive

//imposto le dimensioni del canvas
var bb: any = document.querySelector ('#mappa-pannel').getBoundingClientRect();
var maxMappaWidth: number = bb.right - bb.left - 50;
var maxMappaHeight: number = bb.bottom - bb.top - 50;

//avvio la possibilità di fare il drag&drop
var element = document.querySelector('.droppable');
makeDroppable(element, callback);

//costruzione dell'albero
//prima parte: leggo il file con la descrizione della directory
// var MapTreeFile = new  XMLHttpRequest();
// MapTreeFile.open("GET", "https://oc-chnet.cr.cnaf.infn.it:8443/Laura/XRF-App/tree.XML", true);
// MapTreeFile.onreadystatechange = function(){
//     if(MapTreeFile.readyState === 4){
//         if(MapTreeFile.status === 200){
//             var MapTreeText: any = JSON.parse(MapTreeFile.responseText);
//             //alert(MapTreeText[0].name);
//             //creaAlbero(MapTreeText);
//         }
//     }
// }
// MapTreeFile.send(null);

// function openTreeFile() { 
//   var MapTreeFile = new XMLHttpRequest();
//   var obj;
//   MapTreeFile.onreadystatechange = function() {
//     if (this.readyState == 4 && this.status == 200) {
//       parseTreefile(this);
//     }
//   };
//   MapTreeFile.open("GET", "https://oc-chnet.cr.cnaf.infn.it:8443/Laura/XRF-App/tree.XML", true);
//   MapTreeFile.send();
// }

// function parseTreefile(xml) {

//   var parser = new DOMParser();
//   var xmlDoc = parser.parseFromString(xml, "text/xml");

//   //xmlDoc.getElementsByTagName("d:getcontenttype")[0].childNodes[0].nodeValue;

// }
Laura Cappelli's avatar
Laura Cappelli committed

//creo l'albero con treeview
/*function getTree() {
  var tree = [
Laura Cappelli's avatar
Laura Cappelli committed
    {
      text: "XRFfilesystem",
      nodes: [
Laura Cappelli's avatar
Laura Cappelli committed
        {
          text: "Pergamena-Medioevale",
          nodes: [
Laura Cappelli's avatar
Laura Cappelli committed
            {
              text: "La-muta",
              nodes: [
                {
                  text: "La-muta",
                  nodes: [
                    {
                      text: "file.txt",
                      icon: "glyphicon glyphicon-file",
                      selectedIcon: "glyphicon glyphicon-file",
                      url: "https://oc-chnet.cr.cnaf.infn.it:8443/owncloud/remote.php/webdav/Documents/XRFfilesystem/Pergamena-Medioevale/La-muta/La-muta/file.txt"
                    }
                  ]
                }
              ]
Laura Cappelli's avatar
Laura Cappelli committed
            },
            {
              text: "file.txt",
              icon: "glyphicon glyphicon-file",
              selectedIcon: "glyphicon glyphicon-file",
              url: "https://oc-chnet.cr.cnaf.infn.it:8443/owncloud/remote.php/webdav/Documents/XRFfilesystem/Pergamena-Medioevale/file.txt"
            },
Laura Cappelli's avatar
Laura Cappelli committed
            {
              text: "file.txt",
              icon: "glyphicon glyphicon-file",
              selectedIcon: "glyphicon glyphicon-file",
              url: "https://oc-chnet.cr.cnaf.infn.it:8443/owncloud/remote.php/webdav/Documents/XRFfilesystem/Pergamena-Medioevale/file.txt"
Laura Cappelli's avatar
Laura Cappelli committed
            },
            {
              text: "file.txt",
              icon: "glyphicon glyphicon-file",
              selectedIcon: "glyphicon glyphicon-file",
              url: "https://oc-chnet.cr.cnaf.infn.it:8443/owncloud/remote.php/webdav/Documents/XRFfilesystem/Pergamena-Medioevale/file.txt"
            }
          ]
        },
        {
          text: "Raffaello",
          nodes: [
            {
              text: "La-muta",
              nodes: [
                {
                  text: "file.txt",
                  icon: "glyphicon glyphicon-file",
                  selectedIcon: "glyphicon glyphicon-file",
                  url: "https://oc-chnet.cr.cnaf.infn.it:8443/owncloud/remote.php/webdav/Documents/XRFfilesystem/Raffaello/La-muta/file.txt"
                }
              ]
            }
          ]
        }
      ]
    }
  ];
  return tree;
}*/

//funzione che genera automaticamente l'albero
function generateTree(xmlDoc){
  var tree = [];
  var first: boolean = true;
  var oldFolderParent: string = "";
  var oldFolder: string = "";
  //inizio leggendo le entry
  var entry: string[] = xmlDoc.getElementsByTagName("d:href");
  
  //per ogni entry controllo se si tratta di una cartella o di un documento
  for (var i:number = 0; i < entry.length; i++) {
    var path: string[] = entry[i].childNodes[0].nodeValue.split("");
    
    if (path[path.length-1] == "/") { //cartella
      //creo  il nome della cartella
      var folderName: string[] = entry[i].childNodes[0].nodeValue.split("/");
      //creo l'oggetto cartella
      var Folder = {
        text: folderName[folderName.length-2],
        nodes: []
      }
      //alert("Cartella: " + folderName + " n: " + folderName.length);

      //aggiungo l'oggetto cartella nella giusta posizione
      if (first) {  //aggiungo il primo elemento
        tree.push(Folder);
        first=false;
        //memorizzo il path della cartella e il padre
        oldFolder = entry[i].childNodes[0].nodeValue;
        oldFolderParent = oldFolder.slice(0, oldFolder.lastIndexOf(folderName[folderName.length-2]));
        // alert("Path cartella corrente: " + oldFolder);
        // alert("Indice ricorrenza: " + oldFolder.lastIndexOf(folderName[folderName.length-2]+"/"));
        // alert("Caratteri da eliminare: " + (folderName[folderName.length-2]+"/").length);
        //alert(oldFolderParent);
      } else { //dal secondo elemento in poi controllo se si tratta di una sottocartella
        //memorizzo il path della cartella corrente e il padre
        var newFolder: string = entry[i].childNodes[0].nodeValue;
        var newFolderParent: string = newFolder.slice(0, newFolder.lastIndexOf(folderName[folderName.length-2]));

        if(newFolderParent == oldFolderParent){ //cartella sorella con quella memorizzata
          //alert("La cartella(s) " + folderName[folderName.length-2] + " è filgia di " + oldFolderParent);
          oldFolder = newFolder;
          insertOBJinFS(Folder, tree, folderName, 0);
        } else if(newFolderParent == oldFolder){ //cartella figlia di quella memorizzata
          //alert("La cartella(f) " + folderName[folderName.length-2] + " è filgia di " + oldFolder);
          oldFolder = newFolder;
          oldFolderParent = newFolderParent;
          insertOBJinFS(Folder, tree, folderName, 0);
        } else { //nessuno dei casi precedenti
          //arretro nell'albero fino a trovare lo stesso padre
          while(newFolderParent != oldFolderParent){
            oldFolderParent = oldFolderParent.slice(0, oldFolderParent.length-1); //tolgo "/" finale
            oldFolderParent = oldFolderParent.slice(0, (oldFolderParent.lastIndexOf("/")+1)); //tolgo il nome della cartella precedente
          }
          oldFolder = newFolder;
          //alert("La cartella(r) " + folderName[folderName.length-2] + "è filgia di " + oldFolderParent);
          insertOBJinFS(Folder, tree, folderName, 0);
        }
      }

    } else { //documento
      //alert("Documento: " + entry[i].childNodes[0].nodeValue);
      //creo il nome del file
      var fileName: string[] = entry[i].childNodes[0].nodeValue.split("/");
      //creo il path
      var filePath: string = "https://lcappelli_student.unife.it:61nerdolo@oc-chnet.cr.cnaf.infn.it:8443" + entry[i].childNodes[0].nodeValue;
      //creo l'oggetto documento
      var File = {
        text: fileName[fileName.length-1],
        icon: "glyphicon glyphicon-file",
        selectedIcon: "glyphicon glyphicon-file",
        url: filePath
      }
      //aggiungo l'oggetto file nella giusta posizione (da rivedere)
      //alert("File: " + fileName);
      insertOBJinFS(File, tree, fileName, 1);
    }
  }
  return tree;
}

function insertOBJinFS(objfs, tree, objfsName, type){
  var depth: number = objfsName.length;
  if(type) depth++; //se è un file aumento la profondità
  var treePosition;
  switch(depth){
    case 8: treePosition = tree; break;
    case 9: treePosition = tree[tree.length-1].nodes; break;
    case 10: treePosition = tree[tree.length-1].nodes[tree[tree.length-1].nodes.length-1].nodes; break;
    case 11: 
    treePosition = tree[tree.length-1].nodes[tree[tree.length-1].nodes.length-1].nodes[tree[tree.length-1].nodes[tree[tree.length-1].nodes.length-1].nodes.length-1].nodes;
    break;
    case 12:
    treePosition = tree[tree.length-1].nodes[tree[tree.length-1].nodes.length-1].nodes[tree[tree.length-1].nodes[tree[tree.length-1].nodes.length-1].nodes.length-1].nodes[tree[tree.length-1].nodes[tree[tree.length-1].nodes.length-1].nodes[tree[tree.length-1].nodes[tree[tree.length-1].nodes.length-1].nodes.length-1].nodes.length-1].nodes;
    break;
    default: break;
  }
  treePosition[treePosition.length-1].nodes.push(objfs);
Laura Cappelli's avatar
Laura Cappelli committed
}

$(document).ready( function() {
  //Qua ottengo il contenuto del file XML
  var contentfilesystem: any = document.getElementById('contentfilesystem').innerHTML;
  var parser = new DOMParser();
  var xmlDoc = parser.parseFromString(contentfilesystem, "text/xml");

  //ora genero l'albero
  //$('#FileTreeview').treeview({data: getTree()}); //manuale
  $('#FileTreeview').treeview({data: generateTree(xmlDoc)}); //automatico
  $('#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(){
    //qua si salva il nome del file
    var fileName: string = fileInputButton.files[0];
    //creo l'oggetto filereader 
    var readerObject: any = new FileReader(); 
    //dico come andrà letto il file
    readerObject.readAsBinaryString(fileName);  
    readerObject.onload = function() {
      //riempio filestring con il contenuto del file solo dopo che il file
      //è stato caricato
      var fileString: string = readerObject.result; 
      readData(fileString);
    }
  }

  //compressione sidenav settings
  var setLabel: any = $('.btn-settings');
  var isClosedSettings: boolean = false;
  setLabel.click(function () { setLabel_cross(); });

  function setLabel_cross() {
    if (isClosedSettings == true) {
      isClosedSettings = false;
      document.getElementById("mySidenavSet").style.width = "0";
      document.getElementById("wrapper").style.marginRight= "0";
      document.getElementById("setbtn").style.marginRight="-2px";
    } else {
      isClosedSettings = true;
      document.getElementById("mySidenavSet").style.width = "250px";
      document.getElementById("wrapper").style.marginRight = "250px";
      document.getElementById("setbtn").style.marginRight="248px";
    }
  }

  //compressione sidenav file system
  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');
      document.getElementById("mySidenavfs").style.width = "0";
      document.getElementById("wrapper").style.marginLeft= "0";
      document.getElementById("fsbtn").style.marginLeft="-2px";
    } else {
      isClosedfs = true;
      fsLabel.removeClass('is-closed');
      fsLabel.addClass('is-open');
      document.getElementById("mySidenavfs").style.width = "250px";
      document.getElementById("wrapper").style.marginLeft = "250px";
      document.getElementById("fsbtn").style.marginLeft="248px";
    }
  }
Laura Cappelli's avatar
Laura Cappelli committed
});    
Laura Cappelli's avatar
Laura Cappelli committed
function openFileFromServer(url){
    var txtFile = new  XMLHttpRequest();
    txtFile.open("GET", url, true);
    txtFile.onreadystatechange = function(){
        if(txtFile.readyState === 4){
            if(txtFile.status === 200){
                readData((txtFile.responseText));
            }
        }
    }
    txtFile.send(null);    
}

function callback(files) {
  //log il nome del file nella console
  console.log("Open file " + files[files.length-1].name);
  //creo l'oggetto filereader
  var readerObject: any = new FileReader();
  //dico come andrà letto il file
  readerObject.readAsBinaryString(files[files.length-1]);  
  readerObject.onload = function() {
    //riempio filestring con il contenuto del file solo dopo che il file
    //è stato caricato
    var fileString: string = readerObject.result; 
    readData(fileString);
  }
}

function makeDroppable(ele, callback) {

  //creo un elemento "input type file" non visibile nella pagina
  var input = document.createElement('input');
  input.setAttribute('type', 'file');
  input.setAttribute('multiple', true);
  input.style.display = 'none';

  //aggiungo a questo elemento un event listener al change
  input.addEventListener('change', triggerCallback);
  //aggiungo l'input all'elemento ele
  ele.appendChild(input);

  //questo evento è chiamato quando i file sono trascinati ma non ancora lasciati
  ele.addEventListener('dragover', function(e) {
    e.preventDefault(); //impediamo l'apertura del file
    e.stopPropagation();
    e.dataTransfer.dropEffect = 'copy';
    ele.classList.add('dragover'); //cambia lo stile dell'elemento
  });

  //l'evento è chiamato quando un file lascia la zona predefinita per il drag&drop
  ele.addEventListener('dragleave', function(e) {
    e.preventDefault();
    e.stopPropagation();
    ele.classList.remove('dragover');
  });

  //questo evento si innesca quando il drop è effettivamente avvenuto
  ele.addEventListener('drop', function(e) {
    e.preventDefault();
    e.stopPropagation();
    ele.classList.remove('dragover');
    triggerCallback(e);
  });

  //evento in caso di click
  // ele.addEventListener('click', function() {
  //   input.value = null;
  //   input.click();
  // });
Laura Cappelli's avatar
Laura Cappelli committed
}

//funzione che gestisce il tutto
function triggerCallback(e) {
  var files; //array di file
  //controlliamo se il file è stato scelto o se è stato droppato
  if(e.dataTransfer) { //drop
Laura Cappelli's avatar
Laura Cappelli committed
    files = e.dataTransfer.files;
Laura Cappelli's avatar
Laura Cappelli committed
  callback.call(null, files);
}


/*
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){
    var fileStringArray: any = fileString.split("\n");
    var readMode: string;
    var xMin: number = 0, yMin: number = 0;
    var xMax: number = 0, yMax: number = 0;

    //alert(fileStringArray);
    
    for(var i: number = 0; i < fileStringArray.length; i++){
        //mi soffermo solo sulle righe "intestazione delle x"
        if(parseInt(fileStringArray[i]) > 17000 && fileStringArray[i][0] =='5'){
            //se sono alla prima intestazione salvo la x e la y in xMin e yMin
            if(xMin == 0){
                xMin = parseInt(fileStringArray[i]);
                yMin = parseInt(fileStringArray[i+1]);
                i++;
            //se ho già salvato la prima posizione controllo se sto leggendo per
            //righe o per colonne leggendo la seconda intestazione    
            } else {
                if(parseInt(fileStringArray[i]) == xMin){
                    readMode = 'c';
                    //determino il passo (lato del pixel in micorn)
                    passo = Math.abs(yMin - fileStringArray[i+1]);
                    //se sto leggendo per colonne posso determinare qual'è xMax
                    //leggendo il vettore partendo dalla fine
                    for(var j: number = fileStringArray.length; j > i; j--){
                        //se la riga è "intestazione x" memorizzo xMax, lo
                        //confronto con xMin per vedere se occorre scambiarlo ed
                        //esco
                        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;
                        }
                    }
                } else {
                    readMode = 'r';
                    //determino il passo (lato del pixel in micorn)
                    passo = Math.abs(xMin - fileStringArray[i]);
                    //se sto leggendo per righe posso determinare qual'è yMax
                    //leggendo il vettore partendo dalla fine
                    for(var j: number = fileStringArray.length; j > i; j--){
                        //se la riga è "intestazione y" memorizzo yMax, lo
                        //confronto con yMin per vedere se occorre scambiarlo ed
                        //esco
                        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;
                        }
                    }
                }
                //a questo punto posso uscire dal ciclo
                break;
            }
        }
    }

    //alert(xMin + " " + xMax + " " + yMin + " " + yMax + " " + passo);
    
    /*
    A questo punto del codice ho determinato se sto leggendo per righe o per
    colonne e, nel primo caso, xMin e xMax, nel secondo caso yMin e yMax.
    Ora scorro nuovamente l'array distinguendo i casi in cui leggo per righe o
    per colonne, in questo modo determino o yMin e yMax, o xMin e xMax
    */
    for(var i: number = 2; i < fileStringArray.length; i++){
        //se leggo per colonne devo deterinare yMin e yMax
        if(readMode == 'c'){
            
            //mi soffermo sulle righe "intestazione y"
            if (parseInt(fileStringArray[i]) > 17000
                && fileStringArray[i][0] == '6') {
                
                //cerco yMin e yMax
                if (yMin > parseInt(fileStringArray[i])){
                    yMin = parseInt(fileStringArray[i]);
                }
                if(yMax < parseInt(fileStringArray[i])){
                    yMax = parseInt(fileStringArray[i]);
                }
            }

            //quando arrivo a leggere la terza colonna sono sicura di aver già
            //trovato yMin e yMax quindi posso uscire dal ciclo
            if (parseInt(fileStringArray[i]) == xMin + (passo * 2)) {
                break;
            }

        //se leggo per righe devo deterinare xMin e xMax 
        } else if (readMode == 'r') {
            //mi soffermo sulle righe "intestazione x"
            if (parseInt(fileStringArray[i]) > 17000
                && fileStringArray[i][0] == '5') {
                
                //cerco xMin e xMax
                if (xMin > parseInt(fileStringArray[i])){
                    xMin = parseInt(fileStringArray[i]);
                }
                if(xMax < parseInt(fileStringArray[i])){
                    xMax = parseInt(fileStringArray[i]);
                }
            }

            //quando arrivo a leggere la terza riga sono sicura di aver già
            //trovato xMin e xMax quindi posso uscire dal ciclo
            if (parseInt(fileStringArray[i]) == yMin + 2000) {
                break;
            }
        }
    }

    //alert(xMin + " " + xMax + " " + yMin + " " + yMax + " " + passo);

    /*
    a questo punto ho xMin, xMax, yMin e yMax; percorro l'array sistemando gli
    shift
    */
    for(var i: number = 0; i < fileStringArray.length; i++){
        //se leggo per colonne allora aggiungo 1passo 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();
        }
        //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();
            
        }
    }

    /*Ora che ho le posizioni corrette di ogni pixel posso riempire la matrice 
    che conterrà tutti i dati e sulla quale si opererà in tutto il programma.
    Definisco le dimensioni di tale matrice
    */
    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);

    /*
    definisco la matrice DataMatrix: yDim righe da xDim elementi, ogni
    elemento della matrice è un vettore di 16384 elementi
    */
    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;
            }
        }
    }
    
    /*
    ora devo scorrere l'array con il contenuto del file per riempire la matrice
    */
    for(var i: number = 0; i < fileStringArray.length; i++){
        var x: number;
        var y: number;
        var write: boolean;
        //se leggo una riga "intestazione x":
        if(parseInt(fileStringArray[i]) > 17000 && 
            fileStringArray[i][0] == '5'){
            //memorizzo le x e le y del punto e avanzo direttamente al primo
            //conteggio perchè ho già letto la i successiva alla corrente
            x = (parseInt(fileStringArray[i]) - xMin);
            if(x != 0){
                x /= passo;
            }
            y = (parseInt(fileStringArray[i+1]) - yMin);
            if(y != 0){
                y /= passo;
            }
            i++;

            //se non è un pixel del bordo e sto leggendo per colonne allora
            //segnalo che i successivi valori sono da considerare e sistemo
            //la y del pixel così da normalizzarla dopo il taglio dei bordi
            if(readMode == 'c' && y != 0 && y != 1 && y != (yMax - yMin)/passo
                && y != (yMax - yMin)/passo + 1){
                write = true;
                y -= 2;
            }
            //se non è un pixel del bordo e sto leggendo per righe allora
            //segnalo che i successivi valori sono da considerare e sistemo
            //la x del pixel così da normalizzarla dopo il taglio dei bordi
            else if(readMode == 'r' && x != 0 && x != 1 &&
                x != (xMax - xMin)/passo && x != (xMax - xMin)/passo + 1){
                write = true;
                x -= 2;
            }
            //se sto leggendo un pixel del bordo segnalo che i valori successivi
            //sono da ignorare
            else{
                write = false;
            }
            //if(write == true && (y < 0 || y > 92)) alert(x + " " + y);
        }

        //sto leggendo una riga di conteggio e il pixel in questione non è un
        //pixel del bordo
        else if(parseInt(fileStringArray[i]) < 17000 && write == true){
            //Aggiorno i dati nella matrice DataMatrix invertendo la posizione
            //delle x e delle y
            DataMatrix[xDim-x-1][yDim-y-1][parseInt(fileStringArray[i])] += 1;
        }
    }

    //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);
        }
    }
    
    //definisco l'origine da utilizzare per il click del mouse
    newOrigin = {xp: 0, yp: 0};

    //calcolo il conteggio massimo della matrice
    maxAbsolute = findMax(nOfCounts, {xp: 0, yp: 0}, {xp: xDim-1, yp: yDim-1});

    //caricati i dati posso impostare i dati per il grafico nella sua
    //interezza e disegnare l'immagine
    setDataForCompleteChart();
    alert("Dati caricati con successo");
    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);
}


/*
la funzione drawImg disegna il canvas con l'immagine selezionata: può essere
l'immagine completa, l'immagine zoommata o l'immagine che mostra solo alcuni
elementi. La funzione è anche responsabile di gestire le richieste degli utenti
riguardo alla mappa.
*/
function drawImg(pixel1: coordinates, pixel2:coordinates, xMinRange: number, xMaxRange: number){
    
    //determino le dimensioni del canvas e le dimensioni dei pixel per
    //questo disegno    
    var nPixelX: number = pixel2.xp - pixel1.xp + 1;
    var nPixelY: number = pixel2.yp - pixel1.yp + 1;
    var dimPixelx: number = Math.floor(maxMappaWidth/nPixelX);
    var dimPixely: number = Math.floor(maxMappaHeight/nPixelY);
    pixelDim = (dimPixelx < dimPixely) ? dimPixelx : dimPixely;    
    var canvas = <HTMLCanvasElement> document.getElementById("myCanvas");
    canvas.height = nPixelY * pixelDim;
    canvas.width = nPixelX * pixelDim;
    var ctx = canvas.getContext("2d");
Laura Cappelli's avatar
Laura Cappelli committed
    //se il range è completo, quindi non è stato selzionato nessun picco, 
    //procedo utilizzando nOfCounts come valori da rappresentare
    if(xMaxRange - xMinRange >= 55){
        //controllo se devo colorare con il massimo assoluto o con quello
        //relativo
        var max: number;
        if (rePrint) max = findMax(nOfCounts, pixel1, pixel2);
        else max = maxAbsolute;

        //controllo se è richiesta saturazione del massimo
        max = (max * document.getElementById("SaturationSlider").value)/100 ;
        
        //disegno la canvas passando la matrice con i dati e il massimo
        drawCanvas(nOfCounts, max);

    } else {
        //determino i canali da xMinRange e xMaxRange
        var xMinRangeCh: number = Math.floor((((xMinRange*1000)+b)/a)-1); //16
        var xMaxRangeCh: number = Math.floor((((xMaxRange*1000)+b)/a)-1); //16371

        //devo calcolare il numero di conteggi solo delle x selezionate
        var nOfCountsRelative: number[][];
        nOfCountsRelative = new Array(xDim);
        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);
            }
        }
        //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 ;

        //disegno la canvas con i giusti valori
        drawCanvas(nOfCountsRelative, max);
    }

    /*
    La funzione drawCanvas riceve in input la matrice con i dati e il valore
    da utilizzare come massimo. La funzione disegna la mappa nel canvas.
    */
    function drawCanvas(noc, max){
        //alert(pixel1.xp + " " + pixel1.yp + " " + pixel2.xp + " " + pixel2.yp);
        //scorro tutti i pixel da disegnare: ne determino il colore e li disegno
        //nella giusta posizione.

        //prima verifico se devo aggiungere una trasparenza ai pixel
        var setTrsp: number = 1 -
            document.getElementById("TrasparencySlider").value / 100;
        
        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);
            }
        }
        //annullo reprint
        rePrint = false;

        //Determino le dimensioni reali dei pixel
        var canvasDim: any = document.querySelector ('#myCanvas').getBoundingClientRect();
        realPixelDim = round3(((canvasDim.right - canvasDim.left)/nPixelX + (canvasDim.bottom - canvasDim.top)/nPixelY)/2);
        //alert(realPixelDim);
    }
    /*
    mi metto in ascolto della fine dello spostamento dello slider della
    saturazione: ridisegno il canvas con gli stessi input (verrà modificato il
    massimo in fase di disegno)
    */
    var satSlider = <HTMLButtonElement>document.getElementById("SaturationSlider");
    satSlider.onmouseup = function(){
        drawImg(pixel1, pixel2, xMinRange, xMaxRange);
    }  

    /*
    mi metto in ascolto del click sul bottone rePlot. Nel caso venga cliccato
    cambio stato alla variabile reprint, resetto la saturazione e ridisegno il
    canvas con gli stessi input
    */
    var rePlotButton = <HTMLButtonElement>document.getElementById("rePlot");
    rePlotButton.onclick = function(){
        rePrint = true;
        satSlider.value = "100";
        drawImg(pixel1, pixel2, xMinRange, xMaxRange);
    }

    /*
    mi metto in ascolto della fine dello spostamento dello slider della
    trasparenza: ridisegno il canvas con gli stessi input (verrà modificata la
    trasparenza in fase di disegno)
    */
    var trspSlider = <HTMLButtonElement>document.getElementById("TrasparencySlider");
    trspSlider.onmouseup = function(){
        drawImg(pixel1, pixel2, xMinRange, xMaxRange);
    }

    /*
    mi metto in ascolto del click sul bottone reset. Nel caso venga cliccato
    resetto tutte le variabili e disegno immagine e canvas
    */
    var resetButton = <HTMLButtonElement>document.getElementById("reset");
    resetButton.onclick = function(){
        newOrigin = {xp: 0, yp: 0};
        rePrint = false;
        calibrated = false;
        globalxMinRange = 0;
        globalxMaxRange = 55;
        satSlider.value = "100";
        trspSlider.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);
    }

    //mi metto in ascolto del click sul bottone per il download dell'immagine
    var ExportImgButton = <HTMLButtonElement>document.getElementById("ExportImage");
    ExportImgButton.onclick = function(){
        var img = canvas.toDataURL("image/png");
        ExportImgButton.href = img;
        //document.write('<img src="'+img+'"/>');
    }


}


/*la funzione drawChart riceve in input i due estremi dell'immagine (può essere
l'immagine completa o solo una parte) e i due estremi dell'intervallo da 
rappresentare sull'asse x (anche in questo caso può essere l'asse x completa
o un sotto-intervallo). La funzione disegna il grafico richiesto
*/
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 setlinearButton =
        <HTMLButtonElement>document.getElementById("setlinearButton");
    var setlogButton =
        <HTMLButtonElement>document.getElementById("setlogButton");
    var setEnergyButton =
        <HTMLButtonElement>document.getElementById("setEnergyButton");
    var setChannelsButton =
        <HTMLButtonElement>document.getElementById("setChannelsButton");
    var box1 = <HTMLElement>document.getElementById("spinBoxMin");
    var box2 = <HTMLElement>document.getElementById("spinBoxMax");
    var SubmitRangeButton = 
        <HTMLButtonElement>document.getElementById("readSpinbox");
    var elementSelect = 
        <HTMLButtonElement>document.getElementById("elementSelect");
    var ExportGraphButton =
        <HTMLButtonElement>document.getElementById("ExportGraph");
    

    //controllo se il grafico è da disegnare calibrato poi regolo i bottoni
    if(calibrated){
        setEnergyButton.disabled = true;
        setChannelsButton.disabled = false;
        SubmitRangeButton.disabled = false;
    } else {
        setEnergyButton.disabled = false;
        setChannelsButton.disabled = true;
        SubmitRangeButton.disabled = true;
    }
    setlinearButton.disabled = true;
    setlogButton.disabled = false;

    //verifico se devo disegnare il grafico nella sua completezza: in quel caso
    //ho già la stringa con i dati e posso direttamente procedere con il disegno
    if(pixel1.xp == 0 && pixel1.yp == 0 && pixel2.xp == xDim-1 &&
        pixel2.yp == yDim-1){
        //controllo se devo disegare il grafico calibrato o non calibrato
        if(!calibrated){
            var chartTitle: string = "Chart from (0, 0) to (" + (xDim-1) + ", " 
            + (yDim-1) + ")";
            g = setChart(dataCompleteChart, chartTitle);
        } else {
            var chartTitle: string = "Calibrated chart from (0, 0) to (" +
                (xDim-1) + ", " + (yDim-1) + ")";
            g = setChart(dataCompleteChartCalibrated, chartTitle);
        }
    //se devo disegnare il grafico solo parzialmente per alcuni pixel devo
    //calcolare i dati    
    } else {
        //creo un array di 16384 elementi con la somma dei conteggi solo dei
        //pixel da considerare
        var dataForChart: number[] = new Array(16384);
        for(var i: number = 0; i < 16384; i++){
            dataForChart[i] = 0;
        }
        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];
                }
            }
        }
        //controllo se devo disegare il grafico calibrato o non calibrato
        if(!calibrated){
            //definisco i dati da passare al grafico
            var dataChart: string = "Channel,Counts\n";
            for(var i: number = 0; i < 16348; i++){
                dataChart += i + "," + dataForChart[i] + "\n";
            }
            //determino il titolo del grafico
            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) + ")";
            }
            //disegno il grafico
            g = setChart(dataChart, chartTitle);
        } else {
           //definisco i dati da passare al grafico
            var dataChartCalibrated: string = "Energy,Counts\n";
            for(var i: number = 0; i < 16348; i++){
                dataChartCalibrated += round3(((i+1)*a-b)/1000)  +
                "," + dataForChart[i] + "\n";
            }
            //determino il titolo del grafico
            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) + ")";
            }
            //disegno il grafico
            g = setChart(dataChartCalibrated, chartTitle);
        }     
    }

    /*
    la funzione setChart riceve in input la stringa con i dati del grafico e il
    titolo del grafico. Dopo aver disegnato il grafico restituise in output la
    variabile con il grafico stesso 
    */
    function setChart(dataString: string, charTitle: string){
        //definisco la variabile che contiene gli estremi dell'asse x da
        //visualizzare e la riempio a seconda se sto disegnando il grafico
        //calibrato o non calibrato. Definisco anche l'etichetta delll'asse x
        var xArrayRange: number[];
        var xLab: string;
        if(!calibrated){
            xArrayRange = [0, 16383];
            xLab = "ADC Channel";
        }else{
            xArrayRange = [xMinRange, xMaxRange];
            xLab = "Energy (keV)";
        }

        //imposto le dimensioni del grafico
        var bb: any = document.querySelector ('#chart-pannel').getBoundingClientRect();
        var chartWidth = bb.right - bb.left - 50;
        $('#chart').css('width', chartWidth);

        var bb2: any = document.querySelector ('#myCanvas').getBoundingClientRect();
        var chartHeight: number = bb2.bottom - bb2.top;
        $('#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
            }
        );

        //dimenioni responsive del grafico
        document.getElementById("fsbtn").onclick = function (){
            setTimeout(function(){
                g = setChart(dataString, charTitle);
            }, 400);
            
        }
        document.getElementById("setbtn").onclick = function (){
            setTimeout(function(){
                g = setChart(dataString, charTitle);
            }, 400);
        }

Laura Cappelli's avatar
Laura Cappelli committed
        return graphs;
    }

    //mi metto in ascolto dei click sui bottoni relativi al grafico