Skip to content
Snippets Groups Projects
drawImage.ts 7.64 KiB
Newer Older
import G = require("./globals");
import * as $ from "jquery";
import * as Help from "./helper";
import { DrawChart } from "./drawChart";

export interface coordinates // used in multiple files
{
  x: number;
  y: number;
}

export class Calibration //used in multiple files
{
  a: number;
  b: number;
}
export class DrawImage {

  private readonly _saturationSliderID: string = "SaturationSlider";
  private readonly _transparencySliderID: string = "TrasparencySlider";
  private readonly _selectionCanvasID: string = "selectionCanvas";
Fabio Proietti's avatar
Fabio Proietti committed
  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;
Fabio Proietti's avatar
Fabio Proietti committed
  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 = Help.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;
Fabio Proietti's avatar
Fabio Proietti committed
    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 = Help.findMax(this.nOfCounts, this._pixel1, this._pixel2);
        max = this.maxAbsolute;
Fabio Proietti's avatar
Fabio Proietti committed
      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] = Help.sumVect(this.DataMatrix[i][j], xMinRangeCh, xMaxRangeCh);
Fabio Proietti's avatar
Fabio Proietti committed
      let max: number = 0;
      if (this.rePrint) {
        max = Help.findMax(nOfCountsRelative, this._pixel1, this._pixel2);
      } else {
        max = Help.findMax(nOfCountsRelative, { x: 0, y: 0 }, { x: this.width - 1, y: this.height - 1 });
Fabio Proietti's avatar
Fabio Proietti committed
      max *= parseInt(this._saturationSlider.value) / 100;
        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
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) * this.pixelDim, (j - this._pixel1.y) * this.pixelDim, this.pixelDim, this.pixelDim);
    this.rePrint = false; //annullo rePrint
    this._ctx.fillStyle = "rgba(0, 110, 255, 0.25)";

    this._isDown = false;