Skip to content
Snippets Groups Projects
start.ts 25.5 KiB
Newer Older
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);