unageanu/jiji2

View on GitHub
sites/src/js/view/components/chart/positions-view.js

Summary

Maintainability
C
1 day
Test Coverage

import CreateJS               from "easeljs"
import AbstractChartComponent from "./abstract-chart-component"
import CoordinateCalculator   from "../../../viewmodel/chart/coordinate-calculator"

const padding = CoordinateCalculator.padding();

export default class PositionsView extends AbstractChartComponent {

  constructor( chartModel, slidableMask, devicePixelRatio ) {
    super(chartModel, devicePixelRatio);
    this.initSprite(slidableMask);
  }

  addObservers() {
    if (this.chartModel.slider) this.chartModel.slider.addObserver(
      "propertyChanged", this.onSliderPropertyChanged.bind(this), this);
    if (this.chartModel.positions) this.chartModel.positions.addObserver(
      "propertyChanged", this.onPositionsPropertyChanged.bind(this), this);
  }
  attach( stage, stageUpdater ) {
    this.stage = stage;
    this.stageUpdater = stageUpdater;
    this.stage.addChild(this.shape);
  }
  unregisterObservers() {
    if (this.chartModel.positions) {
      this.chartModel.positions.removeAllObservers(this);
    }
    if (this.chartModel.slider) {
      this.chartModel.slider.removeAllObservers(this);
    }
  }

  onPositionsPropertyChanged(name, event) {
    if (event.key === "positionsForDisplay") {
      this.update();
    }
  }
  onSliderPropertyChanged(name, event) {
    if (event.key === "temporaryCurrentRange") {
      if (!event.newValue || !event.newValue.start) return;
      this.slideTo(event.newValue.start);
    }
  }
  slideTo( temporaryStart ) {
    const x = this.calculateSlideX( temporaryStart );
    this.shape.x = x;
    this.stageUpdater.requestUpdate();
  }

  initSprite(slidableMask) {
    this.shape   = this.initializeElement(new CreateJS.Shape());
    this.shape.mask = slidableMask;
  }

  update() {
    this.clearScreen();
    this.renderPositions();
    this.cache();
    this.stageUpdater.requestUpdate();
  }

  clearScreen() {
    this.shape.graphics.clear();
    this.shape.x = this.shape.y = 0;
  }

  renderPositions() {
    const axisPosition = this.chartModel.candleSticks.axisPosition;
    const bottom = axisPosition.verticalSpliter || axisPosition.vertical;

    const slots = this.chartModel.positions.positionsForDisplay;
    let g = this.shape.graphics;
    slots.forEach((positions, index) => {
      const y = bottom - 5 - (index * 10);
      positions.forEach((position)=>{
        this.renderPosition(position, y-0.5, axisPosition, g);
      });
    });
  }

  renderPosition(position, y, axisPosition, graphics) {
    const color = this.calculateColor(position);
    let g = graphics.beginStroke(color);
    g = g.beginFill( position.sellOrBuy === "buy" ? color : "#FFF");
    g = g.drawCircle(position.startX, y, 2);
    if ( position.endX == null ) {
      g = g.moveTo(position.startX+2, y)
           .lineTo(axisPosition.horizontal, y).closePath();
    } else if ( position.endX - position.startX > 4 ) {
     g = g.moveTo(position.startX+2, y)
          .lineTo(position.endX-2, y).closePath();
    }
    if (position.startX !== position.endX) {
      g = g.moveTo(position.endX+2, y)
      g = g.drawCircle(position.endX, y, 2);
    }
    g.endStroke().endFill();
  }

  calculateColor(position) {
    if ( position.profitOrLoss == 0 ) return "#AAAAAA";
    return position.profitOrLoss > 0 ? "#00BFA5" : "#F03950";
  }

  cache() {
    const stageSize = this.chartModel.coordinateCalculator.stageSize;
    const dpr = this.devicePixelRatio;
    this.shape.cache( 0, 0, stageSize.w, stageSize.h, dpr);
  }

}