import { DrawImage } from "./drawImage"; import G = require("./globals"); import Help = require("./helper"); import Dygraph = require("dygraphs"); export class DrawChart { private _drawImage: DrawImage; private _image: G.Image = G.Image.getInstance(); private _chart: G.Chart = G.Chart.getInstance(); private readonly setLinearButtonID: string = "setlinearButton"; private readonly setLogButtonID: string = "setlogButton"; private readonly setEnergyButtonID: string = "setEnergyButton"; private readonly setChannelButtonID: string = "setChannelsButton"; private readonly exportGraphID: string = "ExportGraph"; private readonly readSpinBoxID: string = "readSpinbox"; private readonly chartElementID: string = "chart"; private readonly elementSelectID: string = "elementSelect"; private _graphic: any; private _setLinearButton: HTMLAnchorElement; private _setLogButton: HTMLAnchorElement; private _setEnergyButton: HTMLAnchorElement; private _setChannelButton: HTMLAnchorElement; private _exportgraph: HTMLAnchorElement; private _readSpinBox: HTMLButtonElement; private _chartElement: HTMLElement; private _elementSelect: HTMLSelectElement; private _box1 = <HTMLElement>document.getElementById("spinBoxMin"); private _box2 = <HTMLElement>document.getElementById("spinBoxMax"); private _pixel1: G.coordinates; private _pixel2: G.coordinates; constructor(drawImage: DrawImage) { this._drawImage = drawImage; this._setLinearButton = <HTMLAnchorElement>document.getElementById(this.setLinearButtonID); this._setLinearButton.addEventListener("click", this.setLinearButtonClick, false); this._setLogButton = <HTMLAnchorElement>document.getElementById(this.setLogButtonID); this._setLogButton.addEventListener("click", this.setLogButtonClick, false); this._setEnergyButton = <HTMLAnchorElement>document.getElementById(this.setEnergyButtonID); this._setEnergyButton.addEventListener("click", this.setEnergyButtonClick, false); this._setChannelButton = <HTMLAnchorElement>document.getElementById(this.setChannelButtonID); this._setChannelButton.addEventListener("click", this.setChannelButtonClick, false); this._exportgraph = <HTMLAnchorElement>document.getElementById(this.exportGraphID); this._exportgraph.addEventListener("click", this.exportGraphClick, false); this._readSpinBox = <HTMLButtonElement>document.getElementById(this.readSpinBoxID); this._readSpinBox.addEventListener("click", this.readSpinBoxClick, false); this._chartElement = <HTMLElement>document.getElementById(this.chartElementID); this._chartElement.addEventListener("click", this.chartClick, false); this._elementSelect = <HTMLSelectElement>document.getElementById(this.elementSelectID); this._elementSelect.addEventListener("select", this.elementSelect, false); } private setLinearButtonClick = (event: MouseEvent) => { this._graphic.updateOptions({ logscale: false }); }; private setLogButtonClick = (event: MouseEvent) => { this._graphic.updateOptions({ logscale: true }); }; private setEnergyButtonClick = (event: MouseEvent) => { this._chart.calibrated = true; this.drawChart(this._image, this._pixel1, this._pixel2, 0, this._image.channelDepth); this._box1.setAttribute("value", "0"); this._box2.setAttribute("value", this._image.channelDepth.toString()); }; private setChannelButtonClick = (event: MouseEvent) => { this._chart.calibrated = false; this.drawChart(this._image, this._pixel1, this._pixel2, 0, this._image.channelDepth); this._box1.setAttribute("value", "-"); this._box2.setAttribute("value", "-"); }; private exportGraphClick = (event: MouseEvent) => { let img = <HTMLImageElement>document.getElementById("chartToImg"); Dygraph.Export.asPNG(this._graphic, img); document.getElementById("#ExportGraph").setAttribute("href", img.src.replace("image/png", "image/octet-stream")); }; private readSpinBoxClick = (event: MouseEvent) => { //esportazione grafico this.peackSelection(0, 0, this._image); }; private chartClick = (event: MouseEvent) => { //zoom manuale sul grafico let r: number[]; r = this._graphic.xAxisRange(); if (!this._chart.calibrated) { r[0] = Math.floor(((r[0] + 1) * this._image.calibration.a - this._image.calibration.b) / 1000); r[1] = Math.floor(((r[1] + 1) * this._image.calibration.a - this._image.calibration.b) / 1000); } else { r[0] = Help.round3(r[0]); r[1] = Help.round3(r[1]); this._box1.setAttribute("value", r[0].toString()); this._box2.setAttribute("value", r[1].toString()); } this._image.globalxMinRange = r[0]; this._image.globalxMaxRange = r[1]; this._drawImage.drawImg(this._image, this._pixel1, this._pixel2, r[0], r[1]); }; private elementSelect = (event: MouseEvent) => { //selezione elemento let element: string = (<HTMLInputElement>document.getElementById("elementSelect")).value; switch (element) { case "1": //Ca this.peackSelection(3.6, 3.8, this._image); this._box1.setAttribute("value", "3.60"); this._box2.setAttribute("value", "3.80"); break; case "2": //Pb this.peackSelection(10.4, 10.7, this._image); this._box1.setAttribute("value", "10.40"); this._box2.setAttribute("value", "10.70"); break; case "3": //Hg this.peackSelection(9.8, 10.15, this._image); this._box1.setAttribute("value", "9.80"); this._box2.setAttribute("value", "10.15"); break; case "4": //Fe this.peackSelection(6.3, 6.5, this._image); this._box1.setAttribute("value", "6.30"); this._box2.setAttribute("value", "6.50"); break; case "5": //Cu this.peackSelection(7.85, 8.2, this._image); this._box1.setAttribute("value", "7.85"); this._box2.setAttribute("value", "8.20"); break; case "6": //Zn this.peackSelection(8.5, 8.72, this._image); this._box1.setAttribute("value", "8.50"); this._box2.setAttribute("value", "8.72"); break; case "7": //Ti this.peackSelection(4.35, 4.65, this._image); this._box1.setAttribute("value", "4.35"); this._box2.setAttribute("value", "4.65"); break; case "8": //K this.peackSelection(3.2, 3.42, this._image); this._box1.setAttribute("value", "3.20"); this._box2.setAttribute("value", "3.42"); break; case "9": //Co this.peackSelection(6.8, 7.05, this._image); this._box1.setAttribute("value", "6.80"); this._box2.setAttribute("value", "7.05"); break; default: this.peackSelection(0, this._image.channelDepth, this._image); this._box1.setAttribute("value", "0"); this._box2.setAttribute("value", this._image.channelDepth.toString()); break; } }; 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 this._pixel1 = pixel1; this._pixel2 = pixel2; //disegno il grafico completo if ( pixel1.x == 0 && pixel1.y == 0 && pixel2.x == image.width - 1 && pixel2.y == image.height - 1 ) { if (!this._chart.calibrated) { //canali let chartTitle: string = "Chart from (0, 0) to (" + (image.width - 1) + ", " + (image.height - 1) + ")"; this._graphic = this.setChart(this._chart.dataCompleteChart, chartTitle, xMinRange, xMaxRange); } else { //energie let chartTitle: string = "Calibrated chart from (0, 0) to (" + (image.width - 1) + ", " + (image.height - 1) + ")"; this._graphic = this.setChart(this._chart.dataCompleteChartCalibrated, chartTitle, xMinRange, xMaxRange); } //disegno il grafico parzialmente } else { //determino i conteggi dei pixel da disegnare let dataForChart: number[] = new Array(this._image.depth); for (let i: number = 0; i < this._image.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 < this._image.depth; k++) { dataForChart[k] += image.DataMatrix[i][j][k]; } } } if (!this._chart.calibrated) { //disegno in canali let dataChart: string = "Channel,Counts\n"; for (let i: number = 0; i < this._image.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) + ")"; } this._graphic = this.setChart(dataChart, chartTitle, xMinRange, xMaxRange); } else { //disegno in energie let dataChartCalibrated: string = "Energy,Counts\n"; for (let i: number = 0; i < this._image.depth; i++) { dataChartCalibrated += Help.round3(((i + 1) * this._image.calibration.a - this._image.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) + ")"; } this._graphic = this.setChart(dataChartCalibrated, chartTitle, xMinRange, xMaxRange); } } } //la funzione setChart riceve in input i dati e il titolo del grafico da disegnare //il quale è restituito il output setChart(dataString: string, charTitle: string, xMinRange: number, xMaxRange: number): Dygraph { let xArrayRange: number[]; //estremi asse x da visualizzare let xLab: string; if (!this._chart.calibrated) { xArrayRange = [0, this._image.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; document.getElementById(this.chartElementID).setAttribute("width", chartWidth.toString()); document.getElementById(this.chartElementID).setAttribute("height", "400"); //disegno il grafico this._graphic = new Dygraph(document.getElementById(this.chartElementID), dataString, { title: charTitle, ylabel: "Counts", xlabel: xLab, // labelsDivStyles: { // "text-align": "right" // }, //legend: 'always', dateWindow: xArrayRange, showRangeSelector: true, logscale: false, }); return this._graphic; } //la funzione, dati gli estremi dell'intervallo da rappresentare, aggiorna mappa e grafico private peackSelection(xMinRange: number, xMaxRange: number, image: G.Image) { //let image = this._image; //se l'intervallo è [0, 0] devo leggere dalle i valori dalle spinbox if (xMinRange == 0 && xMaxRange == 0) { xMinRange = parseInt((<HTMLInputElement>this._box1).value); xMaxRange = parseInt((<HTMLInputElement>this._box2).value); } image.globalxMinRange = xMinRange; image.globalxMaxRange = xMaxRange; image.newOrigin = { x: 0, y: 0 }; image.rePrint = false; this._chart.calibrated = true; this._drawImage.drawImg(image, { x: 0, y: 0 }, { x: image.width - 1, y: image.height - 1 }, image.globalxMinRange, image.globalxMaxRange); this.drawChart(image, { x: 0, y: 0 }, { x: image.width - 1, y: image.height - 1 }, image.globalxMinRange, image.globalxMaxRange); } }