Skip to content
Snippets Groups Projects
drawChart.ts 12.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • import { DrawImage } from "./drawImage";
    import G = require("./globals");
    import Help = require("./helper");
    
    Fabio Proietti's avatar
    Fabio Proietti committed
    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
    
    Fabio Proietti's avatar
    Fabio Proietti committed
        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
    
    Fabio Proietti's avatar
    Fabio Proietti committed
        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;
    
    Fabio Proietti's avatar
    Fabio Proietti committed
        this._chartElement.setAttribute("width", chartWidth.toString());
        this._chartElement.setAttribute("height", "400");
    
    Fabio Proietti's avatar
    Fabio Proietti committed
        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);
      }
    }