@tradecanvas/vue 1.1.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +9 -2
- package/dist/index.js +100 -97
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ Streams live Binance data by default. Pass `:data="bars"` for static OHLC, or `:
|
|
|
39
39
|
|
|
40
40
|
## Props & events
|
|
41
41
|
|
|
42
|
-
Props: `symbol`, `timeframe`, `theme`, `chartType`, `indicators
|
|
42
|
+
Props: `symbol`, `timeframe`, `theme`, `chartType`, `indicators` (ids, or `{ id, params, position }`), `data` (bars of your own; no stream), `adapter`, `stream` (`false`: no stream of its own), `historyLimit`, `features` (changes apply after mount too), `autoScale`, `signalMarkers`, `signalMarkerStyle`, `tradeZones`, `tradeZoneStyle`, `overrides` (style overrides by key, all of your app's), `watermarkText`.
|
|
43
43
|
|
|
44
44
|
Events: `@ready="(chart) => …"`, `@crosshairMove="(payload) => …"`.
|
|
45
45
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`vue`),t=require(`@tradecanvas/chart`);var n=(0,e.defineComponent)({__name:`TradeCanvas`,props:{symbol:{default:`BTCUSDT`},timeframe:{default:`5m`},theme:{default:`dark`},chartType:{default:`candlestick`},indicators:{default:()=>[]},data:{},adapter:{},historyLimit:{default:500},features:{},autoScale:{type:Boolean,default:!0},signalMarkers:{},signalMarkerStyle:{},tradeZones:{},tradeZoneStyle:{},overrides:{},watermarkText:{}},emits:[`ready`,`crosshairMove`],setup(n,{expose:r,emit:i}){let a=n,o=i;function s(e){return e===`dark`?t.DARK_THEME:e===`light`?t.LIGHT_THEME:e}let c=(0,e.ref)(),l=null,u=new Map;function d(){return l}function
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`vue`),t=require(`@tradecanvas/chart`);var n=(0,e.defineComponent)({__name:`TradeCanvas`,props:{symbol:{default:`BTCUSDT`},timeframe:{default:`5m`},theme:{default:`dark`},chartType:{default:`candlestick`},indicators:{default:()=>[]},data:{},adapter:{},stream:{type:Boolean,default:!0},historyLimit:{default:500},features:{},autoScale:{type:Boolean,default:!0},signalMarkers:{},signalMarkerStyle:{},tradeZones:{},tradeZoneStyle:{},overrides:{},watermarkText:{}},emits:[`ready`,`crosshairMove`],setup(n,{expose:r,emit:i}){let a=n,o=i;function s(e){return e===`dark`?t.DARK_THEME:e===`light`?t.LIGHT_THEME:e}let c=(0,e.ref)(),l=null,u=new Map,d=null,f=e=>e.map(e=>typeof e==`string`?e:{id:e.id,...e.params?{params:{...e.params}}:{},...e.position?{position:e.position}:{}}),p=JSON.stringify(a.features??null);function m(){if(!l)return;if(!a.stream){d!==null&&l.disconnectStream(),d=null;return}if(a.data)return;let e=`${a.symbol}|${a.timeframe}`;if(d===e)return;let n=d!==null;d=e,n&&l.disconnectStream();let r=a.adapter??new t.BinanceAdapter;l.connect({adapter:r,symbol:a.symbol,timeframe:a.timeframe,historyLimit:a.historyLimit}),n&&a.watermarkText&&l.setWatermark(a.watermarkText)}function h(){return l}function g(e){l?.screenshot(e)}function _(){return l?.screenshotDataURL()??null}return r({getChart:h,screenshot:g,screenshotDataURL:_}),(0,e.onMounted)(()=>{c.value&&(l=new t.Chart(c.value,{chartType:a.chartType,theme:s(a.theme),autoScale:a.autoScale,rightMargin:5,crosshair:{mode:`magnet`},watermark:a.watermarkText?{text:a.watermarkText,fontSize:48,color:`rgba(255,255,255,0.03)`}:void 0,features:{drawings:!0,drawingMagnet:!0,drawingUndoRedo:!0,indicators:!0,trading:!0,volume:!0,legend:!0,crosshair:!0,keyboard:!0,screenshot:!0,alerts:!0,barCountdown:!0,logScale:!0,watermark:!0,...a.features}}),a.data?l.setData(a.data):m(),(0,t.syncIndicators)(l,f(a.indicators),u),a.signalMarkers&&l.setSignalMarkers(a.signalMarkers),a.signalMarkerStyle&&l.setSignalMarkerStyle(a.signalMarkerStyle),a.tradeZones&&l.setTradeZones(a.tradeZones),a.tradeZoneStyle&&l.setTradeZoneStyle(a.tradeZoneStyle),a.overrides&&l.setOverrides(a.overrides),o(`ready`,l))}),(0,e.onUnmounted)(()=>{l&&=(l.disconnectStream(),l.destroy(),null)}),(0,e.watch)(()=>[a.symbol,a.timeframe,!a.data,a.stream],m),(0,e.watch)(()=>a.features,e=>{let t=JSON.stringify(e??null);t!==p&&(p=t,e&&l?.setFeatures({...e}))},{deep:!0}),(0,e.watch)(()=>a.theme,e=>{l?.setTheme(s(e))}),(0,e.watch)(()=>a.chartType,e=>{l?.setChartType(e)}),(0,e.watch)(()=>a.data,e=>{e&&l?.setData(e)},{deep:!0}),(0,e.watch)(()=>a.indicators,e=>{l&&(0,t.syncIndicators)(l,f(e),u)},{deep:!0}),(0,e.watch)(()=>a.signalMarkers,e=>{e&&l?.setSignalMarkers(e)},{deep:!0}),(0,e.watch)(()=>a.signalMarkerStyle,e=>{e&&l?.setSignalMarkerStyle(e)},{deep:!0}),(0,e.watch)(()=>a.tradeZones,e=>{e&&l?.setTradeZones(e)},{deep:!0}),(0,e.watch)(()=>a.tradeZoneStyle,e=>{e&&l?.setTradeZoneStyle(e)},{deep:!0}),(0,e.watch)(()=>a.overrides,e=>{l?.setOverrides({...e})},{deep:!0}),(t,n)=>((0,e.openBlock)(),(0,e.createElementBlock)(`div`,{ref_key:`containerEl`,ref:c,style:{width:`100%`,height:`100%`}},null,512))}});exports.TradeCanvas=n;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":[],"sources":["../src/TradeCanvas.vue","../src/TradeCanvas.vue"],"sourcesContent":["<template>\n <div ref=\"containerEl\" :style=\"{ width: '100%', height: '100%' }\" />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, onUnmounted, watch } from 'vue';\nimport {\n Chart,\n BinanceAdapter,\n DARK_THEME,\n LIGHT_THEME,\n} from '@tradecanvas/chart';\nimport type {\n ChartType,\n TimeFrame,\n FeaturesConfig,\n Theme,\n OHLCBar,\n SignalMarker,\n TradeZone,\n SignalMarkerStyle,\n TradeZoneStyle,\n DataAdapter,\n ChartStyleOverrides,\n} from '@tradecanvas/chart';\n\nconst props = withDefaults(\n defineProps<{\n symbol?: string;\n timeframe?: TimeFrame;\n theme?: 'dark' | 'light' | Theme;\n chartType?: ChartType;\n indicators?: string[];\n data?: OHLCBar[];\n adapter?: DataAdapter;\n historyLimit?: number;\n features?: FeaturesConfig;\n autoScale?: boolean;\n signalMarkers?: SignalMarker[];\n signalMarkerStyle?: SignalMarkerStyle;\n tradeZones?: TradeZone[];\n tradeZoneStyle?: TradeZoneStyle;\n /** Style overrides, by key: all of your app's (`chart.setOverrides`). */\n overrides?: ChartStyleOverrides;\n watermarkText?: string;\n }>(),\n {\n symbol: 'BTCUSDT',\n timeframe: '5m' as TimeFrame,\n theme: 'dark',\n chartType: 'candlestick' as ChartType,\n indicators: () => [],\n historyLimit: 500,\n autoScale: true,\n },\n);\n\nconst emit = defineEmits<{\n ready: [chart: Chart];\n crosshairMove: [payload: unknown];\n}>();\n\nfunction resolveTheme(theme: 'dark' | 'light' | Theme): Theme {\n if (theme === 'dark') return DARK_THEME;\n if (theme === 'light') return LIGHT_THEME;\n return theme as Theme;\n}\n\nconst containerEl = ref<HTMLDivElement>();\nlet chart: Chart | null = null;\nconst indicatorIds = new Map<string, string>();\n\nfunction getChart(): Chart | null {\n return chart;\n}\n\nfunction screenshot(filename?: string): void {\n chart?.screenshot(filename);\n}\n\nfunction screenshotDataURL(): string | null {\n return chart?.screenshotDataURL() ?? null;\n}\n\ndefineExpose({ getChart, screenshot, screenshotDataURL });\n\nonMounted(() => {\n if (!containerEl.value) return;\n\n chart = new Chart(containerEl.value, {\n chartType: props.chartType,\n theme: resolveTheme(props.theme),\n autoScale: props.autoScale,\n rightMargin: 5,\n crosshair: { mode: 'magnet' },\n watermark: props.watermarkText\n ? { text: props.watermarkText, fontSize: 48, color: 'rgba(255,255,255,0.03)' }\n : undefined,\n features: {\n drawings: true,\n drawingMagnet: true,\n drawingUndoRedo: true,\n indicators: true,\n trading: true,\n volume: true,\n legend: true,\n crosshair: true,\n keyboard: true,\n screenshot: true,\n alerts: true,\n barCountdown: true,\n logScale: true,\n watermark: true,\n ...props.features,\n },\n });\n\n if (props.data) {\n chart.setData(props.data);\n } else {\n const adapter = props.adapter ?? new BinanceAdapter();\n chart.connect({ adapter, symbol: props.symbol, timeframe: props.timeframe, historyLimit: props.historyLimit });\n }\n\n // Apply initial reactive collections not covered by the constructor options.\n // Vue's watches aren't immediate, so without this the first render of\n // indicators / signal markers / trade zones would be dropped.\n for (const name of props.indicators) {\n const instanceId = chart.addIndicator(name);\n if (instanceId) indicatorIds.set(name, instanceId);\n }\n if (props.signalMarkers) chart.setSignalMarkers(props.signalMarkers);\n if (props.signalMarkerStyle) chart.setSignalMarkerStyle(props.signalMarkerStyle);\n if (props.tradeZones) chart.setTradeZones(props.tradeZones);\n if (props.tradeZoneStyle) chart.setTradeZoneStyle(props.tradeZoneStyle);\n if (props.overrides) chart.setOverrides(props.overrides);\n\n emit('ready', chart);\n});\n\nonUnmounted(() => {\n if (chart) {\n chart.disconnectStream();\n chart.destroy();\n chart = null;\n }\n});\n\nwatch(\n () => [props.symbol, props.timeframe] as const,\n ([newSymbol, newTimeframe]) => {\n if (!chart || props.data) return;\n chart.disconnectStream();\n const adapter = props.adapter ?? new BinanceAdapter();\n chart.connect({ adapter, symbol: newSymbol, timeframe: newTimeframe, historyLimit: props.historyLimit });\n if (props.watermarkText) chart.setWatermark(props.watermarkText);\n },\n);\n\nwatch(() => props.theme, (t) => { chart?.setTheme(resolveTheme(t)); });\nwatch(() => props.chartType, (ct) => { chart?.setChartType(ct); });\nwatch(() => props.data, (d) => { if (d) chart?.setData(d); }, { deep: true });\n\nwatch(\n () => props.indicators,\n (newIndicators) => {\n if (!chart) return;\n const desired = new Set(newIndicators);\n for (const [name, instanceId] of indicatorIds) {\n if (!desired.has(name)) {\n chart.removeIndicator(instanceId);\n indicatorIds.delete(name);\n }\n }\n for (const name of newIndicators) {\n if (!indicatorIds.has(name)) {\n const instanceId = chart.addIndicator(name);\n if (instanceId) indicatorIds.set(name, instanceId);\n }\n }\n },\n { deep: true },\n);\n\nwatch(() => props.signalMarkers, (m) => { if (m) chart?.setSignalMarkers(m); }, { deep: true });\nwatch(() => props.signalMarkerStyle, (s) => { if (s) chart?.setSignalMarkerStyle(s); }, { deep: true });\nwatch(() => props.tradeZones, (z) => { if (z) chart?.setTradeZones(z); }, { deep: true });\nwatch(() => props.tradeZoneStyle, (s) => { if (s) chart?.setTradeZoneStyle(s); }, { deep: true });\n// All of the host's overrides: keys left out of the prop are taken away.\nwatch(() => props.overrides, (o) => { chart?.setOverrides({ ...o }); }, { deep: true });\n</script>\n","<template>\n <div ref=\"containerEl\" :style=\"{ width: '100%', height: '100%' }\" />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, onUnmounted, watch } from 'vue';\nimport {\n Chart,\n BinanceAdapter,\n DARK_THEME,\n LIGHT_THEME,\n} from '@tradecanvas/chart';\nimport type {\n ChartType,\n TimeFrame,\n FeaturesConfig,\n Theme,\n OHLCBar,\n SignalMarker,\n TradeZone,\n SignalMarkerStyle,\n TradeZoneStyle,\n DataAdapter,\n ChartStyleOverrides,\n} from '@tradecanvas/chart';\n\nconst props = withDefaults(\n defineProps<{\n symbol?: string;\n timeframe?: TimeFrame;\n theme?: 'dark' | 'light' | Theme;\n chartType?: ChartType;\n indicators?: string[];\n data?: OHLCBar[];\n adapter?: DataAdapter;\n historyLimit?: number;\n features?: FeaturesConfig;\n autoScale?: boolean;\n signalMarkers?: SignalMarker[];\n signalMarkerStyle?: SignalMarkerStyle;\n tradeZones?: TradeZone[];\n tradeZoneStyle?: TradeZoneStyle;\n /** Style overrides, by key: all of your app's (`chart.setOverrides`). */\n overrides?: ChartStyleOverrides;\n watermarkText?: string;\n }>(),\n {\n symbol: 'BTCUSDT',\n timeframe: '5m' as TimeFrame,\n theme: 'dark',\n chartType: 'candlestick' as ChartType,\n indicators: () => [],\n historyLimit: 500,\n autoScale: true,\n },\n);\n\nconst emit = defineEmits<{\n ready: [chart: Chart];\n crosshairMove: [payload: unknown];\n}>();\n\nfunction resolveTheme(theme: 'dark' | 'light' | Theme): Theme {\n if (theme === 'dark') return DARK_THEME;\n if (theme === 'light') return LIGHT_THEME;\n return theme as Theme;\n}\n\nconst containerEl = ref<HTMLDivElement>();\nlet chart: Chart | null = null;\nconst indicatorIds = new Map<string, string>();\n\nfunction getChart(): Chart | null {\n return chart;\n}\n\nfunction screenshot(filename?: string): void {\n chart?.screenshot(filename);\n}\n\nfunction screenshotDataURL(): string | null {\n return chart?.screenshotDataURL() ?? null;\n}\n\ndefineExpose({ getChart, screenshot, screenshotDataURL });\n\nonMounted(() => {\n if (!containerEl.value) return;\n\n chart = new Chart(containerEl.value, {\n chartType: props.chartType,\n theme: resolveTheme(props.theme),\n autoScale: props.autoScale,\n rightMargin: 5,\n crosshair: { mode: 'magnet' },\n watermark: props.watermarkText\n ? { text: props.watermarkText, fontSize: 48, color: 'rgba(255,255,255,0.03)' }\n : undefined,\n features: {\n drawings: true,\n drawingMagnet: true,\n drawingUndoRedo: true,\n indicators: true,\n trading: true,\n volume: true,\n legend: true,\n crosshair: true,\n keyboard: true,\n screenshot: true,\n alerts: true,\n barCountdown: true,\n logScale: true,\n watermark: true,\n ...props.features,\n },\n });\n\n if (props.data) {\n chart.setData(props.data);\n } else {\n const adapter = props.adapter ?? new BinanceAdapter();\n chart.connect({ adapter, symbol: props.symbol, timeframe: props.timeframe, historyLimit: props.historyLimit });\n }\n\n // Apply initial reactive collections not covered by the constructor options.\n // Vue's watches aren't immediate, so without this the first render of\n // indicators / signal markers / trade zones would be dropped.\n for (const name of props.indicators) {\n const instanceId = chart.addIndicator(name);\n if (instanceId) indicatorIds.set(name, instanceId);\n }\n if (props.signalMarkers) chart.setSignalMarkers(props.signalMarkers);\n if (props.signalMarkerStyle) chart.setSignalMarkerStyle(props.signalMarkerStyle);\n if (props.tradeZones) chart.setTradeZones(props.tradeZones);\n if (props.tradeZoneStyle) chart.setTradeZoneStyle(props.tradeZoneStyle);\n if (props.overrides) chart.setOverrides(props.overrides);\n\n emit('ready', chart);\n});\n\nonUnmounted(() => {\n if (chart) {\n chart.disconnectStream();\n chart.destroy();\n chart = null;\n }\n});\n\nwatch(\n () => [props.symbol, props.timeframe] as const,\n ([newSymbol, newTimeframe]) => {\n if (!chart || props.data) return;\n chart.disconnectStream();\n const adapter = props.adapter ?? new BinanceAdapter();\n chart.connect({ adapter, symbol: newSymbol, timeframe: newTimeframe, historyLimit: props.historyLimit });\n if (props.watermarkText) chart.setWatermark(props.watermarkText);\n },\n);\n\nwatch(() => props.theme, (t) => { chart?.setTheme(resolveTheme(t)); });\nwatch(() => props.chartType, (ct) => { chart?.setChartType(ct); });\nwatch(() => props.data, (d) => { if (d) chart?.setData(d); }, { deep: true });\n\nwatch(\n () => props.indicators,\n (newIndicators) => {\n if (!chart) return;\n const desired = new Set(newIndicators);\n for (const [name, instanceId] of indicatorIds) {\n if (!desired.has(name)) {\n chart.removeIndicator(instanceId);\n indicatorIds.delete(name);\n }\n }\n for (const name of newIndicators) {\n if (!indicatorIds.has(name)) {\n const instanceId = chart.addIndicator(name);\n if (instanceId) indicatorIds.set(name, instanceId);\n }\n }\n },\n { deep: true },\n);\n\nwatch(() => props.signalMarkers, (m) => { if (m) chart?.setSignalMarkers(m); }, { deep: true });\nwatch(() => props.signalMarkerStyle, (s) => { if (s) chart?.setSignalMarkerStyle(s); }, { deep: true });\nwatch(() => props.tradeZones, (z) => { if (z) chart?.setTradeZones(z); }, { deep: true });\nwatch(() => props.tradeZoneStyle, (s) => { if (s) chart?.setTradeZoneStyle(s); }, { deep: true });\n// All of the host's overrides: keys left out of the prop are taken away.\nwatch(() => props.overrides, (o) => { chart?.setOverrides({ ...o }); }, { deep: true });\n</script>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../src/TradeCanvas.vue","../src/TradeCanvas.vue"],"sourcesContent":["<template>\n <div ref=\"containerEl\" :style=\"{ width: '100%', height: '100%' }\" />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, onUnmounted, watch } from 'vue';\nimport {\n Chart,\n BinanceAdapter,\n DARK_THEME,\n LIGHT_THEME,\n syncIndicators,\n} from '@tradecanvas/chart';\nimport type {\n ChartType,\n TimeFrame,\n FeaturesConfig,\n Theme,\n OHLCBar,\n SignalMarker,\n TradeZone,\n SignalMarkerStyle,\n TradeZoneStyle,\n DataAdapter,\n ChartStyleOverrides,\n IndicatorSpec,\n} from '@tradecanvas/chart';\n\nconst props = withDefaults(\n defineProps<{\n symbol?: string;\n timeframe?: TimeFrame;\n theme?: 'dark' | 'light' | Theme;\n chartType?: ChartType;\n /** Indicators by id (`'rsi'`), or with their inputs (`{ id: 'ema', params: { period: 50 } }`). */\n indicators?: IndicatorSpec[];\n /** Static bars: the chart shows these, and opens no stream of its own when it has them at mount. */\n data?: OHLCBar[];\n adapter?: DataAdapter;\n /** `false`: no stream until you say so (no Binance by default); the chart waits for `data`. Default `true`. */\n stream?: boolean;\n historyLimit?: number;\n /** What users can do on the chart; changes after mount are applied too (the keys given). */\n features?: FeaturesConfig;\n autoScale?: boolean;\n signalMarkers?: SignalMarker[];\n signalMarkerStyle?: SignalMarkerStyle;\n tradeZones?: TradeZone[];\n tradeZoneStyle?: TradeZoneStyle;\n /** Style overrides, by key: all of your app's (`chart.setOverrides`). */\n overrides?: ChartStyleOverrides;\n watermarkText?: string;\n }>(),\n {\n symbol: 'BTCUSDT',\n timeframe: '5m' as TimeFrame,\n theme: 'dark',\n chartType: 'candlestick' as ChartType,\n indicators: () => [],\n stream: true,\n historyLimit: 500,\n autoScale: true,\n },\n);\n\nconst emit = defineEmits<{\n ready: [chart: Chart];\n crosshairMove: [payload: unknown];\n}>();\n\nfunction resolveTheme(theme: 'dark' | 'light' | Theme): Theme {\n if (theme === 'dark') return DARK_THEME;\n if (theme === 'light') return LIGHT_THEME;\n return theme as Theme;\n}\n\nconst containerEl = ref<HTMLDivElement>();\nlet chart: Chart | null = null;\nconst indicatorIds = new Map<string, string>();\n/** The stream open now (`symbol|timeframe`), or null. */\nlet streamKey: string | null = null;\n\n/** The specs as plain values (not Vue's proxies), for the chart to keep. */\nconst plainSpecs = (specs: readonly IndicatorSpec[]): IndicatorSpec[] =>\n specs.map((spec) => (typeof spec === 'string'\n ? spec\n : { id: spec.id, ...(spec.params ? { params: { ...spec.params } } : {}), ...(spec.position ? { position: spec.position } : {}) }));\n/** The features last applied, as text. */\nlet featuresKey = JSON.stringify(props.features ?? null);\n\n/** A stream of its own while it has no data; `stream: false` closes it. Data given later leaves it be. */\nfunction syncStream(): void {\n if (!chart) return;\n if (!props.stream) {\n if (streamKey !== null) chart.disconnectStream();\n streamKey = null;\n return;\n }\n if (props.data) return;\n const key = `${props.symbol}|${props.timeframe}`;\n if (streamKey === key) return;\n const opened = streamKey !== null;\n streamKey = key;\n if (opened) chart.disconnectStream();\n const adapter = props.adapter ?? new BinanceAdapter();\n chart.connect({ adapter, symbol: props.symbol, timeframe: props.timeframe, historyLimit: props.historyLimit });\n if (opened && props.watermarkText) chart.setWatermark(props.watermarkText);\n}\n\nfunction getChart(): Chart | null {\n return chart;\n}\n\nfunction screenshot(filename?: string): void {\n chart?.screenshot(filename);\n}\n\nfunction screenshotDataURL(): string | null {\n return chart?.screenshotDataURL() ?? null;\n}\n\ndefineExpose({ getChart, screenshot, screenshotDataURL });\n\nonMounted(() => {\n if (!containerEl.value) return;\n\n chart = new Chart(containerEl.value, {\n chartType: props.chartType,\n theme: resolveTheme(props.theme),\n autoScale: props.autoScale,\n rightMargin: 5,\n crosshair: { mode: 'magnet' },\n watermark: props.watermarkText\n ? { text: props.watermarkText, fontSize: 48, color: 'rgba(255,255,255,0.03)' }\n : undefined,\n features: {\n drawings: true,\n drawingMagnet: true,\n drawingUndoRedo: true,\n indicators: true,\n trading: true,\n volume: true,\n legend: true,\n crosshair: true,\n keyboard: true,\n screenshot: true,\n alerts: true,\n barCountdown: true,\n logScale: true,\n watermark: true,\n ...props.features,\n },\n });\n\n if (props.data) chart.setData(props.data);\n else syncStream();\n\n // Apply initial reactive collections not covered by the constructor options.\n // Vue's watches aren't immediate, so without this the first render of\n // indicators / signal markers / trade zones would be dropped.\n syncIndicators(chart, plainSpecs(props.indicators), indicatorIds);\n if (props.signalMarkers) chart.setSignalMarkers(props.signalMarkers);\n if (props.signalMarkerStyle) chart.setSignalMarkerStyle(props.signalMarkerStyle);\n if (props.tradeZones) chart.setTradeZones(props.tradeZones);\n if (props.tradeZoneStyle) chart.setTradeZoneStyle(props.tradeZoneStyle);\n if (props.overrides) chart.setOverrides(props.overrides);\n\n emit('ready', chart);\n});\n\nonUnmounted(() => {\n if (chart) {\n chart.disconnectStream();\n chart.destroy();\n chart = null;\n }\n});\n\nwatch(() => [props.symbol, props.timeframe, !props.data, props.stream] as const, syncStream);\nwatch(() => props.features, (f) => {\n const key = JSON.stringify(f ?? null);\n if (key === featuresKey) return;\n featuresKey = key;\n if (f) chart?.setFeatures({ ...f });\n}, { deep: true });\n\nwatch(() => props.theme, (t) => { chart?.setTheme(resolveTheme(t)); });\nwatch(() => props.chartType, (ct) => { chart?.setChartType(ct); });\nwatch(() => props.data, (d) => { if (d) chart?.setData(d); }, { deep: true });\n\nwatch(\n () => props.indicators,\n (specs) => { if (chart) syncIndicators(chart, plainSpecs(specs), indicatorIds); },\n { deep: true },\n);\n\nwatch(() => props.signalMarkers, (m) => { if (m) chart?.setSignalMarkers(m); }, { deep: true });\nwatch(() => props.signalMarkerStyle, (s) => { if (s) chart?.setSignalMarkerStyle(s); }, { deep: true });\nwatch(() => props.tradeZones, (z) => { if (z) chart?.setTradeZones(z); }, { deep: true });\nwatch(() => props.tradeZoneStyle, (s) => { if (s) chart?.setTradeZoneStyle(s); }, { deep: true });\n// All of the host's overrides: keys left out of the prop are taken away.\nwatch(() => props.overrides, (o) => { chart?.setOverrides({ ...o }); }, { deep: true });\n</script>\n","<template>\n <div ref=\"containerEl\" :style=\"{ width: '100%', height: '100%' }\" />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, onUnmounted, watch } from 'vue';\nimport {\n Chart,\n BinanceAdapter,\n DARK_THEME,\n LIGHT_THEME,\n syncIndicators,\n} from '@tradecanvas/chart';\nimport type {\n ChartType,\n TimeFrame,\n FeaturesConfig,\n Theme,\n OHLCBar,\n SignalMarker,\n TradeZone,\n SignalMarkerStyle,\n TradeZoneStyle,\n DataAdapter,\n ChartStyleOverrides,\n IndicatorSpec,\n} from '@tradecanvas/chart';\n\nconst props = withDefaults(\n defineProps<{\n symbol?: string;\n timeframe?: TimeFrame;\n theme?: 'dark' | 'light' | Theme;\n chartType?: ChartType;\n /** Indicators by id (`'rsi'`), or with their inputs (`{ id: 'ema', params: { period: 50 } }`). */\n indicators?: IndicatorSpec[];\n /** Static bars: the chart shows these, and opens no stream of its own when it has them at mount. */\n data?: OHLCBar[];\n adapter?: DataAdapter;\n /** `false`: no stream until you say so (no Binance by default); the chart waits for `data`. Default `true`. */\n stream?: boolean;\n historyLimit?: number;\n /** What users can do on the chart; changes after mount are applied too (the keys given). */\n features?: FeaturesConfig;\n autoScale?: boolean;\n signalMarkers?: SignalMarker[];\n signalMarkerStyle?: SignalMarkerStyle;\n tradeZones?: TradeZone[];\n tradeZoneStyle?: TradeZoneStyle;\n /** Style overrides, by key: all of your app's (`chart.setOverrides`). */\n overrides?: ChartStyleOverrides;\n watermarkText?: string;\n }>(),\n {\n symbol: 'BTCUSDT',\n timeframe: '5m' as TimeFrame,\n theme: 'dark',\n chartType: 'candlestick' as ChartType,\n indicators: () => [],\n stream: true,\n historyLimit: 500,\n autoScale: true,\n },\n);\n\nconst emit = defineEmits<{\n ready: [chart: Chart];\n crosshairMove: [payload: unknown];\n}>();\n\nfunction resolveTheme(theme: 'dark' | 'light' | Theme): Theme {\n if (theme === 'dark') return DARK_THEME;\n if (theme === 'light') return LIGHT_THEME;\n return theme as Theme;\n}\n\nconst containerEl = ref<HTMLDivElement>();\nlet chart: Chart | null = null;\nconst indicatorIds = new Map<string, string>();\n/** The stream open now (`symbol|timeframe`), or null. */\nlet streamKey: string | null = null;\n\n/** The specs as plain values (not Vue's proxies), for the chart to keep. */\nconst plainSpecs = (specs: readonly IndicatorSpec[]): IndicatorSpec[] =>\n specs.map((spec) => (typeof spec === 'string'\n ? spec\n : { id: spec.id, ...(spec.params ? { params: { ...spec.params } } : {}), ...(spec.position ? { position: spec.position } : {}) }));\n/** The features last applied, as text. */\nlet featuresKey = JSON.stringify(props.features ?? null);\n\n/** A stream of its own while it has no data; `stream: false` closes it. Data given later leaves it be. */\nfunction syncStream(): void {\n if (!chart) return;\n if (!props.stream) {\n if (streamKey !== null) chart.disconnectStream();\n streamKey = null;\n return;\n }\n if (props.data) return;\n const key = `${props.symbol}|${props.timeframe}`;\n if (streamKey === key) return;\n const opened = streamKey !== null;\n streamKey = key;\n if (opened) chart.disconnectStream();\n const adapter = props.adapter ?? new BinanceAdapter();\n chart.connect({ adapter, symbol: props.symbol, timeframe: props.timeframe, historyLimit: props.historyLimit });\n if (opened && props.watermarkText) chart.setWatermark(props.watermarkText);\n}\n\nfunction getChart(): Chart | null {\n return chart;\n}\n\nfunction screenshot(filename?: string): void {\n chart?.screenshot(filename);\n}\n\nfunction screenshotDataURL(): string | null {\n return chart?.screenshotDataURL() ?? null;\n}\n\ndefineExpose({ getChart, screenshot, screenshotDataURL });\n\nonMounted(() => {\n if (!containerEl.value) return;\n\n chart = new Chart(containerEl.value, {\n chartType: props.chartType,\n theme: resolveTheme(props.theme),\n autoScale: props.autoScale,\n rightMargin: 5,\n crosshair: { mode: 'magnet' },\n watermark: props.watermarkText\n ? { text: props.watermarkText, fontSize: 48, color: 'rgba(255,255,255,0.03)' }\n : undefined,\n features: {\n drawings: true,\n drawingMagnet: true,\n drawingUndoRedo: true,\n indicators: true,\n trading: true,\n volume: true,\n legend: true,\n crosshair: true,\n keyboard: true,\n screenshot: true,\n alerts: true,\n barCountdown: true,\n logScale: true,\n watermark: true,\n ...props.features,\n },\n });\n\n if (props.data) chart.setData(props.data);\n else syncStream();\n\n // Apply initial reactive collections not covered by the constructor options.\n // Vue's watches aren't immediate, so without this the first render of\n // indicators / signal markers / trade zones would be dropped.\n syncIndicators(chart, plainSpecs(props.indicators), indicatorIds);\n if (props.signalMarkers) chart.setSignalMarkers(props.signalMarkers);\n if (props.signalMarkerStyle) chart.setSignalMarkerStyle(props.signalMarkerStyle);\n if (props.tradeZones) chart.setTradeZones(props.tradeZones);\n if (props.tradeZoneStyle) chart.setTradeZoneStyle(props.tradeZoneStyle);\n if (props.overrides) chart.setOverrides(props.overrides);\n\n emit('ready', chart);\n});\n\nonUnmounted(() => {\n if (chart) {\n chart.disconnectStream();\n chart.destroy();\n chart = null;\n }\n});\n\nwatch(() => [props.symbol, props.timeframe, !props.data, props.stream] as const, syncStream);\nwatch(() => props.features, (f) => {\n const key = JSON.stringify(f ?? null);\n if (key === featuresKey) return;\n featuresKey = key;\n if (f) chart?.setFeatures({ ...f });\n}, { deep: true });\n\nwatch(() => props.theme, (t) => { chart?.setTheme(resolveTheme(t)); });\nwatch(() => props.chartType, (ct) => { chart?.setChartType(ct); });\nwatch(() => props.data, (d) => { if (d) chart?.setData(d); }, { deep: true });\n\nwatch(\n () => props.indicators,\n (specs) => { if (chart) syncIndicators(chart, plainSpecs(specs), indicatorIds); },\n { deep: true },\n);\n\nwatch(() => props.signalMarkers, (m) => { if (m) chart?.setSignalMarkers(m); }, { deep: true });\nwatch(() => props.signalMarkerStyle, (s) => { if (s) chart?.setSignalMarkerStyle(s); }, { deep: true });\nwatch(() => props.tradeZones, (z) => { if (z) chart?.setTradeZones(z); }, { deep: true });\nwatch(() => props.tradeZoneStyle, (s) => { if (s) chart?.setTradeZoneStyle(s); }, { deep: true });\n// All of the host's overrides: keys left out of the prop are taken away.\nwatch(() => props.overrides, (o) => { chart?.setOverrides({ ...o }); }, { deep: true });\n</script>\n"],"mappings":"ylBA4BA,IAAM,EAAQ,EAqCR,EAAO,EAKb,SAAS,EAAa,EAAwC,CAG5D,OAFI,IAAU,OAAe,EAAA,WACzB,IAAU,QAAgB,EAAA,YACvB,EAGT,IAAM,GAAA,EAAA,EAAA,MAAmC,CACrC,EAAsB,KACpB,EAAe,IAAI,IAErB,EAA2B,KAGzB,EAAc,GAClB,EAAM,IAAK,GAAU,OAAO,GAAS,SACjC,EACA,CAAE,GAAI,EAAK,GAAI,GAAI,EAAK,OAAS,CAAE,OAAQ,CAAE,GAAG,EAAK,OAAQ,CAAE,CAAG,EAAE,CAAG,GAAI,EAAK,SAAW,CAAE,SAAU,EAAK,SAAU,CAAG,EAAE,CAAG,CAAE,CAElI,EAAc,KAAK,UAAU,EAAM,UAAY,KAAK,CAGxD,SAAS,GAAmB,CAC1B,GAAI,CAAC,EAAO,OACZ,GAAI,CAAC,EAAM,OAAQ,CACb,IAAc,MAAM,EAAM,kBAAkB,CAChD,EAAY,KACZ,OAEF,GAAI,EAAM,KAAM,OAChB,IAAM,EAAM,GAAG,EAAM,OAAO,GAAG,EAAM,YACrC,GAAI,IAAc,EAAK,OACvB,IAAM,EAAS,IAAc,KAC7B,EAAY,EACR,GAAQ,EAAM,kBAAkB,CACpC,IAAM,EAAU,EAAM,SAAW,IAAI,EAAA,eACrC,EAAM,QAAQ,CAAE,UAAS,OAAQ,EAAM,OAAQ,UAAW,EAAM,UAAW,aAAc,EAAM,aAAc,CAAC,CAC1G,GAAU,EAAM,eAAe,EAAM,aAAa,EAAM,cAAc,CAG5E,SAAS,GAAyB,CAChC,OAAO,EAGT,SAAS,EAAW,EAAyB,CAC3C,GAAO,WAAW,EAAS,CAG7B,SAAS,GAAmC,CAC1C,OAAO,GAAO,mBAAmB,EAAI,YAGvC,EAAa,CAAE,WAAU,aAAY,oBAAmB,CAAC,EAEzD,EAAA,EAAA,eAAgB,CACT,EAAY,QAEjB,EAAQ,IAAI,EAAA,MAAM,EAAY,MAAO,CACnC,UAAW,EAAM,UACjB,MAAO,EAAa,EAAM,MAAM,CAChC,UAAW,EAAM,UACjB,YAAa,EACb,UAAW,CAAE,KAAM,SAAU,CAC7B,UAAW,EAAM,cACb,CAAE,KAAM,EAAM,cAAe,SAAU,GAAI,MAAO,yBAAyB,CAC3E,IAAA,GACJ,SAAU,CACR,SAAU,GACV,cAAe,GACf,gBAAiB,GACjB,WAAY,GACZ,QAAS,GACT,OAAQ,GACR,OAAQ,GACR,UAAW,GACX,SAAU,GACV,WAAY,GACZ,OAAQ,GACR,aAAc,GACd,SAAU,GACV,UAAW,GACX,GAAG,EAAM,SACV,CACF,CAAC,CAEE,EAAM,KAAM,EAAM,QAAQ,EAAM,KAAK,CACpC,GAAY,EAKjB,EAAA,EAAA,gBAAe,EAAO,EAAW,EAAM,WAAW,CAAE,EAAa,CAC7D,EAAM,eAAe,EAAM,iBAAiB,EAAM,cAAc,CAChE,EAAM,mBAAmB,EAAM,qBAAqB,EAAM,kBAAkB,CAC5E,EAAM,YAAY,EAAM,cAAc,EAAM,WAAW,CACvD,EAAM,gBAAgB,EAAM,kBAAkB,EAAM,eAAe,CACnE,EAAM,WAAW,EAAM,aAAa,EAAM,UAAU,CAExD,EAAK,QAAS,EAAM,GACpB,EAEF,EAAA,EAAA,iBAAkB,CAChB,AAGE,KAFA,EAAM,kBAAkB,CACxB,EAAM,SAAS,CACP,OAEV,EAEF,EAAA,EAAA,WAAY,CAAC,EAAM,OAAQ,EAAM,UAAW,CAAC,EAAM,KAAM,EAAM,OAAO,CAAW,EAAW,EAC5F,EAAA,EAAA,WAAY,EAAM,SAAW,GAAM,CACjC,IAAM,EAAM,KAAK,UAAU,GAAK,KAAK,CACjC,IAAQ,IACZ,EAAc,EACV,GAAG,GAAO,YAAY,CAAE,GAAG,EAAG,CAAC,GAClC,CAAE,KAAM,GAAM,CAAC,EAElB,EAAA,EAAA,WAAY,EAAM,MAAQ,GAAM,CAAE,GAAO,SAAS,EAAa,EAAE,CAAC,EAAI,EACtE,EAAA,EAAA,WAAY,EAAM,UAAY,GAAO,CAAE,GAAO,aAAa,EAAG,EAAI,EAClE,EAAA,EAAA,WAAY,EAAM,KAAO,GAAM,CAAM,GAAG,GAAO,QAAQ,EAAE,EAAK,CAAE,KAAM,GAAM,CAAC,EAE7E,EAAA,EAAA,WACQ,EAAM,WACX,GAAU,CAAM,IAAO,EAAA,EAAA,gBAAe,EAAO,EAAW,EAAM,CAAE,EAAa,EAC9E,CAAE,KAAM,GAAM,CACf,EAED,EAAA,EAAA,WAAY,EAAM,cAAgB,GAAM,CAAM,GAAG,GAAO,iBAAiB,EAAE,EAAK,CAAE,KAAM,GAAM,CAAC,EAC/F,EAAA,EAAA,WAAY,EAAM,kBAAoB,GAAM,CAAM,GAAG,GAAO,qBAAqB,EAAE,EAAK,CAAE,KAAM,GAAM,CAAC,EACvG,EAAA,EAAA,WAAY,EAAM,WAAa,GAAM,CAAM,GAAG,GAAO,cAAc,EAAE,EAAK,CAAE,KAAM,GAAM,CAAC,EACzF,EAAA,EAAA,WAAY,EAAM,eAAiB,GAAM,CAAM,GAAG,GAAO,kBAAkB,EAAE,EAAK,CAAE,KAAM,GAAM,CAAC,EAEjG,EAAA,EAAA,WAAY,EAAM,UAAY,GAAM,CAAE,GAAO,aAAa,CAAE,GAAG,EAAG,CAAC,EAAK,CAAE,KAAM,GAAM,CAAC,oDAxMjB,MAAA,SAA3D,cAAJ,IAAI,EAAe,MAAO,CAAA,MAAA,OAAA,OAAA,OAAiC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { ComponentProvideOptions } from 'vue';
|
|
|
6
6
|
import { DataAdapter } from '@tradecanvas/chart';
|
|
7
7
|
import { DefineComponent } from 'vue';
|
|
8
8
|
import { FeaturesConfig } from '@tradecanvas/chart';
|
|
9
|
+
import { IndicatorSpec } from '@tradecanvas/chart';
|
|
9
10
|
import { OHLCBar } from '@tradecanvas/chart';
|
|
10
11
|
import { PublicProps } from 'vue';
|
|
11
12
|
import { SignalMarker } from '@tradecanvas/chart';
|
|
@@ -20,10 +21,15 @@ declare type __VLS_Props = {
|
|
|
20
21
|
timeframe?: TimeFrame;
|
|
21
22
|
theme?: 'dark' | 'light' | Theme;
|
|
22
23
|
chartType?: ChartType;
|
|
23
|
-
|
|
24
|
+
/** Indicators by id (`'rsi'`), or with their inputs (`{ id: 'ema', params: { period: 50 } }`). */
|
|
25
|
+
indicators?: IndicatorSpec[];
|
|
26
|
+
/** Static bars: the chart shows these, and opens no stream of its own when it has them at mount. */
|
|
24
27
|
data?: OHLCBar[];
|
|
25
28
|
adapter?: DataAdapter;
|
|
29
|
+
/** `false`: no stream until you say so (no Binance by default); the chart waits for `data`. Default `true`. */
|
|
30
|
+
stream?: boolean;
|
|
26
31
|
historyLimit?: number;
|
|
32
|
+
/** What users can do on the chart; changes after mount are applied too (the keys given). */
|
|
27
33
|
features?: FeaturesConfig;
|
|
28
34
|
autoScale?: boolean;
|
|
29
35
|
signalMarkers?: SignalMarker[];
|
|
@@ -56,7 +62,8 @@ symbol: string;
|
|
|
56
62
|
timeframe: TimeFrame;
|
|
57
63
|
theme: "dark" | "light" | Theme;
|
|
58
64
|
chartType: ChartType;
|
|
59
|
-
indicators:
|
|
65
|
+
indicators: IndicatorSpec[];
|
|
66
|
+
stream: boolean;
|
|
60
67
|
historyLimit: number;
|
|
61
68
|
autoScale: boolean;
|
|
62
69
|
}, {}, {}, {}, string, ComponentProvideOptions, false, {
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createElementBlock as e, defineComponent as t, onMounted as n, onUnmounted as r, openBlock as i, ref as a, watch as o } from "vue";
|
|
2
|
-
import { BinanceAdapter as s, Chart as c, DARK_THEME as l, LIGHT_THEME as u } from "@tradecanvas/chart";
|
|
2
|
+
import { BinanceAdapter as s, Chart as c, DARK_THEME as l, LIGHT_THEME as u, syncIndicators as d } from "@tradecanvas/chart";
|
|
3
3
|
//#endregion
|
|
4
4
|
//#region src/TradeCanvas.vue
|
|
5
|
-
var
|
|
5
|
+
var f = /* @__PURE__ */ t({
|
|
6
6
|
__name: "TradeCanvas",
|
|
7
7
|
props: {
|
|
8
8
|
symbol: { default: "BTCUSDT" },
|
|
@@ -12,6 +12,10 @@ var d = /* @__PURE__ */ t({
|
|
|
12
12
|
indicators: { default: () => [] },
|
|
13
13
|
data: {},
|
|
14
14
|
adapter: {},
|
|
15
|
+
stream: {
|
|
16
|
+
type: Boolean,
|
|
17
|
+
default: !0
|
|
18
|
+
},
|
|
15
19
|
historyLimit: { default: 500 },
|
|
16
20
|
features: {},
|
|
17
21
|
autoScale: {
|
|
@@ -26,110 +30,109 @@ var d = /* @__PURE__ */ t({
|
|
|
26
30
|
watermarkText: {}
|
|
27
31
|
},
|
|
28
32
|
emits: ["ready", "crosshairMove"],
|
|
29
|
-
setup(t, { expose:
|
|
30
|
-
let
|
|
31
|
-
function
|
|
33
|
+
setup(t, { expose: f, emit: p }) {
|
|
34
|
+
let m = t, h = p;
|
|
35
|
+
function g(e) {
|
|
32
36
|
return e === "dark" ? l : e === "light" ? u : e;
|
|
33
37
|
}
|
|
34
|
-
let
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
let _ = a(), v = null, y = /* @__PURE__ */ new Map(), b = null, x = (e) => e.map((e) => typeof e == "string" ? e : {
|
|
39
|
+
id: e.id,
|
|
40
|
+
...e.params ? { params: { ...e.params } } : {},
|
|
41
|
+
...e.position ? { position: e.position } : {}
|
|
42
|
+
}), S = JSON.stringify(m.features ?? null);
|
|
43
|
+
function C() {
|
|
44
|
+
if (!v) return;
|
|
45
|
+
if (!m.stream) {
|
|
46
|
+
b !== null && v.disconnectStream(), b = null;
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (m.data) return;
|
|
50
|
+
let e = `${m.symbol}|${m.timeframe}`;
|
|
51
|
+
if (b === e) return;
|
|
52
|
+
let t = b !== null;
|
|
53
|
+
b = e, t && v.disconnectStream();
|
|
54
|
+
let n = m.adapter ?? new s();
|
|
55
|
+
v.connect({
|
|
56
|
+
adapter: n,
|
|
57
|
+
symbol: m.symbol,
|
|
58
|
+
timeframe: m.timeframe,
|
|
59
|
+
historyLimit: m.historyLimit
|
|
60
|
+
}), t && m.watermarkText && v.setWatermark(m.watermarkText);
|
|
61
|
+
}
|
|
62
|
+
function w() {
|
|
63
|
+
return v;
|
|
37
64
|
}
|
|
38
|
-
function
|
|
39
|
-
|
|
65
|
+
function T(e) {
|
|
66
|
+
v?.screenshot(e);
|
|
40
67
|
}
|
|
41
|
-
function
|
|
42
|
-
return
|
|
68
|
+
function E() {
|
|
69
|
+
return v?.screenshotDataURL() ?? null;
|
|
43
70
|
}
|
|
44
|
-
return
|
|
45
|
-
getChart:
|
|
46
|
-
screenshot:
|
|
47
|
-
screenshotDataURL:
|
|
71
|
+
return f({
|
|
72
|
+
getChart: w,
|
|
73
|
+
screenshot: T,
|
|
74
|
+
screenshotDataURL: E
|
|
48
75
|
}), n(() => {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
...p.features
|
|
77
|
-
}
|
|
78
|
-
}), p.data) _.setData(p.data);
|
|
79
|
-
else {
|
|
80
|
-
let e = p.adapter ?? new s();
|
|
81
|
-
_.connect({
|
|
82
|
-
adapter: e,
|
|
83
|
-
symbol: p.symbol,
|
|
84
|
-
timeframe: p.timeframe,
|
|
85
|
-
historyLimit: p.historyLimit
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
for (let e of p.indicators) {
|
|
89
|
-
let t = _.addIndicator(e);
|
|
90
|
-
t && v.set(e, t);
|
|
76
|
+
_.value && (v = new c(_.value, {
|
|
77
|
+
chartType: m.chartType,
|
|
78
|
+
theme: g(m.theme),
|
|
79
|
+
autoScale: m.autoScale,
|
|
80
|
+
rightMargin: 5,
|
|
81
|
+
crosshair: { mode: "magnet" },
|
|
82
|
+
watermark: m.watermarkText ? {
|
|
83
|
+
text: m.watermarkText,
|
|
84
|
+
fontSize: 48,
|
|
85
|
+
color: "rgba(255,255,255,0.03)"
|
|
86
|
+
} : void 0,
|
|
87
|
+
features: {
|
|
88
|
+
drawings: !0,
|
|
89
|
+
drawingMagnet: !0,
|
|
90
|
+
drawingUndoRedo: !0,
|
|
91
|
+
indicators: !0,
|
|
92
|
+
trading: !0,
|
|
93
|
+
volume: !0,
|
|
94
|
+
legend: !0,
|
|
95
|
+
crosshair: !0,
|
|
96
|
+
keyboard: !0,
|
|
97
|
+
screenshot: !0,
|
|
98
|
+
alerts: !0,
|
|
99
|
+
barCountdown: !0,
|
|
100
|
+
logScale: !0,
|
|
101
|
+
watermark: !0,
|
|
102
|
+
...m.features
|
|
91
103
|
}
|
|
92
|
-
|
|
93
|
-
}
|
|
104
|
+
}), m.data ? v.setData(m.data) : C(), d(v, x(m.indicators), y), m.signalMarkers && v.setSignalMarkers(m.signalMarkers), m.signalMarkerStyle && v.setSignalMarkerStyle(m.signalMarkerStyle), m.tradeZones && v.setTradeZones(m.tradeZones), m.tradeZoneStyle && v.setTradeZoneStyle(m.tradeZoneStyle), m.overrides && v.setOverrides(m.overrides), h("ready", v));
|
|
94
105
|
}), r(() => {
|
|
95
|
-
|
|
96
|
-
}), o(() => [
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}), o(() =>
|
|
107
|
-
|
|
108
|
-
}), o(() =>
|
|
109
|
-
|
|
110
|
-
}), o(() =>
|
|
111
|
-
|
|
112
|
-
}, { deep: !0 }), o(() =>
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}, { deep: !0 }), o(() =>
|
|
121
|
-
|
|
122
|
-
}, { deep: !0 }), o(() => p.signalMarkerStyle, (e) => {
|
|
123
|
-
e && _?.setSignalMarkerStyle(e);
|
|
124
|
-
}, { deep: !0 }), o(() => p.tradeZones, (e) => {
|
|
125
|
-
e && _?.setTradeZones(e);
|
|
126
|
-
}, { deep: !0 }), o(() => p.tradeZoneStyle, (e) => {
|
|
127
|
-
e && _?.setTradeZoneStyle(e);
|
|
128
|
-
}, { deep: !0 }), o(() => p.overrides, (e) => {
|
|
129
|
-
_?.setOverrides({ ...e });
|
|
106
|
+
v &&= (v.disconnectStream(), v.destroy(), null);
|
|
107
|
+
}), o(() => [
|
|
108
|
+
m.symbol,
|
|
109
|
+
m.timeframe,
|
|
110
|
+
!m.data,
|
|
111
|
+
m.stream
|
|
112
|
+
], C), o(() => m.features, (e) => {
|
|
113
|
+
let t = JSON.stringify(e ?? null);
|
|
114
|
+
t !== S && (S = t, e && v?.setFeatures({ ...e }));
|
|
115
|
+
}, { deep: !0 }), o(() => m.theme, (e) => {
|
|
116
|
+
v?.setTheme(g(e));
|
|
117
|
+
}), o(() => m.chartType, (e) => {
|
|
118
|
+
v?.setChartType(e);
|
|
119
|
+
}), o(() => m.data, (e) => {
|
|
120
|
+
e && v?.setData(e);
|
|
121
|
+
}, { deep: !0 }), o(() => m.indicators, (e) => {
|
|
122
|
+
v && d(v, x(e), y);
|
|
123
|
+
}, { deep: !0 }), o(() => m.signalMarkers, (e) => {
|
|
124
|
+
e && v?.setSignalMarkers(e);
|
|
125
|
+
}, { deep: !0 }), o(() => m.signalMarkerStyle, (e) => {
|
|
126
|
+
e && v?.setSignalMarkerStyle(e);
|
|
127
|
+
}, { deep: !0 }), o(() => m.tradeZones, (e) => {
|
|
128
|
+
e && v?.setTradeZones(e);
|
|
129
|
+
}, { deep: !0 }), o(() => m.tradeZoneStyle, (e) => {
|
|
130
|
+
e && v?.setTradeZoneStyle(e);
|
|
131
|
+
}, { deep: !0 }), o(() => m.overrides, (e) => {
|
|
132
|
+
v?.setOverrides({ ...e });
|
|
130
133
|
}, { deep: !0 }), (t, n) => (i(), e("div", {
|
|
131
134
|
ref_key: "containerEl",
|
|
132
|
-
ref:
|
|
135
|
+
ref: _,
|
|
133
136
|
style: {
|
|
134
137
|
width: "100%",
|
|
135
138
|
height: "100%"
|
|
@@ -138,6 +141,6 @@ var d = /* @__PURE__ */ t({
|
|
|
138
141
|
}
|
|
139
142
|
});
|
|
140
143
|
//#endregion
|
|
141
|
-
export {
|
|
144
|
+
export { f as TradeCanvas };
|
|
142
145
|
|
|
143
146
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/TradeCanvas.vue","../src/TradeCanvas.vue"],"sourcesContent":["<template>\n <div ref=\"containerEl\" :style=\"{ width: '100%', height: '100%' }\" />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, onUnmounted, watch } from 'vue';\nimport {\n Chart,\n BinanceAdapter,\n DARK_THEME,\n LIGHT_THEME,\n} from '@tradecanvas/chart';\nimport type {\n ChartType,\n TimeFrame,\n FeaturesConfig,\n Theme,\n OHLCBar,\n SignalMarker,\n TradeZone,\n SignalMarkerStyle,\n TradeZoneStyle,\n DataAdapter,\n ChartStyleOverrides,\n} from '@tradecanvas/chart';\n\nconst props = withDefaults(\n defineProps<{\n symbol?: string;\n timeframe?: TimeFrame;\n theme?: 'dark' | 'light' | Theme;\n chartType?: ChartType;\n indicators?: string[];\n data?: OHLCBar[];\n adapter?: DataAdapter;\n historyLimit?: number;\n features?: FeaturesConfig;\n autoScale?: boolean;\n signalMarkers?: SignalMarker[];\n signalMarkerStyle?: SignalMarkerStyle;\n tradeZones?: TradeZone[];\n tradeZoneStyle?: TradeZoneStyle;\n /** Style overrides, by key: all of your app's (`chart.setOverrides`). */\n overrides?: ChartStyleOverrides;\n watermarkText?: string;\n }>(),\n {\n symbol: 'BTCUSDT',\n timeframe: '5m' as TimeFrame,\n theme: 'dark',\n chartType: 'candlestick' as ChartType,\n indicators: () => [],\n historyLimit: 500,\n autoScale: true,\n },\n);\n\nconst emit = defineEmits<{\n ready: [chart: Chart];\n crosshairMove: [payload: unknown];\n}>();\n\nfunction resolveTheme(theme: 'dark' | 'light' | Theme): Theme {\n if (theme === 'dark') return DARK_THEME;\n if (theme === 'light') return LIGHT_THEME;\n return theme as Theme;\n}\n\nconst containerEl = ref<HTMLDivElement>();\nlet chart: Chart | null = null;\nconst indicatorIds = new Map<string, string>();\n\nfunction getChart(): Chart | null {\n return chart;\n}\n\nfunction screenshot(filename?: string): void {\n chart?.screenshot(filename);\n}\n\nfunction screenshotDataURL(): string | null {\n return chart?.screenshotDataURL() ?? null;\n}\n\ndefineExpose({ getChart, screenshot, screenshotDataURL });\n\nonMounted(() => {\n if (!containerEl.value) return;\n\n chart = new Chart(containerEl.value, {\n chartType: props.chartType,\n theme: resolveTheme(props.theme),\n autoScale: props.autoScale,\n rightMargin: 5,\n crosshair: { mode: 'magnet' },\n watermark: props.watermarkText\n ? { text: props.watermarkText, fontSize: 48, color: 'rgba(255,255,255,0.03)' }\n : undefined,\n features: {\n drawings: true,\n drawingMagnet: true,\n drawingUndoRedo: true,\n indicators: true,\n trading: true,\n volume: true,\n legend: true,\n crosshair: true,\n keyboard: true,\n screenshot: true,\n alerts: true,\n barCountdown: true,\n logScale: true,\n watermark: true,\n ...props.features,\n },\n });\n\n if (props.data) {\n chart.setData(props.data);\n } else {\n const adapter = props.adapter ?? new BinanceAdapter();\n chart.connect({ adapter, symbol: props.symbol, timeframe: props.timeframe, historyLimit: props.historyLimit });\n }\n\n // Apply initial reactive collections not covered by the constructor options.\n // Vue's watches aren't immediate, so without this the first render of\n // indicators / signal markers / trade zones would be dropped.\n for (const name of props.indicators) {\n const instanceId = chart.addIndicator(name);\n if (instanceId) indicatorIds.set(name, instanceId);\n }\n if (props.signalMarkers) chart.setSignalMarkers(props.signalMarkers);\n if (props.signalMarkerStyle) chart.setSignalMarkerStyle(props.signalMarkerStyle);\n if (props.tradeZones) chart.setTradeZones(props.tradeZones);\n if (props.tradeZoneStyle) chart.setTradeZoneStyle(props.tradeZoneStyle);\n if (props.overrides) chart.setOverrides(props.overrides);\n\n emit('ready', chart);\n});\n\nonUnmounted(() => {\n if (chart) {\n chart.disconnectStream();\n chart.destroy();\n chart = null;\n }\n});\n\nwatch(\n () => [props.symbol, props.timeframe] as const,\n ([newSymbol, newTimeframe]) => {\n if (!chart || props.data) return;\n chart.disconnectStream();\n const adapter = props.adapter ?? new BinanceAdapter();\n chart.connect({ adapter, symbol: newSymbol, timeframe: newTimeframe, historyLimit: props.historyLimit });\n if (props.watermarkText) chart.setWatermark(props.watermarkText);\n },\n);\n\nwatch(() => props.theme, (t) => { chart?.setTheme(resolveTheme(t)); });\nwatch(() => props.chartType, (ct) => { chart?.setChartType(ct); });\nwatch(() => props.data, (d) => { if (d) chart?.setData(d); }, { deep: true });\n\nwatch(\n () => props.indicators,\n (newIndicators) => {\n if (!chart) return;\n const desired = new Set(newIndicators);\n for (const [name, instanceId] of indicatorIds) {\n if (!desired.has(name)) {\n chart.removeIndicator(instanceId);\n indicatorIds.delete(name);\n }\n }\n for (const name of newIndicators) {\n if (!indicatorIds.has(name)) {\n const instanceId = chart.addIndicator(name);\n if (instanceId) indicatorIds.set(name, instanceId);\n }\n }\n },\n { deep: true },\n);\n\nwatch(() => props.signalMarkers, (m) => { if (m) chart?.setSignalMarkers(m); }, { deep: true });\nwatch(() => props.signalMarkerStyle, (s) => { if (s) chart?.setSignalMarkerStyle(s); }, { deep: true });\nwatch(() => props.tradeZones, (z) => { if (z) chart?.setTradeZones(z); }, { deep: true });\nwatch(() => props.tradeZoneStyle, (s) => { if (s) chart?.setTradeZoneStyle(s); }, { deep: true });\n// All of the host's overrides: keys left out of the prop are taken away.\nwatch(() => props.overrides, (o) => { chart?.setOverrides({ ...o }); }, { deep: true });\n</script>\n","<template>\n <div ref=\"containerEl\" :style=\"{ width: '100%', height: '100%' }\" />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, onUnmounted, watch } from 'vue';\nimport {\n Chart,\n BinanceAdapter,\n DARK_THEME,\n LIGHT_THEME,\n} from '@tradecanvas/chart';\nimport type {\n ChartType,\n TimeFrame,\n FeaturesConfig,\n Theme,\n OHLCBar,\n SignalMarker,\n TradeZone,\n SignalMarkerStyle,\n TradeZoneStyle,\n DataAdapter,\n ChartStyleOverrides,\n} from '@tradecanvas/chart';\n\nconst props = withDefaults(\n defineProps<{\n symbol?: string;\n timeframe?: TimeFrame;\n theme?: 'dark' | 'light' | Theme;\n chartType?: ChartType;\n indicators?: string[];\n data?: OHLCBar[];\n adapter?: DataAdapter;\n historyLimit?: number;\n features?: FeaturesConfig;\n autoScale?: boolean;\n signalMarkers?: SignalMarker[];\n signalMarkerStyle?: SignalMarkerStyle;\n tradeZones?: TradeZone[];\n tradeZoneStyle?: TradeZoneStyle;\n /** Style overrides, by key: all of your app's (`chart.setOverrides`). */\n overrides?: ChartStyleOverrides;\n watermarkText?: string;\n }>(),\n {\n symbol: 'BTCUSDT',\n timeframe: '5m' as TimeFrame,\n theme: 'dark',\n chartType: 'candlestick' as ChartType,\n indicators: () => [],\n historyLimit: 500,\n autoScale: true,\n },\n);\n\nconst emit = defineEmits<{\n ready: [chart: Chart];\n crosshairMove: [payload: unknown];\n}>();\n\nfunction resolveTheme(theme: 'dark' | 'light' | Theme): Theme {\n if (theme === 'dark') return DARK_THEME;\n if (theme === 'light') return LIGHT_THEME;\n return theme as Theme;\n}\n\nconst containerEl = ref<HTMLDivElement>();\nlet chart: Chart | null = null;\nconst indicatorIds = new Map<string, string>();\n\nfunction getChart(): Chart | null {\n return chart;\n}\n\nfunction screenshot(filename?: string): void {\n chart?.screenshot(filename);\n}\n\nfunction screenshotDataURL(): string | null {\n return chart?.screenshotDataURL() ?? null;\n}\n\ndefineExpose({ getChart, screenshot, screenshotDataURL });\n\nonMounted(() => {\n if (!containerEl.value) return;\n\n chart = new Chart(containerEl.value, {\n chartType: props.chartType,\n theme: resolveTheme(props.theme),\n autoScale: props.autoScale,\n rightMargin: 5,\n crosshair: { mode: 'magnet' },\n watermark: props.watermarkText\n ? { text: props.watermarkText, fontSize: 48, color: 'rgba(255,255,255,0.03)' }\n : undefined,\n features: {\n drawings: true,\n drawingMagnet: true,\n drawingUndoRedo: true,\n indicators: true,\n trading: true,\n volume: true,\n legend: true,\n crosshair: true,\n keyboard: true,\n screenshot: true,\n alerts: true,\n barCountdown: true,\n logScale: true,\n watermark: true,\n ...props.features,\n },\n });\n\n if (props.data) {\n chart.setData(props.data);\n } else {\n const adapter = props.adapter ?? new BinanceAdapter();\n chart.connect({ adapter, symbol: props.symbol, timeframe: props.timeframe, historyLimit: props.historyLimit });\n }\n\n // Apply initial reactive collections not covered by the constructor options.\n // Vue's watches aren't immediate, so without this the first render of\n // indicators / signal markers / trade zones would be dropped.\n for (const name of props.indicators) {\n const instanceId = chart.addIndicator(name);\n if (instanceId) indicatorIds.set(name, instanceId);\n }\n if (props.signalMarkers) chart.setSignalMarkers(props.signalMarkers);\n if (props.signalMarkerStyle) chart.setSignalMarkerStyle(props.signalMarkerStyle);\n if (props.tradeZones) chart.setTradeZones(props.tradeZones);\n if (props.tradeZoneStyle) chart.setTradeZoneStyle(props.tradeZoneStyle);\n if (props.overrides) chart.setOverrides(props.overrides);\n\n emit('ready', chart);\n});\n\nonUnmounted(() => {\n if (chart) {\n chart.disconnectStream();\n chart.destroy();\n chart = null;\n }\n});\n\nwatch(\n () => [props.symbol, props.timeframe] as const,\n ([newSymbol, newTimeframe]) => {\n if (!chart || props.data) return;\n chart.disconnectStream();\n const adapter = props.adapter ?? new BinanceAdapter();\n chart.connect({ adapter, symbol: newSymbol, timeframe: newTimeframe, historyLimit: props.historyLimit });\n if (props.watermarkText) chart.setWatermark(props.watermarkText);\n },\n);\n\nwatch(() => props.theme, (t) => { chart?.setTheme(resolveTheme(t)); });\nwatch(() => props.chartType, (ct) => { chart?.setChartType(ct); });\nwatch(() => props.data, (d) => { if (d) chart?.setData(d); }, { deep: true });\n\nwatch(\n () => props.indicators,\n (newIndicators) => {\n if (!chart) return;\n const desired = new Set(newIndicators);\n for (const [name, instanceId] of indicatorIds) {\n if (!desired.has(name)) {\n chart.removeIndicator(instanceId);\n indicatorIds.delete(name);\n }\n }\n for (const name of newIndicators) {\n if (!indicatorIds.has(name)) {\n const instanceId = chart.addIndicator(name);\n if (instanceId) indicatorIds.set(name, instanceId);\n }\n }\n },\n { deep: true },\n);\n\nwatch(() => props.signalMarkers, (m) => { if (m) chart?.setSignalMarkers(m); }, { deep: true });\nwatch(() => props.signalMarkerStyle, (s) => { if (s) chart?.setSignalMarkerStyle(s); }, { deep: true });\nwatch(() => props.tradeZones, (z) => { if (z) chart?.setTradeZones(z); }, { deep: true });\nwatch(() => props.tradeZoneStyle, (s) => { if (s) chart?.setTradeZoneStyle(s); }, { deep: true });\n// All of the host's overrides: keys left out of the prop are taken away.\nwatch(() => props.overrides, (o) => { chart?.setOverrides({ ...o }); }, { deep: true });\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0BA,IAAM,IAAQ,GA+BR,IAAO;EAKb,SAAS,EAAa,GAAwC;AAG5D,UAFI,MAAU,SAAe,IACzB,MAAU,UAAgB,IACvB;;EAGT,IAAM,IAAc,GAAqB,EACrC,IAAsB,MACpB,oBAAe,IAAI,KAAqB;EAE9C,SAAS,IAAyB;AAChC,UAAO;;EAGT,SAAS,EAAW,GAAyB;AAC3C,MAAO,WAAW,EAAS;;EAG7B,SAAS,IAAmC;AAC1C,UAAO,GAAO,mBAAmB,IAAI;;SAGvC,EAAa;GAAE;GAAU;GAAY;GAAmB,CAAC,EAEzD,QAAgB;AACT,SAAY,OA8BjB;QA5BA,IAAQ,IAAI,EAAM,EAAY,OAAO;KACnC,WAAW,EAAM;KACjB,OAAO,EAAa,EAAM,MAAM;KAChC,WAAW,EAAM;KACjB,aAAa;KACb,WAAW,EAAE,MAAM,UAAU;KAC7B,WAAW,EAAM,gBACb;MAAE,MAAM,EAAM;MAAe,UAAU;MAAI,OAAO;MAAyB,GAC3E,KAAA;KACJ,UAAU;MACR,UAAU;MACV,eAAe;MACf,iBAAiB;MACjB,YAAY;MACZ,SAAS;MACT,QAAQ;MACR,QAAQ;MACR,WAAW;MACX,UAAU;MACV,YAAY;MACZ,QAAQ;MACR,cAAc;MACd,UAAU;MACV,WAAW;MACX,GAAG,EAAM;MACV;KACF,CAAC,EAEE,EAAM,KACR,GAAM,QAAQ,EAAM,KAAK;SACpB;KACL,IAAM,IAAU,EAAM,WAAW,IAAI,GAAgB;AACrD,OAAM,QAAQ;MAAE;MAAS,QAAQ,EAAM;MAAQ,WAAW,EAAM;MAAW,cAAc,EAAM;MAAc,CAAC;;AAMhH,SAAK,IAAM,KAAQ,EAAM,YAAY;KACnC,IAAM,IAAa,EAAM,aAAa,EAAK;AAC3C,KAAI,KAAY,EAAa,IAAI,GAAM,EAAW;;AAQpD,IANI,EAAM,iBAAe,EAAM,iBAAiB,EAAM,cAAc,EAChE,EAAM,qBAAmB,EAAM,qBAAqB,EAAM,kBAAkB,EAC5E,EAAM,cAAY,EAAM,cAAc,EAAM,WAAW,EACvD,EAAM,kBAAgB,EAAM,kBAAkB,EAAM,eAAe,EACnE,EAAM,aAAW,EAAM,aAAa,EAAM,UAAU,EAExD,EAAK,SAAS,EAAM;;IACpB,EAEF,QAAkB;AAChB,GAGE,OAFA,EAAM,kBAAkB,EACxB,EAAM,SAAS,EACP;IAEV,EAEF,QACQ,CAAC,EAAM,QAAQ,EAAM,UAAU,GACpC,CAAC,GAAW,OAAkB;AAC7B,OAAI,CAAC,KAAS,EAAM,KAAM;AAC1B,KAAM,kBAAkB;GACxB,IAAM,IAAU,EAAM,WAAW,IAAI,GAAgB;AAErD,GADA,EAAM,QAAQ;IAAE;IAAS,QAAQ;IAAW,WAAW;IAAc,cAAc,EAAM;IAAc,CAAC,EACpG,EAAM,iBAAe,EAAM,aAAa,EAAM,cAAc;IAEnE,EAED,QAAY,EAAM,QAAQ,MAAM;AAAE,MAAO,SAAS,EAAa,EAAE,CAAC;IAAI,EACtE,QAAY,EAAM,YAAY,MAAO;AAAE,MAAO,aAAa,EAAG;IAAI,EAClE,QAAY,EAAM,OAAO,MAAM;AAAE,GAAI,KAAG,GAAO,QAAQ,EAAE;KAAK,EAAE,MAAM,IAAM,CAAC,EAE7E,QACQ,EAAM,aACX,MAAkB;AACjB,OAAI,CAAC,EAAO;GACZ,IAAM,IAAU,IAAI,IAAI,EAAc;AACtC,QAAK,IAAM,CAAC,GAAM,MAAe,EAC/B,CAAK,EAAQ,IAAI,EAAK,KACpB,EAAM,gBAAgB,EAAW,EACjC,EAAa,OAAO,EAAK;AAG7B,QAAK,IAAM,KAAQ,EACjB,KAAI,CAAC,EAAa,IAAI,EAAK,EAAE;IAC3B,IAAM,IAAa,EAAM,aAAa,EAAK;AAC3C,IAAI,KAAY,EAAa,IAAI,GAAM,EAAW;;KAIxD,EAAE,MAAM,IAAM,CACf,EAED,QAAY,EAAM,gBAAgB,MAAM;AAAE,GAAI,KAAG,GAAO,iBAAiB,EAAE;KAAK,EAAE,MAAM,IAAM,CAAC,EAC/F,QAAY,EAAM,oBAAoB,MAAM;AAAE,GAAI,KAAG,GAAO,qBAAqB,EAAE;KAAK,EAAE,MAAM,IAAM,CAAC,EACvG,QAAY,EAAM,aAAa,MAAM;AAAE,GAAI,KAAG,GAAO,cAAc,EAAE;KAAK,EAAE,MAAM,IAAM,CAAC,EACzF,QAAY,EAAM,iBAAiB,MAAM;AAAE,GAAI,KAAG,GAAO,kBAAkB,EAAE;KAAK,EAAE,MAAM,IAAM,CAAC,EAEjG,QAAY,EAAM,YAAY,MAAM;AAAE,MAAO,aAAa,EAAE,GAAG,GAAG,CAAC;KAAK,EAAE,MAAM,IAAM,CAAC,kBA5LrF,EAAoE,OAAA;YAA3D;GAAJ,KAAI;GAAe,OAAO;IAAA,OAAA;IAAA,QAAA;IAAiC"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/TradeCanvas.vue","../src/TradeCanvas.vue"],"sourcesContent":["<template>\n <div ref=\"containerEl\" :style=\"{ width: '100%', height: '100%' }\" />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, onUnmounted, watch } from 'vue';\nimport {\n Chart,\n BinanceAdapter,\n DARK_THEME,\n LIGHT_THEME,\n syncIndicators,\n} from '@tradecanvas/chart';\nimport type {\n ChartType,\n TimeFrame,\n FeaturesConfig,\n Theme,\n OHLCBar,\n SignalMarker,\n TradeZone,\n SignalMarkerStyle,\n TradeZoneStyle,\n DataAdapter,\n ChartStyleOverrides,\n IndicatorSpec,\n} from '@tradecanvas/chart';\n\nconst props = withDefaults(\n defineProps<{\n symbol?: string;\n timeframe?: TimeFrame;\n theme?: 'dark' | 'light' | Theme;\n chartType?: ChartType;\n /** Indicators by id (`'rsi'`), or with their inputs (`{ id: 'ema', params: { period: 50 } }`). */\n indicators?: IndicatorSpec[];\n /** Static bars: the chart shows these, and opens no stream of its own when it has them at mount. */\n data?: OHLCBar[];\n adapter?: DataAdapter;\n /** `false`: no stream until you say so (no Binance by default); the chart waits for `data`. Default `true`. */\n stream?: boolean;\n historyLimit?: number;\n /** What users can do on the chart; changes after mount are applied too (the keys given). */\n features?: FeaturesConfig;\n autoScale?: boolean;\n signalMarkers?: SignalMarker[];\n signalMarkerStyle?: SignalMarkerStyle;\n tradeZones?: TradeZone[];\n tradeZoneStyle?: TradeZoneStyle;\n /** Style overrides, by key: all of your app's (`chart.setOverrides`). */\n overrides?: ChartStyleOverrides;\n watermarkText?: string;\n }>(),\n {\n symbol: 'BTCUSDT',\n timeframe: '5m' as TimeFrame,\n theme: 'dark',\n chartType: 'candlestick' as ChartType,\n indicators: () => [],\n stream: true,\n historyLimit: 500,\n autoScale: true,\n },\n);\n\nconst emit = defineEmits<{\n ready: [chart: Chart];\n crosshairMove: [payload: unknown];\n}>();\n\nfunction resolveTheme(theme: 'dark' | 'light' | Theme): Theme {\n if (theme === 'dark') return DARK_THEME;\n if (theme === 'light') return LIGHT_THEME;\n return theme as Theme;\n}\n\nconst containerEl = ref<HTMLDivElement>();\nlet chart: Chart | null = null;\nconst indicatorIds = new Map<string, string>();\n/** The stream open now (`symbol|timeframe`), or null. */\nlet streamKey: string | null = null;\n\n/** The specs as plain values (not Vue's proxies), for the chart to keep. */\nconst plainSpecs = (specs: readonly IndicatorSpec[]): IndicatorSpec[] =>\n specs.map((spec) => (typeof spec === 'string'\n ? spec\n : { id: spec.id, ...(spec.params ? { params: { ...spec.params } } : {}), ...(spec.position ? { position: spec.position } : {}) }));\n/** The features last applied, as text. */\nlet featuresKey = JSON.stringify(props.features ?? null);\n\n/** A stream of its own while it has no data; `stream: false` closes it. Data given later leaves it be. */\nfunction syncStream(): void {\n if (!chart) return;\n if (!props.stream) {\n if (streamKey !== null) chart.disconnectStream();\n streamKey = null;\n return;\n }\n if (props.data) return;\n const key = `${props.symbol}|${props.timeframe}`;\n if (streamKey === key) return;\n const opened = streamKey !== null;\n streamKey = key;\n if (opened) chart.disconnectStream();\n const adapter = props.adapter ?? new BinanceAdapter();\n chart.connect({ adapter, symbol: props.symbol, timeframe: props.timeframe, historyLimit: props.historyLimit });\n if (opened && props.watermarkText) chart.setWatermark(props.watermarkText);\n}\n\nfunction getChart(): Chart | null {\n return chart;\n}\n\nfunction screenshot(filename?: string): void {\n chart?.screenshot(filename);\n}\n\nfunction screenshotDataURL(): string | null {\n return chart?.screenshotDataURL() ?? null;\n}\n\ndefineExpose({ getChart, screenshot, screenshotDataURL });\n\nonMounted(() => {\n if (!containerEl.value) return;\n\n chart = new Chart(containerEl.value, {\n chartType: props.chartType,\n theme: resolveTheme(props.theme),\n autoScale: props.autoScale,\n rightMargin: 5,\n crosshair: { mode: 'magnet' },\n watermark: props.watermarkText\n ? { text: props.watermarkText, fontSize: 48, color: 'rgba(255,255,255,0.03)' }\n : undefined,\n features: {\n drawings: true,\n drawingMagnet: true,\n drawingUndoRedo: true,\n indicators: true,\n trading: true,\n volume: true,\n legend: true,\n crosshair: true,\n keyboard: true,\n screenshot: true,\n alerts: true,\n barCountdown: true,\n logScale: true,\n watermark: true,\n ...props.features,\n },\n });\n\n if (props.data) chart.setData(props.data);\n else syncStream();\n\n // Apply initial reactive collections not covered by the constructor options.\n // Vue's watches aren't immediate, so without this the first render of\n // indicators / signal markers / trade zones would be dropped.\n syncIndicators(chart, plainSpecs(props.indicators), indicatorIds);\n if (props.signalMarkers) chart.setSignalMarkers(props.signalMarkers);\n if (props.signalMarkerStyle) chart.setSignalMarkerStyle(props.signalMarkerStyle);\n if (props.tradeZones) chart.setTradeZones(props.tradeZones);\n if (props.tradeZoneStyle) chart.setTradeZoneStyle(props.tradeZoneStyle);\n if (props.overrides) chart.setOverrides(props.overrides);\n\n emit('ready', chart);\n});\n\nonUnmounted(() => {\n if (chart) {\n chart.disconnectStream();\n chart.destroy();\n chart = null;\n }\n});\n\nwatch(() => [props.symbol, props.timeframe, !props.data, props.stream] as const, syncStream);\nwatch(() => props.features, (f) => {\n const key = JSON.stringify(f ?? null);\n if (key === featuresKey) return;\n featuresKey = key;\n if (f) chart?.setFeatures({ ...f });\n}, { deep: true });\n\nwatch(() => props.theme, (t) => { chart?.setTheme(resolveTheme(t)); });\nwatch(() => props.chartType, (ct) => { chart?.setChartType(ct); });\nwatch(() => props.data, (d) => { if (d) chart?.setData(d); }, { deep: true });\n\nwatch(\n () => props.indicators,\n (specs) => { if (chart) syncIndicators(chart, plainSpecs(specs), indicatorIds); },\n { deep: true },\n);\n\nwatch(() => props.signalMarkers, (m) => { if (m) chart?.setSignalMarkers(m); }, { deep: true });\nwatch(() => props.signalMarkerStyle, (s) => { if (s) chart?.setSignalMarkerStyle(s); }, { deep: true });\nwatch(() => props.tradeZones, (z) => { if (z) chart?.setTradeZones(z); }, { deep: true });\nwatch(() => props.tradeZoneStyle, (s) => { if (s) chart?.setTradeZoneStyle(s); }, { deep: true });\n// All of the host's overrides: keys left out of the prop are taken away.\nwatch(() => props.overrides, (o) => { chart?.setOverrides({ ...o }); }, { deep: true });\n</script>\n","<template>\n <div ref=\"containerEl\" :style=\"{ width: '100%', height: '100%' }\" />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, onUnmounted, watch } from 'vue';\nimport {\n Chart,\n BinanceAdapter,\n DARK_THEME,\n LIGHT_THEME,\n syncIndicators,\n} from '@tradecanvas/chart';\nimport type {\n ChartType,\n TimeFrame,\n FeaturesConfig,\n Theme,\n OHLCBar,\n SignalMarker,\n TradeZone,\n SignalMarkerStyle,\n TradeZoneStyle,\n DataAdapter,\n ChartStyleOverrides,\n IndicatorSpec,\n} from '@tradecanvas/chart';\n\nconst props = withDefaults(\n defineProps<{\n symbol?: string;\n timeframe?: TimeFrame;\n theme?: 'dark' | 'light' | Theme;\n chartType?: ChartType;\n /** Indicators by id (`'rsi'`), or with their inputs (`{ id: 'ema', params: { period: 50 } }`). */\n indicators?: IndicatorSpec[];\n /** Static bars: the chart shows these, and opens no stream of its own when it has them at mount. */\n data?: OHLCBar[];\n adapter?: DataAdapter;\n /** `false`: no stream until you say so (no Binance by default); the chart waits for `data`. Default `true`. */\n stream?: boolean;\n historyLimit?: number;\n /** What users can do on the chart; changes after mount are applied too (the keys given). */\n features?: FeaturesConfig;\n autoScale?: boolean;\n signalMarkers?: SignalMarker[];\n signalMarkerStyle?: SignalMarkerStyle;\n tradeZones?: TradeZone[];\n tradeZoneStyle?: TradeZoneStyle;\n /** Style overrides, by key: all of your app's (`chart.setOverrides`). */\n overrides?: ChartStyleOverrides;\n watermarkText?: string;\n }>(),\n {\n symbol: 'BTCUSDT',\n timeframe: '5m' as TimeFrame,\n theme: 'dark',\n chartType: 'candlestick' as ChartType,\n indicators: () => [],\n stream: true,\n historyLimit: 500,\n autoScale: true,\n },\n);\n\nconst emit = defineEmits<{\n ready: [chart: Chart];\n crosshairMove: [payload: unknown];\n}>();\n\nfunction resolveTheme(theme: 'dark' | 'light' | Theme): Theme {\n if (theme === 'dark') return DARK_THEME;\n if (theme === 'light') return LIGHT_THEME;\n return theme as Theme;\n}\n\nconst containerEl = ref<HTMLDivElement>();\nlet chart: Chart | null = null;\nconst indicatorIds = new Map<string, string>();\n/** The stream open now (`symbol|timeframe`), or null. */\nlet streamKey: string | null = null;\n\n/** The specs as plain values (not Vue's proxies), for the chart to keep. */\nconst plainSpecs = (specs: readonly IndicatorSpec[]): IndicatorSpec[] =>\n specs.map((spec) => (typeof spec === 'string'\n ? spec\n : { id: spec.id, ...(spec.params ? { params: { ...spec.params } } : {}), ...(spec.position ? { position: spec.position } : {}) }));\n/** The features last applied, as text. */\nlet featuresKey = JSON.stringify(props.features ?? null);\n\n/** A stream of its own while it has no data; `stream: false` closes it. Data given later leaves it be. */\nfunction syncStream(): void {\n if (!chart) return;\n if (!props.stream) {\n if (streamKey !== null) chart.disconnectStream();\n streamKey = null;\n return;\n }\n if (props.data) return;\n const key = `${props.symbol}|${props.timeframe}`;\n if (streamKey === key) return;\n const opened = streamKey !== null;\n streamKey = key;\n if (opened) chart.disconnectStream();\n const adapter = props.adapter ?? new BinanceAdapter();\n chart.connect({ adapter, symbol: props.symbol, timeframe: props.timeframe, historyLimit: props.historyLimit });\n if (opened && props.watermarkText) chart.setWatermark(props.watermarkText);\n}\n\nfunction getChart(): Chart | null {\n return chart;\n}\n\nfunction screenshot(filename?: string): void {\n chart?.screenshot(filename);\n}\n\nfunction screenshotDataURL(): string | null {\n return chart?.screenshotDataURL() ?? null;\n}\n\ndefineExpose({ getChart, screenshot, screenshotDataURL });\n\nonMounted(() => {\n if (!containerEl.value) return;\n\n chart = new Chart(containerEl.value, {\n chartType: props.chartType,\n theme: resolveTheme(props.theme),\n autoScale: props.autoScale,\n rightMargin: 5,\n crosshair: { mode: 'magnet' },\n watermark: props.watermarkText\n ? { text: props.watermarkText, fontSize: 48, color: 'rgba(255,255,255,0.03)' }\n : undefined,\n features: {\n drawings: true,\n drawingMagnet: true,\n drawingUndoRedo: true,\n indicators: true,\n trading: true,\n volume: true,\n legend: true,\n crosshair: true,\n keyboard: true,\n screenshot: true,\n alerts: true,\n barCountdown: true,\n logScale: true,\n watermark: true,\n ...props.features,\n },\n });\n\n if (props.data) chart.setData(props.data);\n else syncStream();\n\n // Apply initial reactive collections not covered by the constructor options.\n // Vue's watches aren't immediate, so without this the first render of\n // indicators / signal markers / trade zones would be dropped.\n syncIndicators(chart, plainSpecs(props.indicators), indicatorIds);\n if (props.signalMarkers) chart.setSignalMarkers(props.signalMarkers);\n if (props.signalMarkerStyle) chart.setSignalMarkerStyle(props.signalMarkerStyle);\n if (props.tradeZones) chart.setTradeZones(props.tradeZones);\n if (props.tradeZoneStyle) chart.setTradeZoneStyle(props.tradeZoneStyle);\n if (props.overrides) chart.setOverrides(props.overrides);\n\n emit('ready', chart);\n});\n\nonUnmounted(() => {\n if (chart) {\n chart.disconnectStream();\n chart.destroy();\n chart = null;\n }\n});\n\nwatch(() => [props.symbol, props.timeframe, !props.data, props.stream] as const, syncStream);\nwatch(() => props.features, (f) => {\n const key = JSON.stringify(f ?? null);\n if (key === featuresKey) return;\n featuresKey = key;\n if (f) chart?.setFeatures({ ...f });\n}, { deep: true });\n\nwatch(() => props.theme, (t) => { chart?.setTheme(resolveTheme(t)); });\nwatch(() => props.chartType, (ct) => { chart?.setChartType(ct); });\nwatch(() => props.data, (d) => { if (d) chart?.setData(d); }, { deep: true });\n\nwatch(\n () => props.indicators,\n (specs) => { if (chart) syncIndicators(chart, plainSpecs(specs), indicatorIds); },\n { deep: true },\n);\n\nwatch(() => props.signalMarkers, (m) => { if (m) chart?.setSignalMarkers(m); }, { deep: true });\nwatch(() => props.signalMarkerStyle, (s) => { if (s) chart?.setSignalMarkerStyle(s); }, { deep: true });\nwatch(() => props.tradeZones, (z) => { if (z) chart?.setTradeZones(z); }, { deep: true });\nwatch(() => props.tradeZoneStyle, (s) => { if (s) chart?.setTradeZoneStyle(s); }, { deep: true });\n// All of the host's overrides: keys left out of the prop are taken away.\nwatch(() => props.overrides, (o) => { chart?.setOverrides({ ...o }); }, { deep: true });\n</script>\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tradecanvas/vue",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Vue 3 component for @tradecanvas/chart — reactive props, template ref, zero boilerplate.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"README.md"
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@tradecanvas/chart": "1.
|
|
37
|
+
"@tradecanvas/chart": "1.16.0"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"vue": ">=3.3.0"
|