// require() is ES5 and allows modifying global variables // ES6's `from` does not import G = require("./globals"); import * as $ from "jquery"; import * as Dygraph from "dygraphs"; import * as Help from "./helper" //la funzione drawImg disegna il canvas con l'immagine desiderata ed è responsabile //della gestione di tutti gli eventi ad essa associati export function drawImg(image: G.Image, pixel1: G.coordinates, pixel2: G.coordinates, xMinRange: number, xMaxRange: number, callback?: () => void) { //alert("disegno in corso"); //numero di pixel per dimensione let nPixelX: number = pixel2.x - pixel1.x + 1; let nPixelY: number = pixel2.y - pixel1.y + 1; //dimensione dei canvas let mappaPannelDim: any = document.querySelector('#mappa-pannel').getBoundingClientRect(); let mappaWidth: number = mappaPannelDim.right - mappaPannelDim.left - 40; let mappaHeigth: number = 400; //dimensione reale dei pixel let dimPixelx: number = Math.floor(mappaWidth / nPixelX); let dimPixely: number = Math.floor(mappaHeigth / nPixelY); image.pixelDim = (dimPixelx < dimPixely) ? dimPixelx : dimPixely; //dimensioni esatte dei canvas (<HTMLCanvasElement>document.getElementById("myCanvas")).height = nPixelY * image.pixelDim; (<HTMLCanvasElement>document.getElementById("myCanvas")).width = nPixelX * image.pixelDim; (<HTMLCanvasElement>document.getElementById("selectionCanvas")).height = nPixelY * image.pixelDim; (<HTMLCanvasElement>document.getElementById("selectionCanvas")).width = nPixelX * image.pixelDim; let ctx = (<HTMLCanvasElement>document.getElementById('myCanvas')).getContext('2d'); //contesto del canvas if (xMaxRange - xMinRange >= image.channelDepth) { //range completo let max: number; //massimo relativo o assoluto if (image.rePrint) { max = Help.findMax(image.nOfCounts, pixel1, pixel2); } else { max = image.maxAbsolute; } max = (max * $("#SaturationSlider").val()) / 100; drawCanvas(image, image.nOfCounts, max); } else { //range parziale (solo alcuni canali) let xMinRangeCh: number = Math.floor((((xMinRange * 1000) + G.Image.getInstance().calibration.b) / G.Image.getInstance().calibration.a) - 1); //16 let xMaxRangeCh: number = Math.floor((((xMaxRange * 1000) + G.Image.getInstance().calibration.b) / G.Image.getInstance().calibration.a) - 1); //16371 console.log(G.Image.getInstance().calibration.a); //calcolo il numero di conteggi solo dei canali selezionati let nOfCountsRelative: number[][]; nOfCountsRelative = new Array(image.width); for (let i: number = 0; i < image.width; i++) { nOfCountsRelative[i] = new Array(image.height); for (let j: number = 0; j < image.height; j++) { nOfCountsRelative[i][j] = Help.sumVect(image.DataMatrix[i][j], xMinRangeCh, xMaxRangeCh); } } //calcolo il massimo let max: number; if (image.rePrint) { max = Help.findMax(nOfCountsRelative, pixel1, pixel2); } else { max = Help.findMax(nOfCountsRelative, { x: 0, y: 0 }, { x: image.width - 1, y: image.height - 1 }); } max = (max * $("#SaturationSlider").val()) / 100; drawCanvas(image, nOfCountsRelative, max); } //La funzione, ricevuti dati e massimo, disegna la mappa nel canvas function drawCanvas(image: G.Image, noc, max) { //controllo il valore della trasparenza let setTrsp: number = 1 - ($("#TrasparencySlider").val() / 100); //let setTrsp: number = 1-(parseInt($("#TrasparencySlider").attr("value"))/100); //scorro tutti i pixel: ne determino il colore e li disegno let color: string = ""; for (let i: number = pixel1.x; i <= pixel2.x; i++) { for (let j: number = pixel1.y; j <= pixel2.y; 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 + ")"; else //rosso -verde color = "rgba(255," + (255 - Math.floor((intensity - 4 / 5) * 5 * 255)) + ", 0, " + setTrsp + ")"; ctx.fillStyle = color; ctx.fillRect((i - pixel1.x) * image.pixelDim, (j - pixel1.y) * image.pixelDim, image.pixelDim, image.pixelDim); } } image.rePrint = false; //annullo rePrint zoomRect(); } $("#SaturationSlider").mouseup(function () { //Slider della saturazione drawImg(image, pixel1, pixel2, xMinRange, xMaxRange); }); $("#rePlot").click(function () { //bottone per colorare con il max relativo image.rePrint = true; (<HTMLInputElement>document.getElementById("SaturationSlider")).value = "100"; drawImg(image, pixel1, pixel2, xMinRange, xMaxRange); }); $("#TrasparencySlider").mouseup(function () { //Slider della trasparenza drawImg(image, pixel1, pixel2, xMinRange, xMaxRange); }); $("#reset").click(function () { //bottone per il reset dell'applicazione let image = G.Image.getInstance(); image.newOrigin = { x: 0, y: 0 }; image.rePrint = false; G.Chart.getInstance().calibrated = false; image.globalxMinRange = 0; image.globalxMaxRange = image.channelDepth; (<HTMLInputElement>document.getElementById("SaturationSlider")).value = "100"; (<HTMLInputElement>document.getElementById("TrasparencySlider")).value = "0"; document.getElementById("spinBoxMin").setAttribute("value", "-"); document.getElementById("spinBoxMax").setAttribute("value", "-"); drawImg(image, { x: 0, y: 0 }, { x: image.width - 1, y: image.height - 1 }, 0, image.channelDepth); drawChart(image, { x: 0, y: 0 }, { x: image.width - 1, y: image.height - 1 }, 0, image.channelDepth); }); $("#ExportImage").click(function () { //esportazione immagine let img = (<HTMLCanvasElement>document.getElementById("myCanvas")).toDataURL("image/png"); $("#ExportLink").attr("href", img); //document.write('<img src="'+img+'"/>'); }); callback(); } //la funzione drawChart (input: estremi dell'immagine, estremi dell'intervallo) //disegna il grafico richiesto relativo alla mappa visualizzata export function drawChart(image: G.Image, pixel1: G.coordinates, pixel2: G.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 let g: any; let box1 = <HTMLElement>document.getElementById("spinBoxMin"); let box2 = <HTMLElement>document.getElementById("spinBoxMax"); //disegno il grafico completo if (pixel1.x == 0 && pixel1.y == 0 && pixel2.x == image.width - 1 && pixel2.y == image.height - 1) { if (!G.Chart.getInstance().calibrated) { //canali let chartTitle: string = "Chart from (0, 0) to (" + (image.width - 1) + ", " + (image.height - 1) + ")"; g = setChart(G.Chart.getInstance().dataCompleteChart, chartTitle); } else { //energie let chartTitle: string = "Calibrated chart from (0, 0) to (" + (image.width - 1) + ", " + (image.height - 1) + ")"; g = setChart(G.Chart.getInstance().dataCompleteChartCalibrated, chartTitle); } //disegno il grafico parzialmente } else { //determino i conteggi dei pixel da disegnare let dataForChart: number[] = new Array(G.Image.getInstance().depth); for (let i: number = 0; i < G.Image.getInstance().depth; i++) { dataForChart[i] = 0; } for (let i: number = pixel1.x; i <= pixel2.x; i++) { for (let j: number = pixel1.y; j <= pixel2.y; j++) { for (let k: number = 0; k < G.Image.getInstance().depth; k++) { dataForChart[k] += image.DataMatrix[i][j][k]; } } } if (!G.Chart.getInstance().calibrated) { //disegno in canali let dataChart: string = "Channel,Counts\n"; for (let i: number = 0; i < G.Image.getInstance().depth; i++) { dataChart += i + "," + dataForChart[i] + "\n"; } let chartTitle: string; if (pixel1.x == pixel2.x && pixel1.y == pixel2.y) { chartTitle = "Chart pixel (" + pixel1.x + ", " + (image.height - pixel1.y - 1) + ")"; } else { chartTitle = "Chart from (" + pixel1.x + "," + pixel2.x + ") to (" + (image.height - pixel1.y - 1) + ", " + (image.height - pixel2.y - 1) + ")"; } g = setChart(dataChart, chartTitle); } else { //disegno in energie let dataChartCalibrated: string = "Energy,Counts\n"; for (let i: number = 0; i < G.Image.getInstance().depth; i++) { dataChartCalibrated += Help.round3(((i + 1) * G.Image.getInstance().calibration.a - G.Image.getInstance().calibration.b) / 1000) + "," + dataForChart[i] + "\n"; } let chartTitle: string; if (pixel1.x == pixel2.x && pixel1.y == pixel2.y) { chartTitle = "Calibrated chart pixel (" + pixel1.x + ", " + (image.height - pixel1.y - 1) + ")"; } else { chartTitle = "Calibrated chart from (" + pixel1.x + ", " + pixel2.x + ") to (" + (image.height - pixel1.y - 1) + ", " + (image.height - pixel2.y - 1) + ")"; } g = setChart(dataChartCalibrated, chartTitle); } } console.log("ci sono"); $('#setlinearButton').on('click', function () { //selezione scala lineare g.updateOptions({ logscale: false }); }); $('#setlogButton').on('click', function () { //selezione scala logaritmica g.updateOptions({ logscale: true }); }); $('#setEnergyButton').on('click', function () { //selezione energie G.Chart.getInstance().calibrated = true; drawChart(image, pixel1, pixel2, 0, image.channelDepth); box1.setAttribute("value", "0"); box2.setAttribute("value", "image.channelDepth"); }); $('#setChannelsButton').on('click', function () { //selezione canali G.Chart.getInstance().calibrated = false; drawChart(image, pixel1, pixel2, 0, image.channelDepth); box1.setAttribute("value", "-"); box2.setAttribute("value", "-"); }); $('#ExportGraph').on('click', function () { //esportazione grafico let img = <HTMLImageElement>document.getElementById("chartToImg"); Dygraph.Export.asPNG(g, img); $("#ExportGraph").attr("href", img.src.replace('image/png', 'image/octet-stream')); }); $('#readSpinbox').on('click', function () { //esportazione grafico peackSelection(0, 0); }); $('#chart').on('click', function () { //zoom manuale sul grafico let r: number[]; r = g.xAxisRange(); if (!G.Chart.getInstance().calibrated) { r[0] = Math.floor((((r[0] + 1) * G.Image.getInstance().calibration.a) - G.Image.getInstance().calibration.b) / 1000); r[1] = Math.floor((((r[1] + 1) * G.Image.getInstance().calibration.a) - G.Image.getInstance().calibration.b) / 1000); } else { r[0] = Help.round3(r[0]); r[1] = Help.round3(r[1]); box1.setAttribute("value", r[0].toString()); box2.setAttribute("value", r[1].toString()); } image.globalxMinRange = r[0]; image.globalxMaxRange = r[1]; drawImg(image, pixel1, pixel2, r[0], r[1]); }); $('#elementSelect').on('change', function () { //selezione elemento let element: string = (<HTMLInputElement>document.getElementById("elementSelect")).value; switch (element) { case "1": //Ca peackSelection(3.6, 3.8); box1.setAttribute("value", "3.60"); box2.setAttribute("value", "3.80"); break; case "2": //Pb peackSelection(10.4, 10.7); box1.setAttribute("value", "10.40"); box2.setAttribute("value", "10.70"); break; case "3": //Hg peackSelection(9.8, 10.15); box1.setAttribute("value", "9.80"); box2.setAttribute("value", "10.15"); break; case "4": //Fe peackSelection(6.3, 6.5); box1.setAttribute("value", "6.30"); box2.setAttribute("value", "6.50"); break; case "5": //Cu peackSelection(7.85, 8.2); box1.setAttribute("value", "7.85"); box2.setAttribute("value", "8.20"); break; case "6": //Zn peackSelection(8.5, 8.72); box1.setAttribute("value", "8.50"); box2.setAttribute("value", "8.72"); break; case "7": //Ti peackSelection(4.35, 4.65); box1.setAttribute("value", "4.35"); box2.setAttribute("value", "4.65"); break; case "8": //K peackSelection(3.2, 3.42); box1.setAttribute("value", "3.20"); box2.setAttribute("value", "3.42"); break; case "9": //Co peackSelection(6.8, 7.05); box1.setAttribute("value", "6.80"); box2.setAttribute("value", "7.05"); break; default: peackSelection(0, image.channelDepth); box1.setAttribute("value", "0"); box2.setAttribute("value", "image.channelDepth"); break; } }); //la funzione setChart riceve in input i dati e il titolo del grafico da disegnare //il quale è restituito il output function setChart(dataString: string, charTitle: string) { let xArrayRange: number[]; //estremi asse x da visualizzare let xLab: string; if (!G.Chart.getInstance().calibrated) { xArrayRange = [0, G.Image.getInstance().depth]; xLab = "ADC Channel"; } else { xArrayRange = [xMinRange, xMaxRange]; xLab = "Energy (keV)"; } //dimensioni grafico let chartDim: any = document.querySelector('#chart-pannel').getBoundingClientRect(); let chartWidth = chartDim.right - chartDim.left - 50; $('#chart').css('width', chartWidth); $('#chart').css('height', "400"); //disegno il grafico let 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 }); return graphs; } //la funzione, dati gli estremi dell'intervallo da rappresentare, aggiorna mappa e grafico function peackSelection(xMinRange: number, xMaxRange: number) { //let image = G.Image.getInstance(); //se l'intervallo è [0, 0] devo leggere dalle i valori dalle spinbox if (xMinRange == 0 && xMaxRange == 0) { xMinRange = parseInt((<HTMLInputElement>box1).value); xMaxRange = parseInt((<HTMLInputElement>box2).value); } image.globalxMinRange = xMinRange; image.globalxMaxRange = xMaxRange; image.newOrigin = { x: 0, y: 0 }; image.rePrint = false; G.Chart.getInstance().calibrated = true; drawImg(image, { x: 0, y: 0 }, { x: image.width - 1, y: image.height - 1 }, image.globalxMinRange, image.globalxMaxRange); drawChart(image, { x: 0, y: 0 }, { x: image.width - 1, y: image.height - 1 }, image.globalxMinRange, image.globalxMaxRange); } } //la funzione disegna il rettangolo durante la selezione di un'area della mappa function zoomRect() { let selectCanvas = <HTMLCanvasElement>document.getElementById("selectionCanvas"); let ctx = selectCanvas.getContext("2d"); // style the context ctx.fillStyle = "rgba(0, 110, 255, 0.25)"; // this flage is true when the user is dragging the mouse let isDown = false; // these vars will hold the starting mouse position let startX: number; let startY: number; let mouseX: number; let mouseY: number; // these vars will hold the starting mouse position function handleMouseDown(e) { e.preventDefault(); e.stopPropagation(); //calculate mouse position let scrollTOP: number = (document.documentElement.scrollTop) ? document.documentElement.scrollTop : document.body.scrollTop; let scrollLEFT: number = (document.documentElement.scrollLeft) ? document.documentElement.scrollLeft : document.body.scrollLeft; 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; // set a flag indicating the drag has begun isDown = true; } function handleMouseUp(e) { e.preventDefault(); e.stopPropagation(); // the drag is over, clear the dragging flag isDown = false; ctx.clearRect(0, 0, selectCanvas.width, selectCanvas.height); } function handleMouseOut(e) { e.preventDefault(); e.stopPropagation(); // the drag is over, clear the dragging flag isDown = false; ctx.clearRect(0, 0, selectCanvas.width, selectCanvas.height); } function handleMouseMove(e) { e.preventDefault(); e.stopPropagation(); // if we're not dragging, just return if (!isDown) { return; } //calculate mouse position let scrollTOP: number = (document.documentElement.scrollTop) ? document.documentElement.scrollTop : document.body.scrollTop; let scrollLEFT: number = (document.documentElement.scrollLeft) ? document.documentElement.scrollLeft : document.body.scrollLeft; 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; // Put your mousemove stuff here // clear the canvas ctx.clearRect(0, 0, selectCanvas.width, selectCanvas.height); // calculate the rectangle width/height based // on starting vs current mouse position let width = mouseX - startX; let height = mouseY - startY; // draw a new rect from the start position // to the current mouse position ctx.fillRect(startX, startY, width, height); } // listen for mouse events $("#selectionCanvas").mousedown(function (e) { handleMouseDown(e); }); $("#selectionCanvas").mousemove(function (e) { handleMouseMove(e); }); $("#selectionCanvas").mouseup(function (e) { handleMouseUp(e); }); $("#selectionCanvas").mouseout(function (e) { handleMouseOut(e); }); }