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