Загрузка данных


function getCenterLabelCenterY(
  entryY: number,
  targetY: number,
  stopY: number,
  boxHeight: number,
  labelOffset: number,
  viewportHeight: number,
): number {
  const targetSpace = Math.abs(targetY - entryY);
  const stopSpace = Math.abs(stopY - entryY);
  const referenceY = targetSpace < stopSpace ? stopY : targetY;
  const direction = referenceY < entryY ? -1 : 1;

  return clampTextBoxCenter(
    entryY + direction * (labelOffset + boxHeight / 2),
    boxHeight,
    viewportHeight,
  );
}








public setState(state: unknown): void {
  if (!state || typeof state !== 'object') {
    return;
  }

  const next = state as Partial<SliderPositionState>;
  const {
    hidden = this.hidden,
    mode = this.mode,
    startTime = this.startTime,
    endTime = this.endTime,
    entryPrice = this.entryPrice,
  } = next;

  this.hidden = hidden;
  this.mode = mode;
  this.startTime = startTime;
  this.endTime = endTime;
  this.entryPrice = entryPrice;

  if (next.stopPrice !== undefined) {
    const shouldNormalize = next.stopPrice !== null && this.entryPrice !== null;

    this.stopPrice = shouldNormalize
      ? this.normalizeStop(this.entryPrice, next.stopPrice)
      : next.stopPrice;
  }

  if (next.targetPrice !== undefined) {
    const shouldNormalize = next.targetPrice !== null && this.entryPrice !== null;

    this.targetPrice = shouldNormalize
      ? this.normalizeTarget(this.entryPrice, next.targetPrice)
      : next.targetPrice;
  } else if (
    this.entryPrice !== null &&
    this.stopPrice !== null &&
    typeof next.riskRewardRatio === 'number' &&
    next.riskRewardRatio >= 0
  ) {
    const risk = Math.abs(this.entryPrice - this.stopPrice);
    const direction = this.side === 'long' ? 1 : -1;

    this.targetPrice = this.normalizeTarget(
      this.entryPrice,
      this.entryPrice + risk * next.riskRewardRatio * direction,
    );
  }

  if (next.settings) {
    this.settings = {
      ...createDefaultSettings(),
      ...next.settings,
    };
  }

  if (typeof next.amount === 'number' && next.amount >= 0) {
    this.settings.accountSize = next.amount;
  }

  this.render();
}











private getHandleTarget(point: Point): DragTarget {
  const geometry = this.getGeometry();

  if (!geometry) {
    return null;
  }

  if (Math.abs(point.x - geometry.startX) <= HIT_TOLERANCE) {
    const entryDistance = Math.abs(point.y - geometry.entryY);

    if (entryDistance < 1) {
      return 'entry';
    }

    const pointerSide = Math.sign(point.y - geometry.entryY);
    const targetSide =
      Math.sign(geometry.targetY - geometry.entryY) ||
      -Math.sign(geometry.stopY - geometry.entryY);

    if (targetSide !== 0) {
      const isTargetSide = pointerSide === targetSide;
      const handleY = isTargetSide ? geometry.targetY : geometry.stopY;
      const handleId: SliderHandleId = isTargetSide ? 'target' : 'stop';

      if (Math.abs(point.y - handleY) <= HIT_TOLERANCE) {
        return handleId;
      }
    }

    if (entryDistance <= HIT_TOLERANCE) {
      return 'entry';
    }
  }

  const handle = this.getDrawingHandleAtPoint(point);

  if (handle) {
    return handle.id;
  }

  const bounds: Bounds = {
    left: geometry.leftX,
    right: geometry.rightX,
    top: Math.min(geometry.targetY, geometry.stopY),
    bottom: Math.max(geometry.targetY, geometry.stopY),
  };

  return isPointInBounds(point, bounds) ? 'body' : null;
}