Skip to content
Snippets Groups Projects
drawImage.ts 13.8 KiB
Newer Older
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;
Fabio Proietti's avatar
Fabio Proietti committed
  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;
Fabio Proietti's avatar
Fabio Proietti committed
  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");

Fabio Proietti's avatar
Fabio Proietti committed
    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);
Fabio Proietti's avatar
Fabio Proietti committed
    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 => {
Fabio Proietti's avatar
Fabio Proietti committed
    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";
Fabio Proietti's avatar
Fabio Proietti committed
    // opacity value?
    this.drawImg(this._image, this._pixel1, this._pixel2, this._image.globalxMinRange, this._image.globalxMaxRange);
  };

  private trasparencySliderMouseUp = (event: MouseEvent) => {
Fabio Proietti's avatar
Fabio Proietti committed
    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;
Fabio Proietti's avatar
Fabio Proietti committed
    this._saturationSlider.value = "100";
    this._transparencySlider.value = "0";
    document.getElementById("spinBoxMin").setAttribute("value", "-");
    document.getElementById("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
Fabio Proietti's avatar
Fabio Proietti committed

    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
    //alert(this._image.zPixel1.x + ", " + this._image.zPixel1.y + " - " + this._image.zPixel2.x + ", " + this._image.zPixel2.y);
    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;
Fabio Proietti's avatar
Fabio Proietti committed
    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;
Fabio Proietti's avatar
Fabio Proietti committed
    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;

    // Put your mousemove stuff here

    // 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
Fabio Proietti's avatar
Fabio Proietti committed
    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;
      }
Fabio Proietti's avatar
Fabio Proietti committed
      
      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
Fabio Proietti's avatar
Fabio Proietti committed
      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 });
      }
Fabio Proietti's avatar
Fabio Proietti committed
      max *= parseInt(this._saturationSlider.value) / 100;
      
      this.drawCanvas(image, nOfCountsRelative, max);
    }

    if (typeof (callback) != typeof (undefined))
      callback();
  }
  private drawCanvas(image: G.Image, noc, max) {
    //controllo il valore della trasparenza
Fabio Proietti's avatar
Fabio Proietti committed
    
    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;