Skip to main content

Introduction

Vue 3 overlay for the TradingView Charting Library that adds iC Candle’s pattern scanner, results iframe, pattern tracker, and news/event integration in one package.

Published as ESM and CommonJS; component styles are bundled and injected at runtime (no separate CSS import).

SurfaceRole
Scanner popupDraggable overlay over the chart. Select a bar window via the managed date_range selector, then run a scan or subscribe to pattern alerts.
Results iframeHost-owned side panel pointing at the iC Candle embed app (embed-iccandle-app.iccandle.ai) — search results, similar events, auth, billing. Navigate it via submitCallback; use header=false to hide embed chrome.
Chart syncBidirectional postMessage bridge: pattern selection, chart replay, news marks, sign-in tokens, loading state, pricing, chart resolution.

Install​

npm install @iccandle/vuejs-widget
# or
pnpm add @iccandle/vuejs-widget

Prerequisites​

RequirementDetails
Vue 3.5+vue is a peer dependency — install it in your app. axios is a runtime dependency of this package.
TradingView Charting LibraryObtain from TradingView, host static assets (e.g. /charting_library/ in public), and bootstrap the widget yourself. This package does not ship the charting library.

Quick start​

<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref, shallowRef, watch } from "vue";
import type {
ChartingLibraryWidgetOptions,
IChartingLibraryWidget,
ResolutionString,
} from "charting_library/charting_library";
import { widget } from "charting_library/charting_library";
import {
WidgetIccandle,
withPlayChart,
getCustomIndicators,
handleResultIframeLoad,
WIDGET_RESULT_URL,
} from "@iccandle/vuejs-widget";

const LIBRARY_PATH = "/charting_library/";

const containerRef = ref<HTMLDivElement | null>(null);
const chartWidget = shallowRef<IChartingLibraryWidget | null>(null);
const iframeSrc = ref(`${WIDGET_RESULT_URL}/en?theme=light&header=false`);
const iframeLoaded = ref(false);
const resultIframeRef = ref<HTMLIFrameElement | null>(null);
const resultIframeBox = { current: null as HTMLIFrameElement | null };

watch(
resultIframeRef,
(el) => {
resultIframeBox.current = el;
},
{ immediate: true },
);

let tv: IChartingLibraryWidget | null = null;

const submitCallback = (nextSrc: string) => {
const url = new URL(nextSrc);
url.searchParams.set("header", "false");
const next = url.toString();
if (iframeSrc.value !== next) {
iframeSrc.value = next;
}
};

const handleIframeLoad = () => {
iframeLoaded.value = true;
handleResultIframeLoad(resultIframeRef.value);
};

onMounted(() => {
const el = containerRef.value;
if (!el) return;

const options: ChartingLibraryWidgetOptions = {
container: el,
library_path: LIBRARY_PATH,
symbol: "EURUSD",
interval: "60" as ResolutionString,
datafeed: withPlayChart(yourDatafeed), // enables chart replay injection
locale: "en",
autosize: true,
drawings_access: {
type: "black",
tools: [{ name: "Date Range" }],
},
custom_indicators_getter: () => getCustomIndicators("light"),
};

tv = new widget(options);
chartWidget.value = tv;
});

onBeforeUnmount(() => {
try {
tv?.remove();
} catch {
/* no-op */
}
chartWidget.value = null;
tv = null;
});
</script>

<template>
<div class="iccandle-selector-widget__container">
<div class="iccandle-selector-widget__chart-pane">
<WidgetIccandle
:chart-widget="chartWidget"
:submit-callback="submitCallback"
theme="light"
language="en"
:iframe-loaded="iframeLoaded"
:result-iframe-ref="resultIframeBox"
>
<div ref="containerRef" style="height: 100%; width: 100%" />
</WidgetIccandle>
</div>
<iframe
ref="resultIframeRef"
:src="iframeSrc"
class="iccandle-selector-widget__iframe"
title="iC Candle results"
@load="handleIframeLoad"
/>
</div>
</template>

result-iframe-ref is a mutable { current } box, not a Vue ref. Sync it from the iframe element as shown above.

Typical flow​

  1. User activates the scanner and adjusts the bar window (the widget manages a date_range shape on the chart).
  2. Scanner caches the selected candles and calls submitCallback with an embed URL (host sets the results iframe src; use header=false to hide embed chrome).
  3. The embed app returns matches; selecting a pattern redraws the range on the chart. Replay / news flows inject predicted candles via custom indicators.

Next steps​