Skip to content
Snippets Groups Projects
start.ts 25.5 KiB
Newer Older
  • Learn to ignore specific revisions
  • Francesco Giacomini's avatar
    Francesco Giacomini committed
    // Copyright 2017 Istituto Nazionale di Fisica Nucleare
    //
    // Licensed under the EUPL
    
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
    import $ from "jquery";
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    //dichiarazione interfacce e variabili globali
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
    interface coordinates
    {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
      xp: number;
      yp: number;
    }
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
    let a: number = 3.36275; //costante moltiplicativa per la calibrazione
    let b: number = 58.2353; //costante additiva per la calibrazione
    let pixelDim: number; //dimensione dei pixel responsive
    let maxAbsolute: number; //massimo conteggio della matrice nOfCounts
    let xDim: number = 0, yDim: number = 0; //numero di pixel nelle due dimensioni
    let DataMatrix: number[][][], nOfCounts: number[][]; //matrici con i dati
    let rePrint: boolean = false; //variabile per ricolorare con il max relativo
    let newOrigin: coordinates; //nuovo origine nel caso di zoom
    let zPixel1: coordinates; //pixel1 dello zoom
    let zPixel2: coordinates; //pixel2 dello zoom
    let dataCompleteChart: string = "Channel,Counts\n";
    let dataCompleteChartCalibrated: string = "Energy,Counts\n";
    let calibrated: boolean = false; //variabile per il controllo sulla calibrazione
    let depth: number = 8000; //profondità massima della matrice
    let channelDepth: number = round3(((depth + 1) * a - b) / 1000); //profondità massima in canali
    let globalxMinRange: number = 0, globalxMaxRange: number = channelDepth;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    //INIZIO DELLO SCRIPT
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
    $(document).ready(function ()
    {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      //abilito tooltip
    
      $('[data-toggle="tooltip"]').tooltip();
    
    Laura Cappelli's avatar
    Laura Cappelli committed
      //creazione dell'albero e gestione barre laterali
      setImportFile();
    
      compressingSidenav();
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
      //abilitazione drag&drop
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      let droppableArea: any = document.querySelector('.droppable');
    
    Laura Cappelli's avatar
    Laura Cappelli committed
      makeDroppable(droppableArea, callback);
    
    
      //inizializzazione variabili
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      zPixel1 = { xp: 0, yp: 0 };
      zPixel2 = { xp: 0, yp: 0 };
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    });
    
    //funzione per la compressione della sidenav sx
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
    function compressingSidenav()
    {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      let fsLabel: any = $('.sidebar-label');
      let isClosedfs: boolean = false;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
      fsLabel.click(function () { fsLabel_cross(); });
    
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      function fsLabel_cross()
      {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        if (isClosedfs == true) {
          isClosedfs = false;
    
          $('.w3-bar-block').css('width', "65px");
          $('.text-sidenav').css('display', 'none');
          $('#collapse-symbol').attr('title', 'Open Sidebar');
          $("#collapse-symbol").removeClass("fa-angle-double-left");
          $("#collapse-symbol").addClass("fa-angle-double-right");
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        } else {
          isClosedfs = true;
    
          $('.w3-bar-block').css('width', "200px");
          $('.text-sidenav').css('display', 'inline');
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
          $('#collapse-symbol').attr('title', 'Close Sidebar');
    
          $("#collapse-symbol").removeClass("fa-angle-double-right");
          $("#collapse-symbol").addClass("fa-angle-double-left");
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        }
      }
    
    }
    
    //funzione che definisce l'area su cui si può eseguire il drag&drop
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
    function makeDroppable(droppableArea, callback)
    {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
      //creo l'elemento "input type file" non visibile e lo aggiungo a "droppableArea"
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      let 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);
    
      //questo evento è chiamato quando i file sono trascinati ma non ancora lasciati
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      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');
      });
    
      //l'evento è chiamato quando un file lascia la zona predefinita per il drag&drop
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      droppableArea.addEventListener('dragleave', function (e)
      {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        e.preventDefault();
        e.stopPropagation();
        droppableArea.classList.remove('dragover');
      });
    
      //questo evento si innesca quando il drop è effettivamente avvenuto
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      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()
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
    function callback(files)
    {
    
      $("#load-spinner").css("display", "inline");
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      console.log("Try to open " + files[files.length - 1].name + " ...");
      let readerObject: any = new FileReader();
      readerObject.readAsBinaryString(files[files.length - 1]);
      readerObject.onload = function ()
      {
        let fileString: string = readerObject.result;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        readData(fileString);
      }
    }
    
    //la funzione prepara i dati per il grafico completo
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
    function setDataForCompleteChart()
    {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
      //per ogni pixel sommo i conteggi di tutti i canali rilevati
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      let dataForChart: number[] = new Array(depth);
      for (let i: number = 0; i < depth; i++) {
        dataForChart[i] = 0;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
      }
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      for (let i: number = 0; i < xDim; i++) {
        for (let j: number = 0; j < yDim; j++) {
          for (let k: number = 0; k < depth; k++) {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
            dataForChart[k] += DataMatrix[i][j][k];
          }
        }
      }
      //riempio le stringhe con i dati per il grafico
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      for (let i: number = 0; i < depth; i++) {
        dataCompleteChart += (i + 1) + "," + dataForChart[i] + "\n";
        dataCompleteChartCalibrated += round3(((i + 1) * a - b) / 1000) + "," + dataForChart[i] + "\n";
    
    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 
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
    function sumVect(vect: number[], from: number, to: number)
    {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      let sum: number = 0;
      for (let i: number = from; i < to; i++) { sum += vect[i]; }
    
    Laura Cappelli's avatar
    Laura Cappelli committed
      return sum;
    
    }
    
    //La funzione riceve in input la matrice e gli estremi della sottomatrice di cui
    //calcola il massimo
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
    function findMax(matrix: number[][], pixel1: coordinates, pixel2: coordinates)
    {
    
      let max: number = 0;
      for (let i: number = pixel1.xp; i <= pixel2.xp; i++) {
        for (let j: number = pixel1.yp; j <= pixel2.yp; j++) {
          if (matrix[i][j] > max) {
            max = matrix[i][j];
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      }
      return max;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    }
    
    //Funzione per arrotondare il numero in input alla terza cifra decimale
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
    function round3(val: number)
    {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      return (Math.round(val * Math.pow(10, 3)) / Math.pow(10, 3));
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    }
    
    //la funzione findPosition definisce la posizione del cursore del mouse
    //relativa al canvas nel momento in cui avviene l'evento passato in input 
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
    function findPosition(event: any, pixel: coordinates)
    {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      let scrollTOP: number = (document.documentElement.scrollTop) ?
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        document.documentElement.scrollTop : document.body.scrollTop;
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      let scrollLEFT: number = (document.documentElement.scrollLeft) ?
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        document.documentElement.scrollLeft : document.body.scrollLeft;
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      let allX: number = event.clientX + scrollLEFT;
      let allY: number = event.clientY + scrollTOP;
      let elParent: any = document.getElementById('myCanvas');
      let objX: number = 0, objY: number = 0;
      while (elParent) {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        objX += elParent.offsetLeft;
        objY += elParent.offsetTop;
        elParent = elParent.offsetParent;
      }
    
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      pixel.xp = Math.floor((allX - objX - 1) / pixelDim) + newOrigin.xp;
      pixel.yp = Math.floor((allY - objY - 1) / pixelDim) + newOrigin.yp;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    }
    
    
    //la funzione findPosDown memorizza la posizione del pixel cliccato
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
    function findPosDown(event: any)
    {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
      findPosition(event, zPixel1);
    
    }
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
    
    
    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.
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
    function findPosUp(event: any)
    {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
      findPosition(event, zPixel2);
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      let tmp: number;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
      if (zPixel1.xp > zPixel2.xp) {
        tmp = zPixel1.xp;
        zPixel1.xp = zPixel2.xp;
        zPixel2.xp = tmp;
      }
      if (zPixel1.yp > zPixel2.yp) {
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        tmp = zPixel1.yp;
        zPixel1.yp = zPixel2.yp;
        zPixel2.yp = tmp;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
      }
      //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);
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      if (zPixel1.xp != zPixel2.xp || zPixel1.yp != zPixel2.yp) {
        newOrigin = { xp: zPixel1.xp, yp: zPixel1.yp };
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        drawImg(zPixel1, zPixel2, globalxMinRange, globalxMaxRange);
      }
      drawChart(zPixel1, zPixel2, globalxMinRange, globalxMaxRange);
    
    }
    
    //la funzione disegna il rettangolo durante la selezione di un'area della mappa
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
    function zoomRect()
    {
      let selectCanvas = <HTMLCanvasElement>document.getElementById("selectionCanvas");
      let ctx = selectCanvas.getContext("2d");
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
      // style the context
      ctx.fillStyle = "rgba(0, 110, 255, 0.25)";
    
      // this flage is true when the user is dragging the mouse
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      let isDown = false;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
      // these vars will hold the starting mouse position
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      let startX: number;
      let startY: number;
      let mouseX: number;
      let mouseY: number;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
      // these vars will hold the starting mouse position
    
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      function handleMouseDown(e)
      {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        e.preventDefault();
        e.stopPropagation();
    
    
        //calculate mouse position
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        let scrollTOP: number = (document.documentElement.scrollTop) ?
    
          document.documentElement.scrollTop : document.body.scrollTop;
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        let scrollLEFT: number = (document.documentElement.scrollLeft) ?
    
          document.documentElement.scrollLeft : document.body.scrollLeft;
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        let allX: number = e.clientX + scrollLEFT;
        let allY: number = e.clientY + scrollTOP;
        let elParent: any = document.getElementById('myCanvas');
        let objX: number = 0, objY: number = 0;
        while (elParent) {
    
          objX += elParent.offsetLeft;
          objY += elParent.offsetTop;
          elParent = elParent.offsetParent;
        }
        startX = allX - objX;
        startY = allY - objY;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
        // set a flag indicating the drag has begun
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        isDown = true;
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      function handleMouseUp(e)
      {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        e.preventDefault();
        e.stopPropagation();
    
        // the drag is over, clear the dragging flag
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        isDown = false;
        ctx.clearRect(0, 0, selectCanvas.width, selectCanvas.height);
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      function handleMouseOut(e)
      {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        e.preventDefault();
        e.stopPropagation();
    
        // the drag is over, clear the dragging flag
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        isDown = false;
        ctx.clearRect(0, 0, selectCanvas.width, selectCanvas.height);
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      function handleMouseMove(e)
      {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        e.preventDefault();
        e.stopPropagation();
    
        // if we're not dragging, just return
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        if (!isDown) { return; }
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
        //calculate mouse position
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        let scrollTOP: number = (document.documentElement.scrollTop) ?
    
          document.documentElement.scrollTop : document.body.scrollTop;
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        let scrollLEFT: number = (document.documentElement.scrollLeft) ?
    
          document.documentElement.scrollLeft : document.body.scrollLeft;
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        let allX: number = e.clientX + scrollLEFT;
        let allY: number = e.clientY + scrollTOP;
        let elParent: any = document.getElementById('myCanvas');
        let objX: number = 0, objY: number = 0;
        while (elParent) {
    
          objX += elParent.offsetLeft;
          objY += elParent.offsetTop;
          elParent = elParent.offsetParent;
        }
        mouseX = allX - objX;
        mouseY = allY - objY;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
        // Put your mousemove stuff here
    
        // clear the canvas
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        ctx.clearRect(0, 0, selectCanvas.width, selectCanvas.height);
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
        // calculate the rectangle width/height based
        // on starting vs current mouse position
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        let width = mouseX - startX;
        let height = mouseY - startY;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
        // draw a new rect from the start position 
        // to the current mouse position
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        ctx.fillRect(startX, startY, width, height);
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
      }
    
      // listen for mouse events
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      $("#selectionCanvas").mousedown(function (e) { handleMouseDown(e); });
      $("#selectionCanvas").mousemove(function (e) { handleMouseMove(e); });
      $("#selectionCanvas").mouseup(function (e) { handleMouseUp(e); });
      $("#selectionCanvas").mouseout(function (e) { handleMouseOut(e); });
    
    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
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
    function drawImg(pixel1: coordinates, pixel2: coordinates, xMinRange: number, xMaxRange: number)
    {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
      //alert("disegno in corso");
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      let nPixelX: number = pixel2.xp - pixel1.xp + 1;
      let nPixelY: number = pixel2.yp - pixel1.yp + 1;
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      let mappaPannelDim: any = document.querySelector('#mappa-pannel').getBoundingClientRect();
      let mappaWidth: number = mappaPannelDim.right - mappaPannelDim.left - 40;
      let mappaHeigth: number = 400;
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      let dimPixelx: number = Math.floor(mappaWidth / nPixelX);
      let dimPixely: number = Math.floor(mappaHeigth / nPixelY);
    
    Laura Cappelli's avatar
    Laura Cappelli committed
      pixelDim = (dimPixelx < dimPixely) ? dimPixelx : dimPixely;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
      (<HTMLCanvasElement>document.getElementById("myCanvas")).height = nPixelY * pixelDim;
      (<HTMLCanvasElement>document.getElementById("myCanvas")).width = nPixelX * pixelDim;
      (<HTMLCanvasElement>document.getElementById("selectionCanvas")).height = nPixelY * pixelDim;
      (<HTMLCanvasElement>document.getElementById("selectionCanvas")).width = nPixelX * pixelDim;
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      let ctx = (<HTMLCanvasElement>document.getElementById('myCanvas')).getContext('2d'); //contesto del canvas
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      if (xMaxRange - xMinRange >= channelDepth) { //range completo
        let max: number; //massimo relativo o assoluto
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        if (rePrint) max = findMax(nOfCounts, pixel1, pixel2);
        else max = maxAbsolute;
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        max = (max * document.getElementById("SaturationSlider").value) / 100;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        //max = (max * parseInt($("#SaturationSlider").attr("value")))/100 ; //saturazione
        drawCanvas(nOfCounts, max); //disegno
    
      } else { //range parziale (solo alcuni canali)
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        let xMinRangeCh: number = Math.floor((((xMinRange * 1000) + b) / a) - 1); //16
        let xMaxRangeCh: number = Math.floor((((xMaxRange * 1000) + b) / a) - 1); //16371
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        //calcolo il numero di conteggi solo dei canali selezionati
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        let nOfCountsRelative: number[][];
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        nOfCountsRelative = new Array(xDim);
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        for (let i: number = 0; i < xDim; i++) {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
          nOfCountsRelative[i] = new Array(yDim);
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
          for (let j: number = 0; j < yDim; j++) {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
            nOfCountsRelative[i][j] = sumVect(DataMatrix[i][j], xMinRangeCh, xMaxRangeCh);
          }
        }
        //calcolo il massimo
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        let max: number;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        if (rePrint) { max = findMax(nOfCountsRelative, pixel1, pixel2); }
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        else { max = findMax(nOfCountsRelative, { xp: 0, yp: 0 }, { xp: xDim - 1, yp: yDim - 1 }); }
        max = (max * document.getElementById("SaturationSlider").value) / 100;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        //max = (max * parseInt($("#SaturationSlider").attr("value")))/100 ; //saturazione
        drawCanvas(nOfCountsRelative, max); //disegno
      }
    
      //La funzione, ricevuti dati e massimo, disegna la mappa nel canvas
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      function drawCanvas(noc, max)
      {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
        //controllo il valore della trasparenza 
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        let setTrsp: number = 1 - (document.getElementById("TrasparencySlider").value / 100);
        //let setTrsp: number = 1-(parseInt($("#TrasparencySlider").attr("value"))/100);
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
        //scorro tutti i pixel: ne determino il colore e li disegno      
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        let color: string = "";
        for (let i: number = pixel1.xp; i <= pixel2.xp; i++) {
          for (let j: number = pixel1.yp; j <= pixel2.yp; j++) {
            let 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 + ")";
    
    Laura Cappelli's avatar
    Laura Cappelli committed
            else //rosso -verde
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
              color = "rgba(255," + (255 - Math.floor((intensity - 4 / 5) * 5 * 255)) + ", 0, " + setTrsp + ")";
    
    Laura Cappelli's avatar
    Laura Cappelli committed
            ctx.fillStyle = color;
            ctx.fillRect((i - pixel1.xp) * pixelDim, (j - pixel1.yp) * pixelDim, pixelDim, pixelDim);
          }
        }
        rePrint = false; //annullo rePrint
        zoomRect();
      }
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
    
      $("#SaturationSlider").mouseup(function ()
      { //Slider della saturazione
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        drawImg(pixel1, pixel2, xMinRange, xMaxRange);
      });
    
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      $("#rePlot").click(function ()
      { //bottone per colorare con il max relativo
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        rePrint = true;
        (<HTMLInputElement>document.getElementById("SaturationSlider")).value = "100";
        drawImg(pixel1, pixel2, xMinRange, xMaxRange);
      });
    
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      $("#TrasparencySlider").mouseup(function ()
      { //Slider della trasparenza
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        drawImg(pixel1, pixel2, xMinRange, xMaxRange);
      });
    
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      $("#reset").click(function ()
      { //bottone per il reset dell'applicazione
        newOrigin = { xp: 0, yp: 0 };
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        rePrint = false;
        calibrated = false;
        globalxMinRange = 0;
    
        globalxMaxRange = channelDepth;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        (<HTMLInputElement>document.getElementById("SaturationSlider")).value = "100";
        (<HTMLInputElement>document.getElementById("TrasparencySlider")).value = "0";
        document.getElementById("spinBoxMin").setAttribute("value", "-");
        document.getElementById("spinBoxMax").setAttribute("value", "-");
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        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);
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      $("#ExportImage").click(function ()
      { //esportazione immagine
        let img = (<HTMLCanvasElement>document.getElementById("myCanvas")).toDataURL("image/png");
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        //document.write('<img src="'+img+'"/>');
      });
    
    }
    
    //la funzione drawChart (input: estremi dell'immagine, estremi dell'intervallo)
    //disegna il grafico richiesto relativo alla mappa visualizzata
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
    function drawChart(pixel1: coordinates, pixel2: coordinates, xMinRange: number, xMaxRange: number)
    {
    
    
    Laura Cappelli's avatar
    Laura Cappelli committed
      //definisco la variabile "grafico", i bottoni relativi al grafico, il tag
      //select e le due spinbox con il relativo botton
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      let g: any;
      let box1 = <HTMLElement>document.getElementById("spinBoxMin");
      let box2 = <HTMLElement>document.getElementById("spinBoxMax");
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
      //disegno il grafico completo
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      if (pixel1.xp == 0 && pixel1.yp == 0 && pixel2.xp == xDim - 1 && pixel2.yp == yDim - 1) {
        if (!calibrated) { //canali
          let chartTitle: string = "Chart from (0, 0) to (" + (xDim - 1) + ", " + (yDim - 1) + ")";
    
    Laura Cappelli's avatar
    Laura Cappelli committed
          g = setChart(dataCompleteChart, chartTitle);
        } else { //energie
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
          let chartTitle: string = "Calibrated chart from (0, 0) to (" + (xDim - 1) + ", " + (yDim - 1) + ")";
    
    Laura Cappelli's avatar
    Laura Cappelli committed
          g = setChart(dataCompleteChartCalibrated, chartTitle);
        }
    
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        //disegno il grafico parzialmente 
    
    Laura Cappelli's avatar
    Laura Cappelli committed
      } else {
        //determino i conteggi dei pixel da disegnare
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        let dataForChart: number[] = new Array(depth);
        for (let i: number = 0; i < depth; i++) {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
          dataForChart[i] = 0;
        }
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        for (let i: number = pixel1.xp; i <= pixel2.xp; i++) {
          for (let j: number = pixel1.yp; j <= pixel2.yp; j++) {
            for (let k: number = 0; k < depth; k++) {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
              dataForChart[k] += DataMatrix[i][j][k];
            }
          }
        }
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
    
        if (!calibrated) { //disegno in canali
          let dataChart: string = "Channel,Counts\n";
          for (let i: number = 0; i < depth; i++) {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
            dataChart += i + "," + dataForChart[i] + "\n";
          }
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
          if (pixel1.xp == pixel2.xp && pixel1.yp == pixel2.yp) {
            let chartTitle: string = "Chart pixel (" + pixel1.xp + ", " + (yDim - pixel1.yp - 1) + ")";
    
    Laura Cappelli's avatar
    Laura Cappelli committed
          } else {
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
            let chartTitle: string = "Chart from (" + pixel1.xp + "," + pixel2.xp + ") to (" +
    
    Laura Cappelli's avatar
    Laura Cappelli committed
              (yDim - pixel1.yp - 1) + ", " + (yDim - pixel2.yp - 1) + ")";
          }
          g = setChart(dataChart, chartTitle);
    
        } else { //disegno in energie
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
          let dataChartCalibrated: string = "Energy,Counts\n";
          for (let i: number = 0; i < depth; i++) {
            dataChartCalibrated += round3(((i + 1) * a - b) / 1000) + "," + dataForChart[i] + "\n";
    
    Laura Cappelli's avatar
    Laura Cappelli committed
          }
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
          if (pixel1.xp == pixel2.xp && pixel1.yp == pixel2.yp) {
            let chartTitle: string = "Calibrated chart pixel (" + pixel1.xp + ", " + (yDim - pixel1.yp - 1) + ")";
    
    Laura Cappelli's avatar
    Laura Cappelli committed
          } else {
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
            let chartTitle: string = "Calibrated chart from (" + pixel1.xp + ", " + pixel2.xp +
              ") to (" + (yDim - pixel1.yp - 1) + ", " + (yDim - pixel2.yp - 1) + ")";
    
    Laura Cappelli's avatar
    Laura Cappelli committed
          }
          g = setChart(dataChartCalibrated, chartTitle);
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        }
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      $('#setlinearButton').on('click', function ()
      { //selezione scala lineare
        g.updateOptions({ logscale: false });
    
    Laura Cappelli's avatar
    Laura Cappelli committed
      });
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      $('#setlogButton').on('click', function ()
      { //selezione scala logaritmica
        g.updateOptions({ logscale: true });
    
    Laura Cappelli's avatar
    Laura Cappelli committed
      });
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      $('#setEnergyButton').on('click', function ()
      { //selezione energie
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        calibrated = true;
    
        drawChart(pixel1, pixel2, 0, channelDepth);
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        box1.setAttribute("value", "0");
    
        box2.setAttribute("value", "channelDepth");
    
    Laura Cappelli's avatar
    Laura Cappelli committed
      });
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      $('#setChannelsButton').on('click', function ()
      { //selezione canali
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        calibrated = false;
    
        drawChart(pixel1, pixel2, 0, channelDepth);
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        box1.setAttribute("value", "-");
        box2.setAttribute("value", "-");
      });
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      $('#ExportGraph').on('click', function ()
      { //esportazione grafico
        let img = <HTMLImageElement>document.getElementById("chartToImg");
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        Dygraph.Export.asPNG(g, img);
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        $("#ExportGraph").attr("href", img.src.replace('image/png', 'image/octet-stream'));
    
    Laura Cappelli's avatar
    Laura Cappelli committed
      });
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      $('#readSpinbox').on('click', function ()
      { //esportazione grafico
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        peackSelection(0, 0);
      });
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      $('#chart').on('click', function ()
      { //zoom manuale sul grafico
        let r: number[];
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        r = g.xAxisRange();
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        if (!calibrated) {
          r[0] = Math.floor((((r[0] + 1) * a) - b) / 1000);
          r[1] = Math.floor((((r[1] + 1) * a) - b) / 1000);
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        } else {
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
          r[0] = round3(r[0]);
          r[1] = round3(r[1]);
          box1.setAttribute("value", r[0].toString());
          box2.setAttribute("value", r[1].toString());
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        }
        globalxMinRange = r[0];
        globalxMaxRange = r[1];
        drawImg(pixel1, pixel2, r[0], r[1]);
      });
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      $('#elementSelect').on('change', function ()
      { //selezione elemento
        let element: string = (<HTMLInputElement>document.getElementById("elementSelect")).value;
        switch (element) {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
          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");
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
            break;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
          case "3":  //Hg
            peackSelection(9.8, 10.15);
            box1.setAttribute("value", "9.80");
            box2.setAttribute("value", "10.15");
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
            break;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
          case "4": //Fe
            peackSelection(6.3, 6.5);
            box1.setAttribute("value", "6.30");
            box2.setAttribute("value", "6.50");
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
            break;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
          case "5":  //Cu
            peackSelection(7.85, 8.2);
            box1.setAttribute("value", "7.85");
            box2.setAttribute("value", "8.20");
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
            break;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
          case "6": //Zn
            peackSelection(8.5, 8.72);
            box1.setAttribute("value", "8.50");
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
            box2.setAttribute("value", "8.72");
    
    Laura Cappelli's avatar
    Laura Cappelli committed
            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");
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
            break;
    
    Laura Cappelli's avatar
    Laura Cappelli committed
          case "9": //Co
            peackSelection(6.8, 7.05);
            box1.setAttribute("value", "6.80");
            box2.setAttribute("value", "7.05");
            break;
          default:
    
            peackSelection(0, channelDepth);
    
    Laura Cappelli's avatar
    Laura Cappelli committed
            box1.setAttribute("value", "0");
    
            box2.setAttribute("value", "channelDepth");
    
    Laura Cappelli's avatar
    Laura Cappelli committed
            break;
        }
      });
    
      //la funzione setChart riceve in input i dati e il titolo del grafico da disegnare
      //il quale è restituito il output
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      function setChart(dataString: string, charTitle: string)
      {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        let xArrayRange: number[]; //estremi asse x da visualizzare
        let xLab: string;
        if (!calibrated) {
    
          xArrayRange = [0, depth];
    
    Laura Cappelli's avatar
    Laura Cappelli committed
          xLab = "ADC Channel";
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        } else {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
          xArrayRange = [xMinRange, xMaxRange];
          xLab = "Energy (keV)";
        }
    
        //dimensioni grafico
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        let chartDim: any = document.querySelector('#chart-pannel').getBoundingClientRect();
        let chartWidth = chartDim.right - chartDim.left - 50;
        $('#chart').css('width', chartWidth);
    
    Laura Cappelli's avatar
    Laura Cappelli committed
    
        //disegno il grafico
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        let graphs: any = new Dygraph(document.getElementById("chart"), dataString, {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
          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
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
      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
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        if (xMinRange == 0 && xMaxRange == 0) {
    
    Laura Cappelli's avatar
    Laura Cappelli committed
          xMinRange = parseInt((<HTMLInputElement>box1).value);
          xMaxRange = parseInt((<HTMLInputElement>box2).value);
        }
    
        globalxMinRange = xMinRange;
        globalxMaxRange = xMaxRange;
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        newOrigin = { xp: 0, yp: 0 };
    
    Laura Cappelli's avatar
    Laura Cappelli committed
        rePrint = false;
        calibrated = true;
    
    Francesco Giacomini's avatar
    Francesco Giacomini committed
        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);