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


import { CanvasRenderingTarget2D } from 'fancy-canvas';
import {
  IPrimitivePaneRenderer,
  IPrimitivePaneView,
  ISeriesPrimitiveAxisView,
  PrimitivePaneViewZOrder,
} from 'lightweight-charts';

import type { AxisLabel, AxisSegment } from '@core/Drawings/types';

interface CustomPriceAxisPaneViewParams {
  getAxisSegments(): AxisSegment[];
  zOrder?: PrimitivePaneViewZOrder;
}

interface CustomPriceAxisViewParams {
  getAxisLabel(labelKind: string): AxisLabel | null;
  labelKind: string;
}

export class CustomPriceAxisPaneView implements IPrimitivePaneView {
  private readonly rendererInstance: CustomPriceAxisPaneRenderer;
  private readonly paneZOrder: PrimitivePaneViewZOrder;

  constructor({ getAxisSegments, zOrder = 'bottom' }: CustomPriceAxisPaneViewParams) {
    this.rendererInstance = new CustomPriceAxisPaneRenderer(getAxisSegments);
    this.paneZOrder = zOrder;
  }

  public update(): void {}

  public renderer(): IPrimitivePaneRenderer {
    return this.rendererInstance;
  }

  public zOrder(): PrimitivePaneViewZOrder {
    return this.paneZOrder;
  }
}

class CustomPriceAxisPaneRenderer implements IPrimitivePaneRenderer {
  constructor(private readonly getAxisSegments: () => AxisSegment[]) {}

  public draw(target: CanvasRenderingTarget2D): void {
    const axisSegments = this.getAxisSegments();

    if (!axisSegments.length) {
      return;
    }

    target.useBitmapCoordinateSpace(({ context, verticalPixelRatio, bitmapSize }) => {
      context.save();

      for (const axisSegment of axisSegments) {
        const segmentStart = Math.min(axisSegment.from, axisSegment.to) * verticalPixelRatio;
        const segmentEnd = Math.max(axisSegment.from, axisSegment.to) * verticalPixelRatio;

        context.fillStyle = axisSegment.color;
        context.fillRect(0, segmentStart, bitmapSize.width, segmentEnd - segmentStart);
      }

      context.restore();
    });
  }
}

export class CustomPriceAxisView implements ISeriesPrimitiveAxisView {
  private readonly getAxisLabel: (labelKind: string) => AxisLabel | null;
  private readonly labelKind: string;

  constructor({ getAxisLabel, labelKind }: CustomPriceAxisViewParams) {
    this.getAxisLabel = getAxisLabel;
    this.labelKind = labelKind;
  }

  public update(): void {}

  public visible(): boolean {
    return Boolean(this.getCurrentLabel()?.text);
  }

  public tickVisible(): boolean {
    return false;
  }

  public coordinate(): number {
    return this.getCurrentLabel()?.coordinate ?? 0;
  }

  public text(): string {
    return this.getCurrentLabel()?.text ?? '';
  }

  public textColor(): string {
    return this.getCurrentLabel()?.textColor ?? '';
  }

  public backColor(): string {
    return this.getCurrentLabel()?.backgroundColor ?? '';
  }

  private getCurrentLabel(): AxisLabel | null {
    return this.getAxisLabel(this.labelKind);
  }
}
















import { CanvasRenderingTarget2D } from 'fancy-canvas';
import {
  IPrimitivePaneRenderer,
  IPrimitivePaneView,
  ISeriesPrimitiveAxisView,
  PrimitivePaneViewZOrder,
} from 'lightweight-charts';

import type { AxisLabel, AxisSegment } from '@core/Drawings/types';

interface CustomTimeAxisPaneViewParams {
  getAxisSegments(): AxisSegment[];
  zOrder?: PrimitivePaneViewZOrder;
}

interface CustomTimeAxisViewParams {
  getAxisLabel(labelKind: string): AxisLabel | null;
  labelKind: string;
}

export class CustomTimeAxisPaneView implements IPrimitivePaneView {
  private readonly rendererInstance: CustomTimeAxisPaneRenderer;
  private readonly paneZOrder: PrimitivePaneViewZOrder;

  constructor({ getAxisSegments, zOrder = 'bottom' }: CustomTimeAxisPaneViewParams) {
    this.rendererInstance = new CustomTimeAxisPaneRenderer(getAxisSegments);
    this.paneZOrder = zOrder;
  }

  public update(): void {}

  public renderer(): IPrimitivePaneRenderer {
    return this.rendererInstance;
  }

  public zOrder(): PrimitivePaneViewZOrder {
    return this.paneZOrder;
  }
}

class CustomTimeAxisPaneRenderer implements IPrimitivePaneRenderer {
  constructor(private readonly getAxisSegments: () => AxisSegment[]) {}

  public draw(target: CanvasRenderingTarget2D): void {
    const axisSegments = this.getAxisSegments();

    if (!axisSegments.length) {
      return;
    }

    target.useBitmapCoordinateSpace(({ context, horizontalPixelRatio, bitmapSize }) => {
      context.save();

      for (const axisSegment of axisSegments) {
        const segmentStart = Math.min(axisSegment.from, axisSegment.to) * horizontalPixelRatio;
        const segmentEnd = Math.max(axisSegment.from, axisSegment.to) * horizontalPixelRatio;

        context.fillStyle = axisSegment.color;
        context.fillRect(segmentStart, 0, segmentEnd - segmentStart, bitmapSize.height);
      }

      context.restore();
    });
  }
}

export class CustomTimeAxisView implements ISeriesPrimitiveAxisView {
  private readonly getAxisLabel: (labelKind: string) => AxisLabel | null;
  private readonly labelKind: string;

  constructor({ getAxisLabel, labelKind }: CustomTimeAxisViewParams) {
    this.getAxisLabel = getAxisLabel;
    this.labelKind = labelKind;
  }

  public update(): void {}

  public visible(): boolean {
    return Boolean(this.getCurrentLabel()?.text);
  }

  public tickVisible(): boolean {
    return false;
  }

  public coordinate(): number {
    return this.getCurrentLabel()?.coordinate ?? 0;
  }

  public text(): string {
    return this.getCurrentLabel()?.text ?? '';
  }

  public textColor(): string {
    return this.getCurrentLabel()?.textColor ?? '';
  }

  public backColor(): string {
    return this.getCurrentLabel()?.backgroundColor ?? '';
  }

  private getCurrentLabel(): AxisLabel | null {
    return this.getAxisLabel(this.labelKind);
  }
}