diff --git a/examples/GraphicIndicator.js b/examples/GraphicIndicator.js index 5e0c2f6..cefae54 100644 --- a/examples/GraphicIndicator.js +++ b/examples/GraphicIndicator.js @@ -13,8 +13,8 @@ chart.setMarket('BINANCE:BTCEUR', { timeframe: 'W', }); -// TradingView.getIndicator('PUB;5xi4DbWeuIQrU0Fx6ZKiI2odDvIW9q2j').then((indic) => { -TradingView.getIndicator('USER;8bbd8017fd3e4881bf91f4fea5e3d538').then((indic) => { +// TradingView.getIndicator('USER;01efac32df544348810bc843a7515f36').then((indic) => { +TradingView.getIndicator('PUB;5xi4DbWeuIQrU0Fx6ZKiI2odDvIW9q2j').then((indic) => { const STD = new chart.Study(indic); STD.onError((...err) => { @@ -25,19 +25,10 @@ TradingView.getIndicator('USER;8bbd8017fd3e4881bf91f4fea5e3d538').then((indic) = console.log('STD Loaded !'); }); - STD.onUpdate((changes) => { - // STD.graphic; - console.log('Update:', changes); + STD.onUpdate(() => { + console.log(STD.graphic); + // console.log('Tables:', changes, STD.graphic.tables); + // console.log('Cells', STD.graphic.tables[0].cells()); + client.end(); }); }); - -setInterval(() => { - chart.fetchMore(100); -}, 2000); - -setTimeout(() => { - console.log('Setting timeframe to: \'D\''); - chart.setSeries('D'); -}, 5000); - -chart.onUpdate(() => console.log(chart.periods.length)); diff --git a/src/chart/graphicParser.js b/src/chart/graphicParser.js index 79bbada..40c149f 100644 --- a/src/chart/graphicParser.js +++ b/src/chart/graphicParser.js @@ -1,21 +1,159 @@ +const TRANSLATOR = { + /** @typedef {'right' | 'left' | 'both' | 'none'} ExtendValue */ + extend: { + r: 'right', + l: 'left', + b: 'both', + n: 'none', + }, + + /** @typedef {'price' | 'abovebar' | 'belowbar'} yLocValue */ + yLoc: { + pr: 'price', + ab: 'abovebar', + bl: 'belowbar', + }, + + /** + * @typedef {'none' | 'xcross' | 'cross' | 'triangleup' + * | 'triangledown' | 'flag' | 'circle' | 'arrowup' + * | 'arrowdown' | 'label_up' | 'label_down' | 'label_left' + * | 'label_right' | 'label_lower_left' | 'label_lower_right' + * | 'label_upper_left' | 'label_upper_right' | 'label_center' + * | 'square' | 'diamond' + * } LabelStyleValue + * */ + labelStyle: { + n: 'none', + xcr: 'xcross', + cr: 'cross', + tup: 'triangleup', + tdn: 'triangledown', + flg: 'flag', + cir: 'circle', + aup: 'arrowup', + adn: 'arrowdown', + lup: 'label_up', + ldn: 'label_down', + llf: 'label_left', + lrg: 'label_right', + llwlf: 'label_lower_left', + llwrg: 'label_lower_right', + luplf: 'label_upper_left', + luprg: 'label_upper_right', + lcn: 'label_center', + sq: 'square', + dia: 'diamond', + }, + + /** + * @typedef {'solid' | 'dotted' | 'dashed'| 'arrow_left' + * | 'arrow_right' | 'arrow_both'} LineStyleValue + */ + lineStyle: { + sol: 'solid', + dot: 'dotted', + dsh: 'dashed', + al: 'arrow_left', + ar: 'arrow_right', + ab: 'arrow_both', + }, + + /** @typedef {'solid' | 'dotted' | 'dashed'} BoxStyleValue */ + boxStyle: { + sol: 'solid', + dot: 'dotted', + dsh: 'dashed', + }, +}; + +/** + * @typedef {'auto' | 'huge' | 'large' + * | 'normal' | 'small' | 'tiny'} SizeValue + */ +/** @typedef {'top' | 'center' | 'bottom'} VAlignValue */ +/** @typedef {'left' | 'center' | 'right'} HAlignValue */ +/** @typedef {'none' | 'auto'} TextWrapValue */ +/** + * @typedef {'top_left' | 'top_center' | 'top_right' + * | 'middle_left' | 'middle_center' | 'middle_right' + * | 'bottom_left' | 'bottom_center' | 'bottom_right' + * } TablePositionValue + */ + /** * @typedef {Object} GraphicLabel * @prop {number} id Drawing ID + * @prop {number} x Label x position + * @prop {number} y Label y position + * @prop {yLocValue} yLoc yLoc mode + * @prop {string} text Label text + * @prop {LabelStyleValue} style Label style + * @prop {number} color + * @prop {number} textColor + * @prop {SizeValue} size Label size + * @prop {HAlignValue} textAlign Text horizontal align + * @prop {string} toolTip Tooltip text */ /** * @typedef {Object} GraphicLine * @prop {number} id Drawing ID + * @prop {number} x1 First x position + * @prop {number} y1 First y position + * @prop {number} x2 Second x position + * @prop {number} y2 Second y position + * @prop {ExtendValue} extend Horizontal extend + * @prop {LineStyleValue} style Line style + * @prop {number} color Line color + * @prop {number} width Line width */ /** * @typedef {Object} GraphicBox * @prop {number} id Drawing ID + * @prop {number} x1 First x position + * @prop {number} y1 First y position + * @prop {number} x2 Second x position + * @prop {number} y2 Second y position + * @prop {number} color Box color + * @prop {number} bgColor Background color + * @prop {ExtendValue} extend Horizontal extend + * @prop {BoxStyleValue} style Box style + * @prop {number} width Box width + * @prop {string} text Text + * @prop {SizeValue} textSize Text size + * @prop {number} textColor Text color + * @prop {VAlignValue} textVAlign Text vertical align + * @prop {HAlignValue} textHAlign Text horizontal align + * @prop {TextWrapValue} textWrap Text wrap + */ + +/** + * @typedef {Object} TableCell + * @prop {number} id Drawing ID + * @prop {string} text Cell text + * @prop {number} width Cell width + * @prop {number} height Cell height + * @prop {number} textColor Text color + * @prop {HAlignValue} textHAlign Text horizontal align + * @prop {VAlignValue} textVAlign Text Vertical align + * @prop {SizeValue} textSize Text size + * @prop {number} bgColor Background color */ /** * @typedef {Object} GraphicTable * @prop {number} id Drawing ID + * @prop {TablePositionValue} position Table position + * @prop {number} rows Number of rows + * @prop {number} columns Number of columns + * @prop {number} bgColor Background color + * @prop {number} frameColor Frame color + * @prop {number} frameWidth Frame width + * @prop {number} borderColor Border color + * @prop {number} borderWidth Border width + * @prop {() => TableCell[][]} cells Table cells matrix */ /** @@ -70,19 +208,79 @@ module.exports = function graphicParse(rawGraphic = {}, indexes = []) { // console.log('indexes', indexes); return { labels: Object.values(rawGraphic.dwglabels ?? {}).map((l) => ({ - ...l, + id: l.id, + x: indexes[l.x], + y: l.y, + yLoc: TRANSLATOR.yLoc[l.yl] ?? l.yl, + text: l.t, + style: TRANSLATOR.labelStyle[l.st] ?? l.st, + color: l.ci, + textColor: l.tci, + size: l.sz, + textAlign: l.ta, + toolTip: l.tt, })), lines: Object.values(rawGraphic.dwglines ?? {}).map((l) => ({ - ...l, + id: l.id, + x1: indexes[l.x1], + y1: l.y1, + x2: indexes[l.x2], + y2: l.y2, + extend: TRANSLATOR.extend[l.ex] ?? l.ex, + style: TRANSLATOR.lineStyle[l.st] ?? l.st, + color: l.ci, + width: l.w, })), boxes: Object.values(rawGraphic.dwgboxes ?? {}).map((b) => ({ - ...b, + id: b.id, + x1: indexes[b.x1], + y1: b.y1, + x2: indexes[b.x2], + y2: b.y2, + color: b.c, + bgColor: b.bc, + extend: TRANSLATOR.extend[b.ex] ?? b.ex, + style: TRANSLATOR.boxStyle[b.st] ?? b.st, + width: b.w, + text: b.t, + textSize: b.ts, + textColor: b.tc, + textVAlign: b.tva, + textHAlign: b.tha, + textWrap: b.tw, })), tables: Object.values(rawGraphic.dwgtables ?? {}).map((t) => ({ - ...t, + id: t.id, + position: t.pos, + rows: t.rows, + columns: t.cols, + bgColor: t.bgc, + frameColor: t.frmc, + frameWidth: t.frmw, + borderColor: t.brdc, + borderWidth: t.brdw, + cells: () => { + const matrix = []; + Object.values(rawGraphic.dwgtablecells ?? {}).forEach((cell) => { + if (cell.tid !== t.id) return; + if (!matrix[cell.row]) matrix[cell.row] = []; + matrix[cell.row][cell.col] = { + id: cell.id, + text: cell.t, + width: cell.w, + height: cell.h, + textColor: cell.tc, + textHAlign: cell.tha, + textVAlign: cell.tva, + textSize: cell.ts, + bgColor: cell.bgc, + }; + }); + return matrix; + }, })), horizLines: Object.values(rawGraphic.horizlines ?? {}).map((h) => ({