Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • faproietti/XRF-App
  • chnet/XRF-App
2 results
Show changes
Commits on Source (10)
Showing with 1645 additions and 6387 deletions
......@@ -3,3 +3,4 @@ node_modules
*.js
coverage
.vscode
package-lock.json
\ No newline at end of file
export class CallbackManager
{
private static _instance: CallbackManager = new CallbackManager();
private constructor(){
if(CallbackManager._instance) {
throw new Error("Error: Image object is already instantiated");
}
else{
CallbackManager._instance = this;
}
}
public static getInstance(): CallbackManager {
return CallbackManager._instance;
}
class CallbackManager {
constructor() {
}
public showElement(elementID: string, show: boolean): void {
if(show){
if (show) {
document.getElementById(elementID).style.display = "inline";
}
else
{
else {
document.getElementById(elementID).style.display = "none";
}
}
public closeBootstrapModel(elementID: string): void{
public closeBootstrapModel(elementID: string): void {
document.getElementById(elementID).click();
}
}
export { CallbackManager };
\ No newline at end of file
import { Image, coordinates } from "./image";
import * as Utility from "./utility";
import "dygraphs"
class Chart {
graphic: any;
private readonly chartElementID: string = "chart";
private setLinearButton: HTMLAnchorElement;
private setLogButton: HTMLAnchorElement;
private setEnergyButton: HTMLAnchorElement;
private setChannelButton: HTMLAnchorElement;
private exportgraph: HTMLAnchorElement;
private readSpinBox: HTMLButtonElement;
private chartElement: HTMLElement;
private elementSelect: HTMLSelectElement;
public spinBoxMin: HTMLInputElement;
public spinBoxMax: HTMLInputElement;
dataCompleteChart: string = "Channel,Counts\n";
dataCompleteChartCalibrated: string = "Energy,Counts\n";
calibrated: boolean = false; //variabile per il controllo sulla calibrazione
constructor() {
this.chartElement = <HTMLElement>document.getElementById(this.chartElementID);
this.spinBoxMin = <HTMLInputElement>document.getElementById("spinBoxMin");
this.spinBoxMax = <HTMLInputElement>document.getElementById("spinBoxMax");
}
drawChart(image: Image, pixel1: coordinates, pixel2: coordinates, xMinRange: number, xMaxRange: number) {
//definisco la variabile "grafico", i bottoni relativi al grafico, il tag
//select e le due spinbox con il relativo botton
//disegno il grafico completo
if (pixel1.x == 0 && pixel1.y == 0 && pixel2.x == image.width - 1 && pixel2.y == image.height - 1) {
if (!this.calibrated) {
//canali
let chartTitle: string = "Chart from (0, 0) to (" + (image.width - 1) + ", " + (image.height - 1) + ")";
this.graphic = this.setChart(image, this.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(image, this.dataCompleteChartCalibrated, chartTitle, xMinRange, xMaxRange);
}
//disegno il grafico parzialmente
} else {
//determino i conteggi dei pixel da disegnare
let dataForChart: number[] = new Array(image.depth);
for (let i: number = 0; i < 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 < image.depth; k++) {
dataForChart[k] += image.DataMatrix[i][j][k];
}
}
}
if (!this.calibrated) {
//disegno in canali
let dataChart: string = "Channel,Counts\n";
for (let i: number = 0; i < 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(image, dataChart, chartTitle, xMinRange, xMaxRange);
} else {
//disegno in energie
let dataChartCalibrated: string = "Energy,Counts\n";
for (let i: number = 0; i < image.depth; i++) {
dataChartCalibrated += Utility.round3(((i + 1) * image.calibration.a - 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(image, 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(image: Image, dataString: string, charTitle: string, xMinRange: number, xMaxRange: number): Dygraph {
let xArrayRange: number[]; //estremi asse x da visualizzare
let xLab: string;
if (!this.calibrated) {
xArrayRange = [0, 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;
this.chartElement.setAttribute("width", chartWidth.toString());
this.chartElement.setAttribute("height", "400");
//disegno il grafico
this.graphic = new Dygraph(this.chartElement, 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
peackSelection(xMinRange: number, xMaxRange: number, image: Image) {
//se l'intervallo è [0, 0] devo leggere dalle i valori dalle spinbox
if (xMinRange == 0 && xMaxRange == 0) {
xMinRange = parseInt((this.spinBoxMin).value);
xMaxRange = parseInt((this.spinBoxMax).value);
}
image.globalxMinRange = xMinRange;
image.globalxMaxRange = xMaxRange;
image.newOrigin = { x: 0, y: 0 };
image.rePrint = false;
this.calibrated = true;
image.drawImg({ 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);
}
}
export { Chart };
import { DrawImage } from "./drawImage";
import G = require("./globals");
import Help = require("./helper");
import dygraph = require("dygraphs");
import * as Dygraph from "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;
public spinBoxMin: HTMLInputElement;
public spinBoxMax: HTMLInputElement;
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);
this.spinBoxMin = <HTMLInputElement>document.getElementById("spinBoxMin");
this.spinBoxMax = <HTMLInputElement>document.getElementById("spinBoxMax");
}
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.spinBoxMin.setAttribute("value", "0");
this.spinBoxMax.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.spinBoxMin.setAttribute("value", "-");
this.spinBoxMax.setAttribute("value", "-");
};
private exportGraphClick = (event: MouseEvent) => {
let img = <HTMLImageElement>document.getElementById("chartToImg");
Dygraph.Export.asPNG(this._graphic, img);
this._exportgraph.setAttribute("href", img.src.replace("image/png", "image/octet-stream"));
};
private readSpinBoxClick = (event: MouseEvent) => {
//esportazione grafico
console.log("readspinbox");
this.peackSelection(0, 0, this._image);
};
private chartClick = (event: MouseEvent) => {
//zoom manuale sul grafico
console.log("chartClick");
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.spinBoxMin.setAttribute("value", r[0].toString());
this.spinBoxMax.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 = this._elementSelect.value;
switch (element) {
case "1": //Ca
this.peackSelection(3.6, 3.8, this._image);
this.spinBoxMin.setAttribute("value", "3.60");
this.spinBoxMax.setAttribute("value", "3.80");
break;
case "2": //Pb
this.peackSelection(10.4, 10.7, this._image);
this.spinBoxMin.setAttribute("value", "10.40");
this.spinBoxMax.setAttribute("value", "10.70");
break;
case "3": //Hg
this.peackSelection(9.8, 10.15, this._image);
this.spinBoxMin.setAttribute("value", "9.80");
this.spinBoxMax.setAttribute("value", "10.15");
break;
case "4": //Fe
this.peackSelection(6.3, 6.5, this._image);
this.spinBoxMin.setAttribute("value", "6.30");
this.spinBoxMax.setAttribute("value", "6.50");
break;
case "5": //Cu
this.peackSelection(7.85, 8.2, this._image);
this.spinBoxMin.setAttribute("value", "7.85");
this.spinBoxMax.setAttribute("value", "8.20");
break;
case "6": //Zn
this.peackSelection(8.5, 8.72, this._image);
this.spinBoxMin.setAttribute("value", "8.50");
this.spinBoxMax.setAttribute("value", "8.72");
break;
case "7": //Ti
this.peackSelection(4.35, 4.65, this._image);
this.spinBoxMin.setAttribute("value", "4.35");
this.spinBoxMax.setAttribute("value", "4.65");
break;
case "8": //K
this.peackSelection(3.2, 3.42, this._image);
this.spinBoxMin.setAttribute("value", "3.20");
this.spinBoxMax.setAttribute("value", "3.42");
break;
case "9": //Co
this.peackSelection(6.8, 7.05, this._image);
this.spinBoxMin.setAttribute("value", "6.80");
this.spinBoxMax.setAttribute("value", "7.05");
break;
default:
this.peackSelection(0, this._image.channelDepth, this._image);
this.spinBoxMin.setAttribute("value", "0");
this.spinBoxMax.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;
this._chartElement.setAttribute("width", chartWidth.toString());
this._chartElement.setAttribute("height", "400");
//disegno il grafico
this._graphic = new dygraph(this._chartElement, 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((this.spinBoxMin).value);
xMaxRange = parseInt((this.spinBoxMax).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);
}
}
import G = require("./globals");
import * as $ from "jquery";
import Help = require("./helper");
import { DrawChart } from "./drawChart";
export class DrawImage {
public _drawChart: DrawChart;
private _image = G.Image.getInstance();
private readonly _saturationSliderID: string = "SaturationSlider";
private readonly _replotButtonID: string = "rePlot";
private readonly _transparencySliderID: string = "TrasparencySlider";
private readonly _resetID: string = "reset";
private readonly _exportImageID: string = "ExportImage";
private readonly _selectionCanvasID: string;
private readonly _myCanvasID: string = "myCanvas";
private _context: CanvasRenderingContext2D;
private _saturationSlider: HTMLInputElement;
private _replotButton: HTMLButtonElement;
private _transparencySlider: HTMLInputElement;
private _reset: HTMLDivElement;
private _exportImage: HTMLDivElement;
private _pixel1: G.coordinates;
private _pixel2: G.coordinates;
private _xMinRange: number;
private _xMaxRange: number;
private _selectionCanvas: HTMLCanvasElement;
private _myCanvas: HTMLCanvasElement;
private _ctx;
private _startX: number;
private _startY: number;
private _mouseX: number;
private _mouseY: number;
private _isDown = false;
constructor(canvas: string) {
this._drawChart = new DrawChart(this);
this._selectionCanvasID = canvas;
this._selectionCanvas = <HTMLCanvasElement>document.getElementById(this._selectionCanvasID);
this._ctx = this._selectionCanvas.getContext("2d");
this._myCanvas = <HTMLCanvasElement>document.getElementById(this._myCanvasID);
this._saturationSlider = <HTMLInputElement>document.getElementById(this._saturationSliderID);
this._replotButton = <HTMLButtonElement>document.getElementById(this._replotButtonID);
this._transparencySlider = <HTMLInputElement>document.getElementById(this._transparencySliderID);
this._reset = <HTMLDivElement>document.getElementById(this._resetID);
this._exportImage = <HTMLDivElement>document.getElementById(this._exportImageID);
this._saturationSlider.addEventListener("mouseup", this.saturationSliderMouseUp, false);
this._replotButton.addEventListener("click", this.replotButtonClick, false);
this._transparencySlider.addEventListener("mouseup", this.trasparencySliderMouseUp, false);
this._reset.addEventListener("click", this.resetClick, false);
this._exportImage.addEventListener("click", this.exportImageClick, false);
this._selectionCanvas.addEventListener("mousedown", this.selectionCanvasMouseDown, false);
this._selectionCanvas.addEventListener("mouseup", this.clickdown, false);
this._selectionCanvas.addEventListener("mousemove", this.selectionCanvasMouseMove, false);
this._selectionCanvas.addEventListener("mouseup", this.selectionCanvasMouseUp, false);
this._selectionCanvas.addEventListener("mouseout", this.selectionCanvasMouseOut, false);
}
private saturationSliderMouseUp = (event: MouseEvent): void => {
this.drawImg(this._image, this._pixel1, this._pixel2, this._image.globalxMinRange, this._image.globalxMaxRange);
};
private replotButtonClick = (event: MouseEvent) => {
//bottone per colorare con il max relativo
this._image.rePrint = true;
this._saturationSlider.value = "100";
// opacity value?
this.drawImg(this._image, this._pixel1, this._pixel2, this._image.globalxMinRange, this._image.globalxMaxRange);
};
private trasparencySliderMouseUp = (event: MouseEvent) => {
this.drawImg(this._image, this._pixel1, this._pixel2, this._image.globalxMinRange, this._image.globalxMaxRange);
};
private resetClick = (event: MouseEvent) => {
this._image.newOrigin = { x: 0, y: 0 };
this._image.rePrint = false;
G.Chart.getInstance().calibrated = false;
this._image.globalxMinRange = 0;
this._image.globalxMaxRange = this._image.channelDepth;
this._saturationSlider.value = "100";
this._transparencySlider.value = "0";
this._drawChart.spinBoxMin.setAttribute("value", "-");
this._drawChart.spinBoxMax.setAttribute("value", "-");
this.drawImg(this._image, { x: 0, y: 0 }, { x: this._image.width - 1, y: this._image.height - 1 }, 0, this._image.channelDepth);
this._drawChart.drawChart(this._image, { x: 0, y: 0 }, { x: this._image.width - 1, y: this._image.height - 1 }, 0, this._image.channelDepth);
};
private exportImageClick = (event: MouseEvent) => {
//esportazione immagine
let img = this._selectionCanvas.toDataURL("image/png");
this._selectionCanvas.setAttribute("href", img.replace("image/png", "image/octet-stream"));
document.getElementById("ExportLink").setAttribute("href", img);
};
private clickdown = (event: MouseEvent): void => {
this.setPosition(event, this._image.zPixel2, this._selectionCanvasID);
let tmp: number;
if (this._image.zPixel1.y > this._image.zPixel2.y) {
tmp = this._image.zPixel1.y;
this._image.zPixel1.y = this._image.zPixel2.y;
this._image.zPixel2.y = tmp;
}
//se è stato cliccato un punto disegno il grafico, altrimenti disegno anche il
//canvas e aggiorno l'origine
if (this._image.zPixel1.x != this._image.zPixel2.x || this._image.zPixel1.y != this._image.zPixel2.y) {
this._image.newOrigin = { x: this._image.zPixel1.x, y: this._image.zPixel1.y };
this.drawImg(this._image, this._image.zPixel1, this._image.zPixel2, this._image.globalxMinRange, this._image.globalxMaxRange);
}
this._drawChart.drawChart(this._image, this._image.zPixel1, this._image.zPixel2, this._image.globalxMinRange, this._image.globalxMaxRange);
};
private selectionCanvasMouseDown = (event: MouseEvent) => {
event.preventDefault();
event.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 = event.clientX + scrollLEFT;
let allY: number = event.clientY + scrollTOP;
let elParent: any = this._myCanvas;
let objX: number = 0, objY: number = 0;
while (elParent) {
objX += elParent.offsetLeft;
objY += elParent.offsetTop;
elParent = elParent.offsetParent;
}
this._startX = allX - objX;
this._startY = allY - objY;
// set a flag indicating the drag has begun
this._isDown = true;
};
private selectionCanvasMouseUp = (event: MouseEvent) => {
event.preventDefault();
event.stopPropagation();
// the drag is over, clear the dragging flag
this._isDown = false;
//this._ctx.clearRect(0, 0, this._selectionCanvas.width, this._selectionCanvas.height);
};
private selectionCanvasMouseMove = (event: MouseEvent) => {
event.preventDefault();
event.stopPropagation();
// if we're not dragging, just return
if (!this._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 = event.clientX + scrollLEFT;
let allY: number = event.clientY + scrollTOP;
let elParent: any = this._myCanvas;
let objX: number = 0, objY: number = 0;
while (elParent) {
objX += elParent.offsetLeft;
objY += elParent.offsetTop;
elParent = elParent.offsetParent;
}
this._mouseX = allX - objX;
this._mouseY = allY - objY;
// clear the canvas
//this._ctx.clearRect(0, 0, this._selectionCanvas.width, this._selectionCanvas.height);
// calculate the rectangle width/height based
// on starting vs current mouse position
let width = this._mouseX - this._startX;
let height = this._mouseY - this._startY;
// draw a new rect from the start position
// to the current mouse position
this._ctx.fillRect(this._startX, this._startY, width, height);
};
private selectionCanvasMouseOut = (event: MouseEvent) => {
event.preventDefault();
event.stopPropagation();
// the drag is over, clear the dragging flag
this._isDown = false;
//this._ctx.clearRect(0, 0, this._selectionCanvas.width, this._selectionCanvas.height);
};
//Il metodo findPosition definisce la posizione del cursore del mouse
//relativa al canvas nel momento in cui avviene l'evento passato in input
private setPosition(event: any, pixel: G.coordinates, canvasID: string) {
let image = G.Image.getInstance();
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 = event.clientX + scrollLEFT;
let allY: number = event.clientY + scrollTOP;
let elParent: any = document.getElementById(canvasID);
let objX: number = 0,
objY: number = 0;
while (elParent) {
objX += elParent.offsetLeft;
objY += elParent.offsetTop;
elParent = elParent.offsetParent;
}
pixel.x = Math.floor((allX - objX - 1) / image.pixelDim) + image.newOrigin.x;
pixel.y = Math.floor((allY - objY - 1) / image.pixelDim) + image.newOrigin.y;
}
drawImg(image: G.Image, pixel1: G.coordinates, pixel2: G.coordinates, xMinRange: number, xMaxRange: number, callback?: () => void) {
this._pixel1 = pixel1;
this._pixel2 = pixel2;
//alert("disegno in corso");
//numero di pixel per dimensione
let nPixelX: number = this._pixel2.x - this._pixel1.x + 1;
let nPixelY: number = this._pixel2.y - this._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
this._myCanvas.height = nPixelY * image.pixelDim;
this._myCanvas.width = nPixelX * image.pixelDim;
this._selectionCanvas.height = nPixelY * image.pixelDim;
this._selectionCanvas.width = nPixelX * image.pixelDim;
let ctx = this._myCanvas.getContext("2d"); //contesto del canvas
if (xMaxRange - xMinRange >= image.channelDepth) {
//range completo
let max: number = 0; //massimo relativo o assoluto
if (image.rePrint) {
max = Help.findMax(image.nOfCounts, this._pixel1, this._pixel2);
} else {
max = image.maxAbsolute;
}
max *= parseInt(this._saturationSlider.value) / 100;
this.drawCanvas(image, image.nOfCounts, max);
} else {
//range parziale (solo alcuni canali)
let xMinRangeCh: number = Math.floor((xMinRange * 1000 + this._image.calibration.b) / this._image.calibration.a - 1); //16
let xMaxRangeCh: number = Math.floor((xMaxRange * 1000 + this._image.calibration.b) / this._image.calibration.a - 1); //16371
//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 = 0;
if (image.rePrint) {
max = Help.findMax(nOfCountsRelative, this._pixel1, this._pixel2);
} else {
max = Help.findMax(nOfCountsRelative, { x: 0, y: 0 }, { x: image.width - 1, y: image.height - 1 });
}
max *= parseInt(this._saturationSlider.value) / 100;
if(max == 0)
alert("WARNING: max value is 0");
else
this.drawCanvas(image, nOfCountsRelative, max);
}
if (typeof (callback) != typeof (undefined))
callback();
}
private drawCanvas(image: G.Image, noc, max) {
//controllo il valore della trasparenza
let setTrsp: number = 1 - parseInt(this._transparencySlider.value) / 100;
//scorro tutti i pixel: ne determino il colore e li disegno
let color: string = "";
for (let i: number = this._pixel1.x; i <= this._pixel2.x; i++) {
for (let j: number = this._pixel1.y; j <= this._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 + ")";
//rosso -verde
else
color = "rgba(255," + (255 - Math.floor((intensity - 4 / 5) * 5 * 255)) + ", 0, " + setTrsp + ")";
this._ctx.fillStyle = color;
this._ctx.fillRect((i - this._pixel1.x) * image.pixelDim, (j - this._pixel1.y) * image.pixelDim, image.pixelDim, image.pixelDim);
}
}
//console.log(color);
image.rePrint = false; //annullo rePrint
this._ctx.fillStyle = "rgba(0, 110, 255, 0.25)";
this._isDown = false;
}
}
// // require() is ES5 and allows modifying global variables
// // ES6's `from` does not
// import G = require("./globals");
// import * as $ from 'jquery';
// import Dygraph from 'dygraphs';
// import * as Help from './helper';
// //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,
// labelsDivStyles: {
// 'text-align': 'right'
// },
// //legend: 'always',
// dateWindow: xArrayRange,
// showRangeSelector: true,
// logscale: false,
// y: {}
// },);
// 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
import { Image } from "./image"
import { Chart } from "./chart"
import * as Utility from "./utility"
import "dygraphs"
class Events {
private image: Image;
private chart: Chart;
//////////////////// Chart ///////////////////////////
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 setLinearButton: HTMLAnchorElement;
private setLogButton: HTMLAnchorElement;
private setEnergyButton: HTMLAnchorElement;
private setChannelButton: HTMLAnchorElement;
private exportgraph: HTMLAnchorElement;
private readSpinBox: HTMLButtonElement;
private chartElement: HTMLElement;
private elementSelect: HTMLSelectElement;
public spinBoxMin: HTMLInputElement;
public spinBoxMax: HTMLInputElement;
//////////////////// Image ///////////////////////////
private startX: number;
private startY: number;
private mouseX: number;
private mouseY: number;
private readonly saturationSliderID: string = "SaturationSlider";
private readonly replotButtonID: string = "rePlot";
private readonly transparencySliderID: string = "TrasparencySlider";
private readonly resetID: string = "reset";
private readonly exportImageID: string = "ExportImage";
private readonly selectionCanvasID: string = "selectionCanvas";
private readonly myCanvasID: string = "myCanvas";
private saturationSlider: HTMLInputElement;
private replotButton: HTMLButtonElement;
private transparencySlider: HTMLInputElement;
private reset: HTMLDivElement;
private exportImage: HTMLDivElement;
private selectionCanvas: HTMLCanvasElement;
private myCanvas: HTMLCanvasElement;
private ctx;
private isDown = false;
constructor(image: Image, chart: Chart) {
this.image = image;
this.chart = chart;
//////////////////// Chart ///////////////////////////
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("mouseup", this.chartClick, false);
this.elementSelect = <HTMLSelectElement>document.getElementById(this.elementSelectID);
this.elementSelect.addEventListener("select", this.elementSelectEvent, false);
//////////////////// Image ///////////////////////////
this.selectionCanvas = <HTMLCanvasElement>document.getElementById(this.selectionCanvasID);
this.ctx = this.selectionCanvas.getContext("2d");
this.myCanvas = <HTMLCanvasElement>document.getElementById(this.myCanvasID);
this.saturationSlider = <HTMLInputElement>document.getElementById(this.saturationSliderID);
this.replotButton = <HTMLButtonElement>document.getElementById(this.replotButtonID);
this.transparencySlider = <HTMLInputElement>document.getElementById(this.transparencySliderID);
this.reset = <HTMLDivElement>document.getElementById(this.resetID);
this.exportImage = <HTMLDivElement>document.getElementById(this.exportImageID);
this.saturationSlider.addEventListener("mouseup", this.saturationSliderMouseUp, false);
this.replotButton.addEventListener("click", this.replotButtonClick, false);
this.transparencySlider.addEventListener("mouseup", this.trasparencySliderMouseUp, false);
this.reset.addEventListener("click", this.resetClick, false);
this.exportImage.addEventListener("click", this.exportImageClick, false);
this.selectionCanvas.addEventListener("mousedown", this.selectionCanvasMouseDown, false);
this.selectionCanvas.addEventListener("mouseup", this.clickdown, false);
this.selectionCanvas.addEventListener("mousemove", this.selectionCanvasMouseMove, false);
this.selectionCanvas.addEventListener("mouseup", this.selectionCanvasMouseUp, false);
this.selectionCanvas.addEventListener("mouseout", this.selectionCanvasMouseOut, false);
}
private saturationSliderMouseUp = (event: MouseEvent): void => {
this.image.drawImg(this.image.pixel1, this.image.pixel2, this.image.globalxMinRange, this.image.globalxMaxRange);
};
private replotButtonClick = (event: MouseEvent) => {
//bottone per colorare con il max relativo
this.image.rePrint = true;
this.saturationSlider.value = "100";
// opacity value?
this.image.drawImg(this.image.pixel1, this.image.pixel2, this.image.globalxMinRange, this.image.globalxMaxRange);
};
private trasparencySliderMouseUp = (event: MouseEvent) => {
this.image.drawImg(this.image.pixel1, this.image.pixel2, this.image.globalxMinRange, this.image.globalxMaxRange);
};
private resetClick = (event: MouseEvent) => {
this.image.newOrigin = { x: 0, y: 0 };
this.image.rePrint = false;
this.chart.calibrated = false;
this.image.globalxMinRange = 0;
this.image.globalxMaxRange = this.image.channelDepth;
this.saturationSlider.value = "100";
this.transparencySlider.value = "0";
this.chart.spinBoxMin.setAttribute("value", "-");
this.chart.spinBoxMax.setAttribute("value", "-");
this.image.drawImg({ x: 0, y: 0 }, { x: this.image.width - 1, y: this.image.height - 1 }, 0, this.image.channelDepth);
this.chart.drawChart(this.image, { x: 0, y: 0 }, { x: this.image.width - 1, y: this.image.height - 1 }, 0, this.image.channelDepth);
};
private exportImageClick = (event: MouseEvent) => {
//esportazione immagine
let img = this.selectionCanvas.toDataURL("image/png");
this.selectionCanvas.setAttribute("href", img.replace("image/png", "image/octet-stream"));
document.getElementById("ExportLink").setAttribute("href", img);
};
private clickdown = (event: MouseEvent): void => {
this.image.setPosition(event, this.image.zPixel2, this.selectionCanvasID);
let tmp: number;
if (this.image.zPixel1.y > this.image.zPixel2.y) {
tmp = this.image.zPixel1.y;
this.image.zPixel1.y = this.image.zPixel2.y;
this.image.zPixel2.y = tmp;
}
//se è stato cliccato un punto disegno il grafico, altrimenti disegno anche il
//canvas e aggiorno l'origine
if (this.image.zPixel1.x != this.image.zPixel2.x || this.image.zPixel1.y != this.image.zPixel2.y) {
this.image.newOrigin = { x: this.image.zPixel1.x, y: this.image.zPixel1.y };
this.image.drawImg(this.image.zPixel1, this.image.zPixel2, this.image.globalxMinRange, this.image.globalxMaxRange);
}
this.chart.drawChart(this.image, this.image.zPixel1, this.image.zPixel2, this.image.globalxMinRange, this.image.globalxMaxRange);
};
private selectionCanvasMouseDown = (event: MouseEvent) => {
event.preventDefault();
event.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 = event.clientX + scrollLEFT;
let allY: number = event.clientY + scrollTOP;
let elParent: any = this.myCanvas;
let objX: number = 0, objY: number = 0;
while (elParent) {
objX += elParent.offsetLeft;
objY += elParent.offsetTop;
elParent = elParent.offsetParent;
}
this.startX = allX - objX;
this.startY = allY - objY;
// set a flag indicating the drag has begun
this.isDown = true;
};
private selectionCanvasMouseUp = (event: MouseEvent) => {
event.preventDefault();
event.stopPropagation();
// the drag is over, clear the dragging flag
this.isDown = false;
//this.ctx.clearRect(0, 0, this.selectionCanvas.width, this.selectionCanvas.height);
};
private selectionCanvasMouseMove = (event: MouseEvent) => {
event.preventDefault();
event.stopPropagation();
// if we're not dragging, just return
if (!this.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 = event.clientX + scrollLEFT;
let allY: number = event.clientY + scrollTOP;
let elParent: any = this.myCanvas;
let objX: number = 0, objY: number = 0;
while (elParent) {
objX += elParent.offsetLeft;
objY += elParent.offsetTop;
elParent = elParent.offsetParent;
}
this.mouseX = allX - objX;
this.mouseY = allY - objY;
// clear the canvas
//this.ctx.clearRect(0, 0, this.selectionCanvas.width, this.selectionCanvas.height);
// calculate the rectangle width/height based
// on starting vs current mouse position
let width = this.mouseX - this.startX;
let height = this.mouseY - this.startY;
// draw a new rect from the start position
// to the current mouse position
this.ctx.fillRect(this.startX, this.startY, width, height);
};
private selectionCanvasMouseOut = (event: MouseEvent) => {
event.preventDefault();
event.stopPropagation();
// the drag is over, clear the dragging flag
this.isDown = false;
//this.ctx.clearRect(0, 0, this.selectionCanvas.width, this.selectionCanvas.height);
};
private setLinearButtonClick = (event: MouseEvent) => {
this.chart.graphic.updateOptions({ logscale: false });
};
private setLogButtonClick = (event: MouseEvent) => {
this.chart.graphic.updateOptions({ logscale: true });
};
private setEnergyButtonClick = (event: MouseEvent) => {
this.chart.calibrated = true;
this.chart.drawChart(this.image, this.image.pixel1, this.image.pixel2, 0, this.image.channelDepth);
this.spinBoxMin.setAttribute("value", "0");
this.spinBoxMax.setAttribute("value", this.image.channelDepth.toString());
};
private setChannelButtonClick = (event: MouseEvent) => {
this.chart.calibrated = false;
this.chart.drawChart(this.image, this.image.pixel1, this.image.pixel2, 0, this.image.channelDepth);
this.spinBoxMin.setAttribute("value", "-");
this.spinBoxMax.setAttribute("value", "-");
};
private exportGraphClick = (event: MouseEvent) => {
let img = <HTMLImageElement>document.getElementById("chartToImg");
//Dygraph..asPNG(this.chart.graphic, img);
this.exportgraph.setAttribute("href", img.src.replace("image/png", "image/octet-stream"));
};
private readSpinBoxClick = (event: MouseEvent) => {
//esportazione grafico
console.log("readspinbox");
this.chart.peackSelection(0, 0, this.image);
};
private chartClick = (event: MouseEvent) => {
//zoom manuale sul grafico
console.log("chartClick");
let r: number[];
r = this.chart.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] = Utility.round3(r[0]);
r[1] = Utility.round3(r[1]);
this.spinBoxMin.setAttribute("value", r[0].toString());
this.spinBoxMax.setAttribute("value", r[1].toString());
}
this.image.globalxMinRange = r[0];
this.image.globalxMaxRange = r[1];
this.image.drawImg(this.image.pixel1, this.image.pixel2, r[0], r[1]);
};
private elementSelectEvent = (event: MouseEvent) => {
//selezione elemento
let element: string = this.elementSelect.value;
switch (element) {
case "1": //Ca
this.chart.peackSelection(3.6, 3.8, this.image);
this.spinBoxMin.setAttribute("value", "3.60");
this.spinBoxMax.setAttribute("value", "3.80");
break;
case "2": //Pb
this.chart.peackSelection(10.4, 10.7, this.image);
this.spinBoxMin.setAttribute("value", "10.40");
this.spinBoxMax.setAttribute("value", "10.70");
break;
case "3": //Hg
this.chart.peackSelection(9.8, 10.15, this.image);
this.spinBoxMin.setAttribute("value", "9.80");
this.spinBoxMax.setAttribute("value", "10.15");
break;
case "4": //Fe
this.chart.peackSelection(6.3, 6.5, this.image);
this.spinBoxMin.setAttribute("value", "6.30");
this.spinBoxMax.setAttribute("value", "6.50");
break;
case "5": //Cu
this.chart.peackSelection(7.85, 8.2, this.image);
this.spinBoxMin.setAttribute("value", "7.85");
this.spinBoxMax.setAttribute("value", "8.20");
break;
case "6": //Zn
this.chart.peackSelection(8.5, 8.72, this.image);
this.spinBoxMin.setAttribute("value", "8.50");
this.spinBoxMax.setAttribute("value", "8.72");
break;
case "7": //Ti
this.chart.peackSelection(4.35, 4.65, this.image);
this.spinBoxMin.setAttribute("value", "4.35");
this.spinBoxMax.setAttribute("value", "4.65");
break;
case "8": //K
this.chart.peackSelection(3.2, 3.42, this.image);
this.spinBoxMin.setAttribute("value", "3.20");
this.spinBoxMax.setAttribute("value", "3.42");
break;
case "9": //Co
this.chart.peackSelection(6.8, 7.05, this.image);
this.spinBoxMin.setAttribute("value", "6.80");
this.spinBoxMax.setAttribute("value", "7.05");
break;
default:
this.chart.peackSelection(0, this.image.channelDepth, this.image);
this.spinBoxMin.setAttribute("value", "0");
this.spinBoxMax.setAttribute("value", this.image.channelDepth.toString());
break;
}
};
}
export { Events };
\ No newline at end of file
import G = require("./globals");
import * as gfs from "./fs";
import {Fs} from "./fs";
import * as fs from "fs";
import * as md5 from "ts-md5/dist/md5";
import { Image } from "./image";
import { Chart } from "./chart";
let content: Buffer;
let lines: string[];
let numbers: number[];
let image: Image = new Image();
let chart: Chart = new Chart();
let filesys: Fs = new Fs();
beforeAll(() =>
{
content = fs.readFileSync("XRF-File-System/Pergamena-Medioevale/codapavone_500.txt");
......@@ -16,7 +21,7 @@ beforeAll(() =>
test("get_metadata", () =>
{
let metadata = gfs.get_metadata(numbers);
let metadata = filesys.get_metadata(image, numbers);
expect(metadata).toEqual({
xMin: 50088000,
xMax: 50103000,
......@@ -29,14 +34,7 @@ test("get_metadata", () =>
test("readImage", () =>
{
let image = gfs.readImage(content.toString());
expect(md5.Md5.hashAsciiStr(JSON.stringify(image))).toBe("0a77bca5eb4c9bdd137c753a21b98545"); // coda_pavone_500
let readImage = filesys.readImage(image, chart, content.toString());
expect(md5.Md5.hashAsciiStr(JSON.stringify(readImage))).toBe("0a77bca5eb4c9bdd137c753a21b98545"); // coda_pavone_500
//expect(md5.Md5.hashAsciiStr(JSON.stringify(image))).toBe("b9e7fb96f36452cc3c2350d6132b50c6"); // coda_pavone_250
})
/* test("readImage_lc", () =>
{
let image = gfs.readImage_lc(content.toString());
console.log(md5.Md5.hashAsciiStr(JSON.stringify(image));
})
*/
This diff is collapsed.
export interface coordinates
{
x: number;
y: number;
}
export class Calibration
{
a: number;
b: number;
}
export enum ReadDirection {
u,// lettura non definita
r,//lettura per righe
c//lettura per colonne
}
export class Metadata
{
private static _instance: Metadata = new Metadata();
private constructor() {
if(Metadata._instance) {
throw new Error("Error: Image object is already instantiated");
}
else {
Metadata._instance = this;
}
}
xMin: number = 0;
xMax: number = 0;
yMin: number = 0;
yMax: number = 0;
step: number = 0;
direction: ReadDirection = ReadDirection.u;
public static getInstance(): Metadata {
return Metadata._instance;
}
}
export class Image
{
private static _instance: Image = new Image();
private constructor() {
if(Image._instance)
{
throw new Error ("Error: Image object is already instantiated");
}
else
{
Image._instance = this;
}
}
DataMatrix: number[][][];
width: number;
height: number;
readonly calibration: Calibration = {a: 3.36275, b: 58.2353};
readonly depth: number = 8000;
readonly maxCoordValueX = 60000000;
readonly headerSetValue = 17000;
readonly xCoordHeaderFirstValue = 5; //instestazione X
readonly yCoordHeaderFirstValue = 6; //intestazione y
channelDepth: number = require("./helper").round3(((this.depth + 1) * this.calibration.a - this.calibration.b) / 1000); //profondità massima in canali
globalxMinRange: number = 0;
globalxMaxRange: number = this.channelDepth;
zPixel1: coordinates;
zPixel2: coordinates; //pixel2 dello zoom
newOrigin: coordinates = { x: 0, y: 0}; //nuovo origine nel caso di zoom
maxAbsolute: number; //massimo conteggio della matrice nOfCounts
pixelDim: number; //dimensione dei pixel responsive
nOfCounts: number[][]; //matrici con i dati
rePrint: boolean = false; //variabile per ricolorare con il max relativo
public static getInstance(): Image
{
return Image._instance;
}
}
export class Chart {
private static _instance: Chart = new Chart();
private constructor()
{
if(Chart._instance)
{
throw new Error("Error: Image object is already instantiated");
}
else
{
Chart._instance = this;
}
}
dataCompleteChart: string = "Channel,Counts\n";
dataCompleteChartCalibrated: string = "Energy,Counts\n";
calibrated: boolean = false; //variabile per il controllo sulla calibrazione
public static getInstance(): Chart
{
return Chart._instance;
}
}
import * as Utility from "./utility";
interface coordinates // used in multiple files
{
x: number;
y: number;
}
class Calibration //used in multiple files
{
a: number;
b: number;
}
class Image {
private readonly saturationSliderID: string = "SaturationSlider";
private readonly transparencySliderID: string = "TrasparencySlider";
private readonly selectionCanvasID: string = "selectionCanvas";
private readonly myCanvasID: string = "myCanvas";
private context: CanvasRenderingContext2D;
private saturationSlider: HTMLInputElement;
private transparencySlider: HTMLInputElement;
pixel1: coordinates;
pixel2: coordinates;
private xMinRange: number;
private xMaxRange: number;
private selectionCanvas: HTMLCanvasElement;
private myCanvas: HTMLCanvasElement;
private ctx;
private isDown = false;
DataMatrix: number[][][];
width: number;
height: number;
readonly calibration: Calibration = { a: 3.36275, b: 58.2353 };
readonly depth: number = 8000;
channelDepth: number = Utility.round3(((this.depth + 1) * this.calibration.a - this.calibration.b) / 1000); //profondità massima in canali
readonly maxCoordValueX = 60000000; // to check
readonly headerSetValue = 17000;
readonly xCoordHeaderFirstValue = 5; //instestazione X
readonly yCoordHeaderFirstValue = 6; //intestazione y
globalxMinRange: number = 0;
globalxMaxRange: number = this.channelDepth;
zPixel1: coordinates;
zPixel2: coordinates; //pixel2 dello zoom
newOrigin: coordinates = { x: 0, y: 0 }; //nuovo origine nel caso di zoomù
maxAbsolute: number; //massimo conteggio della matrice nOfCounts
pixelDim: number; //dimensione dei pixel responsive
nOfCounts: number[][]; //matrici con i dati
rePrint: boolean = false; //variabile per ricolorare con il max relativo
constructor() {
this.selectionCanvas = <HTMLCanvasElement>document.getElementById(this.selectionCanvasID);
this.ctx = this.selectionCanvas.getContext("2d");
this.myCanvas = <HTMLCanvasElement>document.getElementById(this.myCanvasID);
this.saturationSlider = <HTMLInputElement>document.getElementById(this.saturationSliderID);
this.transparencySlider = <HTMLInputElement>document.getElementById(this.transparencySliderID);
}
//Il metodo findPosition definisce la posizione del cursore del mouse
//relativa al canvas nel momento in cui avviene l'evento passato in input
setPosition(event: any, pixel: coordinates, canvasID: string) {
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 = event.clientX + scrollLEFT;
let allY: number = event.clientY + scrollTOP;
let elParent: any = document.getElementById(canvasID);
let objX: number = 0,
objY: number = 0;
while (elParent) {
objX += elParent.offsetLeft;
objY += elParent.offsetTop;
elParent = elParent.offsetParent;
}
pixel.x = Math.floor((allX - objX - 1) / this.pixelDim) + this.newOrigin.x;
pixel.y = Math.floor((allY - objY - 1) / this.pixelDim) + this.newOrigin.y;
}
drawImg(pixel1: coordinates, pixel2: coordinates, xMinRange: number, xMaxRange: number, callback?: () => void) {
this.pixel1 = pixel1;
this.pixel2 = pixel2;
//alert("disegno in corso");
//numero di pixel per dimensione
let nPixelX: number = this.pixel2.x - this.pixel1.x + 1;
let nPixelY: number = this.pixel2.y - this.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);
this.pixelDim = dimPixelx < dimPixely ? dimPixelx : dimPixely;
//dimensioni esatte dei canvas
this.myCanvas.height = nPixelY * this.pixelDim;
this.myCanvas.width = nPixelX * this.pixelDim;
this.selectionCanvas.height = nPixelY * this.pixelDim;
this.selectionCanvas.width = nPixelX * this.pixelDim;
let ctx = this.myCanvas.getContext("2d"); //contesto del canvas
if (xMaxRange - xMinRange >= this.channelDepth) {
//range completo
let max: number = 0; //massimo relativo o assoluto
if (this.rePrint) {
max = Utility.findMax(this.nOfCounts, this.pixel1, this.pixel2);
} else {
max = this.maxAbsolute;
}
max *= parseInt(this.saturationSlider.value) / 100;
this.drawCanvas(this.nOfCounts, max);
} else {
//range parziale (solo alcuni canali)
let xMinRangeCh: number = Math.floor((xMinRange * 1000 + this.calibration.b) / this.calibration.a - 1); //16
let xMaxRangeCh: number = Math.floor((xMaxRange * 1000 + this.calibration.b) / this.calibration.a - 1); //16371
//calcolo il numero di conteggi solo dei canali selezionati
let nOfCountsRelative: number[][];
nOfCountsRelative = new Array(this.width);
for (let i: number = 0; i < this.width; i++) {
nOfCountsRelative[i] = new Array(this.height);
for (let j: number = 0; j < this.height; j++) {
nOfCountsRelative[i][j] = Utility.sumVect(this.DataMatrix[i][j], xMinRangeCh, xMaxRangeCh);
}
}
//calcolo il massimo
let max: number = 0;
if (this.rePrint) {
max = Utility.findMax(nOfCountsRelative, this.pixel1, this.pixel2);
} else {
max = Utility.findMax(nOfCountsRelative, { x: 0, y: 0 }, { x: this.width - 1, y: this.height - 1 });
}
max *= parseInt(this.saturationSlider.value) / 100;
if (max == 0)
alert("WARNING: max value is 0");
else
this.drawCanvas(nOfCountsRelative, max);
}
if (typeof (callback) != typeof (undefined))
callback();
}
private drawCanvas(noc, max) {
//controllo il valore della trasparenza
let setTrsp: number = 1 - parseInt(this.transparencySlider.value) / 100;
//scorro tutti i pixel: ne determino il colore e li disegno
let color: string = "";
for (let i: number = this.pixel1.x; i <= this.pixel2.x; i++) {
for (let j: number = this.pixel1.y; j <= this.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 + ")";
//rosso -verde
else
color = "rgba(255," + (255 - Math.floor((intensity - 4 / 5) * 5 * 255)) + ", 0, " + setTrsp + ")";
this.ctx.fillStyle = color;
this.ctx.fillRect((i - this.pixel1.x) * this.pixelDim, (j - this.pixel1.y) * this.pixelDim, this.pixelDim, this.pixelDim);
}
}
//console.log(color);
this.rePrint = false; //annullo rePrint
this.ctx.fillStyle = "rgba(0, 110, 255, 0.25)";
this.isDown = false;
}
}
export { coordinates, Calibration, Image };
import { Image } from "./image";
import { Chart } from "./chart";
import { Fs } from "./fs";
import { CallbackManager } from "./callbacks"
import $ = require("jquery");
class ImportFile {
private image: Image;
private chart: Chart;
private fs: Fs;
private callbackManager: CallbackManager;
constructor(drawImage: Image, drawChart: Chart) {
this.image = drawImage;
this.chart = drawChart;
this.fs = new Fs();
this.callbackManager = new CallbackManager();
}
//funzione che definisce tutti gli elementi responsabili dell'apertura di un file.
//Sono definiti quindi l'albero e il bottone per l'importazione da locale
setImportFile() {
// genero e leggo il contenuto della directory "filesystem"
// comment out waiting to properly address the request
// let xmlDoc: Document;
// let xmlListingFile: any = new XMLHttpRequest();
// xmlListingFile.open("PROPFIND", "CHNET/", false);
// xmlListingFile.setRequestHeader("Depth", "infinity");
// xmlListingFile.onreadystatechange = function () {
// if (xmlListingFile.readyState === 4) {
// if (xmlListingFile.status === 207) {
// let parser = new DOMParser();
// xmlDoc = parser.parseFromString(xmlListingFile.responseText, "text/xml");
// }
// }
// }
// xmlListingFile.send(null);
//ora genero l'albero e definisco l'evento in caso di selezione di un nodo
// jQuery(document.getElementById('FileTreeview')).treeview({ data: this.fs.generateTree(xmlDoc) });
// $('#FileTreeview').on('nodeSelected', (e, node) => {
// if (node['url'] != undefined) {
// $("#load-spinner").css("display", "inline");
// this.fs.openFileFromServer(node['url']);
// }
// });
// import a local file
let fileInputButton: any = document.getElementById("myImport");
fileInputButton.onchange = () => {
this.callbackManager.showElement("load-spinner", true);
let file: File = fileInputButton.files[0];
let readerObject = new FileReader();
readerObject.onload = () => {
let content = readerObject.result;
let image = this.fs.readImage(this.image, this.chart, content);
this.callbackManager.showElement("load-spinner", false);
this.image.drawImg({ x: 0, y: 0 }, { x: image.width - 1, y: image.height - 1 }, 0, image.channelDepth,
() => { this.callbackManager.closeBootstrapModel("btnCloseModal"); });
this.chart.drawChart(image, { x: 0, y: 0 }, { x: image.width - 1, y: image.height - 1 }, 0, image.channelDepth);
};
readerObject.readAsText(file);
};
}
//funzione per la compressione della sidenav sx
compressingSidenav() {
let fsLabel = document.getElementById("collapse-symbol");
let isClosedfs = false;
let fsLabel_cross = () => {
if (isClosedfs == true) {
isClosedfs = false;
console.log("closed");
$(".w3-bar-block").css("width", "65px");
$(".text-sidenav").css("display", "none");
document.getElementById("collapse-symbol").title = "Open Sidebar";
document.getElementById("collapse-symbol").classList.replace("fa-angle-double-left", "fa-angle-double-right");
} else {
isClosedfs = true;
$(".w3-bar-block").css("width", "200px");
$(".text-sidenav").css("display", "inline");
document.getElementById("collapse-symbol").title = "Close Sidebar";
document.getElementById("collapse-symbol").classList.replace("fa-angle-double-right", "fa-angle-double-left");
}
};
fsLabel.addEventListener("mousedown", fsLabel_cross, false);
}
//funzione che definisce l'area su cui si può eseguire il drag&drop
makeDroppable(droppableArea) {
//creo l'elemento "input type file" non visibile e lo aggiungo a "droppableArea"
let input: any = document.createElement("input");
input.type = "file";
input.multiple = true;
input.style.display = "none";
droppableArea.appendChild(input);
//questo evento è chiamato quando i file sono trascinati ma non ancora lasciati
droppableArea.addEventListener("dragover", function (e) {
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
droppableArea.addEventListener("dragleave", function (e) {
e.preventDefault();
e.stopPropagation();
droppableArea.classList.remove("dragover");
});
//questo evento si innesca quando il drop è effettivamente avvenuto
droppableArea.addEventListener("drop", function (e) {
e.preventDefault();
e.stopPropagation();
droppableArea.classList.remove("dragover");
this.callback(e.dataTransfer.files, this.image, this.chart);
});
}
//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()
private callback(files, drawImage: Image, drawChart: Chart, fs: Fs) {
this.callbackManager.showElement("load-spinner", true);
let file: File = files[files.length - 1];
console.log("Try to open " + file.name + " ...");
let readerObject = new FileReader();
readerObject.onload = () => {
let content = readerObject.result;
fs.readImage(drawImage, drawChart, content);
this.callbackManager.showElement("load-spinner", false);
};
readerObject.readAsText(file);
}
}
export { ImportFile };
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!--Compatibilita' con Microsoft e Responsivita'-->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>XRF analysis viewer</title>
<!-- CSS -->
<link href="src/css/bootstrap.min.css" rel="stylesheet" media="screen">
<link rel="stylesheet" type="text/css" href="style.css">
<link rel="stylesheet" type="text/css" href="src/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="src/bootstrap-treeview/dist/bootstrap-treeview.min.css">
<link rel="stylesheet" type="text/css" href="src/bootstrap-select/dist/bootstrap-select.min.css">
<link rel="stylesheet" type="text/css" href="src/font-awesome/dist/font-awesome.min.css">
<!-- Librerie -->
<script type="text/javascript" src="src/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="src/js/bootstrap.min.js"></script>
<!-- <script type="text/javascript" src="node_modules/bootstrap/js/dist/tooltip.js"></script> -->
<script type="text/javascript" src="src/bootstrap-treeview/dist/bootstrap-treeview.min.js"></script>
<script type="text/javascript" src="src/bootstrap-select/dist/bootstrap-select.min.js"></script>
<script type="text/javascript" src="node_modules/dygraphs/dist/dygraph.min.js"></script>
<!-- <script type="text/javascript" src="src/dygraph/dist/dygraph-combined-dev.js"></script>
<script type="text/javascript" src="src/dygraph/dist/dygraph-extra.js"></script> -->
<script type="text/javascript" src="xrf.js"></script>
<!-- ./Librerie -->
</head>
<body>
<!-- Spinner -->
<div align="center">
<div id="load-spinner" style="display:none">
<i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i>
<span class="sr-only">Loading...</span>
</div>
</div>
<!-- /.spinner -->
<!-- Navbar -->
<nav class="navbar navbar-fixed-top bg-primary">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/presentation/XRF-App/">
<img id="logo-chnet" src="Logo-chnet.png" width="35" height="35" alt="" class="img-rounded">
<div id="testo-logo-chnet">XRF Analysis Viewer</div>
</a>
</div>
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<!-- <?php
$pic=$_SERVER["OIDC_CLAIM_picture"];
if (filter_var($pic, FILTER_VALIDATE_URL))
{
echo "<img src=\"$pic\" class=\"img-circle\" width=\"25\">";
} else {
echo "<img src=\"./default-avatar.png\" class=\"img-circle\" width=\"25\">";
}
// echo " ".ucfirst($_SERVER["OIDC_CLAIM_name"]);
?> -->
<span class="glyphicon glyphicon-chevron-down"></span>
</a>
<ul class="dropdown-menu">
<li>
<!-- <?php
echo "<div class=\"usrname\">".ucfirst($_SERVER["OIDC_CLAIM_name"])."</div>";
echo "<i class=\"usrmail\">".ucfirst($_SERVER["OIDC_CLAIM_email"])."</i>";
?> -->
</li>
<li class="divider"></li>
<li class="usr-menu"><a href="https://chnet-iam.cloud.cnaf.infn.it/dashboard#/home">Profile</a></li>
<li class="usr-menu"><a href="/presentation/.redirect/?logout=http%3A%2F%2Fchnet.infn.it%2F">Sign out</a></li>
</ul>
</li>
</ul>
</div>
</nav>
<!-- ./navbar -->
<!-- Sidenav -->
<div class="w3-bar-block w3-border" id="sidenav">
<div class="w3-bar-item w3-button">
<a href="">
<i class="fa fa-home" data-toggle="tooltip" data-placement="right" title="Home"></i>
<span class="text-sidenav" style="display:none">Home</span>
</a>
</div>
<div class="w3-bar-item w3-button" data-toggle="modal" data-target="#myModal">
<i class="fa fa-folder-o" data-toggle="tooltip" data-placement="right" title="Open File"></i>
<span class="text-sidenav" style="display:none">Open file</span>
</div>
<div class="w3-bar-item w3-button" data-toggle="collapse" data-target=".collapse-settings">
<i class="fa fa-cog" data-toggle="tooltip" data-placement="right" title="Settings"></i>
<span class="text-sidenav" style="display:none">Settings</span>
</div>
<div class="w3-bar-item w3-button" id="reset">
<i class="fa fa-refresh" data-toggle="tooltip" data-placement="right" title="Reset"></i>
<span class="text-sidenav" style="display:none">Refresh</span>
</div>
<div class="w3-bar-item w3-button">
<a id="ExportLink" download="Canvas.png" href="#" class="w3-bar-item w3-button">
<div id="ExportImage">
<i class="fa fa-file-image-o" data-toggle="tooltip" data-placement="right" title="Export Map"></i>
<span class="text-sidenav" style="display:none">Export Map</span>
</div>
</a>
</div>
<div class="w3-bar-item w3-button">
<a href="#" id="ExportGraph" download="Spectrum.png" class="w3-bar-item w3-button">
<i class="fa fa-bar-chart" data-toggle="tooltip" data-placement="right" title="Export Chart"></i>
<span class="text-sidenav" style="display:none">Export Chart</span>
</a>
</div>
<div class="w3-bar-item w3-button collapse-sidebar-manually sidebar-label">
<i id="collapse-symbol" class="fa fa-angle-double-right" data-toggle="tooltip" data-placement="right" title="Open Sidebar"></i>
<span class="text-sidenav" style="display:none">Collapse sidebar</span>
</div>
</div>
<!-- ./sidenav -->
<!-- Modal -->
<div id="myModal" class="modal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content" id="importPanel">
<div class="modal-header">
<button id="btnCloseModal" type="button" class="close" data-dismiss="modal">&times;</button>
<h3 class="modal-title">Import File</h3>
</div>
<div class="modal-body">
<h4>Select file from server</h4>
<div id="FileTreeview"></div>
Import File From Local Repository
<label class="btn-bs-file btn btn-primary btn-sm">
<span class="glyphicon glyphicon-open"></span> Choose a file...
<input id="myImport" type="file" / >
</label>
</div>
</div>
</div>
</div>
<!-- ./modal -->
<!-- COLLAPSABLE PAGE -->
<div class="container-fluid droppable" id="myContent" dropzone="copy f:text/plain">
<!-- PAGE CONTENT -->
<div class="row">
<!-- MAPPA -->
<div class="col-sm-4">
<div class="well" id="mappa-pannel">
<h2>XRF Image</h2>
<!-- canvas -->
<div style="position: relative; height: 400px;">
<canvas id="selectionCanvas" height="400px" width="360px"></canvas>
<canvas id="myCanvas" height="400px" width="360px"></canvas>
</div>
<!-- ./canvas -->
<div class="collapse collapse-settings" align="center">
<div class="panel panel-default">
<div class="panel-body">
Saturation<input type="range" id="SaturationSlider" value="100">
</div>
</div>
<div class="panel panel-default">
<div class="panel-body">
Opacity<input type="range" id="TrasparencySlider" value="0">
</div>
</div>
<button type="button" class="btn btn-primary btn-sm" id="rePlot">Re-color</button>
</div>
</div>
<!-- ./ pannello-mappa -->
</div>
<!-- ./mappa -->
<!-- SPETTRO -->
<div class="col-md-8">
<div class="well" id="chart-pannel">
<h2>XRF Spectrum</h2>
<!-- grafico -->
<p id="chart" class="p-chart"></p>
<img id="chartToImg" style="display:none;">
<!-- impostazioni -->
<p><div class="collapse collapse-settings" align="center">
<!-- Asse y -->
<div class="btn-group">
<button type="button" class="btn dropdown-toggle btn-primary btn-sm" data-toggle="dropdown">Scale <span class="caret"></span></button>
<ul class="dropdown-menu" role="menu">
<li><a href="#" id="setlinearButton">Linear</a></li>
<li><a href="#" id="setlogButton">Log</a></li>
</ul>
</div>
<!-- Asse x -->
<div class="btn-group">
<button type="button" class="btn dropdown-toggle btn-primary btn-sm" data-toggle="dropdown">x Label <span class="caret"></span></button>
<ul class="dropdown-menu" role="menu">
<li><a href="#" id="setEnergyButton">Energy</a></li>
<li><a href="#" id="setChannelsButton">Channels</a></li>
</ul>
</div>
<!-- Selezione picco -->
<div class="btn-group">
<div class="form-group" id="myform">
<label for="spinBoxMin"><h6>Peak selection (only calibrated)</h6></label>
<p><input type="number" class="form-control" id="spinBoxMin" min="0" max="55" step="0.01">
<input type="number" class="form-control" id="spinBoxMax" min="0" max="55" step="0.01"></p>
<div align="center">
<button id="readSpinbox" class="btn btn-primary btn-sm" style="margin-left: -25px;">Select range</button>
</div>
</div>
</div>
<!-- Selezione elemento -->
<select class="form-control selectpicker" data-style="btn-primary btn-sm" data-width="25%" data-live-search="true" id="elementSelect">
<option value="0">- inspect element -</option>
<option value="1">Ca</option>
<option value="2">Pb</option>
<option value="3">Hg</option>
<option value="4">Fe</option>
<option value="5">Cu</option>
<option value="6">Zn</option>
<option value="7">Ti</option>
<option value="8">K</option>
<option value="9">Co</option>
</select>
</div></p>
<!-- ./impostazioni -->
</div>
<!-- ./pannello-spettro -->
</div>
<!-- ./colonna-spettro -->
</div>
<!-- ./riga 1 -->
</div>
<!-- /.collapsable-page -->
</body>
</html>
<!DOCTYPE html>
<html>
<head>
......@@ -10,23 +9,17 @@
<title>XRF analysis viewer</title>
<!-- CSS -->
<link href="src/css/bootstrap.min.css" rel="stylesheet" media="screen">
<link rel="stylesheet" type="text/css" href="style.css">
<link rel="stylesheet" type="text/css" href="src/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="src/bootstrap-treeview/dist/bootstrap-treeview.min.css">
<link rel="stylesheet" type="text/css" href="src/bootstrap-select/dist/bootstrap-select.min.css">
<link rel="stylesheet" type="text/css" href="src/font-awesome/dist/font-awesome.min.css">
<!-- Librerie -->
<script type="text/javascript" src="src/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="src/js/bootstrap.min.js"></script>
<!-- <script type="text/javascript" src="node_modules/bootstrap/js/dist/tooltip.js"></script> -->
<script type="text/javascript" src="src/bootstrap-treeview/dist/bootstrap-treeview.min.js"></script>
<script type="text/javascript" src="src/bootstrap-select/dist/bootstrap-select.min.js"></script>
<script type="text/javascript" src="node_modules/dygraphs/dist/dygraph.min.js"></script>
<!-- <script type="text/javascript" src="src/dygraph/dist/dygraph-combined-dev.js"></script>
<script type="text/javascript" src="src/dygraph/dist/dygraph-extra.js"></script> -->
<script type="text/javascript" src="xrf.js"></script>
<!-- CSS -->
<link rel="stylesheet" type="text/css" href="style.css">
<link rel="stylesheet" type="text/css" href="node_modules/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="node_modules/bootstrap-select/dist/css/bootstrap-select.min.css">
<link rel="stylesheet" type="text/css" href="src/font-awesome/dist/font-awesome.min.css">
<!-- Librerie -->
<script type="text/javascript" src="node_modules/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<script type="text/javascript" src="node_modules/dygraphs/dist/dygraph.min.js"></script>
<script type="text/javascript" src="xrf.js"></script>
<!-- ./Librerie -->
</head>
......@@ -61,7 +54,7 @@
} else {
echo "<img src=\"./default-avatar.png\" class=\"img-circle\" width=\"25\">";
}
// echo " ".ucfirst($_SERVER["OIDC_CLAIM_name"]);
//echo " ".ucfirst($_SERVER["OIDC_CLAIM_name"]);
?>
<span class="glyphicon glyphicon-chevron-down"></span>
</a>
......@@ -83,7 +76,7 @@
<!-- ./navbar -->
<!-- Sidenav -->
<div class="w3-bar-block w3-border">
<div class="w3-bar-block w3-border" id="sidenav">
<div class="w3-bar-item w3-button">
<a href="">
<i class="fa fa-home" data-toggle="tooltip" data-placement="right" title="Home"></i>
......@@ -160,7 +153,7 @@
<h2>XRF Image</h2>
<!-- canvas -->
<div style="position: relative; height=400px;">
<div style="position: relative; height: 400px;">
<canvas id="selectionCanvas" height="400px" width="360px"></canvas>
<canvas id="myCanvas" height="400px" width="360px"></canvas>
</div>
......
This diff is collapsed.
{
"name": "chnet-xrf",
"version": "0.1.0",
"scripts": {
"test": "jest"
},
"dependencies": {
"assert": "latest",
"bootstrap": "latest",
"bootstrap": "v3.3.7",
"bootstrap-select": "^1.12.4",
"bootstrap-slider": "^10.0.0",
"bootstrap-tooltip": "^3.1.1",
"bootstrap-treeview": "^1.2.0",
"bower": "^1.8.4",
"dygraphs": "^2.0.0",
"jquery": "^3.3.1",
"popper": "^1.0.1",
"popper.js": "^1.14.3"
"jquery": "^3.3.1"
},
"description": "Web application to analyse XRF images",
"scripts": {
"test": "jest"
},
"license": "EUPL",
"repository": {
"type": "git",
"url": "https://baltig.infn.it/chnet/XRF-App.git"
},
"devDependencies": {
"@types/dygraphs": "^1.1.8",
"@types/jest": "^21.1.6",
"@types/node": "^8.0.51",
"@types/jquery": "^3.3.4",
"@types/node": "^8.10.18",
"jest": "^21.2.1",
"ts-jest": "^21.2.2",
"ts-md5": "^1.2.2",
"ts-node": "^6.0.3",
"typescript": "^2.6.1"
"ts-node": "^6.1.0",
"typescript": "^2.9.1"
},
"jest": {
"testEnvironment": "node",
......
/*!
* Bootstrap-select v1.12.4 (http://silviomoreto.github.io/bootstrap-select)
*
* Copyright 2013-2017 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
*/select.bs-select-hidden,select.selectpicker{display:none!important}.bootstrap-select{width:220px\9}.bootstrap-select>.dropdown-toggle{width:100%;padding-right:25px;z-index:1}.bootstrap-select>.dropdown-toggle.bs-placeholder,.bootstrap-select>.dropdown-toggle.bs-placeholder:active,.bootstrap-select>.dropdown-toggle.bs-placeholder:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder:hover{color:#999}.bootstrap-select>select{position:absolute!important;bottom:0;left:50%;display:block!important;width:.5px!important;height:100%!important;padding:0!important;opacity:0!important;border:none}.bootstrap-select>select.mobile-device{top:0;left:0;display:block!important;width:100%!important;z-index:2}.error .bootstrap-select .dropdown-toggle,.has-error .bootstrap-select .dropdown-toggle{border-color:#b94a48}.bootstrap-select.fit-width{width:auto!important}.bootstrap-select:not([class*=col-]):not([class*=form-control]):not(.input-group-btn){width:220px}.bootstrap-select .dropdown-toggle:focus{outline:thin dotted #333!important;outline:5px auto -webkit-focus-ring-color!important;outline-offset:-2px}.bootstrap-select.form-control{margin-bottom:0;padding:0;border:none}.bootstrap-select.form-control:not([class*=col-]){width:100%}.bootstrap-select.form-control.input-group-btn{z-index:auto}.bootstrap-select.form-control.input-group-btn:not(:first-child):not(:last-child)>.btn{border-radius:0}.bootstrap-select.btn-group:not(.input-group-btn),.bootstrap-select.btn-group[class*=col-]{float:none;display:inline-block;margin-left:0}.bootstrap-select.btn-group.dropdown-menu-right,.bootstrap-select.btn-group[class*=col-].dropdown-menu-right,.row .bootstrap-select.btn-group[class*=col-].dropdown-menu-right{float:right}.form-group .bootstrap-select.btn-group,.form-horizontal .bootstrap-select.btn-group,.form-inline .bootstrap-select.btn-group{margin-bottom:0}.form-group-lg .bootstrap-select.btn-group.form-control,.form-group-sm .bootstrap-select.btn-group.form-control{padding:0}.form-group-lg .bootstrap-select.btn-group.form-control .dropdown-toggle,.form-group-sm .bootstrap-select.btn-group.form-control .dropdown-toggle{height:100%;font-size:inherit;line-height:inherit;border-radius:inherit}.form-inline .bootstrap-select.btn-group .form-control{width:100%}.bootstrap-select.btn-group.disabled,.bootstrap-select.btn-group>.disabled{cursor:not-allowed}.bootstrap-select.btn-group.disabled:focus,.bootstrap-select.btn-group>.disabled:focus{outline:0!important}.bootstrap-select.btn-group.bs-container{position:absolute;height:0!important;padding:0!important}.bootstrap-select.btn-group.bs-container .dropdown-menu{z-index:1060}.bootstrap-select.btn-group .dropdown-toggle .filter-option{display:inline-block;overflow:hidden;width:100%;text-align:left}.bootstrap-select.btn-group .dropdown-toggle .caret{position:absolute;top:50%;right:12px;margin-top:-2px;vertical-align:middle}.bootstrap-select.btn-group[class*=col-] .dropdown-toggle{width:100%}.bootstrap-select.btn-group .dropdown-menu{min-width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-select.btn-group .dropdown-menu.inner{position:static;float:none;border:0;padding:0;margin:0;border-radius:0;-webkit-box-shadow:none;box-shadow:none}.bootstrap-select.btn-group .dropdown-menu li{position:relative}.bootstrap-select.btn-group .dropdown-menu li.active small{color:#fff}.bootstrap-select.btn-group .dropdown-menu li.disabled a{cursor:not-allowed}.bootstrap-select.btn-group .dropdown-menu li a{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.bootstrap-select.btn-group .dropdown-menu li a.opt{position:relative;padding-left:2.25em}.bootstrap-select.btn-group .dropdown-menu li a span.check-mark{display:none}.bootstrap-select.btn-group .dropdown-menu li a span.text{display:inline-block}.bootstrap-select.btn-group .dropdown-menu li small{padding-left:.5em}.bootstrap-select.btn-group .dropdown-menu .notify{position:absolute;bottom:5px;width:96%;margin:0 2%;min-height:26px;padding:3px 5px;background:#f5f5f5;border:1px solid #e3e3e3;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05);pointer-events:none;opacity:.9;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-select.btn-group .no-results{padding:3px;background:#f5f5f5;margin:0 5px;white-space:nowrap}.bootstrap-select.btn-group.fit-width .dropdown-toggle .filter-option{position:static}.bootstrap-select.btn-group.fit-width .dropdown-toggle .caret{position:static;top:auto;margin-top:-1px}.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a span.check-mark{position:absolute;display:inline-block;right:15px;margin-top:5px}.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text{margin-right:34px}.bootstrap-select.show-menu-arrow.open>.dropdown-toggle{z-index:1061}.bootstrap-select.show-menu-arrow .dropdown-toggle:before{content:'';border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid rgba(204,204,204,.2);position:absolute;bottom:-4px;left:9px;display:none}.bootstrap-select.show-menu-arrow .dropdown-toggle:after{content:'';border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;bottom:-4px;left:10px;display:none}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:before{bottom:auto;top:-3px;border-top:7px solid rgba(204,204,204,.2);border-bottom:0}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after{bottom:auto;top:-3px;border-top:6px solid #fff;border-bottom:0}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before{right:12px;left:auto}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:after{right:13px;left:auto}.bootstrap-select.show-menu-arrow.open>.dropdown-toggle:after,.bootstrap-select.show-menu-arrow.open>.dropdown-toggle:before{display:block}.bs-actionsbox,.bs-donebutton,.bs-searchbox{padding:4px 8px}.bs-actionsbox{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bs-actionsbox .btn-group button{width:50%}.bs-donebutton{float:left;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bs-donebutton .btn-group button{width:100%}.bs-searchbox+.bs-actionsbox{padding:0 8px 4px}.bs-searchbox .form-control{margin-bottom:0;width:100%;float:none}
\ No newline at end of file
This diff is collapsed.