import {useChartOrderStore} from "@/orderbuild.js"; import {invokeCallbacks, prototype} from "@/common.js"; export let widget = null export let chart = null export let crosshairPoint = null export function initWidget(el) { widget = window.tvWidget = new TradingView.widget({ library_path: "/tradingview/charting_library/", // debug: true, autosize: true, symbol: 'AAPL', interval: '1D', container: el, datafeed: new Datafeeds.UDFCompatibleDatafeed("https://demo-feed-data.tradingview.com"), locale: "en", disabled_features: [], enabled_features: [], drawings_access: {type: 'white', tools: [],}, // show no tools }); widget.subscribe('drawing_event', handleDrawingEvent) widget.subscribe('onSelectedLineToolChanged', onSelectedLineToolChanged) widget.onChartReady(initChart) } function initChart() { console.log('init chart') chart = widget.activeChart() chart.crossHairMoved().subscribe(null, (point)=>{ crosshairPoint=point const co = useChartOrderStore() invokeCallbacks(co.drawingCallbacks, 'onRedraw') }) } // noinspection JSUnusedLocalSymbols export const ShapeCallback = { onDraw: () => { }, // start drawing a new shape for the builder onRedraw: () => { }, // the mouse moved while in drawing mode onUndraw: () => { }, // drawing was canceled by clicking on a different tool onAddPoint: () => { }, // the user clicked a point while drawing (that point is added to the points list) onCreate: (shapeId, points, props) => { }, // the user has finished creating all the control points. drawing mode is exited and the initial shape is created. onPoints: (shapeId, points) => { }, // the control points of an existing shape were changed onProps: (shapeId, props) => { }, // the display properties of an existing shape were changed onMove: (shapeId, points) => { }, // the entire shape was moved. todo same as onPoints? onHide: (shapeId, props) => { }, onShow: (shapeId, props) => { }, onClick: (shapeId) => { }, // the shape was selected onDelete: (shapeId) => { }, } // noinspection JSUnusedLocalSymbols export const VerboseCallback = prototype(ShapeCallback, { onDraw: ()=>{console.log('onDraw')}, // onRedraw: ()=>{console.log('onRedraw')}, onUndraw: ()=>{console.log('onUndraw')}, onAddPoint: ()=>{console.log('onAddPoint')}, onCreate: (shapeId, points, props)=>{console.log('onCreate')}, onPoints: (shapeId, points)=>{console.log('onPoints')}, onProps: (shapeId, props)=>{console.log('onProps')}, onMove: (shapeId, points)=>{console.log('onMove')}, onHide: (shapeId, props)=>{console.log('onHide')}, onShow: (shapeId, props)=>{console.log('onShow')}, onClick: (shapeId)=>{console.log('onClick')}, onDelete: (shapeId)=>{console.log('onDelete')}, }) export const BuilderUpdateCallback = prototype(ShapeCallback,{ onCreate(shapeId, points, props) { this.builder.shapes[this.tag] = shapeId; }, onPoints(shapeId, points) { this.builder.points[this.tag] = points; }, onProps(shapeId, props) { this.builder.props[this.tag] = props; }, onMove(shapeId, points) { this.builder.points[this.tag] = points; }, }) export function drawShape(shapeType, ...callbacks) { // puts the chart into a line-drawing mode for a new shape console.log('drawShape', callbacks, shapeType.name, shapeType.code) const co = useChartOrderStore() if( co.drawingCallbacks ) invokeCallbacks(co.drawingCallbacks, 'onUndraw') co.drawingCallbacks = callbacks co.drawing = true widget.selectLineTool(shapeType.code) invokeCallbacks(callbacks, 'onDraw') } export function createShape(shapeType, points, options, ...callbacks) { options.shape = shapeType.code // programatically adds a shape to the chart let shapeId if( points.time || points.price ) shapeId = chart.createShape(points, options) else if( points.length === 1 ) shapeId = chart.createShape(points[0], options) else shapeId = chart.createMultipointShape(points, options) if( callbacks.length ) shapeCallbacks[shapeId] = callbacks console.log('created shape', shapeId) return shapeId } export function cancelDrawing() { const co = useChartOrderStore() if (co.drawing) { invokeCallbacks(co.drawingCallbacks, 'onUndraw') co.drawing = false } } export function builderUpdater(builder, tag='a') { return prototype(BuilderUpdateCallback, {builder,tag}) } export function builderShape(builder, tag, shapeType, ...callbacks) { const updater = builderUpdater(builder, tag) console.log('updater', updater) drawShape(shapeType, updater, ...callbacks) } export function setPoints( shapeId, points ) { if( points.time || points.price ) points = [points] console.log('setting points', shapeId, points) let shape try { shape = chart.getShapeById(shapeId) } catch (e) { return } shape.setPoints(points) } const shapeCallbacks = {} function onSelectedLineToolChanged() { const tool = widget.selectedLineTool(); console.log('line tool changed', tool) if( tool !== 'cursor' ) // 'cursor' cannot be selected manually and only happens just before the 'create' event is issued cancelDrawing(); } function handleDrawingEvent(id, event) { console.log('drawing event', id, event) const shape = event === 'remove' ? null : chart.getShapeById(id); if (event === 'create') { const co = useChartOrderStore(); const callbacks = co.drawingCallbacks console.log('drawing callbacks', callbacks) if (callbacks !== null) { shapeCallbacks[id] = callbacks co.drawing = false const points = shape.getPoints() const props = shape.getProperties() invokeCallbacks(shapeCallbacks[id], 'onCreate', id, points, props) invokeCallbacks(shapeCallbacks[id], 'onPoints', id, points) invokeCallbacks(shapeCallbacks[id], 'onProps', id, props) } } else if (event === 'points_changed') { if (id in shapeCallbacks) { const points = shape.getPoints() console.log('points', points) invokeCallbacks(shapeCallbacks[id], 'onPoints', id, points) } } else if (event === 'properties_changed') { console.log('id in shapes', id in shapeCallbacks, id, shapeCallbacks) if (id in shapeCallbacks) { const props = shape.getProperties() console.log('props', props) invokeCallbacks(shapeCallbacks[id], 'onProps', id, props) } } else if (event === 'move') { if (id in shapeCallbacks) { invokeCallbacks(shapeCallbacks[id], 'onMove', id) } } else if (event === 'remove') { if (id in shapeCallbacks) { invokeCallbacks(shapeCallbacks[id], 'onDelete', id) } } else if (event === 'click') { if (id in shapeCallbacks) { invokeCallbacks(shapeCallbacks[id], 'onClick', id) } } else if (event === 'hide') { if (id in shapeCallbacks) { invokeCallbacks(shapeCallbacks[id], 'onHide', id) } } else if (event === 'show') { if (id in shapeCallbacks) { invokeCallbacks(shapeCallbacks[id], 'onShow', id) } } else console.log('unknown drawing event', event) } export function deleteShape(id) { if( id in shapeCallbacks ) delete shapeCallbacks[id] console.log('removing entity', id) chart.removeEntity(id) }