Exciting Update: Version 1.0.0 is now available, introducing high-performance technical indicators and custom drawing tools. Read more
Version: 1.0.0

Price Lines

Create custom horizontal price level overlays featuring Y-axis scale badges using Series Primitives.

Introduction

Price lines draw horizontal dashed overlays at fixed price values across the main grid. Additionally, they paint a high-visibility badge showing the level directly on the Y-axis price scale.

Price Line Class Definition

Below is the full implementation code of the CustomPriceLinePrimitive from custom-primitives.js:

class CustomPriceLinePrimitive {
  constructor(price, color, label) {
    this.price = price;
    this.color = color || "#ff9800";
    this.label = label || "Target Price";
  }

  attached({ chart, requestUpdate }) {
    this.chart = chart;
    this.requestUpdate = requestUpdate;
    console.log("🔌 [Primitive] CustomPriceLinePrimitive attached.");
  }

  detached() {
    this.chart = null;
    this.requestUpdate = null;
  }

  // Draws horizontal line across the main pane
  draw(ctx, chartW, chartH) {
    if (!this.chart || this.chart.bars.length === 0) return;
    const minMax = this.chart.getVisibleMinMax();
    if (!minMax) return;
    
    const y = this.chart.priceToY(this.price, minMax.minPrice, minMax.maxPrice);
    
    ctx.save();
    ctx.strokeStyle = this.color;
    ctx.lineWidth = 1.5;
    ctx.setLineDash([6, 4]);
    ctx.beginPath();
    ctx.moveTo(0, y);
    ctx.lineTo(chartW, y);
    ctx.stroke();
    ctx.restore();
  }

  // Draws on the price scale (Y-axis)
  drawPriceScale(ctx, priceScaleW, chartH) {
    if (!this.chart || this.chart.bars.length === 0) return;
    const minMax = this.chart.getVisibleMinMax();
    if (!minMax) return;
    
    const y = this.chart.priceToY(this.price, minMax.minPrice, minMax.maxPrice);
    const chartW = this.chart.logicalWidth - this.chart.paddingRight;

    ctx.save();
    ctx.fillStyle = this.color;
    
    // Draw tag background box on price scale
    const boxH = 18;
    const boxW = priceScaleW - 10;
    ctx.fillRect(chartW + 2, y - boxH / 2, boxW, boxH);

    // Draw price text label
    ctx.fillStyle = "#ffffff";
    ctx.font = "bold 10px Inter, Arial, sans-serif";
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.fillText(this.price.toFixed(2), chartW + 2 + boxW / 2, y);
    ctx.restore();
  }
}

Attaching to Chart

Instantiate and attach primitives to your active chart widget context:

// Create a line at target level $25,000
const priceLine = new CustomPriceLinePrimitive(25000, "#2962ff", "Target Level");

// Attach to chart context
chart.attachPrimitive(priceLine);

Lifecycle Hooks

Primitives interact with chart drawing cycles using these hooks:

  • attached: Fired when the primitive is registered. Stores reference handles to parent charts and re-render triggers.
  • draw: Invoked during canvas rendering passes. Controls main area path calculations.
  • drawPriceScale: Invoked during Y-axis rendering passes. Renders price tag markers.