{"version":3,"file":"255.65cd8aef.js","mappings":"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","sources":["webpack://@finviz/website/../charts/app/lib/shims.ts","webpack://@finviz/website/../charts/app/logger.js","webpack://@finviz/website/../charts/app/models/chart-event-element.ts","webpack://@finviz/website/../charts/app/models/indicator.ts","webpack://@finviz/website/../charts/app/models/overlay.ts","webpack://@finviz/website/../charts/app/models/relationships.ts","webpack://@finviz/website/../charts/app/index.ts","webpack://@finviz/website/../charts/app/controllers/header/fullscreen_button.tsx","webpack://@finviz/website/../charts/app/controllers/header/layout_dropdown.tsx","webpack://@finviz/website/../charts/app/helpers/sorter.ts","webpack://@finviz/website/../charts/app/controllers/header/theme_toggle_button.tsx","webpack://@finviz/website/../charts/app/controllers/header/index.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/stock-detail-timeframe-bar.tsx","webpack://@finviz/website/../charts/app/utils/convert_ta.ts","webpack://@finviz/website/./js/app/charts-lib.ts","webpack://@finviz/website/./js/app/quote/modules/create-alert/async-modules.ts","webpack://@finviz/website/./js/app/quote/modules/save-to-portfolio/async-modules.ts","webpack://@finviz/website/./js/app/shared/tracking.ts","webpack://@finviz/website/./js/main/components/portfolio/async-modules.ts","webpack://@finviz/website/./js/charts_lib_entry_do_not_directly_use_in_website.ts","webpack://@finviz/website/./js/main/hooks/use-track-pageview.ts","webpack://@finviz/website/./js/main/services/async-modules-utils.tsx","webpack://@finviz/website/./js/main/services/import-with-retry.ts","webpack://@finviz/website/../charts/app/canvas/ElementBaseConfig.ts","webpack://@finviz/website/../charts/app/canvas/arrow.ts","webpack://@finviz/website/../charts/app/canvas/brush/brush_v1.ts","webpack://@finviz/website/../charts/app/canvas/callout/callout_utils.ts","webpack://@finviz/website/../charts/app/canvas/callout/callout_v1.ts","webpack://@finviz/website/../charts/app/canvas/curve.ts","webpack://@finviz/website/../charts/app/canvas/ellipse.ts","webpack://@finviz/website/../charts/app/canvas/rotated_rectangle.ts","webpack://@finviz/website/../charts/app/canvas/symbol.ts","webpack://@finviz/website/../charts/app/canvas/drawingTools.ts","webpack://@finviz/website/../charts/app/canvas/element.ts","webpack://@finviz/website/../charts/app/canvas/elliott_waves/elliott_waves.ts","webpack://@finviz/website/../charts/app/canvas/ellipse/ellipse_v1.ts","webpack://@finviz/website/../charts/app/canvas/fibonacci_retracements.ts","webpack://@finviz/website/../charts/app/canvas/horizontal_line.ts","webpack://@finviz/website/../charts/app/canvas/line.ts","webpack://@finviz/website/../charts/app/canvas/measure.ts","webpack://@finviz/website/../charts/app/canvas/pitchfork/pitchfork_utils.ts","webpack://@finviz/website/../charts/app/canvas/pitchfork/pitchfork_v1.ts","webpack://@finviz/website/../charts/app/canvas/polygon.ts","webpack://@finviz/website/../charts/app/canvas/position.ts","webpack://@finviz/website/../charts/app/canvas/rectangle.ts","webpack://@finviz/website/../charts/app/canvas/rotated_rectangle/rotated_rectangle_v1.ts","webpack://@finviz/website/../charts/app/canvas/scaled_line.ts","webpack://@finviz/website/../charts/app/canvas/scaled_text.ts","webpack://@finviz/website/../charts/app/canvas/text.ts","webpack://@finviz/website/../charts/app/canvas/thumb.ts","webpack://@finviz/website/../charts/app/canvas/triangle.ts","webpack://@finviz/website/../charts/app/canvas/vertical_line.ts","webpack://@finviz/website/../charts/app/canvas/xabcd.ts","webpack://@finviz/website/../charts/app/canvas/cache.js","webpack://@finviz/website/../charts/app/models/chart_settings/interfaces.ts","webpack://@finviz/website/../charts/app/charts/utils.ts","webpack://@finviz/website/../charts/app/charts/base_chart.ts","webpack://@finviz/website/../charts/app/charts/candle_stick.ts","webpack://@finviz/website/../charts/app/charts/candle_stick_hollow.ts","webpack://@finviz/website/../charts/app/charts/heikin_ashi.ts","webpack://@finviz/website/../charts/app/charts/line_chart.ts","webpack://@finviz/website/../charts/app/charts/market_sentiment.ts","webpack://@finviz/website/../charts/app/charts/multi_line_chart.ts","webpack://@finviz/website/../charts/app/charts/ohlc_chart.ts","webpack://@finviz/website/../charts/app/charts/perf_chart.ts","webpack://@finviz/website/../charts/app/charts/charts.ts","webpack://@finviz/website/../charts/app/constants/common.ts","webpack://@finviz/website/../charts/app/controllers/autosave/utils.ts","webpack://@finviz/website/../charts/app/controllers/chart-controls/chart-type-select.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/use-chart-types.ts","webpack://@finviz/website/../charts/app/controllers/chart-controls/settings-button.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/use-chart-controls.ts","webpack://@finviz/website/../charts/app/model-hooks/useModelRef.ts","webpack://@finviz/website/../charts/app/controllers/chart-controls/use-chart-model-custom-date-range-values.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/use-charts-path-location.ts","webpack://@finviz/website/../charts/app/controllers/chart-controls/utils.ts","webpack://@finviz/website/../charts/app/controllers/chart-events/async-modules.ts","webpack://@finviz/website/../charts/app/controllers/chart-settings/async-modules.ts","webpack://@finviz/website/../charts/app/modals/background.tsx","webpack://@finviz/website/../charts/app/modals/color_range_row.tsx","webpack://@finviz/website/../charts/app/modals/border.tsx","webpack://@finviz/website/../charts/app/modals/checkbox.tsx","webpack://@finviz/website/../charts/app/modals/font.tsx","webpack://@finviz/website/../charts/app/modals/line.tsx","webpack://@finviz/website/../charts/app/modals/multiline_string.tsx","webpack://@finviz/website/../charts/app/modals/number.tsx","webpack://@finviz/website/../charts/app/modals/string.tsx","webpack://@finviz/website/../charts/app/modals/trend.tsx","webpack://@finviz/website/../charts/app/modals/visibility/visibility-input.tsx","webpack://@finviz/website/../charts/app/modals/visibility/index.tsx","webpack://@finviz/website/../charts/app/modals/element_style.tsx","webpack://@finviz/website/../charts/app/controllers/autosave/constants.ts","webpack://@finviz/website/../charts/app/controllers/autosave/use-drawing-autosave-api.tsx","webpack://@finviz/website/../charts/app/utils/string-byte-length.ts","webpack://@finviz/website/../charts/app/controllers/autosave/use-drawing-auto-save-controls.ts","webpack://@finviz/website/../charts/app/controllers/autosave/use-is-auto-save-active.ts","webpack://@finviz/website/../charts/app/controllers/autosave/with-auto-save.tsx","webpack://@finviz/website/../charts/app/utils/use-prev-state.ts","webpack://@finviz/website/../charts/app/controllers/chart-controls/daily-change-display.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/draw-button.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/fullscreen-button.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/search.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/chart-controls.tsx","webpack://@finviz/website/../charts/app/models/context_menu.ts","webpack://@finviz/website/../charts/app/controllers/context_menu.tsx","webpack://@finviz/website/../charts/app/controllers/pane/chart-event-popover-with-state.tsx","webpack://@finviz/website/../charts/app/utils/use-click-away.ts","webpack://@finviz/website/../charts/app/controllers/pane/load-latest-data-button.tsx","webpack://@finviz/website/../charts/app/utils/use-is-mounted.ts","webpack://@finviz/website/../charts/app/controllers/pane/zoom_controls.tsx","webpack://@finviz/website/../charts/app/controllers/pane/pane.tsx","webpack://@finviz/website/../charts/app/controllers/pane/with-pane-model.tsx","webpack://@finviz/website/../charts/app/controllers/chart/chart-spinner-overlay.tsx","webpack://@finviz/website/../charts/app/controllers/chart/constants.ts","webpack://@finviz/website/../charts/app/controllers/chart/chart.tsx","webpack://@finviz/website/../charts/app/controllers/chart/with-chart-init.tsx","webpack://@finviz/website/../charts/app/controllers/chart/with-watched-panes-on-chart-model.tsx","webpack://@finviz/website/../charts/app/creators/async-modules.ts","webpack://@finviz/website/../charts/app/controllers/toolbar/drawingActions.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/drawingSettings.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/drawingTools.ts","webpack://@finviz/website/../charts/app/controllers/toolbar/toolbar.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/index.ts","webpack://@finviz/website/../charts/app/controllers/toolbar/auto-save-notes/auto-save-notes.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/auto-save-notes/auto-save-notes-dialog.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/confirmation_dialog.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/mobile/toolbar-mobile.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/auto-save-state-indicator.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/chart-layout-auto-save-note.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/publish_old_button_click_listener.tsx","webpack://@finviz/website/../charts/app/controllers/autosave/idea-leave-dialog.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-chart-route-change.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/chart_layout_component.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-quote-cache-management.tsx","webpack://@finviz/website/../charts/app/controllers/with_dialog_state_hook.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-chart-page-title.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-idea-model-state.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/chart_layout.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/constants.ts","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-complete-layout-model-init.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-quote-polling.tsx","webpack://@finviz/website/../charts/app/modals/ideas/utils.ts","webpack://@finviz/website/../charts/app/modals/ideas/IdeaItem.tsx","webpack://@finviz/website/../charts/app/modals/ideas/IdeasTabs.tsx","webpack://@finviz/website/../charts/app/modals/ideas/Ideas.tsx","webpack://@finviz/website/../charts/app/controllers/header/ideas_dropdown.tsx","webpack://@finviz/website/../charts/app/controllers/header/publish.tsx","webpack://@finviz/website/../charts/app/controllers/header/tour_button.tsx","webpack://@finviz/website/../charts/app/utils/chart-date-range-utils.ts","webpack://@finviz/website/../charts/app/controllers/renderUtils.ts","webpack://@finviz/website/../charts/app/controllers/sidebar/constants.ts","webpack://@finviz/website/../charts/app/controllers/sidebar/hooks/sidebar-context.tsx","webpack://@finviz/website/../charts/app/controllers/sidebar/modules/module-load-failed.tsx","webpack://@finviz/website/../charts/app/controllers/sidebar/modules/portfolio-watchlist/async-modules.ts","webpack://@finviz/website/../charts/app/controllers/sidebar/modules/modules.ts","webpack://@finviz/website/../charts/app/controllers/sidebar/modules/with-module-async-load.tsx","webpack://@finviz/website/../charts/app/controllers/sidebar/sidebar-tabs.tsx","webpack://@finviz/website/../charts/app/controllers/sidebar/sidebar-content.tsx","webpack://@finviz/website/../charts/app/controllers/sidebar/sidebar.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/interfaces.ts","webpack://@finviz/website/../charts/app/controllers/utils.ts","webpack://@finviz/website/../charts/app/helpers/atr.ts","webpack://@finviz/website/../charts/app/chart-events/chart-event.ts","webpack://@finviz/website/../charts/app/chart-events/dividends.ts","webpack://@finviz/website/../charts/app/chart-events/earnings.ts","webpack://@finviz/website/../charts/app/chart-events/split.ts","webpack://@finviz/website/../charts/app/chart-events/index.ts","webpack://@finviz/website/../charts/app/helpers/get-canvas-element-by-type.ts","webpack://@finviz/website/../charts/app/helpers/math.ts","webpack://@finviz/website/../charts/app/indicator-calculation/ema.ts","webpack://@finviz/website/../charts/app/indicator-calculation/main.ts","webpack://@finviz/website/../charts/app/indicators/configs/indicatorBaseConfig.ts","webpack://@finviz/website/../charts/app/indicators/configs/shrtfl.ts","webpack://@finviz/website/../charts/app/indicators/configs/shrtra.ts","webpack://@finviz/website/../charts/app/indicators/configs/adx.ts","webpack://@finviz/website/../charts/app/indicators/indicator.ts","webpack://@finviz/website/../charts/app/utils/canvas-render.ts","webpack://@finviz/website/../charts/app/indicators/adx.ts","webpack://@finviz/website/../charts/app/indicators/configs/aro.ts","webpack://@finviz/website/../charts/app/indicator-calculation/aroon.ts","webpack://@finviz/website/../charts/app/indicators/aro.ts","webpack://@finviz/website/../charts/app/indicators/configs/aroosc.ts","webpack://@finviz/website/../charts/app/indicators/aroosc.ts","webpack://@finviz/website/../charts/app/indicators/configs/atr.ts","webpack://@finviz/website/../charts/app/indicators/atr.ts","webpack://@finviz/website/../charts/app/indicators/configs/cci.ts","webpack://@finviz/website/../charts/app/indicators/cci.ts","webpack://@finviz/website/../charts/app/indicators/configs/cot.ts","webpack://@finviz/website/../charts/app/indicators/cot.ts","webpack://@finviz/website/../charts/app/indicators/configs/fi.ts","webpack://@finviz/website/../charts/app/indicator-calculation/fi.ts","webpack://@finviz/website/../charts/app/indicators/fi.ts","webpack://@finviz/website/../charts/app/indicators/configs/macd.ts","webpack://@finviz/website/../charts/app/indicator-calculation/macd.ts","webpack://@finviz/website/../charts/app/indicators/macd.ts","webpack://@finviz/website/../charts/app/indicators/configs/mfi.ts","webpack://@finviz/website/../charts/app/indicators/mfi.ts","webpack://@finviz/website/../charts/app/indicators/configs/none.ts","webpack://@finviz/website/../charts/app/indicators/none.ts","webpack://@finviz/website/../charts/app/indicators/configs/obv.ts","webpack://@finviz/website/../charts/app/indicators/obv.ts","webpack://@finviz/website/../charts/app/indicators/configs/perf.ts","webpack://@finviz/website/../charts/app/indicators/perf.ts","webpack://@finviz/website/../charts/app/indicators/configs/rmi.ts","webpack://@finviz/website/../charts/app/indicators/rmi.ts","webpack://@finviz/website/../charts/app/indicators/configs/roc.ts","webpack://@finviz/website/../charts/app/indicators/roc.ts","webpack://@finviz/website/../charts/app/indicators/configs/rsi.ts","webpack://@finviz/website/../charts/app/indicator-calculation/rsi.ts","webpack://@finviz/website/../charts/app/indicators/rsi.ts","webpack://@finviz/website/../charts/app/indicators/configs/rvol.ts","webpack://@finviz/website/../charts/app/indicators/rvol.ts","webpack://@finviz/website/../charts/app/indicators/configs/rwi.ts","webpack://@finviz/website/../charts/app/indicators/rwi.ts","webpack://@finviz/website/../charts/app/indicators/financialIndicator.ts","webpack://@finviz/website/../charts/app/indicators/shrtfl.ts","webpack://@finviz/website/../charts/app/indicators/shrtra.ts","webpack://@finviz/website/../charts/app/indicators/configs/stofa.ts","webpack://@finviz/website/../charts/app/indicators/configs/stofu.ts","webpack://@finviz/website/../charts/app/indicators/stofu.ts","webpack://@finviz/website/../charts/app/indicators/stofa.ts","webpack://@finviz/website/../charts/app/indicators/configs/stosl.ts","webpack://@finviz/website/../charts/app/indicators/stosl.ts","webpack://@finviz/website/../charts/app/indicators/configs/trix.ts","webpack://@finviz/website/../charts/app/indicator-calculation/trix.ts","webpack://@finviz/website/../charts/app/indicators/trix.ts","webpack://@finviz/website/../charts/app/indicators/configs/ult.ts","webpack://@finviz/website/../charts/app/indicators/ult.ts","webpack://@finviz/website/../charts/app/indicators/configs/vol.ts","webpack://@finviz/website/../charts/app/indicators/vol.ts","webpack://@finviz/website/../charts/app/indicators/configs/wr.ts","webpack://@finviz/website/../charts/app/indicators/wr.ts","webpack://@finviz/website/../charts/app/indicators/indicators.ts","webpack://@finviz/website/../charts/app/modals/publish/async-modules.ts","webpack://@finviz/website/../charts/app/model-hooks/use-model-state.ts","webpack://@finviz/website/../charts/app/models/chart.ts","webpack://@finviz/website/../charts/app/models/chart/contstants.ts","webpack://@finviz/website/../charts/app/models/chart_layout.ts","webpack://@finviz/website/../charts/app/models/chart_settings/index.ts","webpack://@finviz/website/../charts/app/models/constants.ts","webpack://@finviz/website/../charts/app/models/drawings-internal-store.ts","webpack://@finviz/website/../charts/app/models/element.ts","webpack://@finviz/website/../charts/app/models/mouse/mouse-utils.ts","webpack://@finviz/website/../charts/app/models/mouse/mouse.ts","webpack://@finviz/website/../charts/app/models/pane.ts","webpack://@finviz/website/../charts/app/models/quoteCache.ts","webpack://@finviz/website/../charts/app/models/quote.ts","webpack://@finviz/website/../charts/app/models/quote/constants.ts","webpack://@finviz/website/../charts/app/models/chart_settings/constants.ts","webpack://@finviz/website/../charts/app/models/chart_settings/interactive_chart_settings.ts","webpack://@finviz/website/../charts/app/models/settings.ts","webpack://@finviz/website/../charts/app/models/utils.ts","webpack://@finviz/website/../charts/app/overlays/configs/ema.ts","webpack://@finviz/website/../charts/app/overlays/configs/overlayBaseConfig.ts","webpack://@finviz/website/../charts/app/overlays/configs/bb.ts","webpack://@finviz/website/../charts/app/indicator-calculation/bb.ts","webpack://@finviz/website/../charts/app/overlays/overlay.ts","webpack://@finviz/website/../charts/app/overlays/bb.ts","webpack://@finviz/website/../charts/app/overlays/configs/dch.ts","webpack://@finviz/website/../charts/app/overlays/dch.ts","webpack://@finviz/website/../charts/app/overlays/ema.ts","webpack://@finviz/website/../charts/app/overlays/configs/ema2.ts","webpack://@finviz/website/../charts/app/overlays/ema2.ts","webpack://@finviz/website/../charts/app/overlays/configs/hilo.ts","webpack://@finviz/website/../charts/app/overlays/hilo.ts","webpack://@finviz/website/../charts/app/overlays/configs/hline.ts","webpack://@finviz/website/../charts/app/overlays/hline.ts","webpack://@finviz/website/../charts/app/overlays/configs/ic.ts","webpack://@finviz/website/../charts/app/overlays/ic.ts","webpack://@finviz/website/../charts/app/overlays/configs/icf.ts","webpack://@finviz/website/../charts/app/overlays/icf.ts","webpack://@finviz/website/../charts/app/overlays/configs/kch.ts","webpack://@finviz/website/../charts/app/overlays/kch.ts","webpack://@finviz/website/../charts/app/overlays/configs/none.ts","webpack://@finviz/website/../charts/app/overlays/none.ts","webpack://@finviz/website/../charts/app/overlays/configs/patterns.ts","webpack://@finviz/website/../charts/app/overlays/patterns.ts","webpack://@finviz/website/../charts/app/overlays/configs/pp.ts","webpack://@finviz/website/../charts/app/overlays/pp.ts","webpack://@finviz/website/../charts/app/overlays/configs/sar.ts","webpack://@finviz/website/../charts/app/overlays/sar.ts","webpack://@finviz/website/../charts/app/overlays/configs/sma.ts","webpack://@finviz/website/../charts/app/indicator-calculation/sma.ts","webpack://@finviz/website/../charts/app/overlays/sma.ts","webpack://@finviz/website/../charts/app/overlays/configs/sma2.ts","webpack://@finviz/website/../charts/app/overlays/sma2.ts","webpack://@finviz/website/../charts/app/overlays/configs/str.ts","webpack://@finviz/website/../charts/app/overlays/str.ts","webpack://@finviz/website/../charts/app/overlays/configs/vp.ts","webpack://@finviz/website/../charts/app/overlays/vp.ts","webpack://@finviz/website/../charts/app/overlays/configs/vwap.ts","webpack://@finviz/website/../charts/app/indicator-calculation/vwap.ts","webpack://@finviz/website/../charts/app/overlays/vwap.ts","webpack://@finviz/website/../charts/app/overlays/overlays.ts","webpack://@finviz/website/../charts/app/utils.ts","webpack://@finviz/website/../charts/app/utils/abort_controller.ts","webpack://@finviz/website/../charts/app/utils/async-modules-utils.ts","webpack://@finviz/website/../charts/app/utils/canvas.ts","webpack://@finviz/website/../charts/app/utils/chart-events-utils.ts","webpack://@finviz/website/../charts/app/utils/chart-grid-render-utils.ts","webpack://@finviz/website/../charts/app/utils/chart.ts","webpack://@finviz/website/../charts/app/utils/colors.ts","webpack://@finviz/website/../charts/app/utils/cursor.ts","webpack://@finviz/website/../charts/app/utils/draw_in_visible_area.ts","webpack://@finviz/website/../charts/app/utils/fetch_api.ts","webpack://@finviz/website/../charts/app/utils/force-update.ts","webpack://@finviz/website/../charts/app/utils/helpers.ts","webpack://@finviz/website/../charts/app/utils/hlc.ts","webpack://@finviz/website/../charts/app/utils/useChartLayoutGlobalModelAsync.ts","webpack://@finviz/website/../charts/types/shared.ts"],"sourcesContent":["import Spine from '@finviz/spine'\r\n\r\n// eslint-disable-next-line no-extend-native\r\nArray.prototype.last = function () {\r\n return this[this.length - 1]\r\n}\r\n\r\n// eslint-disable-next-line no-extend-native\r\nString.prototype.padLeft = function (paddingValue) {\r\n return String(paddingValue + this).slice(-paddingValue.length)\r\n}\r\n\r\n// eslint-disable-next-line no-extend-native\r\nString.prototype.startsWith = function (str) {\r\n return this.indexOf(str) === 0\r\n}\r\n\r\ninterface CallbackCacheItem {\r\n newCb: (...args: any[]) => any\r\n origCb: (...args: any[]) => any\r\n}\r\n\r\nconst _callbackCache: CallbackCacheItem[] = []\r\nSpine.Collection.prototype.bind = function (ev, callback) {\r\n // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n const that = this\r\n const cb = (record: Spine.Model, ...rest: any[]) => {\r\n if (record[that.fkey as keyof Spine.Model] === that.record.id) {\r\n return callback(record, ...rest)\r\n }\r\n }\r\n _callbackCache.push({ newCb: cb, origCb: callback })\r\n this.model.bind(ev, cb)\r\n return this\r\n}\r\n\r\nSpine.Collection.prototype.unbind = function (ev, callback) {\r\n let cb\r\n for (const item of _callbackCache) {\r\n if (item.origCb === callback) {\r\n cb = item.newCb\r\n break\r\n }\r\n }\r\n return this.model.unbind(ev, cb)\r\n}\r\n\r\nSpine.Model.findIndex = function (element) {\r\n const iterable = this.all()\r\n for (let index = 0; index < iterable.length; index++) {\r\n const el = iterable[index]\r\n if (element.eql(el)) {\r\n return index\r\n }\r\n }\r\n}\r\n","import Spine from '@finviz/spine'\r\n\r\nexport const defaults = {\r\n enabled: false,\r\n collapsed: true,\r\n duration: false,\r\n timestamp: true,\r\n logErrors: true,\r\n withStackTrace: false,\r\n level: 'log',\r\n logger: console,\r\n filterChanges: (model, attrs) => {\r\n const props = Object.keys(attrs)\r\n return (\r\n model.constructor.name === 'Mouse' ||\r\n model.constructor.name === 'Quote' ||\r\n (props.length === 1 && (props[0] === 'scale' || props[0] === 'leftOffset'))\r\n )\r\n },\r\n errorTransformer: (error) => error,\r\n titleFormatter: ({ timestamp, duration }, title, time, took) => {\r\n const parts = ['model']\r\n parts.push(`%c${String(title)}`)\r\n if (timestamp) {\r\n parts.push(`%c@ ${time}`)\r\n }\r\n if (duration) {\r\n parts.push(`%c(in ${took.toFixed(2)} ms)`)\r\n }\r\n return parts.join(' ')\r\n },\r\n colors: {\r\n title: () => 'inherit',\r\n prevState: () => '#9E9E9E',\r\n action: () => '#03A9F4',\r\n nextState: () => '#4CAF50',\r\n error: () => '#F20404',\r\n },\r\n}\r\n\r\nconst repeat = (str, times) => new Array(times + 1).join(str)\r\nconst pad = (num, maxLength = 2) => repeat('0', maxLength - num.toString().length) + num\r\nconst formatTime = (time) =>\r\n `${pad(time.getHours())}:${pad(time.getMinutes())}:${pad(time.getSeconds())}.${pad(time.getMilliseconds(), 3)}`\r\n\r\nexport const printLogEntry = (logEntry, options = {}) => {\r\n const { logger, logErrors, titleFormatter, collapsed, timestamp, duration, withStackTrace, colors, level } = {\r\n ...defaults,\r\n ...options,\r\n }\r\n const { startedTime, title, prevState, data, error, nextState, took } = logEntry\r\n\r\n const formattedTime = formatTime(startedTime)\r\n const titleCSS = colors.title ? `color: ${colors.title(title)};` : ''\r\n const headerCSS = ['color: gray; font-weight: lighter;']\r\n headerCSS.push(titleCSS)\r\n if (timestamp) {\r\n headerCSS.push('color: gray; font-weight: lighter;')\r\n }\r\n if (duration) {\r\n headerCSS.push('color: gray; font-weight: lighter;')\r\n }\r\n const formattedTitle = titleFormatter(defaults, title, formattedTime, took)\r\n\r\n try {\r\n if (collapsed) {\r\n if (colors.title) {\r\n logger.groupCollapsed(`%c ${formattedTitle}`, ...headerCSS)\r\n } else {\r\n logger.groupCollapsed(formattedTitle)\r\n }\r\n } else if (colors.title) {\r\n logger.group(`%c ${formattedTitle}`, ...headerCSS)\r\n } else {\r\n logger.group(formattedTitle)\r\n }\r\n } catch {\r\n logger.log(formattedTitle)\r\n }\r\n\r\n if (colors.prevState) {\r\n const styles = `color: ${colors.prevState(prevState)}; font-weight: bold`\r\n logger[level]('%c prev state', styles, prevState)\r\n } else {\r\n logger[level]('prev state', prevState)\r\n }\r\n\r\n if (colors.action) {\r\n const styles = `color: ${colors.action(data)}; font-weight: bold`\r\n logger[level]('%c arguments ', styles, data)\r\n } else {\r\n logger[level]('arguments ', data)\r\n }\r\n\r\n if (error && logErrors) {\r\n if (colors.error) {\r\n const styles = `color: ${colors.error(error, prevState)}; font-weight: bold;`\r\n logger['error']('%c error ', styles, error)\r\n } else {\r\n logger['error']('error ', error)\r\n }\r\n }\r\n\r\n if (colors.nextState) {\r\n const styles = `color: ${colors.nextState(nextState)}; font-weight: bold`\r\n logger[level]('%c next state', styles, nextState)\r\n } else {\r\n logger[level]('next state', nextState)\r\n }\r\n\r\n if (withStackTrace) {\r\n logger.groupCollapsed('TRACE')\r\n logger.trace()\r\n logger.groupEnd()\r\n }\r\n\r\n try {\r\n logger.groupEnd()\r\n } catch {\r\n logger.log('—— log end ——')\r\n }\r\n}\r\n\r\nexport const initialize = () => {\r\n window['logger'] = defaults\r\n\r\n const protoModelLoad = Spine.Model.prototype.load\r\n Spine.Model.prototype.load = function (attrs) {\r\n if (defaults.enabled && !defaults.filterChanges(this, attrs)) {\r\n const started = Date.now()\r\n const logEntry = {\r\n title: `${this.constructor.name}[#${this.id || this.cid}]`,\r\n started: started,\r\n startedTime: new Date(started),\r\n prevState: this.attributes(),\r\n data: attrs,\r\n }\r\n\r\n let returnedValue\r\n try {\r\n returnedValue = protoModelLoad.apply(this, arguments)\r\n } catch (e) {\r\n logEntry.error = e\r\n }\r\n\r\n logEntry.nextState = this.attributes()\r\n logEntry.took = Date.now() - logEntry.started\r\n\r\n printLogEntry(logEntry)\r\n return returnedValue\r\n } else {\r\n return protoModelLoad.apply(this, arguments)\r\n }\r\n }\r\n}\r\n","import { ObjectHash } from '../../types/shared'\r\nimport { Theme } from '../../types/shared'\r\nimport ChartEvent from '../chart-events/chart-event'\r\nimport { ChartEventBadgeType } from '../constants/common'\r\nimport { chartEventsAsyncModule } from '../controllers/chart-events/async-modules'\r\nimport { ChartEventBadgeState, IChartEventBadgeProps } from '../utils/chart-events-utils'\r\nimport { captureException } from '../utils/helpers'\r\nimport { CHART_EVENT_BADGE_SIZE } from './constants'\r\nimport ElementModel from './element'\r\nimport Pane from './pane'\r\n\r\nlet badgeImages: ObjectHash<{ image: HTMLImageElement; isLoaded?: boolean }, string> | null = null\r\n\r\ntype ChartEventBadgeCommonType = Omit & { badgeType: ChartEventBadgeType }\r\n\r\nfunction getSvgImageCacheKey(props: Pick) {\r\n return `${props.badgeType}-${props.theme}-${props.state}`\r\n}\r\n\r\nasync function fetchAndCacheChartEventBadges({ onBadgeInitLoad }: { onBadgeInitLoad: () => void }) {\r\n // Currently node charts don't render badges and if the code below is executed on server it will crash because of missing file which is not transpiled\r\n if (typeof window === 'undefined') {\r\n return\r\n }\r\n\r\n if (badgeImages === null) {\r\n badgeImages = {}\r\n } else {\r\n // Early return if cache was already initialized\r\n return\r\n }\r\n\r\n // Temp workaround to prevent node charts from crashing\r\n const { importWithRetry } = await import('@finviz/website')\r\n const { chartBadgeSvgByType } = await importWithRetry(chartEventsAsyncModule.importFn)\r\n\r\n const handleImageResolve = () => {\r\n const hasSomeUnresolvedImages = Object.values(badgeImages!).some(({ isLoaded }) => isLoaded === undefined)\r\n if (!hasSomeUnresolvedImages) {\r\n onBadgeInitLoad()\r\n }\r\n }\r\n\r\n Object.values(ChartEventBadgeState).forEach((badgeState) => {\r\n Object.values(ChartEventBadgeType).forEach((badgeType) => {\r\n Object.values(Theme).forEach((theme) => {\r\n const cacheKey = getSvgImageCacheKey({\r\n badgeType,\r\n state: badgeState,\r\n theme,\r\n })\r\n const svgHTML = chartBadgeSvgByType[badgeType]({\r\n state: badgeState,\r\n theme,\r\n width: CHART_EVENT_BADGE_SIZE,\r\n })\r\n const img = new Image()\r\n img.onload = () => {\r\n badgeImages![cacheKey].isLoaded = true\r\n handleImageResolve()\r\n }\r\n img.onerror = () => {\r\n badgeImages![cacheKey].isLoaded = false\r\n handleImageResolve()\r\n captureException(new Error(`Image with cache key ${cacheKey} is invalid`), { extra: { src: img.src } })\r\n }\r\n img.src = `data:image/svg+xml,${encodeURIComponent(svgHTML)}`\r\n badgeImages![cacheKey] = {\r\n image: img,\r\n }\r\n })\r\n })\r\n })\r\n}\r\n\r\nclass ChartEventElement extends ElementModel {\r\n static initClass(paneModel: typeof Pane) {\r\n this.configure('ChartEventElement', 'instance', 'lastChange', 'zIndex', 'yIndex', 'elementId')\r\n this.belongsTo('pane', paneModel)\r\n }\r\n\r\n declare instance: ChartEvent\r\n yIndex = 0\r\n\r\n getChartEventBadgeImage(props: ChartEventBadgeCommonType) {\r\n const cacheKey = getSvgImageCacheKey(props)\r\n const badgeImage = badgeImages?.[cacheKey]\r\n if (badgeImage) {\r\n // Possible fix for https://finvizcom.sentry.io/issues/4737062163\r\n if (badgeImage.isLoaded && badgeImage.image.width > 0 && badgeImage.image.height > 0) {\r\n return badgeImage.image\r\n }\r\n return undefined\r\n }\r\n\r\n void fetchAndCacheChartEventBadges({\r\n onBadgeInitLoad: () => this.trigger('change', this),\r\n })\r\n }\r\n\r\n getChartEventData() {\r\n return this.instance.model\r\n .chart()\r\n .quote()\r\n ?.chartEvents?.find((stockEvent) => stockEvent.elementId === this?.elementId)\r\n }\r\n\r\n toObject() {\r\n return {\r\n ...super.toObject(),\r\n yIndex: this.yIndex,\r\n }\r\n }\r\n\r\n toConfig() {\r\n return {\r\n ...super.toConfig(),\r\n yIndex: this.yIndex,\r\n }\r\n }\r\n}\r\n\r\nexport default ChartEventElement\r\n","import Spine from '@finviz/spine'\r\n\r\nimport Chart from './chart'\r\n\r\nclass Indicator extends Spine.Model {\r\n static initClass(chartModel: typeof Chart) {\r\n this.configure('Indicator', 'instance')\r\n this.belongsTo('chart', chartModel)\r\n }\r\n\r\n declare chart: () => Chart\r\n\r\n // instance - todo - not sure what instance type to put here\r\n}\r\n\r\nexport default Indicator\r\n","import Spine from '@finviz/spine'\r\n\r\nimport Chart from './chart'\r\n\r\nclass Overlay extends Spine.Model {\r\n static initClass(chartModel: typeof Chart) {\r\n this.configure('Overlay', 'overlay')\r\n this.belongsTo('chart', chartModel)\r\n }\r\n\r\n declare overlay: any\r\n declare chart: () => Chart\r\n}\r\n\r\nexport default Overlay\r\n","/**\r\n * This file sets up the relationships between models and solves circular dependencies\r\n * This file needs to be imported in the index file so that the relationships are\r\n * called in time for instantiation.\r\n */\r\nimport Chart from './chart'\r\nimport ChartEventElement from './chart-event-element'\r\nimport ChartLayout from './chart_layout'\r\nimport DrawingsInternalStore from './drawings-internal-store'\r\nimport Element from './element'\r\nimport Indicator from './indicator'\r\nimport Overlay from './overlay'\r\nimport Pane from './pane'\r\nimport Quote from './quote'\r\n\r\nChart.initClass(Pane, Quote, ChartLayout)\r\nChartLayout.initClass(Chart, DrawingsInternalStore)\r\nDrawingsInternalStore.initClass()\r\nElement.initClass(Pane)\r\nChartEventElement.initClass(Pane)\r\nIndicator.initClass(Chart)\r\nOverlay.initClass(Chart)\r\nPane.initClass(Element, ChartEventElement, Chart)\r\n","import './lib/shims'\r\nimport { initialize } from './logger'\r\nimport './models/relationships'\r\n\r\nif (document.location.hostname === 'localhost') {\r\n initialize()\r\n}\r\n","import { Button } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport Utils, { getExitFullscreen, getFullscreenStatus, getRequestFullscreen } from '../../utils'\r\n\r\nconst isIPad = Utils.isIPad()\r\nconst IPAD_FULLSCREEN_CLASS = 'is-ipad-fullscreen'\r\n\r\nexport function FullscreenButton() {\r\n const [isFullscreen, setIsFullscreen] = React.useState(getFullscreenStatus())\r\n const requestFullscreen = getRequestFullscreen(document.documentElement)\r\n const exitFullscreen = getExitFullscreen()\r\n\r\n const onClick = React.useRef(() => {\r\n if (getFullscreenStatus()) {\r\n exitFullscreen.call(document)\r\n } else {\r\n requestFullscreen.call(document.documentElement)\r\n }\r\n })\r\n\r\n React.useEffect(() => {\r\n const checkFullscreen = () => {\r\n if (isIPad) {\r\n if (getFullscreenStatus()) {\r\n document.body.classList.add(IPAD_FULLSCREEN_CLASS)\r\n } else {\r\n document.body.classList.remove(IPAD_FULLSCREEN_CLASS)\r\n }\r\n }\r\n setIsFullscreen(getFullscreenStatus())\r\n }\r\n\r\n document.addEventListener('webkitfullscreenchange', checkFullscreen)\r\n document.addEventListener('fullscreenchange', checkFullscreen)\r\n return () => {\r\n document.removeEventListener('webkitfullscreenchange', checkFullscreen)\r\n document.removeEventListener('fullscreenchange', checkFullscreen)\r\n }\r\n }, [])\r\n\r\n if (!requestFullscreen) return null\r\n\r\n return (\r\n \r\n {isFullscreen ? 'Exit Full screen' : 'Full screen'}\r\n \r\n )\r\n}\r\n","import { Button, Dropdown, DropdownItem, Icon, IconNameType, MenuGroup, Paragraph } from '@finviz/website'\r\nimport * as React from 'react'\r\nimport { useLocation, useNavigate } from 'react-router-dom'\r\n\r\nimport { LAYOUTS } from '../../constants/common'\r\nimport { sortObjects } from '../../helpers/sorter'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { ChartSyncableParts } from '../../models/chart/contstants'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { decodeQueryString } from '../../utils/query_string'\r\nimport { useChartsPathLocation } from '../chart-controls/use-charts-path-location'\r\n\r\nconst SORTED_LAYOUT_KEYS = sortObjects(\r\n Object.entries(LAYOUTS).map(([key, value]) => ({ ...value, key })),\r\n [{ sortBy: 'columns' }, { sortBy: 'count' }]\r\n).map(({ key }) => key)\r\n\r\nexport function ChartLayoutDropdown({ model }: { model: ChartLayout }) {\r\n const location = useLocation()\r\n const navigate = useNavigate()\r\n const parsedQuery = decodeQueryString(location.search)\r\n const chartLayoutModel = useModelState(model, { watchProperties: ['layout', 'syncChartParts'] })\r\n const { getChartsToPath } = useChartsPathLocation({ chartLayoutModel })\r\n\r\n return (\r\n \r\n Layout\r\n \r\n }\r\n >\r\n
\r\n
\r\n {SORTED_LAYOUT_KEYS.map((layout) => (\r\n {\r\n navigate(getChartsToPath({ layout }))\r\n }}\r\n >\r\n \r\n \r\n ))}\r\n
\r\n \r\n
\r\n
\r\n Sync:\r\n
\r\n {ChartSyncableParts.map(({ value, label }) => {\r\n const isChartPartInSync = chartLayoutModel.getIsChartPartInSync(value)\r\n return (\r\n {\r\n chartLayoutModel.setSyncChartParts(value, !isChartPartInSync)\r\n if (!isChartPartInSync) window.gtag?.('event', 'sync', { event_label: value })\r\n }}\r\n >\r\n {label}\r\n \r\n )\r\n })}\r\n
\r\n
\r\n
\r\n \r\n )\r\n}\r\n","import { ObjectHash } from '../../types/shared'\r\nimport { SORT_DIRECTION } from '../constants/common'\r\n\r\nexport function sortObjects(\r\n arr: ObjectHash[],\r\n options: Array<{ sortBy: string; sortDirection?: keyof typeof SORT_DIRECTION }> = []\r\n) {\r\n return arr.sort((a, b) =>\r\n options.reduce((acc, option) => {\r\n const { sortBy, sortDirection = SORT_DIRECTION.ASC } = option\r\n const directionMultiplier = sortDirection === SORT_DIRECTION.ASC ? 1 : -1\r\n return acc === 0 ? (a[sortBy] - b[sortBy]) * directionMultiplier : acc\r\n }, 0)\r\n )\r\n}\r\n","import { Button, setCookieRequest } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { updateSettings } from '../../models/settings'\r\n\r\nexport function ThemeToggleButton({ model }: { model: ChartLayout }) {\r\n const chartLayoutModel = useModelState(model, { watchProperties: ['theme'] })\r\n const isDarkMode = model.theme === 'dark'\r\n\r\n const onClick = () => {\r\n const theme = isDarkMode ? 'light' : 'dark'\r\n chartLayoutModel.updateAttributes({ theme, settings: updateSettings(chartLayoutModel, theme) })\r\n chartLayoutModel.trigger('theme', chartLayoutModel)\r\n setCookieRequest('chartsTheme', theme).catch(() => {})\r\n\r\n if (isDarkMode) {\r\n document.documentElement.classList.remove('dark')\r\n } else {\r\n document.documentElement.classList.add('dark')\r\n }\r\n }\r\n\r\n if (!chartLayoutModel) {\r\n return null\r\n }\r\n\r\n return (\r\n \r\n )\r\n}\r\n","import { Button, Time, TimeBreakpoint } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { FullscreenButton } from './fullscreen_button'\r\nimport { IdeasDropdown } from './ideas_dropdown'\r\nimport { ChartLayoutDropdown } from './layout_dropdown'\r\nimport { Publish } from './publish'\r\nimport { ThemeToggleButton } from './theme_toggle_button'\r\nimport { TourButton } from './tour_button'\r\n\r\nconst BREAKPOINTS: TimeBreakpoint[] = [\r\n { minWidth: -Infinity, marketBadgeText: false, timeFormat: 'timeOnly' },\r\n { minWidth: 550, marketBadgeText: false, timeFormat: 'short' },\r\n { minWidth: 700, marketBadgeText: false, timeFormat: 'long' },\r\n { minWidth: 768, marketBadgeText: true, timeFormat: 'long' },\r\n]\r\n\r\ninterface ChartLayoutHeaderProps {\r\n model: ChartLayout\r\n onSettingsOpen: () => void\r\n hasPublish: boolean\r\n}\r\n\r\nexport function ChartLayoutHeaderComponent({ model, onSettingsOpen = () => {}, hasPublish }: ChartLayoutHeaderProps) {\r\n const chartLayout = useModelState(model, { watchProperties: ['idea'] })!\r\n\r\n return (\r\n <>\r\n
\r\n \r\n Ideas\r\n \r\n
\r\n
\r\n \r\n Chart tour\r\n \r\n \r\n \r\n {hasPublish && (\r\n \r\n Share\r\n \r\n )}\r\n \r\n \r\n \r\n
\r\n \r\n )\r\n}\r\n\r\nexport const ChartLayoutHeader = React.memo(\r\n ChartLayoutHeaderComponent,\r\n (prevProps, nextProps) =>\r\n prevProps.model === nextProps.model &&\r\n prevProps.onSettingsOpen === nextProps.onSettingsOpen &&\r\n prevProps.hasPublish === nextProps.hasPublish\r\n)\r\n","import {\r\n ButtonSizeType,\r\n CustomDateRange,\r\n TimeframeBar,\r\n useCustomDateRangeDialog,\r\n useFavoriteTimeframes,\r\n withSuspense,\r\n} from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { Instrument } from '../../../types/shared'\r\nimport { TIMEFRAME } from '../../constants/common'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { isRedesignEnabled } from '../../utils'\r\nimport { useChartLayoutGlobalModelAsync } from '../../utils/useChartLayoutGlobalModelAsync'\r\nimport { useChartControls } from './use-chart-controls'\r\nimport { useChartModelCustomDateRangeValues } from './use-chart-model-custom-date-range-values'\r\n\r\nconst hasRedesign = isRedesignEnabled()\r\n\r\nfunction StockDetailTimeframeBarRaw({\r\n chartIndex,\r\n size = 'regular',\r\n className = '!m-0 space-x-2',\r\n isDateRangeAvailable,\r\n isPremium,\r\n isLoadingOverride,\r\n isScrollIntoViewEnabled = false,\r\n onTimeframeSelect = () => {},\r\n onDateRangeSelect = () => {},\r\n}: {\r\n chartIndex?: number\r\n size?: ButtonSizeType\r\n className?: string\r\n isDateRangeAvailable: boolean\r\n isPremium: boolean\r\n isLoadingOverride?: boolean\r\n isScrollIntoViewEnabled?: boolean\r\n onTimeframeSelect?: (timeframe: any) => void\r\n onDateRangeSelect?: (timeframe: any) => void\r\n}) {\r\n const { chartLayoutModel } = useChartLayoutGlobalModelAsync()\r\n const chartModelUnwatched = React.useMemo(() => chartLayoutModel?.getAllCharts()[0] ?? null, [chartLayoutModel])\r\n const { favoriteTimeframes, toggleFavoriteTimeframe } = useFavoriteTimeframes(isPremium)\r\n const chartModel = useModelState(chartModelUnwatched, {\r\n watchProperties: ['timeframe', 'dateRange'],\r\n })\r\n const { instrument = Instrument.Stock } = chartModel?.quote() || {}\r\n const { isLoading } = useChartControls({\r\n chartModel,\r\n isInteractive: isDateRangeAvailable,\r\n })\r\n\r\n const {\r\n anchorDate,\r\n generateChartLayoutRouterPath,\r\n timeframeGroupsWithHref,\r\n dateRangeGroupsWithHref,\r\n isFetching,\r\n handleCustomDateRangeValidation,\r\n } = useChartModelCustomDateRangeValues({ chartModel, isPremium })\r\n const { onDialogSubmit, customDateRangeDialogState, handleDateRangeSelect, getDateRangeTimeframe } =\r\n useCustomDateRangeDialog({\r\n instrument,\r\n anchorDate,\r\n pathGenerator: generateChartLayoutRouterPath,\r\n })\r\n\r\n const dateRangeGroups = dateRangeGroupsWithHref({ isPremium, customRange: chartModel?.dateRange, instrument })\r\n const timeFrameGroups = timeframeGroupsWithHref(isPremium)\r\n const selectedTimeframe = chartModel?.timeframe ?? ''\r\n\r\n async function handleCustomRangeSubmit(values: { dateRange: string | null }) {\r\n const dateRangeTimeframe = values.dateRange\r\n ? getDateRangeTimeframe(values.dateRange)\r\n : { value: '', timeframe: chartModel!.timeframe }\r\n\r\n if (dateRangeTimeframe === null) {\r\n return\r\n } else if (dateRangeTimeframe.value) {\r\n const isValid = await handleCustomDateRangeValidation(dateRangeTimeframe)\r\n if (!isValid) {\r\n return\r\n }\r\n }\r\n\r\n onDialogSubmit(dateRangeTimeframe, onDateRangeSelect)\r\n }\r\n\r\n return (\r\n <>\r\n {\r\n handleDateRangeSelect(value)\r\n onDateRangeSelect?.(value)\r\n }}\r\n onCustomDateRangeClick={() => {\r\n if (isPremium) customDateRangeDialogState.show()\r\n }}\r\n onTimeframeSelect={onTimeframeSelect}\r\n onFavoriteTimeframeToggle={({ value }: { value: string }) => {\r\n toggleFavoriteTimeframe(value as TIMEFRAME)\r\n }}\r\n isDateRangeAvailable={isDateRangeAvailable}\r\n containerElement={document.body}\r\n className={className}\r\n isFavoritesEnabled={isPremium}\r\n isScrollIntoViewEnabled={isScrollIntoViewEnabled}\r\n />\r\n\r\n {chartModel && (\r\n \r\n )}\r\n \r\n )\r\n}\r\n\r\nexport const StockDetailTimeframeBar = withSuspense(StockDetailTimeframeBarRaw)\r\n","import { ChartConfigChartPane, Position, RootChartConfigObject } from '../../types/shared'\r\nimport { ChartElementType, IndicatorType, OverlayType, PANE_HEIGHT_DEFAULT, ScaleType } from '../constants/common'\r\n\r\nfunction hasPaneWithCOTCode(panes: ChartConfigChartPane[], code: string) {\r\n return panes.some(({ elements }) =>\r\n elements.some((element) => element.type === IndicatorType.Cot && element.code === code)\r\n )\r\n}\r\nfunction pushIndicators(\r\n panes: ChartConfigChartPane[],\r\n indicator: { name: string; parameters: string },\r\n options?: { COTs?: string[] }\r\n) {\r\n if (indicator.name === 'cot') {\r\n const cotKeys = options?.COTs ?? []\r\n if (cotKeys.length === 0) {\r\n cotKeys.push('')\r\n }\r\n cotKeys.forEach(function (code: string) {\r\n if (!hasPaneWithCOTCode(panes, code)) {\r\n panes.push({\r\n height: PANE_HEIGHT_DEFAULT.indicator,\r\n elements: [\r\n {\r\n type: IndicatorType.Cot,\r\n code,\r\n },\r\n ],\r\n })\r\n }\r\n })\r\n } else {\r\n panes.push({\r\n height: PANE_HEIGHT_DEFAULT.indicator,\r\n elements: [\r\n {\r\n type: ('indicators/' + indicator.name) as IndicatorType,\r\n period: indicator.parameters,\r\n },\r\n ],\r\n })\r\n }\r\n}\r\n\r\nfunction getChartTypeByTaConfigStyle(style: string) {\r\n const chartTypeMap = {\r\n candlestick: ChartElementType.CandleStick,\r\n heikinashi: ChartElementType.HeikinAshi,\r\n hollowcandlestick: ChartElementType.HollowCandleStick,\r\n line: ChartElementType.LineChart,\r\n ohlc: ChartElementType.OhlcChart,\r\n }\r\n return chartTypeMap[style as keyof typeof chartTypeMap]\r\n}\r\n\r\nfunction getChartScaleByTaConfigScale(scale: string | undefined) {\r\n const chartScaleMap = {\r\n linear: ScaleType.Linear,\r\n percentage: ScaleType.Percentage,\r\n logarithmic: ScaleType.Logarithmic,\r\n }\r\n return chartScaleMap[scale as keyof typeof chartScaleMap] ?? ScaleType.Linear\r\n}\r\n\r\n/*\r\n * Merges chartConfig (in \"chart\" format) with taConfig (in format that TA is preserved in DB)\r\n */\r\nexport const mergeChartAndTAConfig = function convertTA(\r\n chartConfig: RootChartConfigObject,\r\n taConfig: TaConfigObject,\r\n options?: { COTs: string[] }\r\n) {\r\n const panes = chartConfig.charts[0].panes\r\n const chart = chartConfig.charts[0]\r\n\r\n chart.scale = getChartScaleByTaConfigScale(taConfig.scale)\r\n\r\n taConfig.indicators\r\n .filter((indicator) => indicator.position === Position.Above)\r\n .forEach((indicator) => {\r\n pushIndicators(panes, indicator, options)\r\n })\r\n\r\n const overlays = taConfig.overlays.map(function (overlay) {\r\n return {\r\n type: ('overlays/' + overlay.name) as OverlayType,\r\n period: overlay.parameters ?? '',\r\n color: overlay.color ?? '',\r\n }\r\n })\r\n panes.push({\r\n height: PANE_HEIGHT_DEFAULT.chart,\r\n elements: [\r\n {\r\n type: getChartTypeByTaConfigStyle(taConfig.style),\r\n overlays: overlays,\r\n },\r\n ],\r\n })\r\n\r\n taConfig.indicators\r\n .filter((indicator) => indicator.position === Position.Below)\r\n .forEach((indicator) => {\r\n pushIndicators(panes, indicator, options)\r\n })\r\n\r\n chartConfig.height = chart.height = PANE_HEIGHT_DEFAULT.chart + (panes.length - 1) * PANE_HEIGHT_DEFAULT.indicator\r\n}\r\n\r\nexport const getPanes = function getPanes(taConfig: TaConfigObject) {\r\n const options = {}\r\n const panes: ChartConfigChartPane[] = []\r\n\r\n taConfig.indicators\r\n .filter((indicator) => indicator.position === Position.Above)\r\n .forEach((indicator) => {\r\n pushIndicators(panes, indicator, options)\r\n })\r\n\r\n const overlays = taConfig.overlays.map(function (overlay) {\r\n return {\r\n type: ('overlays/' + overlay.name) as OverlayType,\r\n period: overlay.parameters ?? '',\r\n color: overlay.color ?? '',\r\n }\r\n })\r\n panes.push({\r\n height: PANE_HEIGHT_DEFAULT.chart,\r\n elements: [\r\n {\r\n type: getChartTypeByTaConfigStyle(taConfig.style),\r\n overlays: overlays,\r\n },\r\n ],\r\n })\r\n\r\n taConfig.indicators\r\n .filter((indicator) => indicator.position === Position.Below)\r\n .forEach((indicator) => {\r\n pushIndicators(panes, indicator, options)\r\n })\r\n\r\n return panes\r\n}\r\n","export * from 'finviz-charts/app/lib-export'\r\n\r\nexport enum SettingsTab {\r\n Chart = 'chart',\r\n Colors = 'colors',\r\n}\r\n\r\nexport enum SidebarDirection {\r\n vertical,\r\n horizontal,\r\n}\r\n","export const createAlertAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"create-alert\" */ './module-entry'),\r\n cacheKey: 'create-alert',\r\n}\r\n","export const saveToPortfolioAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"save-to-portfolio\" */ './module-entry'),\r\n cacheKey: 'save-to-portfolio',\r\n}\r\n","export enum AdsProvider {\r\n None,\r\n InvestingChannel,\r\n Freestar,\r\n}\r\n\r\nexport function getAdsProvider() {\r\n if (FinvizSettings.hasUserPremium) return AdsProvider.None\r\n\r\n if (FinvizSettings.adsProvider === 2) {\r\n return AdsProvider.Freestar\r\n }\r\n\r\n return AdsProvider.InvestingChannel\r\n}\r\n\r\n/**\r\n * Tracks virtual page views to google analytics and freestar\r\n */\r\nexport function trackPageView(props: { pathname?: string; query?: string; freestarPageView?: boolean }) {\r\n const { pathname = window.location.pathname, query = window.location.search, freestarPageView = true } = props\r\n\r\n window.gtag?.('set', 'page_path', `${pathname}${query.length ? '?' : ''}${query.replace(/^\\?/, '')}`)\r\n window.gtag?.('event', 'page_view')\r\n\r\n if (freestarPageView && getAdsProvider() === AdsProvider.Freestar) {\r\n window.freestar?.queue.push(() => freestar.trackPageview())\r\n }\r\n}\r\n","export const portfolioWatchlistTableAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"portfolio-watchlist-table\" */ './PortfolioWatchlistTable'),\r\n cacheKey: 'portfolio-watchlist-table',\r\n}\r\n","import logo from './app/shared/assets/logo.png'\r\nimport logo_light from './app/shared/assets/logo_light.png'\r\n\r\nexport * from './main/components'\r\n\r\nexport { getSanitizedTicker } from './app/shared/ticker-sanitizer'\r\nexport * from './app/queryString'\r\nexport * from './main/modules/portfolio/types'\r\n\r\nexport { getFormattedDateString } from './app/header/utils'\r\nexport { decodeQueryString, encodeQueryString } from './app/queryString'\r\nexport { createAlertAsyncModule } from './app/quote/modules/create-alert/async-modules'\r\nexport { saveToPortfolioAsyncModule } from './app/quote/modules/save-to-portfolio/async-modules'\r\nexport { formatDateToStringUS } from './app/shared/utils'\r\nexport { portfolioWatchlistTableAsyncModule } from './main/components/portfolio/async-modules'\r\nexport { useTrackPageView } from './main/hooks/use-track-pageview'\r\nexport {\r\n useAsyncModule,\r\n withSuspense,\r\n type ControlledModuleConfig,\r\n type SuspenseModuleConfig,\r\n} from './main/services/async-modules-utils'\r\nexport { importWithRetry } from './main/services/import-with-retry'\r\nexport * as localStorage from './main/services/local-storage'\r\nexport { waitForPreviousPromise } from './main/services/wait-for-previous-promise'\r\nexport { setCookieRequest } from './main/services/api'\r\nexport { intervalCallbackOnWindowVisible } from './app/shared/documentVisibility'\r\n\r\nexport const assets = { logo, logo_light }\r\n","import * as React from 'react'\r\nimport { useLocation } from 'react-router-dom'\r\n\r\nimport * as tracking from '../../app/shared/tracking'\r\n\r\nexport function useTrackPageView(props?: { trackInitial?: boolean; trackAutomatically?: boolean }) {\r\n const { trackInitial = false, trackAutomatically = true } = props ?? {}\r\n const initialRender = React.useRef(trackInitial)\r\n const location = useLocation()\r\n\r\n const handleTrackView = React.useCallback(() => {\r\n tracking.trackPageView({ pathname: location.pathname, query: location.search })\r\n }, [location.pathname, location.search])\r\n\r\n React.useEffect(() => {\r\n if (!trackAutomatically) return\r\n if (initialRender.current) handleTrackView()\r\n initialRender.current = true\r\n }, [trackAutomatically, handleTrackView, trackInitial])\r\n\r\n return handleTrackView\r\n}\r\n","import * as React from 'react'\r\n\r\nimport { Notification, useNotification } from '../components/notification'\r\nimport { Paragraph } from '../components/typography'\r\nimport { useIsMounted } from '../hooks/use-is-mounted'\r\nimport { importWithRetry } from './import-with-retry'\r\n\r\nconst cache: any = {}\r\nconst errorsCache: any = {}\r\n\r\nenum ErrorSeverity {\r\n medium,\r\n high,\r\n}\r\n\r\nfunction defaultCaptureException(exception: Error, captureContext?: { extra: Record }) {\r\n if (process.env.NODE_ENV === 'development') {\r\n console.error(exception)\r\n } else {\r\n window.Sentry.captureException(exception, captureContext)\r\n }\r\n}\r\n\r\nexport interface ControlledModuleConfig {\r\n /**\r\n * Suspense mode shouldn’t be used together with controlled loading as it could lead to bugs.\r\n * If you know what you’re doing, add an ignore comment explaining the decision\r\n */\r\n isSuspenseMode?: never\r\n shouldLoadModule?: boolean\r\n}\r\nexport interface SuspenseModuleConfig {\r\n /**\r\n * Controlled loading shouldn’t be used together with suspense mode as it could lead to bugs.\r\n * If you know what you’re doing, add an ignore comment explaining the decision\r\n */\r\n shouldLoadModule?: never\r\n isSuspenseMode?: SuspenseMode\r\n}\r\n\r\n/**\r\n * Hook used to asynchronously load a module\r\n *\r\n * Usage: [wiki](https://github.com/finvizhq/Finviz-Website/wiki/Loading-modules-asynchronously#useasyncmodule)\r\n */\r\nexport function useAsyncModule({\r\n importFn,\r\n onError,\r\n errorSeverity,\r\n cacheKey,\r\n captureException = defaultCaptureException,\r\n shouldLoadModule = false,\r\n isSuspenseMode = false as SuspenseMode,\r\n}: {\r\n importFn: () => Promise\r\n onError?: () => void\r\n cacheKey: string\r\n errorSeverity?: keyof typeof ErrorSeverity\r\n captureException?: typeof defaultCaptureException\r\n} & (ControlledModuleConfig | SuspenseModuleConfig)) {\r\n const notificationContext = useNotification()\r\n const [isLoading, setIsLoading] = React.useState(null)\r\n const [isError, setIsError] = React.useState(false)\r\n const getIsMounted = useIsMounted()\r\n\r\n const handleError = () => {\r\n onError?.()\r\n setIsError(true)\r\n\r\n if (errorSeverity === undefined) {\r\n return\r\n }\r\n\r\n if (ErrorSeverity[errorSeverity] === ErrorSeverity.high) {\r\n window.handleScriptNotLoaded()\r\n window.renderScriptNotLoaded()\r\n }\r\n\r\n if (ErrorSeverity[errorSeverity] === ErrorSeverity.medium) {\r\n notificationContext.show(\r\n \r\n \r\n One or more of the required application components couldn’t be loaded.
Please try to repeat the\r\n action or{' '}\r\n window.location.reload()}>\r\n refresh the page\r\n {' '}\r\n if the problem persists.\r\n
\r\n
\r\n )\r\n }\r\n }\r\n\r\n const loadModule = async () => {\r\n if (cache[cacheKey]) {\r\n return cache[cacheKey]\r\n }\r\n\r\n setIsLoading(true)\r\n\r\n try {\r\n cache[cacheKey] = await importWithRetry(importFn)\r\n } catch (error) {\r\n captureException(error as Error)\r\n handleError()\r\n } finally {\r\n if (getIsMounted()) {\r\n setIsLoading(false)\r\n }\r\n }\r\n\r\n return cache[cacheKey]\r\n }\r\n\r\n React.useEffect(() => {\r\n if (shouldLoadModule) {\r\n loadModule()\r\n }\r\n // We want to run it only on shouldLoadModule change\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [shouldLoadModule])\r\n\r\n const cachedModule = cache[cacheKey]\r\n if (isSuspenseMode) {\r\n if (errorsCache[cacheKey]) throw errorsCache[cacheKey]\r\n if (!cachedModule) {\r\n throw importFn()\r\n .then((mod) => (cache[cacheKey] = mod))\r\n .catch((err) => {\r\n handleError()\r\n errorsCache[cacheKey] = err\r\n })\r\n }\r\n }\r\n\r\n return [cachedModule ?? null, { isLoading: !!cachedModule ? false : isLoading, loadModule, isError }] as [\r\n SuspenseMode extends true ? T : T | null,\r\n { isLoading: boolean; loadModule: () => Promise; isError: boolean },\r\n ]\r\n}\r\n\r\n/**\r\n * HOC which wraps component in React.Suspense\r\n *\r\n * Usage: [wiki](https://github.com/finvizhq/Finviz-Website/wiki/Loading-modules-asynchronously#withsuspense)\r\n */\r\nexport function withSuspense

>(\r\n Component: React.ComponentType

,\r\n fallback: React.ReactNode = null\r\n) {\r\n return function WrappedComponent(props: P) {\r\n return (\r\n \r\n \r\n \r\n )\r\n }\r\n}\r\n","const NUM_OF_RETRIES = 3\r\n\r\nexport function importWithRetry(importFn: () => Promise, retries = 0) {\r\n const result = importFn().catch(async (err) => {\r\n if (retries > NUM_OF_RETRIES) {\r\n throw err\r\n }\r\n\r\n await new Promise((r) => setTimeout(r, 1000 * retries))\r\n\r\n return importWithRetry(importFn, retries + 1)\r\n }) as Promise\r\n\r\n return result\r\n}\r\n","export default class ElementBaseConfig {\r\n static type: string\r\n static abbreviation: string\r\n static label: string\r\n static shortLabel: string\r\n static description: string\r\n static optionsOrder: readonly string[]\r\n static optionsLabels: { [key: string]: string }\r\n static inputsOrder: readonly string[]\r\n static inputsLabels: { [key: string]: string }\r\n static calculatedValuesOrder: readonly string[]\r\n static calculatedValuesLabels: { [key: string]: string }\r\n static defaultCalculatedValueOption?: string\r\n\r\n static getShortLabelWithAttrs: (attrs: ObjectHash) => string\r\n static getDefaultCalculatedValues: () => { [key: string]: number[] }\r\n\r\n get type() {\r\n return (this.constructor as typeof ElementBaseConfig).type\r\n }\r\n\r\n get abbreviation() {\r\n return (this.constructor as typeof ElementBaseConfig).abbreviation\r\n }\r\n\r\n get label() {\r\n return (this.constructor as typeof ElementBaseConfig).label\r\n }\r\n\r\n get shortLabel() {\r\n return (this.constructor as typeof ElementBaseConfig).shortLabel\r\n }\r\n\r\n get description() {\r\n return (this.constructor as typeof ElementBaseConfig).description\r\n }\r\n\r\n get optionsOrder() {\r\n return (this.constructor as typeof ElementBaseConfig).optionsOrder\r\n }\r\n\r\n get optionsLabels() {\r\n return (this.constructor as typeof ElementBaseConfig).optionsLabels\r\n }\r\n\r\n get inputsOrder() {\r\n return (this.constructor as typeof ElementBaseConfig).inputsOrder\r\n }\r\n\r\n get inputsLabels() {\r\n return (this.constructor as typeof ElementBaseConfig).inputsLabels\r\n }\r\n\r\n get calculatedValuesOrder() {\r\n return (this.constructor as typeof ElementBaseConfig).calculatedValuesOrder\r\n }\r\n\r\n get calculatedValuesLabels() {\r\n return (this.constructor as typeof ElementBaseConfig).calculatedValuesLabels\r\n }\r\n\r\n get defaultCalculatedValueOption() {\r\n return (this.constructor as typeof ElementBaseConfig).defaultCalculatedValueOption\r\n }\r\n\r\n get getShortLabelWithAttrs() {\r\n return (this.constructor as typeof ElementBaseConfig).getShortLabelWithAttrs\r\n }\r\n\r\n get getDefaultCalculatedValues() {\r\n return (this.constructor as typeof ElementBaseConfig).getDefaultCalculatedValues\r\n }\r\n}\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface IArrowAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n border: DrawingBorder\r\n}\r\n\r\nclass Arrow extends Element {\r\n static type = CanvasElementType.arrow\r\n\r\n declare scaled: Pick\r\n name = 'Arrow'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.renderContent = this.renderContent.bind(this)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'l',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'r',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n border: {\r\n width: 3,\r\n color: this.getChartLayoutSettings().ElementSettings.Colors.line,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, y1, y2 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, y1, y2 })\r\n const translateXY = getXYOffsetFromLine({ lineWidth: this.attrs.border.width, ...roundedXY })\r\n\r\n context.translate(translateXY.x, translateXY.y)\r\n context.beginPath()\r\n context.set('lineCap', 'round')\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n\r\n const angle = Math.PI / 8\r\n const d = 20\r\n\r\n context.beginPath()\r\n context.moveTo(roundedXY.x1, roundedXY.y1)\r\n context.lineTo(roundedXY.x2, roundedXY.y2)\r\n context.stroke()\r\n\r\n const lineAngle = Math.atan2(roundedXY.y2 - roundedXY.y1, roundedXY.x2 - roundedXY.x1)\r\n const h = Math.abs(d / Math.cos(angle))\r\n\r\n const angle1 = lineAngle + angle\r\n const topx = roundedXY.x1 + Math.cos(angle1) * h\r\n const topy = roundedXY.y1 + Math.sin(angle1) * h\r\n const angle2 = lineAngle - angle\r\n const botx = roundedXY.x1 + Math.cos(angle2) * h\r\n const boty = roundedXY.y1 + Math.sin(angle2) * h\r\n\r\n context.beginPath()\r\n context.moveTo(topx, topy)\r\n context.lineTo(roundedXY.x1, roundedXY.y1)\r\n context.lineTo(botx, boty)\r\n context.stroke()\r\n context.translate(translateXY.x * -1, translateXY.y * -1)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.x2 += x\r\n this.attrs.y1 += y\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n if (type === 'l') {\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n } else {\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n if (math.distanceToSegment(area.scaled, this.scaled) <= 10) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nArrow.prototype.modalConfig = {\r\n inputs: [{ type: 'line', name: 'border' }],\r\n}\r\n\r\nexport default Arrow\r\n","import { DrawingBorder, PaneArea, RequireByKey, ResizeByThumbFuncProps } from '../../../types/shared'\r\nimport { CanvasElementType } from '../../constants/common'\r\nimport math from '../../helpers/math'\r\nimport PaneModel from '../../models/pane'\r\nimport { getContextWithCache } from '../../utils/canvas'\r\nimport Element, { EdgeValues } from '../element'\r\nimport Thumb from '../thumb'\r\n\r\nexport type BrushPoints = Array<[x: number, y: number]>\r\n\r\nexport interface IBrushAttrs {\r\n points: BrushPoints\r\n fill: string\r\n border: DrawingBorder\r\n isPolyLineClosed: boolean\r\n positionPointsTimestamps: BrushPoints\r\n}\r\n\r\nclass Brush extends Element {\r\n static type = CanvasElementType.brushV1\r\n\r\n untranslatedContext: CanvasRenderingContext2D | null = null\r\n\r\n name = 'Brush'\r\n\r\n brushPath: Path2D | null = null\r\n\r\n cachedFill = {\r\n previousFill: '',\r\n shouldRenderFill: false,\r\n }\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.untranslatedContext = getContextWithCache(document.createElement('canvas'))\r\n this.setFillCache()\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultTransparentFill,\r\n border: {\r\n width: 3,\r\n color: ElementSettings.Colors.border,\r\n },\r\n isPolyLineClosed: false,\r\n } as Partial\r\n }\r\n\r\n setFillCache() {\r\n this.cachedFill.previousFill = this.attrs.fill\r\n if (this.attrs.fill.length === 9) {\r\n this.cachedFill.shouldRenderFill = this.attrs.fill.slice(7) !== '00'\r\n } else {\r\n this.cachedFill.shouldRenderFill = true\r\n }\r\n }\r\n\r\n getShouldRenderFill() {\r\n if (this.attrs.fill !== this.cachedFill.previousFill) {\r\n this.setFillCache()\r\n }\r\n return this.cachedFill.shouldRenderFill\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n if (this.attrs.border != null) {\r\n context.set('strokeStyle', this.attrs.border.color)\r\n }\r\n context.set('lineCap', 'round')\r\n context.set('lineJoin', 'round')\r\n\r\n const brushPath = new Path2D()\r\n const { points } = this.attrs\r\n context.beginPath()\r\n brushPath.moveTo(this.fx(points[0][0]), this.fy(points[0][1]))\r\n let i\r\n if (points.length > 3) {\r\n for (i = 0; i < points.length - 2; i++) {\r\n const xc = (this.fx(points[i][0]) + this.fx(points[i + 1][0])) / 2\r\n const yc = (this.fy(points[i][1]) + this.fy(points[i + 1][1])) / 2\r\n brushPath.quadraticCurveTo(this.fx(points[i][0]), this.fy(points[i][1]), xc, yc)\r\n }\r\n brushPath.quadraticCurveTo(\r\n this.fx(points[i][0]),\r\n this.fy(points[i][1]),\r\n this.fx(points[i + 1][0]),\r\n this.fy(points[i + 1][1])\r\n )\r\n } else {\r\n for (const point of points) {\r\n brushPath.lineTo(this.fx(point[0]), this.fy(point[1]))\r\n }\r\n }\r\n\r\n if (this.attrs.isPolyLineClosed) {\r\n brushPath.closePath()\r\n }\r\n this.brushPath = brushPath\r\n if (this.attrs.fill && this.getShouldRenderFill()) {\r\n context.set('fillStyle', this.attrs.fill)\r\n context.fill(brushPath)\r\n }\r\n if (this.attrs?.border?.width) {\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.stroke(brushPath)\r\n }\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getThumbs() {\r\n const [firstX, firstY] = this.attrs.points[0]\r\n const [lastX, lastY] = this.attrs.points[this.attrs.points.length - 1]\r\n\r\n return [\r\n new Thumb(\r\n 'first',\r\n () => firstX,\r\n () => firstY,\r\n this.moveByThumb,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'last',\r\n () => lastX,\r\n () => lastY,\r\n this.moveByThumb,\r\n this.model\r\n ),\r\n ]\r\n }\r\n\r\n moveByThumb = ({ difX, difY }: RequireByKey) => {\r\n this.moveBy(difX, difY)\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n if (this.getIsCreator()) return\r\n for (const point of this.attrs.points) {\r\n point[0] += x\r\n point[1] += y\r\n }\r\n }\r\n\r\n onMouseUp() {\r\n const [currentDomainMax, currentDomainMin] = this.model.scale.y.domain()\r\n for (const point of this.attrs.points) {\r\n point[0] = this.roundToFixed(point[0], 2)\r\n point[1] = this.roundY(point[1], currentDomainMax - currentDomainMin)\r\n }\r\n super.onMouseUp()\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const { points } = this.attrs\r\n if (\r\n (this.getShouldRenderFill() || this.attrs.isPolyLineClosed) &&\r\n this.brushPath &&\r\n this.untranslatedContext?.isPointInPath(this.brushPath, area.scaled.x, area.scaled.y)\r\n ) {\r\n return true\r\n } else if (points.length > 1) {\r\n for (let i = 0; i < points.length - 1; i++) {\r\n if (\r\n math.distanceToSegment(area.scaled, {\r\n x1: this.fx(points[i][0]),\r\n y1: this.fy(points[i][1]),\r\n x2: this.fx(points[i + 1][0]),\r\n y2: this.fy(points[i + 1][1]),\r\n }) <= 10\r\n ) {\r\n return true\r\n }\r\n }\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n cachePointPositionTimestamp = () => {\r\n const quote = this.model?.chart()?.quote()\r\n if (quote) {\r\n const positionPointsTimestamps = this.attrs.points.map(([x, y]) => [quote.getTimestampFomPositionX(x), y])\r\n this.set({ positionPointsTimestamps } as Partial)\r\n }\r\n }\r\n\r\n updateScales() {\r\n const quote = this.model.chart().quote()\r\n const { positionPointsTimestamps } = this.attrs\r\n if (!quote || !positionPointsTimestamps) {\r\n // positionPointsTimestamps check is temporary to prevent app from crashing\r\n // caused by corrupted drawings - https://github.com/finvizhq/charts/pull/1386/files\r\n return\r\n }\r\n const points = positionPointsTimestamps.map(([x, y]) => [quote.getPositionXFromTimestamp(x), y])\r\n this.set({ points } as Partial)\r\n }\r\n\r\n roundToFixed = (value: number, places: number) => Number.parseFloat(math.round({ value, overridePlaces: places }))\r\n\r\n roundY = (y: number, domainDiff: number) => {\r\n if (domainDiff < 1) {\r\n const numberOfLeadingZeros = Math.abs(Math.floor(Math.log10(Math.abs(domainDiff)) + 1))\r\n if (numberOfLeadingZeros > 0) {\r\n return this.roundToFixed(y, numberOfLeadingZeros + 4)\r\n } else {\r\n return this.roundToFixed(y, numberOfLeadingZeros + 3)\r\n }\r\n } else if (domainDiff < 10) {\r\n return this.roundToFixed(y, 3)\r\n }\r\n return this.roundToFixed(y, 2)\r\n }\r\n\r\n getAutosaveOmittedProperties() {\r\n return ['points']\r\n }\r\n\r\n getEdgeXYValues() {\r\n if (this.edgeXYValues === null) {\r\n const edgeXYValues = {} as EdgeValues\r\n this.attrs.points.forEach(([x, y]) => {\r\n edgeXYValues.minX = Math.min(x, edgeXYValues.minX ?? x)\r\n edgeXYValues.minY = Math.min(y, edgeXYValues.minY ?? y)\r\n edgeXYValues.maxX = Math.max(x, edgeXYValues.maxX ?? x)\r\n edgeXYValues.maxY = Math.max(y, edgeXYValues.maxY ?? y)\r\n })\r\n\r\n this.edgeXYValues = edgeXYValues\r\n }\r\n\r\n return this.edgeXYValues\r\n }\r\n}\r\n\r\nBrush.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, max: 20, default: {} },\r\n { type: 'checkbox', name: 'isPolyLineClosed', label: 'Close line' },\r\n ],\r\n}\r\n\r\nexport default Brush\r\n","import math from '../../helpers/math'\r\n\r\ninterface ICoordinates {\r\n x: number\r\n y: number\r\n}\r\nexport interface IRectangleSidesCoordinates {\r\n topLeft: ICoordinates\r\n topRight: ICoordinates\r\n rightTop: ICoordinates\r\n rightBottom: ICoordinates\r\n bottomRight: ICoordinates\r\n bottomLeft: ICoordinates\r\n leftBottom: ICoordinates\r\n leftTop: ICoordinates\r\n}\r\n\r\nexport interface ITailCoordinates {\r\n tailRoot: ICoordinates\r\n tailTip: ICoordinates\r\n}\r\n\r\nexport enum TailDirection {\r\n noTail,\r\n topLeftCorner,\r\n topRightCorner,\r\n bottomLeftCorner,\r\n bottomRightCorner,\r\n topSide,\r\n rightSide,\r\n bottomSide,\r\n leftSide,\r\n}\r\n\r\nexport const getRectangleSidesCoordinates = ({\r\n padding,\r\n radius,\r\n x2,\r\n y2,\r\n textWidth,\r\n measuredHeight,\r\n}: {\r\n padding: number\r\n radius: number\r\n x2: number\r\n y2: number\r\n textWidth: number\r\n measuredHeight: number\r\n}): IRectangleSidesCoordinates => ({\r\n topLeft: {\r\n x: x2 - padding + radius,\r\n y: y2 - padding,\r\n },\r\n topRight: {\r\n x: x2 + textWidth + padding - radius,\r\n y: y2 - padding,\r\n },\r\n rightTop: {\r\n x: x2 + textWidth + padding,\r\n y: y2 - padding + radius,\r\n },\r\n rightBottom: {\r\n x: x2 + textWidth + padding,\r\n y: y2 + padding + measuredHeight - radius,\r\n },\r\n bottomRight: {\r\n x: x2 + textWidth + padding - radius,\r\n y: y2 + padding + measuredHeight,\r\n },\r\n bottomLeft: {\r\n x: x2 - padding + radius,\r\n y: y2 + padding + measuredHeight,\r\n },\r\n leftBottom: {\r\n x: x2 - padding,\r\n y: y2 + padding + measuredHeight - radius,\r\n },\r\n leftTop: {\r\n x: x2 - padding,\r\n y: y2 - padding + radius,\r\n },\r\n})\r\n\r\nexport const getTailCoordinates = ({\r\n rectangleSides,\r\n x1,\r\n y1,\r\n}: {\r\n rectangleSides: IRectangleSidesCoordinates\r\n x1: number\r\n y1: number\r\n}): ITailCoordinates => ({\r\n tailRoot: {\r\n x: rectangleSides.topLeft.x + (rectangleSides.topRight.x - rectangleSides.topLeft.x) / 2,\r\n y: rectangleSides.leftTop.y + (rectangleSides.leftBottom.y - rectangleSides.leftTop.y) / 2,\r\n },\r\n tailTip: {\r\n x: x1,\r\n y: y1,\r\n },\r\n})\r\n\r\nconst getTailHalfWidth = (halfWidth: number, p1: ICoordinates, p2: ICoordinates): number => {\r\n const dist = math.distance(p1, p2)\r\n if (dist < halfWidth * 2) {\r\n return dist / 2\r\n } else {\r\n return halfWidth\r\n }\r\n}\r\n\r\nexport const getTailToSideIntersection = ({\r\n tail,\r\n rectangleSides,\r\n}: {\r\n tail: ITailCoordinates\r\n rectangleSides: IRectangleSidesCoordinates\r\n}): TailDirection => {\r\n const { topLeft, topRight, rightTop, rightBottom, bottomRight, bottomLeft, leftBottom, leftTop } = rectangleSides\r\n const { tailTip, tailRoot } = tail\r\n if (math.twoSegmentLinesIntersection(tailTip, tailRoot, topLeft, leftTop)) {\r\n return TailDirection.topLeftCorner\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, topRight, rightTop)) {\r\n return TailDirection.topRightCorner\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, bottomLeft, leftBottom)) {\r\n return TailDirection.bottomLeftCorner\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, bottomRight, rightBottom)) {\r\n return TailDirection.bottomRightCorner\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, topLeft, topRight)) {\r\n return TailDirection.topSide\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, rightTop, rightBottom)) {\r\n return TailDirection.rightSide\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, bottomLeft, bottomRight)) {\r\n return TailDirection.bottomSide\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, leftTop, leftBottom)) {\r\n return TailDirection.leftSide\r\n } else {\r\n return TailDirection.noTail\r\n }\r\n}\r\n\r\ninterface IRenderCallout {\r\n context: any\r\n radius: number\r\n requiredTailHalfWidth: number\r\n tail: ITailCoordinates\r\n rectangleSides: IRectangleSidesCoordinates\r\n tailDirection: TailDirection\r\n}\r\n\r\nexport const renderCallout = ({\r\n context,\r\n radius,\r\n requiredTailHalfWidth,\r\n tail,\r\n rectangleSides,\r\n tailDirection,\r\n}: IRenderCallout): void => {\r\n const { topLeft, topRight, rightTop, rightBottom, bottomRight, bottomLeft, leftBottom, leftTop } = rectangleSides\r\n const { tailTip, tailRoot } = tail\r\n\r\n // draw rounded rectangle from top left corner clockwise\r\n // !!! ORDER OF RENDER MATTERS !!!\r\n\r\n // renderTopLeftCorner\r\n if (tailDirection === TailDirection.topLeftCorner) {\r\n context.moveTo(leftTop.x, leftTop.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(topLeft.x, topLeft.y)\r\n } else {\r\n context.moveTo(leftTop.x, leftTop.y)\r\n context.arcTo(leftTop.x, topLeft.y, topLeft.x, topLeft.y, radius)\r\n }\r\n\r\n // renderTopLine\r\n if (tailDirection === TailDirection.topSide) {\r\n const tailLineToTopLineIntersection = math.twoSegmentLinesIntersection(tailTip, tailRoot, topLeft, topRight)\r\n if (!tailLineToTopLineIntersection) {\r\n context.lineTo(topRight.x, topRight.y)\r\n return\r\n }\r\n const tailHalfWidth = getTailHalfWidth(requiredTailHalfWidth, topLeft, topRight)\r\n if (tailLineToTopLineIntersection.x - tailHalfWidth < topLeft.x) {\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(topLeft.x + tailHalfWidth * 2, tailLineToTopLineIntersection.y)\r\n } else if (tailLineToTopLineIntersection.x + tailHalfWidth > topRight.x) {\r\n context.lineTo(topRight.x - tailHalfWidth * 2, tailLineToTopLineIntersection.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(topRight.x, tailLineToTopLineIntersection.y)\r\n } else {\r\n context.lineTo(tailLineToTopLineIntersection.x - tailHalfWidth, tailLineToTopLineIntersection.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(tailLineToTopLineIntersection.x + tailHalfWidth, tailLineToTopLineIntersection.y)\r\n context.lineTo(topRight.x, topRight.y)\r\n }\r\n } else {\r\n context.lineTo(topRight.x, topRight.y)\r\n }\r\n\r\n // renderTopRightCorner\r\n if (tailDirection === TailDirection.topRightCorner) {\r\n context.lineTo(topRight.x, topRight.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(rightTop.x, rightTop.y)\r\n } else {\r\n context.arcTo(rightTop.x, topRight.y, rightTop.x, rightTop.y, radius)\r\n }\r\n\r\n // renderRightLine\r\n if (tailDirection === TailDirection.rightSide) {\r\n const tailLineToRightLineIntersection = math.twoSegmentLinesIntersection(tailTip, tailRoot, rightTop, rightBottom)\r\n if (!tailLineToRightLineIntersection) {\r\n context.lineTo(rightBottom.x, rightBottom.y)\r\n return\r\n }\r\n const tailHalfWidth = getTailHalfWidth(requiredTailHalfWidth, rightTop, rightBottom)\r\n if (tailLineToRightLineIntersection.y - tailHalfWidth < rightTop.y) {\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(rightTop.x, rightTop.y + tailHalfWidth * 2)\r\n } else if (tailLineToRightLineIntersection.y + tailHalfWidth > rightBottom.y) {\r\n context.lineTo(rightBottom.x, rightBottom.y - tailHalfWidth * 2)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(rightBottom.x, rightBottom.y)\r\n } else {\r\n context.lineTo(tailLineToRightLineIntersection.x, tailLineToRightLineIntersection.y - tailHalfWidth)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(tailLineToRightLineIntersection.x, tailLineToRightLineIntersection.y + tailHalfWidth)\r\n context.lineTo(rightBottom.x, rightBottom.y)\r\n }\r\n } else {\r\n context.lineTo(rightBottom.x, rightBottom.y)\r\n }\r\n\r\n // renderBottomRightCorner\r\n if (tailDirection === TailDirection.bottomRightCorner) {\r\n context.lineTo(rightBottom.x, rightBottom.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(bottomRight.x, bottomRight.y)\r\n } else {\r\n context.arcTo(rightBottom.x, bottomRight.y, bottomRight.x, bottomRight.y, radius)\r\n }\r\n\r\n // renderBottomLine\r\n if (tailDirection === TailDirection.bottomSide) {\r\n const tailLineToBottomLineIntersection = math.twoSegmentLinesIntersection(\r\n tailTip,\r\n tailRoot,\r\n bottomLeft,\r\n bottomRight\r\n )\r\n if (!tailLineToBottomLineIntersection) {\r\n context.lineTo(bottomLeft.x, bottomLeft.y)\r\n return\r\n }\r\n const tailHalfWidth = getTailHalfWidth(requiredTailHalfWidth, bottomLeft, bottomRight)\r\n if (tailLineToBottomLineIntersection.x + tailHalfWidth > bottomRight.x) {\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(bottomRight.x - tailHalfWidth * 2, tailLineToBottomLineIntersection.y)\r\n } else if (tailLineToBottomLineIntersection.x - tailHalfWidth < bottomLeft.x) {\r\n context.lineTo(bottomLeft.x + tailHalfWidth * 2, tailLineToBottomLineIntersection.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(bottomLeft.x, tailLineToBottomLineIntersection.y)\r\n } else {\r\n context.lineTo(tailLineToBottomLineIntersection.x + tailHalfWidth, tailLineToBottomLineIntersection.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(tailLineToBottomLineIntersection.x - tailHalfWidth, tailLineToBottomLineIntersection.y)\r\n context.lineTo(bottomLeft.x, bottomLeft.y)\r\n }\r\n } else {\r\n context.lineTo(bottomLeft.x, bottomLeft.y)\r\n }\r\n\r\n // renderBottomLeftCorner\r\n if (tailDirection === TailDirection.bottomLeftCorner) {\r\n context.lineTo(bottomLeft.x, bottomLeft.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(leftBottom.x, leftBottom.y)\r\n } else {\r\n context.arcTo(leftBottom.x, bottomLeft.y, leftBottom.x, leftBottom.y, radius)\r\n }\r\n\r\n // renderLeftLine\r\n if (tailDirection === TailDirection.leftSide) {\r\n const tailLineToLeftLineIntersection = math.twoSegmentLinesIntersection(tailTip, tailRoot, leftTop, leftBottom)\r\n if (!tailLineToLeftLineIntersection) {\r\n context.lineTo(leftTop.x, leftTop.y)\r\n return\r\n }\r\n const tailHalfWidth = getTailHalfWidth(requiredTailHalfWidth, leftTop, leftBottom)\r\n if (tailLineToLeftLineIntersection.y + tailHalfWidth > leftBottom.y) {\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(leftBottom.x, leftBottom.y - tailHalfWidth * 2)\r\n } else if (tailLineToLeftLineIntersection.y - tailHalfWidth < leftTop.y) {\r\n context.lineTo(leftTop.x, leftTop.y + tailHalfWidth * 2)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(leftTop.x, leftTop.y)\r\n } else {\r\n context.lineTo(tailLineToLeftLineIntersection.x, tailLineToLeftLineIntersection.y + tailHalfWidth)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(tailLineToLeftLineIntersection.x, tailLineToLeftLineIntersection.y - tailHalfWidth)\r\n context.lineTo(leftTop.x, leftTop.y)\r\n }\r\n } else {\r\n context.lineTo(leftTop.x, leftTop.y)\r\n }\r\n}\r\n","import merge from 'lodash.merge'\r\n\r\nimport { PaneArea, RequireByKey, ResizeByThumbWithTypeAndDifs, TextAttrs } from '../../../types/shared'\r\nimport { PADDING } from '../../constants/common'\r\nimport { CanvasElementType } from '../../constants/common'\r\nimport math from '../../helpers/math'\r\nimport Chart from '../../models/chart'\r\nimport PaneModel from '../../models/pane'\r\nimport Text from '../text'\r\nimport Thumb from '../thumb'\r\nimport {\r\n getRectangleSidesCoordinates,\r\n getTailCoordinates,\r\n getTailToSideIntersection,\r\n renderCallout,\r\n} from './callout_utils'\r\n\r\nexport interface ICalloutAttrs {\r\n x1: number\r\n y1: number\r\n x2: number\r\n y2: number\r\n}\r\n\r\ninterface FontFamilyHeightCoefficient {\r\n Arial: {\r\n firstLine: number\r\n otherLines: number\r\n }\r\n Verdana: {\r\n firstLine: number\r\n otherLines: number\r\n }\r\n}\r\n\r\ntype CalloutTextAttrs = ICalloutAttrs & RequireByKey\r\n\r\nclass Callout extends Text {\r\n static type = CanvasElementType.calloutV1\r\n\r\n name = 'Callout'\r\n\r\n declare fontFamilyHeightCoeficient: FontFamilyHeightCoefficient\r\n declare isActualBoundingBoxAvailable: boolean\r\n declare lastAttrs: Attrs\r\n declare scaled: Pick\r\n declare measuredHeight: number\r\n declare font: string\r\n declare context?: CanvasRenderingContext2D\r\n declare lines: {\r\n text: string\r\n metrics: TextMetrics\r\n }[]\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'tail',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n getModalConfigBase() {\r\n return {\r\n inputs: [\r\n { type: 'multiline_string', name: 'text', required: true },\r\n { type: 'font', name: 'font' },\r\n {\r\n type: 'background',\r\n name: 'fillStyle',\r\n label: 'Color',\r\n default: this.getChartLayoutSettings().ElementSettings.Colors.textWithoutBackground,\r\n },\r\n {\r\n type: 'background',\r\n name: 'background',\r\n label: 'Background',\r\n default: 'rgba(0,0,0,0)',\r\n },\r\n {\r\n type: 'border',\r\n name: 'border',\r\n min: 0,\r\n },\r\n ],\r\n }\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n text: '',\r\n font: {\r\n size: 15,\r\n family: 'Arial',\r\n style: 'normal',\r\n weight: 'normal',\r\n },\r\n fillStyle: ElementSettings.Colors.textWithoutBackground,\r\n lineHeight: 15,\r\n // left | right | center | start | end\r\n textAlign: 'left',\r\n // top | middle | alphabetic | bottom\r\n textBaseline: 'alphabetic',\r\n padding: {\r\n top: 0,\r\n right: 0,\r\n bottom: 0,\r\n left: 0,\r\n },\r\n background: ElementSettings.defaultFill,\r\n border: { color: ElementSettings.Colors.line, width: 1 },\r\n } as Partial\r\n }\r\n\r\n setupContext(context: CanvasRenderingContext2D) {\r\n this.context = context\r\n context.set('font', this.font)\r\n context.set('fillStyle', this.attrs.fillStyle)\r\n context.set('textAlign', this.attrs.textAlign)\r\n context.set('textBaseline', this.attrs.textBaseline)\r\n this.setupTextMetricsCache()\r\n }\r\n\r\n setupTextMetricsCache() {\r\n const ctx = this.context\r\n\r\n if (\r\n (this.attrs.text !== this.lastAttrs?.text ||\r\n JSON.stringify(this.attrs.font) !== JSON.stringify(this.lastAttrs?.font)) &&\r\n ctx\r\n ) {\r\n this.lastAttrs = merge({}, this.attrs)\r\n this.lines = this.getLines().map((line) => ({\r\n text: line,\r\n metrics: ctx.measureText(line),\r\n }))\r\n this.measuredHeight = this.lines.reduce((acc, current, currentIndex) => {\r\n const lineHeight =\r\n current.metrics.actualBoundingBoxAscent +\r\n current.metrics.actualBoundingBoxDescent +\r\n (currentIndex !== this.lines.length - 1 ? PADDING.S : 0)\r\n return acc + lineHeight\r\n }, 0)\r\n }\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n this.render(context)\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n renderText() {\r\n if (!this.context) return\r\n let y = this.scaled.y2 + this.attrs.padding.top\r\n let previousDescent = 0\r\n for (let i = 0; i < this.lines.length; i++) {\r\n y += i === 0 ? 0 : this.lines[i].metrics.actualBoundingBoxAscent + previousDescent + PADDING.S\r\n this.context.fillText(this.lines[i].text, this.scaled.x2 + this.attrs.padding.left, y)\r\n previousDescent = this.lines[i].metrics.actualBoundingBoxDescent\r\n }\r\n }\r\n\r\n getCalloutProperties() {\r\n const textWidth = this.attrs.text === '' ? this.attrs.font.size * 2 : this.width\r\n const requiredTailHalfWidth = this.attrs.font.size * 0.5\r\n const padding = this.attrs.border.width / 2 + this.attrs.font.size * 0.5\r\n const radius = textWidth < requiredTailHalfWidth ? textWidth / 2 : requiredTailHalfWidth\r\n\r\n const measuredHeight = this.measuredHeight < requiredTailHalfWidth ? radius * 2 : this.measuredHeight\r\n const y2 = this.scaled.y2 - (this.lines?.[0]?.metrics.actualBoundingBoxAscent || measuredHeight)\r\n\r\n // Points diagram\r\n //.......X-----------------X.......\r\n //.................................\r\n //...X.........................X...\r\n //...|.........................|...\r\n //...|.........................|...\r\n //...X.........................X...\r\n //.................................\r\n //.......X-----------------X.......\r\n\r\n const rectangleSides = getRectangleSidesCoordinates({\r\n padding,\r\n radius,\r\n x2: this.scaled.x2,\r\n y2,\r\n textWidth,\r\n measuredHeight,\r\n })\r\n const tail = getTailCoordinates({ rectangleSides, x1: this.scaled.x1, y1: this.scaled.y1 })\r\n const tailDirection = getTailToSideIntersection({ tail, rectangleSides })\r\n\r\n return {\r\n radius,\r\n requiredTailHalfWidth,\r\n rectangleSides,\r\n tail,\r\n tailDirection,\r\n }\r\n }\r\n\r\n renderBackground() {\r\n if (!this.attrs.background || !this.context) {\r\n return\r\n }\r\n\r\n const { radius, requiredTailHalfWidth, tail, tailDirection, rectangleSides } = this.getCalloutProperties()\r\n\r\n this.context.beginPath()\r\n this.context.set('fillStyle', this.attrs.background)\r\n this.context.lineJoin = 'round'\r\n renderCallout({\r\n context: this.context,\r\n radius,\r\n requiredTailHalfWidth,\r\n tail,\r\n rectangleSides,\r\n tailDirection,\r\n })\r\n this.context.closePath()\r\n this.context.fill()\r\n this.context.set('fillStyle', this.attrs.fillStyle)\r\n this.renderBorder()\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n // is in rectangle\r\n const { tail, rectangleSides, requiredTailHalfWidth } = this.getCalloutProperties()\r\n if (\r\n this.lines &&\r\n rectangleSides &&\r\n rectangleSides.leftTop.x < area.scaled.x &&\r\n rectangleSides.topLeft.y < area.scaled.y &&\r\n rectangleSides.rightBottom.x > area.scaled.x &&\r\n rectangleSides.bottomRight.y > area.scaled.y\r\n ) {\r\n return true\r\n }\r\n // is in tail\r\n if (tail) {\r\n const tailP1 = math.perpendicularPointToLine({\r\n distance: requiredTailHalfWidth,\r\n line: { x1: tail.tailTip.x, y1: tail.tailTip.y, x2: tail.tailRoot.x, y2: tail.tailRoot.y },\r\n })\r\n const pointOffsetX = tailP1.x - tail.tailRoot.x\r\n const pointOffsetY = tailP1.y - tail.tailRoot.y\r\n const tailP2 = { x: tail.tailRoot.x + -1 * pointOffsetX, y: tail.tailRoot.y + -1 * pointOffsetY }\r\n const polygon = [tail.tailTip, tailP1, tailP2]\r\n if (math.pointInPolygon(area.scaled, polygon)) {\r\n return true\r\n }\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n if (type === 'tail') {\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n }\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n if (this.getIsCreator() || !this.lines) {\r\n return true\r\n }\r\n\r\n const { tail, rectangleSides } = this.getCalloutProperties()\r\n\r\n return [...Object.values(rectangleSides), tail.tailRoot, tail.tailTip].some(\r\n ({ x, y }) => x <= -chart.leftOffset + chart.width && x >= -chart.leftOffset && y >= 0 && y <= this.model.height\r\n )\r\n }\r\n}\r\n\r\nexport default Callout\r\n","import { Bezier } from 'bezier-js'\r\n\r\nimport { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface ICurveAttrs {\r\n x1: number\r\n x2: number\r\n x3: number\r\n cp1x: number\r\n cp2x: number\r\n y1: number\r\n y2: number\r\n y3: number\r\n cp1y: number\r\n cp2y: number\r\n border: DrawingBorder\r\n}\r\n\r\nclass Curve extends Element {\r\n static type = CanvasElementType.curve\r\n\r\n name = 'Curve'\r\n declare scaled: Pick\r\n declare curve: Bezier\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.render = this.render.bind(this)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'a',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'b',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c',\r\n () => this.attrs.x3 || this.attrs.x2,\r\n () => this.attrs.y3 || this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n border: {\r\n width: 1,\r\n color: this.getChartLayoutSettings().ElementSettings.Colors.line,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2', 'x3'], y: ['y1', 'y2', 'y3'] })\r\n\r\n drawQuadraticCurve(context: CanvasRenderingContext2D, curve: Bezier) {\r\n const { points } = curve\r\n context.beginPath()\r\n context.moveTo(points[0].x, points[0].y)\r\n context.quadraticCurveTo(points[1].x, points[1].y, points[2].x, points[2].y)\r\n context.stroke()\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, x3, y1, y2, y3 } = this.scaled\r\n context.translate(0.5, 0.5)\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n if (!x3 || !y3) {\r\n context.beginPath()\r\n context.moveTo(x1, y1)\r\n context.lineTo(x2, y2)\r\n context.lineTo(x3, y3)\r\n context.stroke()\r\n } else {\r\n this.curve = Bezier.quadraticFromPoints({ x: x1, y: y1 }, { x: x2, y: y2 }, { x: x3, y: y3 }, 0.5)\r\n this.drawQuadraticCurve(context, this.curve)\r\n }\r\n\r\n context.translate(-0.5, -0.5)\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.x2 += x\r\n this.attrs.x3 += x\r\n this.attrs.cp1x += x\r\n this.attrs.cp2x += x\r\n\r\n this.attrs.y1 += y\r\n this.attrs.y2 += y\r\n this.attrs.y3 += y\r\n this.attrs.cp1y += y\r\n this.attrs.cp2y += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'a':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'b':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'c':\r\n this.attrs.x3 += difX\r\n this.attrs.y3 += difY\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n if (this.curve && this.curve.project(area.scaled).d! <= 10) {\r\n return true\r\n }\r\n return this.thumbsAreInArea(area)\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n if (this.getIsCreator()) {\r\n return true\r\n }\r\n\r\n const { x1, x2, x3, y1, y2, y3 } = this.scaled\r\n if (!x3 || !y3) {\r\n return true\r\n }\r\n const isInView =\r\n Bezier.quadraticFromPoints({ x: x1, y: y1 }, { x: x2, y: y2 }, { x: x3, y: y3 }, 0.5).points.some(\r\n ({ x, y }) => x <= -chart.leftOffset + chart.width && x >= -chart.leftOffset && y >= 0 && y <= this.model.height\r\n ) ?? true\r\n\r\n return isInView\r\n }\r\n}\r\n\r\nCurve.prototype.modalConfig = {\r\n inputs: [{ type: 'line', name: 'border' }],\r\n}\r\n\r\nexport default Curve\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface IEllipseAttrs {\r\n x1: number\r\n x2: number\r\n x3: number\r\n cp1x: number\r\n cp2x: number\r\n y1: number\r\n y2: number\r\n y3: number\r\n cp1y: number\r\n cp2y: number\r\n width: number\r\n fill: string\r\n border: DrawingBorder\r\n}\r\n\r\ninterface ICoordinates {\r\n topCenterX: number\r\n topCenterY: number\r\n topRightX: number\r\n topRightY: number\r\n topLeftX: number\r\n topLeftY: number\r\n centerLeftX: number\r\n centerLeftY: number\r\n centerRightX: number\r\n centerRightY: number\r\n bottomCenterX: number\r\n bottomCenterY: number\r\n bottomLeftX: number\r\n bottomLeftY: number\r\n bottomRightX: number\r\n bottomRightY: number\r\n}\r\n\r\n// OLD Ellipse \"v0\" kept for backward-compatibiluty for old saved ideas\r\n// current Ellipse tool located in ellipse folder\r\nclass Ellipse extends Element {\r\n static type = CanvasElementType.ellipse\r\n\r\n name = 'Ellipse'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'x1',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'x2',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'lw',\r\n () => this.model.scale.x.invert(this.getCoordinates().centerLeftX),\r\n () => this.model.scale.y.invert(this.getCoordinates().centerLeftY),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'rw',\r\n () => this.model.scale.x.invert(this.getCoordinates().centerRightX),\r\n () => this.model.scale.y.invert(this.getCoordinates().centerRightY),\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n const boundingPointKeys = this.getBoundingPointKeys()\r\n this.scale({ x: [...boundingPointKeys.x, 'width'], y: boundingPointKeys.y })\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.line,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const c = this.getCoordinates()\r\n\r\n context.set('fillStyle', this.attrs.fill)\r\n\r\n context.beginPath()\r\n context.moveTo(c.bottomCenterX, c.bottomCenterY)\r\n context.bezierCurveTo(c.bottomRightX, c.bottomRightY, c.topRightX, c.topRightY, c.topCenterX, c.topCenterY)\r\n context.bezierCurveTo(c.topLeftX, c.topLeftY, c.bottomLeftX, c.bottomLeftY, c.bottomCenterX, c.bottomCenterY)\r\n context.closePath()\r\n context.fill()\r\n\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.stroke()\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'x1':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'x2':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'lw':\r\n this.attrs.width += difX\r\n break\r\n case 'rw':\r\n this.attrs.width -= difX\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n getCoordinates(): ICoordinates {\r\n // TODO cache?\r\n // http://stackoverflow.com/questions/14169234/the-relation-of-the-bezier-curve-and-ellipse\r\n const rotationAngle =\r\n Math.PI + Math.atan(-1 / ((this.scaled.y2 - this.scaled.y1) / (this.scaled.x2 - this.scaled.x1)))\r\n\r\n const sign = this.scaled.y1 > this.scaled.y2 ? 1 : -1\r\n const radiusX = this.scaled.width / 2\r\n let radiusY = (sign * Math.abs(this.scaled.y1 - this.scaled.y2)) / Math.cos(rotationAngle) / 2\r\n if (this.scaled.y1 === this.scaled.y2) {\r\n radiusY = Math.abs(this.scaled.x1 - this.scaled.x2) / 2\r\n }\r\n\r\n const width_two_thirds = (radiusX * 4) / 3\r\n\r\n const dx1 = Math.sin(rotationAngle) * radiusY\r\n const dy1 = Math.cos(rotationAngle) * radiusY\r\n const dx2 = Math.cos(rotationAngle) * width_two_thirds\r\n const dy2 = Math.sin(rotationAngle) * width_two_thirds\r\n\r\n const x = this.scaled.x1 + dx1\r\n const y = this.scaled.y1 - dy1\r\n\r\n const topCenterX = x - dx1\r\n const topCenterY = y + dy1\r\n const topRightX = topCenterX + dx2\r\n const topRightY = topCenterY + dy2\r\n const topLeftX = topCenterX - dx2\r\n const topLeftY = topCenterY - dy2\r\n\r\n const bottomCenterX = x + dx1\r\n const bottomCenterY = y - dy1\r\n const bottomRightX = bottomCenterX + dx2\r\n const bottomRightY = bottomCenterY + dy2\r\n const bottomLeftX = bottomCenterX - dx2\r\n const bottomLeftY = bottomCenterY - dy2\r\n\r\n const centerRightX = x + dx2\r\n const centerRightY = y + dy2\r\n const centerLeftX = x - dx2\r\n const centerLeftY = y - dy2\r\n\r\n return {\r\n topCenterX,\r\n topCenterY,\r\n topRightX,\r\n topRightY,\r\n topLeftX,\r\n topLeftY,\r\n centerLeftX,\r\n centerLeftY,\r\n centerRightX,\r\n centerRightY,\r\n bottomCenterX,\r\n bottomCenterY,\r\n bottomLeftX,\r\n bottomLeftY,\r\n bottomRightX,\r\n bottomRightY,\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const c = this.getCoordinates()\r\n const left = Math.min(this.scaled.x1, this.scaled.x2, c.centerRightX)\r\n const right = Math.max(this.scaled.x1, this.scaled.x2, c.centerLeftX)\r\n const top = Math.min(this.scaled.y1, this.scaled.y2, c.centerRightY)\r\n const bottom = Math.max(this.scaled.y1, this.scaled.y2, c.centerLeftY)\r\n if (left < area.scaled.x && area.scaled.x < right && top < area.scaled.y && area.scaled.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getIsInChartView() {\r\n return true\r\n }\r\n}\r\n\r\nEllipse.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default Ellipse\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\ntype RotatedRectangleCoordiantes = [[number, number], [number, number], [number, number], [number, number]]\r\n\r\nexport interface IRotatedRectangleAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n height: number\r\n fill: string\r\n border: DrawingBorder\r\n}\r\n\r\n// OLD RotatedRectangle \"v0\" kept for backward-compatibiluty for old saved ideas\r\n// current RotatedRectangle tool located in rotated_rectangle folder\r\nclass RotatedRectangle extends Element {\r\n static type = CanvasElementType.rotatedRectangle\r\n\r\n name = 'Rotated rectangle'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n const x = this.model.scale.x.invert\r\n const y = this.model.scale.y.invert\r\n this._thumbs = [\r\n new Thumb(\r\n 'ml',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'mr',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'tl',\r\n () => x(this.getRectCoordinates()[0][0]),\r\n () => y(this.getRectCoordinates()[0][1]),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'tr',\r\n () => x(this.getRectCoordinates()[1][0]),\r\n () => y(this.getRectCoordinates()[1][1]),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'bl',\r\n () => x(this.getRectCoordinates()[2][0]),\r\n () => y(this.getRectCoordinates()[2][1]),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'br',\r\n () => x(this.getRectCoordinates()[3][0]),\r\n () => y(this.getRectCoordinates()[3][1]),\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n const boundingPointKeys = this.getBoundingPointKeys()\r\n this.scale({ x: [...boundingPointKeys.x, 'height'], y: boundingPointKeys.y })\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n context.set('fillStyle', this.attrs.fill)\r\n\r\n context.beginPath()\r\n const coords = this.getRectCoordinates()\r\n for (const point of coords) {\r\n context.lineTo(point[0], point[1])\r\n }\r\n context.lineTo(coords[0][0], coords[0][1])\r\n context.fill()\r\n\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.stroke()\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getRectCoordinates(): RotatedRectangleCoordiantes {\r\n const mx1 = this.scaled.x1\r\n const mx2 = this.scaled.x2\r\n const my1 = this.scaled.y1\r\n const my2 = this.scaled.y2\r\n const { height } = this.scaled\r\n\r\n const k = (my2 - my1) / (mx2 - mx1)\r\n const nk = -1 / k\r\n\r\n const sign = my1 > my2 ? 1 : -1\r\n const dx = (sign * Math.sqrt((height * height) / (1 + nk * nk))) / 2\r\n const dy = nk * dx\r\n\r\n let x1 = mx1 - dx\r\n let y1 = my1 - dy\r\n let x2 = mx2 - dx\r\n let y2 = my2 - dy\r\n\r\n let x3 = mx2 + dx\r\n let y3 = my2 + dy\r\n let x4 = mx1 + dx\r\n let y4 = my1 + dy\r\n\r\n if (my1 === my2) {\r\n x1 = mx1\r\n y1 = my1 - height / 2\r\n x2 = mx2\r\n y2 = my2 - height / 2\r\n\r\n x3 = mx2\r\n y3 = my2 + height / 2\r\n x4 = mx1\r\n y4 = my1 + height / 2\r\n }\r\n\r\n return [\r\n [x1, y1],\r\n [x2, y2],\r\n [x3, y3],\r\n [x4, y4],\r\n ]\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'ml':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'mr':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'tl':\r\n case 'tr':\r\n this.attrs.height += difY\r\n break\r\n case 'bl':\r\n case 'br':\r\n this.attrs.height -= difY\r\n break\r\n default:\r\n return\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const coords = this.getRectCoordinates()\r\n const polygon = coords.map((c) => ({ x: c[0], y: c[1] }))\r\n if (math.pointInPolygon(area.scaled, polygon)) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getIsInChartView() {\r\n return true\r\n }\r\n}\r\n\r\nRotatedRectangle.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default RotatedRectangle\r\n","// TODO FontAwesome font or similar needs to be loaded before using Symbol\r\nimport { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface ISymbolAttrs {\r\n x1: number\r\n scaleX: number\r\n y1: number\r\n scaleY: number\r\n angle: number\r\n fill: string\r\n symbol: string\r\n border: DrawingBorder\r\n}\r\n\r\nclass SymbolElement extends Element {\r\n static type = CanvasElementType.symbol\r\n\r\n name = 'Symbol'\r\n\r\n declare textWidth: number\r\n declare textHeight: number\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.resize = this.resize.bind(this)\r\n\r\n const sx = (sign: number) =>\r\n this.getRotatedCoordinates(this.scaled.x1 + sign * (this.textWidth / 2) * this.attrs.scaleX, this.scaled.y1)\r\n const sy = (sign: number) =>\r\n this.getRotatedCoordinates(this.scaled.x1, this.scaled.y1 + sign * (this.textHeight / 2) * this.attrs.scaleY)\r\n this._thumbs = [\r\n new Thumb(\r\n 'xr',\r\n () => this.model.scale.x.invert(sx(+1).x),\r\n () => this.model.scale.y.invert(sx(+1).y),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'xl',\r\n () => this.model.scale.x.invert(sx(-1).x),\r\n () => this.model.scale.y.invert(sx(-1).y),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'yt',\r\n () => this.model.scale.x.invert(sy(+1).x),\r\n () => this.model.scale.y.invert(sy(+1).y),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'yb',\r\n () => this.model.scale.x.invert(sy(-1).x),\r\n () => this.model.scale.y.invert(sy(-1).y),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n this.attrs.angle = this.attrs.angle || 0\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1'], y: ['y1'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n context.set('font', '36px FontAwesome')\r\n context.set('fillStyle', this.attrs.fill)\r\n context.set('textAlign', 'left')\r\n context.set('textBaseline', 'top')\r\n\r\n this.textWidth = context.measureText(this.attrs.symbol).width\r\n this.textHeight = 36\r\n const xScale = this.attrs.scaleX\r\n const yScale = this.attrs.scaleY\r\n\r\n const xOffset = this.textWidth / -2\r\n const yOffset = this.textHeight / -2\r\n\r\n context.save()\r\n context.translate(this.scaled.x1, this.scaled.y1)\r\n context.rotate(this.attrs.angle)\r\n context.scale(xScale, yScale)\r\n context.fillText(this.attrs.symbol, xOffset, yOffset)\r\n context.restore()\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getRotatedCoordinates(x: number, y: number) {\r\n const cx = this.scaled.x1\r\n const cy = this.scaled.y1\r\n const dx = x - cx\r\n const dy = y - cy\r\n const rx = dx * Math.cos(this.attrs.angle) - dy * Math.sin(this.attrs.angle)\r\n const ry = dy * Math.cos(this.attrs.angle) + dx * Math.sin(this.attrs.angle)\r\n return { x: cx + rx, y: cy + ry }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n return (this.attrs.y1 += y)\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'xl':\r\n this.attrs.scaleX -= difX\r\n break\r\n case 'xr':\r\n this.attrs.scaleX += difX\r\n break\r\n case 'yt':\r\n this.attrs.scaleY -= difY\r\n break\r\n case 'yb':\r\n this.attrs.scaleY += difY\r\n break\r\n case 'c':\r\n this.attrs.angle += difX / 5\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const halfWidth = (this.textWidth / 2) * this.attrs.scaleX\r\n const halfHeight = (this.textHeight / 2) * this.attrs.scaleY\r\n const left = Math.min(this.scaled.x1 - halfWidth, this.scaled.x1 + halfWidth)\r\n const right = Math.max(this.scaled.x1 - halfWidth, this.scaled.x1 + halfWidth)\r\n const top = Math.min(this.scaled.y1 - halfHeight, this.scaled.y1 + halfHeight)\r\n const bottom = Math.max(this.scaled.y1 - halfHeight, this.scaled.y1 + halfHeight)\r\n if (left < area.scaled.x && area.scaled.x < right && top < area.scaled.y && area.scaled.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nSymbolElement.prototype.defaults = { fill: 'rgba(0,0,0,1)' }\r\n\r\nSymbolElement.prototype.modalConfig = {\r\n inputs: [{ type: 'background', name: 'fill', label: 'Fill' }],\r\n}\r\n\r\nexport default SymbolElement\r\n","import { CanvasElementType } from '../constants/common'\r\nimport arrow from './arrow'\r\nimport brush_v1 from './brush/brush_v1'\r\nimport callout_v1 from './callout/callout_v1'\r\nimport curve from './curve'\r\nimport element from './element'\r\nimport elliottWaves from './elliott_waves/elliott_waves'\r\nimport ellipse from './ellipse'\r\nimport ellipse_v1 from './ellipse/ellipse_v1'\r\nimport fibonacci from './fibonacci_retracements'\r\nimport horizontalLine from './horizontal_line'\r\nimport line from './line'\r\nimport measure from './measure'\r\nimport pitchfork_v1 from './pitchfork/pitchfork_v1'\r\nimport polygon from './polygon'\r\nimport position from './position'\r\nimport rectangle from './rectangle'\r\nimport rotatedRectangle from './rotated_rectangle'\r\nimport rotatedRectangle_v1 from './rotated_rectangle/rotated_rectangle_v1'\r\nimport scaledLine from './scaled_line'\r\nimport scaledText from './scaled_text'\r\nimport symbolElement from './symbol'\r\nimport text from './text'\r\nimport triangle from './triangle'\r\nimport verticalLine from './vertical_line'\r\nimport xabcd from './xabcd'\r\n\r\nexport const drawingToolsByType = Object.freeze({\r\n [CanvasElementType.element]: element,\r\n [CanvasElementType.arrow]: arrow,\r\n [CanvasElementType.brushV1]: brush_v1,\r\n [CanvasElementType.calloutV1]: callout_v1,\r\n [CanvasElementType.curve]: curve,\r\n [CanvasElementType.elliottWaves]: elliottWaves,\r\n [CanvasElementType.ellipse]: ellipse,\r\n [CanvasElementType.ellipseV1]: ellipse_v1,\r\n [CanvasElementType.fibonacciRetracements]: fibonacci,\r\n [CanvasElementType.horizontalLine]: horizontalLine,\r\n [CanvasElementType.line]: line,\r\n [CanvasElementType.measure]: measure,\r\n [CanvasElementType.pitchforkV1]: pitchfork_v1,\r\n [CanvasElementType.polygon]: polygon,\r\n [CanvasElementType.position]: position,\r\n [CanvasElementType.rectangle]: rectangle,\r\n [CanvasElementType.rotatedRectangle]: rotatedRectangle,\r\n [CanvasElementType.rotatedRectangleV1]: rotatedRectangle_v1,\r\n [CanvasElementType.scaledLine]: scaledLine,\r\n [CanvasElementType.scaledText]: scaledText,\r\n [CanvasElementType.symbol]: symbolElement,\r\n [CanvasElementType.text]: text,\r\n [CanvasElementType.triangle]: triangle,\r\n [CanvasElementType.verticalLine]: verticalLine,\r\n [CanvasElementType.xabcd]: xabcd,\r\n})\r\n","import Spine from '@finviz/spine'\r\nimport merge from 'lodash.merge'\r\nimport mergewith from 'lodash.mergewith'\r\nimport omit from 'lodash.omit'\r\n\r\nimport {\r\n ChartConfigChartPaneElement,\r\n ObjectHash,\r\n PaneArea,\r\n RequireByKey,\r\n TodoObjectHashAnyType,\r\n} from '../../types/shared'\r\nimport {\r\n CanvasElementType,\r\n ChartElementType,\r\n ChartEventType,\r\n IVisibility,\r\n IndicatorType,\r\n MacroTimeframe,\r\n MicroMacroTimeframe,\r\n OverlayType,\r\n SetVisibilityTo,\r\n TIMEFRAME,\r\n} from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport PaneModel, { ScaleAxis } from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport { isInRange } from '../utils/helpers'\r\nimport ElementBaseConfig from './ElementBaseConfig'\r\nimport Thumb from './thumb'\r\n\r\nexport type TodoModalConfig = TodoObjectHashAnyType\r\ntype TodoPositionTimestamps = TodoObjectHashAnyType\r\n\r\nexport interface DefaultAttrs extends ObjectHash {\r\n positionTimestamps?: TodoPositionTimestamps\r\n visibility?: IVisibility\r\n}\r\n\r\nexport type EdgeValues = { minX?: number; maxX?: number; minY?: number; maxY?: number }\r\n\r\nclass Element extends Spine.Module {\r\n static type: CanvasElementType | OverlayType | ChartElementType | IndicatorType | ChartEventType =\r\n CanvasElementType.element\r\n\r\n static fromObject(obj: T['attrs'], model: T['model']) {\r\n return new this(obj, model) as T\r\n }\r\n\r\n static getNumOfBarsBuffer(\r\n _?: RequireByKey | RequireByKey\r\n ) {\r\n return 0\r\n }\r\n\r\n isCreator = false\r\n isCreatorDialogOpen = false\r\n attrs: Attrs = {} as Attrs\r\n declare static config: ElementBaseConfig\r\n\r\n model: any\r\n _thumbs: Thumb[]\r\n\r\n getDefaults?(): Partial\r\n renderCross?(ctx: RenderingContext2DType): void\r\n renderCrossText?(\r\n ctx: RenderingContext2DType,\r\n crossIndex: number,\r\n getDataByCrossIndex?: (key: keyof Quote, shouldReturnRoundedString?: boolean) => string | undefined\r\n ): void\r\n\r\n renderContent?(ctx: RenderingContext2DType): void\r\n renderGrid?(ctx: RenderingContext2DType): void\r\n renderLabels?(ctx: RenderingContext2DType): void\r\n declare defaults?: Partial\r\n getModalConfigBase?(): TodoModalConfig\r\n declare modalConfig?: TodoModalConfig\r\n getMinMax?(): { min: number; max: number }\r\n setupAxis?(fx: ScaleAxis): void | { min: number; max: number }\r\n\r\n activeThumb: Thumb | null = null\r\n isMouseDown = false\r\n isSelected = false\r\n isHovered = false\r\n isEditInProgress = false\r\n edgeXYValues: EdgeValues | null = null\r\n declare scaled?: ObjectHash | Partial\r\n\r\n declare toolsCallback: () => void\r\n\r\n constructor(values: Partial, model: Model) {\r\n super(values, model)\r\n this.model = model\r\n if (this.getDefaults) {\r\n this.set(this.getDefaults() || {})\r\n } else {\r\n this.set(this.defaults || {})\r\n }\r\n this.set(values)\r\n this._thumbs = []\r\n\r\n this.onMouseDown = this.onMouseDown.bind(this)\r\n this.onMouseMove = this.onMouseMove.bind(this)\r\n this.onMouseUp = this.onMouseUp.bind(this)\r\n this.bind('mousedown', this.onMouseDown)\r\n this.bind('mousemove', this.onMouseMove)\r\n this.bind('mouseup', this.onMouseUp)\r\n this.bind('change', () => {\r\n // elements is optional because this.model is not Pane in all usecases, e.g. base_chart extends this element and sets Chart as model\r\n const element = this.getIsChartEvent()\r\n ? this.model.chartEvents?.()?.findByAttribute('instance', this)\r\n : this.model.elements?.()?.findByAttribute('instance', this)\r\n\r\n element?.trigger('change', element)\r\n })\r\n }\r\n\r\n get type() {\r\n return (this.constructor as typeof Element).type\r\n }\r\n\r\n getThumbs() {\r\n return this._thumbs\r\n }\r\n\r\n moveBy(_: number, __: number) {}\r\n\r\n setIsEditInProgress(isEditInProgress: boolean, shouldTriggerChange = true) {\r\n this.isEditInProgress = isEditInProgress\r\n if (shouldTriggerChange) {\r\n this.trigger('change', this)\r\n }\r\n }\r\n\r\n setIsSelected(isSelected: boolean) {\r\n this.isSelected = isSelected\r\n this.trigger('change')\r\n }\r\n\r\n setIsHovered(isHovered: boolean) {\r\n this.isHovered = isHovered\r\n this.trigger('change')\r\n }\r\n\r\n getShouldRenderThumbs() {\r\n return this.isSelected || this.isHovered\r\n }\r\n\r\n getIsPaneSelection(): boolean {\r\n const paneModel = this.model.elements().findByAttribute('instance', this)?.pane() as PaneModel | undefined\r\n return paneModel?.selection === this\r\n }\r\n\r\n set(obj: Partial) {\r\n const attrsSubset = Object.keys(obj).reduce(\r\n (acc, key) => ({ ...acc, [key]: this.attrs[key] }),\r\n {} as Partial\r\n )\r\n if (JSON.stringify(obj) !== JSON.stringify(attrsSubset)) {\r\n const customizer = (objValue: Partial, srcValue: Partial, key: keyof Attrs) => {\r\n if (this.getIsDrawing() && key === 'visibility') {\r\n return srcValue ?? {}\r\n }\r\n }\r\n mergewith(this.attrs, obj, customizer)\r\n if (this.getIsPaneSelection() && !this.getIsCreator()) {\r\n this.cachePointPositionTimestamp()\r\n }\r\n this.trigger('change', this)\r\n }\r\n this.edgeXYValues = null\r\n return this\r\n }\r\n\r\n get(key: T) {\r\n return this.attrs[key]\r\n }\r\n\r\n getBoundingPointKeys = (): { x: string[]; y: string[] } | void => {}\r\n\r\n fx = (x: number) => this.model.scale.x(x)\r\n\r\n fy = (y: number) => this.model.scale.y(y)\r\n\r\n scale({ x, y }: { x: string[]; y: string[] }) {\r\n this.scaled = {}\r\n x.forEach((el) => {\r\n Object.defineProperty(this.scaled, el, {\r\n get: () => this.fx(this.attrs[el]),\r\n })\r\n })\r\n\r\n y.forEach((el) => {\r\n Object.defineProperty(this.scaled, el, {\r\n get: () => this.fy(this.attrs[el]),\r\n })\r\n })\r\n }\r\n\r\n render(_: RenderingContext2DType) {}\r\n\r\n renderThumbs(context: CanvasRenderingContext2D) {\r\n const isHoveredThumbStyle = this.isHovered && !this.isSelected\r\n if (isHoveredThumbStyle) {\r\n context.globalAlpha = 0.5\r\n }\r\n this.getThumbs().map((thumb) => thumb.render(context))\r\n context.globalAlpha = 1\r\n }\r\n\r\n onMouseDown(area: PaneArea) {\r\n this.isMouseDown = true\r\n this.setIsEditInProgress(true, false)\r\n for (const thumb of this.getThumbs()) {\r\n if (thumb.isInArea(area)) {\r\n this.activeThumb = thumb\r\n this.activeThumb.startEditing(area)\r\n return\r\n }\r\n }\r\n }\r\n\r\n onMouseMove(area: PaneArea) {\r\n if (!area.mouseDown) {\r\n return\r\n }\r\n if (this.activeThumb != null) {\r\n this.activeThumb.moveTo(area)\r\n this.trigger('change')\r\n }\r\n }\r\n\r\n onMouseUp(_?: PaneArea) {\r\n this.isMouseDown = false\r\n this.setIsEditInProgress(false, false)\r\n this.activeThumb = null\r\n if (!this.getIsCreator() && !this.getIsChartEvent()) {\r\n this.cachePointPositionTimestamp()\r\n }\r\n this.trigger('change', this)\r\n }\r\n\r\n cachePointPositionTimestamp = () => {\r\n const quote = this.model?.chart().quote()\r\n if (quote) {\r\n const { x: xPointKeys } = this.getBoundingPointKeys()!\r\n const positionTimestamps = xPointKeys.reduce((acc, key) => {\r\n const positionX = this.attrs[key]\r\n const timeStamp = positionX && quote.getTimestampFomPositionX(positionX)\r\n return {\r\n ...acc,\r\n [key]: timeStamp,\r\n }\r\n }, {}) as TodoPositionTimestamps\r\n this.set({ positionTimestamps } as Partial)\r\n }\r\n }\r\n\r\n updateScales() {\r\n const quote = this.model.chart().quote()\r\n const { positionTimestamps } = this.attrs\r\n if (!quote || !positionTimestamps) {\r\n // positionTimestamps check is temporary to prevent app from crashing\r\n // caused by corrupted drawings - https://github.com/finvizhq/charts/pull/1386/files\r\n return\r\n }\r\n const pointPoitionsFromTimestamp = Object.entries(positionTimestamps).reduce(\r\n (acc, [key, timestamp]) => ({\r\n ...acc,\r\n [key]: timestamp && quote.getPositionXFromTimestamp(timestamp),\r\n }),\r\n {}\r\n )\r\n this.set(pointPoitionsFromTimestamp)\r\n }\r\n\r\n thumbsAreInArea(area: PaneArea) {\r\n for (const thumb of this.getThumbs()) {\r\n if (thumb.isInArea(area)) {\r\n return true\r\n }\r\n }\r\n return false\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n return this.thumbsAreInArea(area)\r\n }\r\n\r\n isDrawingElementLockedOrInvisible() {\r\n return this.model.chart().chart_layout().isLockDrawingsActive || !this.getIsVisible()\r\n }\r\n\r\n getModalConfig() {\r\n let config\r\n if (this.getModalConfigBase) {\r\n config = merge({}, this.getModalConfigBase())\r\n } else {\r\n config = merge({}, this.modalConfig)\r\n }\r\n if (this.getIsDrawing()) {\r\n config.inputs.push({ type: 'visibility', name: 'visibility', label: 'Visibility' })\r\n }\r\n if (config.title == null) {\r\n config.title = this.name\r\n }\r\n for (const input of config.inputs) {\r\n if (input.default != null) {\r\n input.value = input.default\r\n }\r\n if (this.attrs[input.name] != null) {\r\n input.value = this.attrs[input.name]\r\n }\r\n }\r\n return config\r\n }\r\n\r\n toObject() {\r\n return merge({}, this.attrs, { type: this.type })\r\n }\r\n\r\n toConfig(): T['attrs'] & { type: T['type'] } {\r\n return this.toObject()\r\n }\r\n\r\n getAutosaveOmittedProperties() {\r\n return this.attrs.positionTimestamps ? Object.keys(this.attrs.positionTimestamps) : []\r\n }\r\n\r\n toAutosaveConfig() {\r\n // We don't want to save attrs which are stored in \"position timestamps\" because they are relative to timeframe for example\r\n // so in order to keep drawings in sync across different timeframes we can't rely on its position but we have to rely on \"position timestamps\" and then call updateScales to calculate correct positions for given timeframe\r\n return omit(this.toConfig(), this.getAutosaveOmittedProperties()) as Partial\r\n }\r\n\r\n replaceMyself(element: Element) {\r\n setTimeout(() => {\r\n element.cachePointPositionTimestamp()\r\n const el = this.model.elements().findByAttribute('instance', this)\r\n if (!el) {\r\n // Temporary code below\r\n // additional info gaining for https://finvizcom.sentry.io/issues/3990343438/events/e87ce8b4108341cf81f15ec78707c65e/?project=33153&query=is%3Aunresolved+Cannot+read+properties+of+undefined&referrer=previous-event&statsPeriod=14d&stream_index=0\r\n window.Sentry?.captureMessage('element.ts replaceMyself', {\r\n extra: {\r\n oldElement: {\r\n type: this?.type,\r\n isCreator: this?.isCreator,\r\n isMouseDown: this?.isMouseDown,\r\n isSelected: this?.isSelected,\r\n isHovered: this?.isHovered,\r\n isEditInProgress: this?.isEditInProgress,\r\n },\r\n newElement: {\r\n type: element?.type,\r\n isCreator: element?.isCreator,\r\n isMouseDown: element?.isMouseDown,\r\n isSelected: element?.isSelected,\r\n isHovered: element?.isHovered,\r\n isEditInProgress: element?.isEditInProgress,\r\n },\r\n },\r\n })\r\n } else {\r\n el.replace(element)\r\n }\r\n })\r\n }\r\n\r\n toString() {\r\n return this.name\r\n }\r\n\r\n getIsCreator() {\r\n return this.isCreator\r\n }\r\n\r\n getIsCreatorDialogOpen() {\r\n return this.isCreatorDialogOpen\r\n }\r\n\r\n release() {\r\n this.cachePointPositionTimestamp()\r\n this.unbind()\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.model.chart().chart_layout())\r\n }\r\n\r\n getIsDrawing() {\r\n return !!this.type.startsWith('canvas/')\r\n }\r\n\r\n getIsChartEvent() {\r\n return !!this?.type.startsWith('chartEvent/')\r\n }\r\n\r\n getIsVisible() {\r\n const { micro, macro } = MicroMacroTimeframe[this.model.chart().quote().timeframe as TIMEFRAME]\r\n const visibility = this.attrs.visibility?.[macro]\r\n\r\n // this.attrs.visibility.minutes === undefined: drawing visible on any minutes timeframe\r\n if (visibility === undefined) return true\r\n // this.attrs.visibility.minutes === {}: drawing invisible on any minutes timeframe\r\n if (Object.keys(visibility).length === 0) return false\r\n // this.attrs.visibility.minutes === {from: 5, to: 15}: drawing visible on minutes TF between 5 & 15 interval\r\n return isInRange({ value: micro, min: visibility.from, max: visibility.to })\r\n }\r\n\r\n setVisibilityTo(setTo: SetVisibilityTo) {\r\n const { macro, micro } = MicroMacroTimeframe[this.model.chart().quote().timeframe as TIMEFRAME]\r\n const currentIndex = Object.keys(MacroTimeframe).indexOf(macro)\r\n\r\n let timeframesToSet: string[] = []\r\n let attrsToSet: { from?: number; to?: number } = {}\r\n\r\n switch (setTo) {\r\n case SetVisibilityTo.currentAndAbove: {\r\n timeframesToSet = Object.keys(MacroTimeframe).filter((key, index) => index < currentIndex)\r\n attrsToSet = { from: micro }\r\n break\r\n }\r\n case SetVisibilityTo.currentAndBelow: {\r\n timeframesToSet = Object.keys(MacroTimeframe).filter((key, index) => index > currentIndex)\r\n attrsToSet = { to: micro }\r\n break\r\n }\r\n case SetVisibilityTo.currentOnly: {\r\n timeframesToSet = Object.keys(MacroTimeframe).filter((key, index) => index !== currentIndex)\r\n attrsToSet = { from: micro, to: micro }\r\n break\r\n }\r\n case SetVisibilityTo.all:\r\n default: {\r\n this.set({ visibility: {} } as Partial)\r\n return\r\n }\r\n }\r\n\r\n this.set({\r\n visibility: Object.assign({}, ...timeframesToSet.map((item) => ({ [item]: {} })), { [macro]: attrsToSet }),\r\n } as Partial)\r\n }\r\n\r\n getEdgeXYValues() {\r\n const { x: xPoints, y: yPoints } = this.getBoundingPointKeys() ?? {}\r\n if (this.edgeXYValues === null) {\r\n const edgeXYValues = {} as EdgeValues\r\n xPoints?.forEach((key) => {\r\n const positionX = this.attrs[key]\r\n if (positionX !== undefined) {\r\n edgeXYValues.minX = Math.min(positionX, edgeXYValues.minX ?? positionX)\r\n edgeXYValues.maxX = Math.max(positionX, edgeXYValues.maxX ?? positionX)\r\n }\r\n })\r\n yPoints?.forEach((key) => {\r\n const positionY = this.attrs[key]\r\n if (positionY !== undefined) {\r\n edgeXYValues.minY = Math.min(positionY, edgeXYValues.minY ?? positionY)\r\n edgeXYValues.maxY = Math.max(positionY, edgeXYValues.maxY ?? positionY)\r\n }\r\n })\r\n\r\n this.edgeXYValues = edgeXYValues\r\n }\r\n\r\n return this.edgeXYValues\r\n }\r\n\r\n getIsInChartView(chart: Chart, options?: { omitX?: boolean; omitY?: boolean }) {\r\n const { minX, maxX, minY, maxY } = this.getEdgeXYValues()\r\n\r\n if (this.getIsCreator()) {\r\n return true\r\n }\r\n\r\n if (!options?.omitX) {\r\n const isMaxXInvalid = maxX === undefined || isNaN(maxX)\r\n const isMinXInvalid = minX === undefined || isNaN(minX)\r\n if (\r\n !isMaxXInvalid &&\r\n !isMinXInvalid &&\r\n !(this.fx(maxX) >= -chart.leftOffset && this.fx(minX) <= -chart.leftOffset + chart.width)\r\n ) {\r\n return false\r\n }\r\n }\r\n\r\n if (!options?.omitY) {\r\n if (minY === undefined || maxY === undefined) {\r\n return true\r\n }\r\n\r\n const topBound = this.model.scale.y.invert(0)\r\n const bottomBound = this.model.scale.y.invert(this.model.height)\r\n return topBound >= minY && bottomBound <= maxY\r\n }\r\n\r\n // If all checks fall through, render element\r\n return true\r\n }\r\n}\r\n\r\nexport default Element\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../../types/shared'\r\nimport { CanvasElementType, TextAlign, TextBaseline } from '../../constants/common'\r\nimport { getOffsetFromLineWidth } from '../../controllers/renderUtils'\r\nimport math from '../../helpers/math'\r\nimport PaneModel from '../../models/pane'\r\nimport Element from '../element'\r\nimport Text from '../text'\r\nimport Thumb from '../thumb'\r\n\r\nexport interface IElliottWavesAttrs {\r\n waves: Array<{ x: number; y: number }>\r\n positionWavesTimestamps?: Array<{ x: number; y: number }>\r\n border: DrawingBorder\r\n}\r\n\r\nclass ElliottWaves extends Element {\r\n static type = CanvasElementType.elliottWaves\r\n\r\n name = 'Elliott Wave'\r\n waves = ['', 'I', 'II', 'III', 'IV', 'V']\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n border: {\r\n width: 2,\r\n color: this.getChartLayoutSettings().ElementSettings.Colors.line,\r\n },\r\n } as Partial\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const offset = getOffsetFromLineWidth(this.attrs.border.width)\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n\r\n context.translate(offset, offset)\r\n context.beginPath()\r\n context.moveTo(Math.round(this.fx(this.attrs.waves[0].x)), Math.round(this.fy(this.attrs.waves[0].y)))\r\n for (const p of this.attrs.waves.slice(1)) {\r\n context.lineTo(Math.round(this.fx(p.x)), Math.round(this.fy(p.y)))\r\n }\r\n context.stroke()\r\n context.translate(offset * -1, offset * -1)\r\n\r\n const text = new Text(\r\n {\r\n font: { size: 8, style: 'bold' },\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.center,\r\n fillStyle: this.getChartLayoutSettings().ElementSettings.Colors.textWithoutBackground,\r\n },\r\n this.model\r\n )\r\n for (let i = 0; i < this.attrs.waves.length; i++) {\r\n let y\r\n const p = this.attrs.waves[i]\r\n if (i > 0 && this.attrs.waves[i - 1].y > p.y) {\r\n y = this.fy(p.y) + 8\r\n } else {\r\n y = this.fy(p.y) - 8\r\n }\r\n text.set({ text: this.waves[i], x: this.fx(p.x), y })\r\n text.render(context)\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getThumbs() {\r\n return this.attrs.waves.map(\r\n (wave, index) =>\r\n new Thumb(\r\n `${index}`,\r\n () => wave.x,\r\n () => wave.y,\r\n this.resize,\r\n this.model\r\n )\r\n )\r\n }\r\n\r\n cachePointPositionTimestamp = () => {\r\n const quote = this.model?.chart().quote()\r\n if (quote) {\r\n const positionWavesTimestamps = this.attrs.waves.map((wave) => ({\r\n ...wave,\r\n x: quote.getTimestampFomPositionX(wave.x),\r\n }))\r\n\r\n this.set({ positionWavesTimestamps } as Partial)\r\n }\r\n }\r\n\r\n updateScales() {\r\n const quote = this.model.chart().quote()\r\n const { positionWavesTimestamps } = this.attrs\r\n if (!quote || !positionWavesTimestamps) {\r\n // positionWavesTimestamps check is temporary to prevent app from crashing\r\n // caused by corrupted drawings - https://github.com/finvizhq/charts/pull/1386/files\r\n return\r\n }\r\n const waves = positionWavesTimestamps.map((wave) => ({\r\n ...wave,\r\n x: quote.getPositionXFromTimestamp(wave.x),\r\n }))\r\n this.set({ waves } as Partial)\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n for (const point of this.attrs.waves) {\r\n point.x += x\r\n point.y += y\r\n }\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n this.attrs.waves[+type].x += difX\r\n this.attrs.waves[+type].y += difY\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const waves = this.attrs.waves\r\n for (let i = 0; i < waves.length - 1; i++) {\r\n if (\r\n math.distanceToSegment(area.scaled, {\r\n x1: this.fx(waves[i].x),\r\n y1: this.fy(waves[i].y),\r\n x2: this.fx(waves[i + 1].x),\r\n y2: this.fy(waves[i + 1].y),\r\n }) <= 10\r\n ) {\r\n return true\r\n }\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getAutosaveOmittedProperties() {\r\n return ['waves']\r\n }\r\n}\r\n\r\nElliottWaves.prototype.modalConfig = {\r\n inputs: [{ type: 'line', name: 'border' }],\r\n}\r\n\r\nexport default ElliottWaves\r\n","import { DrawingBorder, PaneArea, Point, ResizeByThumbWithTypeAndDifs } from '../../../types/shared'\r\nimport { CanvasElementType } from '../../constants/common'\r\nimport math from '../../helpers/math'\r\nimport PaneModel from '../../models/pane'\r\nimport { getContextWithCache } from '../../utils/canvas'\r\nimport Element from '../element'\r\nimport Thumb from '../thumb'\r\n\r\nexport interface IEllipseAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n cursorTargetX: number\r\n cursorTargetY: number\r\n\r\n fill: string\r\n border: DrawingBorder\r\n}\r\n\r\ninterface Coordinates {\r\n P1: Point\r\n P2: Point\r\n P3: Point\r\n P4: Point\r\n CP1: Point\r\n CP2: Point\r\n CP3: Point\r\n CP4: Point\r\n}\r\n\r\nclass EllipseV1 extends Element {\r\n static type = CanvasElementType.ellipseV1\r\n\r\n name = 'Ellipse'\r\n\r\n untranslatedContext: CanvasRenderingContext2D | null = null\r\n declare ellipsePath: Path2D\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this.untranslatedContext = getContextWithCache(document.createElement('canvas'))\r\n this._thumbs = [\r\n new Thumb(\r\n 'left',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'right',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'top',\r\n () => this.getEllipsePoints(true).P2.x || this.attrs.x1,\r\n () => this.getEllipsePoints(true).P2.y || this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'bottom',\r\n () => this.getEllipsePoints(true).P4.x || this.attrs.x2,\r\n () => this.getEllipsePoints(true).P4.y || this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2', 'cursorTargetX'], y: ['y1', 'y2', 'cursorTargetY'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const coordinates = this.getEllipsePoints() as Coordinates\r\n const ellipse = new Path2D()\r\n context.set('fillStyle', this.attrs.fill)\r\n context.beginPath()\r\n if (coordinates.P2.x === coordinates.P3.x || coordinates.P2.y === coordinates.P3.y) {\r\n ellipse.lineTo(coordinates.P1.x, coordinates.P1.y)\r\n ellipse.lineTo(coordinates.P2.x, coordinates.P2.y)\r\n } else {\r\n ellipse.moveTo(coordinates.P4.x, coordinates.P4.y)\r\n ellipse.bezierCurveTo(\r\n coordinates.CP4.x,\r\n coordinates.CP4.y,\r\n coordinates.CP1.x,\r\n coordinates.CP1.y,\r\n coordinates.P2.x,\r\n coordinates.P2.y\r\n )\r\n ellipse.bezierCurveTo(\r\n coordinates.CP2.x,\r\n coordinates.CP2.y,\r\n coordinates.CP3.x,\r\n coordinates.CP3.y,\r\n coordinates.P4.x,\r\n coordinates.P4.y\r\n )\r\n ellipse.closePath()\r\n this.ellipsePath = ellipse\r\n context.fill(ellipse)\r\n }\r\n\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n context.stroke(ellipse)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getEllipsePoints(inverted = false) {\r\n const { x1, x2, y1, y2, cursorTargetX, cursorTargetY } = this.scaled\r\n\r\n const P1 = { x: x2, y: y2 }\r\n const P3 = { x: x1, y: y1 }\r\n\r\n let perpendicularPoint\r\n if (!isNaN(cursorTargetX) && !isNaN(cursorTargetY)) {\r\n const cursor = { x: cursorTargetX, y: cursorTargetY }\r\n const line = { x1, y1, x2, y2 }\r\n const distance = math.distanceToLine(cursor, line)\r\n perpendicularPoint = math.perpendicularPointToLine({\r\n distance,\r\n line,\r\n })\r\n } else {\r\n return {\r\n P1: P3,\r\n P2: P1,\r\n P3: P1,\r\n P4: P3,\r\n }\r\n }\r\n\r\n const lineCenterX = (P1.x + P3.x) / 2\r\n const lineCenterY = (P1.y + P3.y) / 2\r\n const pointOffsetX = perpendicularPoint.x - P1.x\r\n const pointOffsetY = perpendicularPoint.y - P1.y\r\n\r\n const P2 = { x: lineCenterX + pointOffsetX, y: lineCenterY + pointOffsetY }\r\n const P4 = { x: lineCenterX + -1 * pointOffsetX, y: lineCenterY + -1 * pointOffsetY }\r\n const invertX = this.model.scale.x.invert\r\n const invertY = this.model.scale.y.invert\r\n if (inverted) {\r\n return {\r\n P2: { x: invertX(P2.x), y: invertY(P2.y) },\r\n P4: { x: invertX(P4.x), y: invertY(P4.y) },\r\n }\r\n }\r\n\r\n const perpendicularPointEllipseOffsetX = (perpendicularPoint.x - P2.x) / 0.75 - (perpendicularPoint.x - P2.x)\r\n const perpendicularPointEllipseOffsetY = (perpendicularPoint.y - P2.y) / 0.75 - (perpendicularPoint.y - P2.y)\r\n\r\n const P1WithOffsetX = P1.x + perpendicularPointEllipseOffsetX\r\n const P1WithOffsetY = P1.y + perpendicularPointEllipseOffsetY\r\n\r\n const P3WithOffsetX = P3.x - perpendicularPointEllipseOffsetX\r\n const P3WithOffsetY = P3.y - perpendicularPointEllipseOffsetY\r\n\r\n const CP1 = {\r\n x: perpendicularPoint.x + perpendicularPointEllipseOffsetX,\r\n y: perpendicularPoint.y + perpendicularPointEllipseOffsetY,\r\n }\r\n const controlPointOffsetX = CP1.x - P1WithOffsetX\r\n const controlPointOffsetY = CP1.y - P1WithOffsetY\r\n\r\n const CP2 = { x: P3WithOffsetX + controlPointOffsetX, y: P3WithOffsetY + controlPointOffsetY }\r\n const CP3 = { x: P3WithOffsetX + -1 * controlPointOffsetX, y: P3WithOffsetY + -1 * controlPointOffsetY }\r\n const CP4 = { x: P1WithOffsetX + -1 * controlPointOffsetX, y: P1WithOffsetY + -1 * controlPointOffsetY }\r\n\r\n return {\r\n P1,\r\n P2,\r\n P3,\r\n P4,\r\n CP1,\r\n CP2,\r\n CP3,\r\n CP4,\r\n }\r\n }\r\n\r\n getRotatedPointCoordinates = ({\r\n rotationAxisPoint,\r\n pointToRotate,\r\n oldLinePoint,\r\n newLinePoint,\r\n }: {\r\n rotationAxisPoint: { x: number; y: number }\r\n pointToRotate: { x: number; y: number }\r\n oldLinePoint: { x: number; y: number }\r\n newLinePoint: { x: number; y: number }\r\n }) => {\r\n const angle = math.sharedPointLinesAngle({\r\n sharedPoint: rotationAxisPoint,\r\n oldLinePoint,\r\n newLinePoint,\r\n })\r\n const rotatedPoinCoordinates = math.rotatedPointCoordinates({\r\n rotationAxisPoint,\r\n angle,\r\n pointToRotate,\r\n })\r\n return {\r\n x: this.model.scale.x.invert(rotatedPoinCoordinates.x),\r\n y: this.model.scale.y.invert(rotatedPoinCoordinates.y),\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n this.attrs.cursorTargetX += x\r\n this.attrs.cursorTargetY += y\r\n }\r\n\r\n resize({ type, difX, difY, area }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'left':\r\n const newLeftPoint = {\r\n x: this.attrs.x1 + difX,\r\n y: this.attrs.y1 + difY,\r\n }\r\n const leftRotatedCursorPoint = this.getRotatedPointCoordinates({\r\n rotationAxisPoint: { x: this.scaled.x2, y: this.scaled.y2 },\r\n pointToRotate: {\r\n x: this.scaled.cursorTargetX,\r\n y: this.scaled.cursorTargetY,\r\n },\r\n oldLinePoint: { x: this.scaled.x1, y: this.scaled.y1 },\r\n newLinePoint: { x: this.model.scale.x(newLeftPoint.x), y: this.model.scale.y(newLeftPoint.y) },\r\n })\r\n this.attrs = {\r\n ...this.attrs,\r\n x1: newLeftPoint.x,\r\n y1: newLeftPoint.y,\r\n cursorTargetX: leftRotatedCursorPoint.x,\r\n cursorTargetY: leftRotatedCursorPoint.y,\r\n }\r\n break\r\n case 'right':\r\n const newRightPoint = {\r\n x: this.attrs.x2 + difX,\r\n y: this.attrs.y2 + difY,\r\n }\r\n const rightRotatedCursorPoint = this.getRotatedPointCoordinates({\r\n rotationAxisPoint: { x: this.scaled.x1, y: this.scaled.y1 },\r\n pointToRotate: {\r\n x: this.scaled.cursorTargetX,\r\n y: this.scaled.cursorTargetY,\r\n },\r\n oldLinePoint: { x: this.scaled.x2, y: this.scaled.y2 },\r\n newLinePoint: { x: this.model.scale.x(newRightPoint.x), y: this.model.scale.y(newRightPoint.y) },\r\n })\r\n this.attrs = {\r\n ...this.attrs,\r\n x2: newRightPoint.x,\r\n y2: newRightPoint.y,\r\n cursorTargetX: rightRotatedCursorPoint.x,\r\n cursorTargetY: rightRotatedCursorPoint.y,\r\n }\r\n break\r\n case 'top':\r\n case 'bottom':\r\n this.attrs = {\r\n ...this.attrs,\r\n cursorTargetX: area.x,\r\n cursorTargetY: area.y,\r\n }\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n if (this.ellipsePath && this.untranslatedContext?.isPointInPath(this.ellipsePath, area.scaled.x, area.scaled.y)) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getIsInChartView() {\r\n return true\r\n }\r\n}\r\n\r\nEllipseV1.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default EllipseV1\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Text, { ITextAttrs } from './text'\r\nimport Thumb from './thumb'\r\n\r\ntype Coefficients = string\r\n\r\nexport interface IFibonacciRetracementsAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n coefficients: Coefficients\r\n border: DrawingBorder\r\n}\r\n\r\nclass FibonacciRetracements<\r\n Attrs extends IFibonacciRetracementsAttrs = IFibonacciRetracementsAttrs,\r\n> extends Element {\r\n static type = CanvasElementType.fibonacciRetracements\r\n\r\n name = 'Fibonacci Retracements'\r\n declare coefficients: { default: string; parsed: number[]; max: number; min: number }\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'oneCoefficient_1',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'oneCoefficient_2',\r\n () => this.attrs.x2,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'zeroCoefficient_1',\r\n () => this.attrs.x1,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'zeroCoefficient_2',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.parseCoefficients(this.attrs.coefficients)\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n border: {\r\n width: 1,\r\n color: this.getChartLayoutSettings().ElementSettings.Colors.line,\r\n },\r\n coefficients: [0, 0.236, 0.382, 0.5, 0.618, 1].toString(),\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n parseCoefficients(coefficients: Coefficients) {\r\n if (!this.coefficients || coefficients !== this.coefficients.default) {\r\n const parsed = coefficients.split(',').map((x) => parseFloat(x.trim()))\r\n this.coefficients = { default: coefficients, parsed, max: Math.max(...parsed), min: Math.min(...parsed) }\r\n }\r\n }\r\n\r\n getMaxCoefficientUnscaledY() {\r\n return this.model.scale.y.invert(this.scaled.y2 - this.coefficients.max * (this.scaled.y2 - this.scaled.y1))\r\n }\r\n\r\n getMinCoefficientUnscaledY() {\r\n return this.model.scale.y.invert(this.scaled.y2 - this.coefficients.min * (this.scaled.y2 - this.scaled.y1))\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, y1, y2 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, y1, y2 })\r\n const translateXY = getXYOffsetFromLine({ lineWidth: this.attrs.border.width, ...roundedXY, y2: roundedXY.y1 })\r\n\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n this.parseCoefficients(this.attrs.coefficients)\r\n\r\n const height = this.attrs.y2 - this.attrs.y1\r\n\r\n context.translate(translateXY.x, translateXY.y)\r\n context.beginPath()\r\n for (const p of this.coefficients.parsed) {\r\n const y = Math.round(this.fy(this.attrs.y2 - p * height))\r\n context.moveTo(roundedXY.x1, y)\r\n context.lineTo(roundedXY.x2, y)\r\n }\r\n context.stroke()\r\n context.translate(translateXY.x * -1, translateXY.y * -1)\r\n\r\n const text = new Text(\r\n {\r\n x: roundedXY.x1,\r\n font: { size: 8, style: 'bold' },\r\n textBaseline: TextBaseline.bottom,\r\n fillStyle: this.attrs.border.color,\r\n textAlign: TextAlign.left,\r\n },\r\n this.model\r\n )\r\n if (roundedXY.x1 > roundedXY.x2) {\r\n text.set({ textAlign: TextAlign.right })\r\n }\r\n\r\n for (const p of this.coefficients.parsed) {\r\n const y = this.attrs.y2 - p * height\r\n text.set({\r\n text: (p * 100).toFixed(1) + '%: ' + y.toFixed(2),\r\n y: Math.round(this.fy(y) - this.attrs.border.width / 2),\r\n } as Partial)\r\n text.render(context)\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getThumbs() {\r\n if (this.coefficients.max > 1 && !this._thumbs.some(({ type }) => type.includes('maxCoefficient'))) {\r\n this._thumbs = [\r\n ...this._thumbs,\r\n new Thumb(\r\n 'maxCoefficient_1',\r\n () => this.attrs.x1,\r\n () => this.getMaxCoefficientUnscaledY(),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'maxCoefficient_2',\r\n () => this.attrs.x2,\r\n () => this.getMaxCoefficientUnscaledY(),\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n }\r\n if (this.coefficients.max <= 1 && this._thumbs.some(({ type }) => type.includes('maxCoefficient'))) {\r\n this._thumbs = this._thumbs.filter(({ type }) => !type.includes('maxCoefficient'))\r\n }\r\n\r\n if (this.coefficients.min < 0 && !this._thumbs.some(({ type }) => type.includes('minCoefficient'))) {\r\n this._thumbs = [\r\n ...this._thumbs,\r\n new Thumb(\r\n 'minCoefficient_1',\r\n () => this.attrs.x1,\r\n () => this.getMinCoefficientUnscaledY(),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'minCoefficient_2',\r\n () => this.attrs.x2,\r\n () => this.getMinCoefficientUnscaledY(),\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n }\r\n if (this.coefficients.min >= 0 && this._thumbs.some(({ type }) => type.includes('minCoefficient'))) {\r\n this._thumbs = this._thumbs.filter(({ type }) => !type.includes('minCoefficient'))\r\n }\r\n\r\n return this._thumbs\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.x2 += x\r\n this.attrs.y1 += y\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'oneCoefficient_1':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'oneCoefficient_2':\r\n this.attrs.x2 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'zeroCoefficient_1':\r\n this.attrs.x1 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'zeroCoefficient_2':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'maxCoefficient_1':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY / this.coefficients.max\r\n break\r\n case 'maxCoefficient_2':\r\n this.attrs.x2 += difX\r\n this.attrs.y1 += difY / this.coefficients.max\r\n break\r\n case 'minCoefficient_1':\r\n this.attrs.x1 += difX\r\n this.attrs.y2 += difY / (Math.abs(this.coefficients.min) + 1)\r\n break\r\n case 'minCoefficient_2':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY / (Math.abs(this.coefficients.min) + 1)\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const maxCoefficientY = this.coefficients.max > 1 && this.getMaxCoefficientUnscaledY()\r\n const minCoefficientY = this.coefficients.min < 0 && this.getMinCoefficientUnscaledY()\r\n const left = Math.min(this.attrs.x1, this.attrs.x2)\r\n const right = Math.max(this.attrs.x1, this.attrs.x2)\r\n const allYValues = [this.attrs.y1, this.attrs.y2, maxCoefficientY, minCoefficientY].filter((item) => item !== false)\r\n const top = Math.min(...allYValues)\r\n const bottom = Math.max(...allYValues)\r\n\r\n if (left < area.x && area.x < right && top < area.y && area.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getEdgeXYValues() {\r\n this.edgeXYValues = super.getEdgeXYValues()\r\n\r\n // Because minY, maxY can go outside of control points boundaries [0,1] we need to compensate\r\n // for that in getEdgeXYValues(), otherwise getIsInChartView() hide drawings sooner than it should\r\n const min = this.getMinCoefficientUnscaledY()\r\n const max = this.getMaxCoefficientUnscaledY()\r\n\r\n if (!isNaN(min) && !isNaN(max)) {\r\n this.edgeXYValues.minY = Math.min(min, max)\r\n this.edgeXYValues.maxY = Math.max(min, max)\r\n }\r\n\r\n return this.edgeXYValues\r\n }\r\n}\r\n\r\nFibonacciRetracements.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'line', name: 'border' },\r\n { type: 'string', name: 'coefficients', label: 'Coefficients' },\r\n ],\r\n}\r\n\r\nexport default FibonacciRetracements\r\n","import { Maybe, RequireByKey, ResizeByThumbFuncProps } from '../../types/shared'\r\nimport { CanvasElementType, TextBaseline } from '../constants/common'\r\nimport math from '../helpers/math'\r\nimport Chart from '../models/chart'\r\nimport PaneModel from '../models/pane'\r\nimport ScaledLine, { IScaledLineAttrs } from './scaled_line'\r\nimport Text from './text'\r\n\r\nconst DEFAULT_DECIMAL_PLACES = 2\r\n\r\nclass HorizontalLine extends ScaledLine {\r\n static type = CanvasElementType.horizontalLine\r\n\r\n name = 'Horizontal line'\r\n decimalPlaces = DEFAULT_DECIMAL_PLACES\r\n declare scaled: Pick\r\n declare model: PaneModel\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.updateDecimalPlaces()\r\n\r\n if (this.attrs.y1) {\r\n this.attrs.y1 = Number(math.round({ value: this.attrs.y1, overridePlaces: this.decimalPlaces }))\r\n }\r\n if (this.modalConfig) {\r\n const step = `0.${'0'.repeat(this.decimalPlaces - 1)}1`\r\n this.modalConfig.inputs[1] = {\r\n ...this.modalConfig.inputs[1],\r\n step,\r\n min: Number(step),\r\n }\r\n }\r\n this.renderContent = this.renderContent.bind(this)\r\n this._thumbs = []\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n updateDecimalPlaces() {\r\n const quote = this.model.chart().quote()\r\n this.decimalPlaces = quote\r\n ? math.getInstrumentDecimalPlaces({\r\n instrument: quote.instrument,\r\n value: quote.lastClose,\r\n })\r\n : DEFAULT_DECIMAL_PLACES\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n this.attrs.y2 = this.attrs.y1\r\n // mixing scaled and unscaled values, do not copy paste as solution\r\n this.attrs.x1 = ChartSettings.left.width * -1\r\n this.attrs.x2 =\r\n this.model\r\n .chart()\r\n .quote()\r\n .getBarIndex(this.model.chart().quote().close.length - 1) + this.model.chart().width\r\n super.renderContent(context)\r\n }\r\n\r\n renderLabels(context: CanvasRenderingContext2D) {\r\n if (this.attrs.y1) {\r\n this.updateDecimalPlaces()\r\n const { ChartSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n const isIndicatorPane = this.model\r\n .elements()\r\n .all()\r\n .some((element) => element.isIndicator())\r\n const settings = isIndicatorPane ? IndicatorSettings : ChartSettings\r\n context.translate(this.model.chart().width - settings.right.width, settings.top.height)\r\n new Text(\r\n {\r\n x: 6,\r\n y: this.scaled.y1,\r\n font: { size: 8, style: 'bold' },\r\n lineHeight: 8,\r\n padding: {\r\n top: 2,\r\n right: 2,\r\n bottom: 2,\r\n left: 2,\r\n },\r\n fillStyle: '#fff',\r\n background: '#000',\r\n textBaseline: TextBaseline.middle,\r\n text: this.attrs.y1.toFixed(this.decimalPlaces).toString(),\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n }\r\n\r\n moveBy(x: Maybe, y: number) {\r\n this.attrs.y1 += y\r\n }\r\n\r\n resize({ difY }: RequireByKey) {\r\n this.moveBy(0, difY)\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n return super.getIsInChartView(chart, { omitX: true })\r\n }\r\n}\r\n\r\nHorizontalLine.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'line', name: 'border' },\r\n { type: 'number', name: 'y1', label: 'Price', allowDecimal: true },\r\n ],\r\n}\r\n\r\nexport default HorizontalLine\r\n","import { PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\ninterface ILineAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n dashLength: number\r\n lineWidth: number\r\n strokeStyle: string\r\n}\r\n\r\nclass Line extends Element {\r\n static type = CanvasElementType.line\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.render = this.render.bind(this)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'l',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'r',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n lineWidth: 1,\r\n strokeStyle: this.getChartLayoutSettings().ElementSettings.Colors.line,\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n const { x1, y1, x2, y2, lineWidth } = this.attrs\r\n const roundedXY = getRoundedObject({ x1, y1, x2, y2 })\r\n const translateXY = getXYOffsetFromLine({ lineWidth, ...roundedXY })\r\n\r\n context.translate(translateXY.x, translateXY.y)\r\n context.beginPath()\r\n context.set('lineWidth', this.attrs.lineWidth)\r\n context.set('strokeStyle', this.attrs.strokeStyle)\r\n\r\n context.moveTo(roundedXY.x1, roundedXY.y1)\r\n if (this.attrs.dashLength) {\r\n context.setLineDash([this.attrs.dashLength])\r\n }\r\n context.lineTo(roundedXY.x2, roundedXY.y2)\r\n context.stroke()\r\n if (this.attrs.dashLength) {\r\n context.setLineDash([])\r\n }\r\n context.translate(translateXY.x * -1, translateXY.y * -1)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.x2 += x\r\n this.attrs.y1 += y\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n if (type === 'l') {\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n } else {\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n if (math.distanceToSegment(area, this.attrs) <= 10) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nexport default Line\r\n","import { PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType, TextBaseline } from '../constants/common'\r\nimport { getRoundedObject } from '../controllers/renderUtils'\r\nimport PaneModel from '../models/pane'\r\nimport { numberToStringWithUnitsSuffix } from '../utils'\r\nimport { getRoundedString } from '../utils/helpers'\r\nimport Element from './element'\r\nimport Text, { ITextAttrs } from './text'\r\nimport Thumb from './thumb'\r\n\r\ninterface Coordinates {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n}\r\n\r\nexport interface IMeasureAttrs extends Coordinates {\r\n fill: string\r\n}\r\n\r\nclass Measure extends Element {\r\n static type = CanvasElementType.measure\r\n\r\n name = 'Measure'\r\n declare scaled: Pick\r\n\r\n x1Dif: number\r\n x2Dif: number\r\n startingX1: number\r\n startingX2: number\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'tl',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'br',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n this.x1Dif = this.x2Dif = 0\r\n\r\n this.startingX1 = this.attrs.x1\r\n this.startingX2 = this.attrs.x2\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n getVolumeSumString = () => {\r\n const { volume, barIndex }: { volume: number[]; barIndex: number[] } = this.model.chart().quote()\r\n const roundedX1 = Math.round(this.attrs.x1)\r\n const roundedX2 = Math.round(this.attrs.x2)\r\n // min/max values are offset by 1 so there's no value on such index\r\n // and at the same time it won't iterate over unlimited number of nonexisting indexes\r\n const minIndexLimit = barIndex[0] - 1\r\n const maxIndexLimit = barIndex[barIndex.length - 1] + 1\r\n const volMinIndex = Math.min(Math.max(Math.min(roundedX1, roundedX2), minIndexLimit), maxIndexLimit)\r\n const volMaxIndex = Math.min(Math.max(Math.max(roundedX1, roundedX2), minIndexLimit), maxIndexLimit)\r\n\r\n let volumeSum = 0\r\n for (let i = volMinIndex; i <= volMaxIndex; i++) {\r\n const volumeIndex = barIndex.indexOf(i)\r\n if (volumeIndex >= 0) {\r\n volumeSum += volume[volumeIndex]\r\n }\r\n }\r\n\r\n return `Vol ${numberToStringWithUnitsSuffix(volumeSum)}`\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n context.set('fillStyle', this.attrs.fill)\r\n const { x1, x2, y1, y2 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, y1, y2 })\r\n\r\n const width = roundedXY.x2 - roundedXY.x1\r\n const height = roundedXY.y2 - roundedXY.y1\r\n context.fillRect(x1, roundedXY.y1, width, height)\r\n\r\n const priceDif = this.attrs.y2 - this.attrs.y1\r\n const percentage = (100 / this.attrs.y1) * priceDif\r\n const heightStr = `${priceDif.toFixed(2)} (${percentage.toFixed(2)}%)`\r\n\r\n const text = new Text(\r\n {\r\n text: `${getRoundedString({ number: Math.abs(this.attrs.x2 - this.attrs.x1), numOfDecimalPlaces: 2 })} bars`,\r\n fillStyle: '#333',\r\n font: { size: 10, family: 'Arial', weight: 'bold' },\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.model\r\n )\r\n const baseX = x1 + width / 2\r\n const baseY = roundedXY.y1 + height / 2\r\n let textWidth = text.measure(context)\r\n text.set({\r\n x: baseX - textWidth / 2,\r\n y: baseY - text.getHeight(),\r\n } as Partial)\r\n text.render(context)\r\n\r\n text.set({ text: heightStr })\r\n textWidth = text.measure(context)\r\n text.set({\r\n x: baseX - textWidth / 2,\r\n y: baseY,\r\n } as Partial)\r\n text.render(context)\r\n\r\n text.set({ text: this.getVolumeSumString() })\r\n textWidth = text.measure(context)\r\n text.set({\r\n x: baseX - textWidth / 2,\r\n y: baseY + text.getHeight(),\r\n } as Partial)\r\n text.render(context)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n addToCoordinates(difs: Partial) {\r\n this.attrs.y1 += difs.y1 || 0\r\n this.attrs.y2 += difs.y2 || 0\r\n\r\n this.x1Dif += difs.x1 || 0\r\n this.x2Dif += difs.x2 || 0\r\n\r\n // The reason for adding +1 is to \"ceil\" the number when moving to the left (decreasing bar index)\r\n const newX1 = ~~(this.startingX1 + this.x1Dif) + (this.x1Dif < 0 ? 1 : 0)\r\n if (~~this.attrs.x1 - newX1 !== 0) {\r\n this.attrs.x1 = newX1\r\n }\r\n const newX2 = ~~(this.startingX2 + this.x2Dif) + (this.x2Dif < 0 ? 1 : 0)\r\n if (~~this.attrs.x2 - newX2 !== 0) {\r\n this.attrs.x2 = newX2\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n return this.addToCoordinates({\r\n x1: x,\r\n y1: y,\r\n x2: x,\r\n y2: y,\r\n })\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n if (type === 'tl') {\r\n this.addToCoordinates({ x1: difX, y1: difY })\r\n } else {\r\n this.addToCoordinates({ x2: difX, y2: difY })\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const x1 = Math.round(this.attrs.x1)\r\n const x2 = Math.round(this.attrs.x2)\r\n\r\n const left = Math.min(x1, x2)\r\n const right = Math.max(x1, x2)\r\n const top = Math.min(this.attrs.y1, this.attrs.y2)\r\n const bottom = Math.max(this.attrs.y1, this.attrs.y2)\r\n if (left < area.x && area.x < right && top < area.y && area.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n onMouseDown(paneArea: PaneArea) {\r\n super.onMouseDown(paneArea)\r\n this.startingX1 = this.attrs.x1\r\n this.startingX2 = this.attrs.x2\r\n }\r\n\r\n onMouseUp(paneArea?: PaneArea) {\r\n super.onMouseUp(paneArea)\r\n this.x1Dif = this.x2Dif = 0\r\n }\r\n}\r\n\r\nMeasure.prototype.defaults = { fill: 'rgba(180,220,255,0.8)' }\r\n\r\nMeasure.prototype.modalConfig = {\r\n inputs: [{ type: 'background', name: 'fill' }],\r\n}\r\n\r\nexport default Measure\r\n","import { Point } from '../../../types/shared'\r\nimport { getRoundedObject } from '../../controllers/renderUtils'\r\nimport math from '../../helpers/math'\r\nimport PaneModel from '../../models/pane'\r\nimport { isInRange } from '../../utils/helpers'\r\nimport { ITrendAttrs } from './pitchfork_v1'\r\n\r\ninterface IGetEdgeIntersectionPointArguments {\r\n sides: { x: number; y: number }[][]\r\n rayOrigin: Point\r\n rayDirection: Point\r\n}\r\n\r\nexport const getEdgeIntersectionPoint = ({ sides, rayOrigin, rayDirection }: IGetEdgeIntersectionPointArguments) => {\r\n if (rayOrigin.x === rayDirection.x && rayOrigin.y === rayDirection.y) return rayDirection\r\n\r\n let intersection = rayDirection\r\n let intersectionDistance = 0\r\n for (let index = 0; index < sides.length; index++) {\r\n const rayToLineIntersection = math.getRayToLineSegmentIntersection(\r\n rayOrigin,\r\n rayDirection,\r\n sides[index][0],\r\n sides[index][1]\r\n )\r\n if (rayToLineIntersection) {\r\n const distance = math.distance(rayToLineIntersection, rayOrigin)\r\n if (distance > intersectionDistance && isInRange({ value: distance })) {\r\n intersectionDistance = distance\r\n intersection = { x: rayToLineIntersection.x, y: rayToLineIntersection.y }\r\n }\r\n }\r\n }\r\n\r\n return intersection\r\n}\r\n\r\nexport const getChartVisibleAreaBoundaries = (paneModel: PaneModel) => {\r\n const { left, right, top, bottom } = paneModel.getChartLayoutSettings().ChartSettings\r\n const { leftOffset, width } = paneModel.chart()\r\n\r\n const chartVisibleAreaLeftX = Math.abs(leftOffset)\r\n const chartVisibleAreaRightX = chartVisibleAreaLeftX + width - left.width - right.width\r\n const chartVisibleAreaTopY = 0\r\n const chartVisibleAreaBottomY = paneModel.height - top.height - bottom.height\r\n\r\n const chartVisibleAreaTopLeftPoint = {\r\n x: chartVisibleAreaLeftX,\r\n y: chartVisibleAreaTopY,\r\n }\r\n const chartVisibleAreaTopRightPoint = {\r\n x: chartVisibleAreaRightX,\r\n y: chartVisibleAreaTopY,\r\n }\r\n const chartVisibleAreaBottomLeftPoint = {\r\n x: chartVisibleAreaLeftX,\r\n y: chartVisibleAreaBottomY,\r\n }\r\n const chartVisibleAreaBottomRightPoint = {\r\n x: chartVisibleAreaRightX,\r\n y: chartVisibleAreaBottomY,\r\n }\r\n const topSide = [chartVisibleAreaTopLeftPoint, chartVisibleAreaTopRightPoint]\r\n const rightSide = [chartVisibleAreaTopRightPoint, chartVisibleAreaBottomRightPoint]\r\n const bottomSide = [chartVisibleAreaBottomLeftPoint, chartVisibleAreaBottomRightPoint]\r\n const leftSide = [chartVisibleAreaTopLeftPoint, chartVisibleAreaBottomLeftPoint]\r\n\r\n const sides = [topSide, rightSide, bottomSide, leftSide]\r\n\r\n return sides\r\n}\r\n\r\ninterface IGetPitchforkCoordinates {\r\n paneModel: PaneModel\r\n rayOrigin: Point\r\n rayDirectionControlPoint1: Point\r\n rayDirectionControlPoint2?: Point\r\n trend1: ITrendAttrs\r\n trend2: ITrendAttrs\r\n}\r\n\r\ninterface ILineSegment {\r\n P1: Point\r\n P2: Point\r\n}\r\n\r\ninterface ICoordinates {\r\n medianRay: ILineSegment\r\n trend1Ray1: ILineSegment | undefined\r\n trend1Ray2: ILineSegment | undefined\r\n trend2Ray1: ILineSegment | undefined\r\n trend2Ray2: ILineSegment | undefined\r\n}\r\n\r\nexport const getPitchforkCoordinates = ({\r\n paneModel,\r\n rayOrigin,\r\n rayDirectionControlPoint1,\r\n rayDirectionControlPoint2,\r\n trend1,\r\n trend2,\r\n}: IGetPitchforkCoordinates) => {\r\n const sides = getChartVisibleAreaBoundaries(paneModel)\r\n\r\n const coordinates: ICoordinates = {\r\n medianRay: { P1: rayOrigin, P2: rayDirectionControlPoint1 },\r\n trend1Ray1: undefined,\r\n trend2Ray1: undefined,\r\n trend1Ray2: undefined,\r\n trend2Ray2: undefined,\r\n }\r\n\r\n // If rayDirectionControlPoint2 doesn't exist return only medianRay with rayDirectionControlPoint1 as rayDirection\r\n if (!rayDirectionControlPoint2) {\r\n coordinates.medianRay = {\r\n P1: getRoundedObject(rayOrigin),\r\n P2: getRoundedObject(\r\n getEdgeIntersectionPoint({\r\n sides,\r\n rayOrigin,\r\n rayDirection: rayDirectionControlPoint1,\r\n })\r\n ),\r\n }\r\n return coordinates\r\n }\r\n\r\n const medianRayDirectionPoint = math.getMiddlePointOnLineSegment(rayDirectionControlPoint1, rayDirectionControlPoint2)\r\n const rayOriginToRayDirectionVector = {\r\n x: medianRayDirectionPoint.x - rayOrigin.x,\r\n y: medianRayDirectionPoint.y - rayOrigin.y,\r\n }\r\n\r\n const rayDirectionControlPoint1ToPoint2Vector = {\r\n x: rayDirectionControlPoint1.x - rayDirectionControlPoint2.x,\r\n y: rayDirectionControlPoint1.y - rayDirectionControlPoint2.y,\r\n }\r\n\r\n const normalizedRayDirectionControlPoint1ToPoint2Vector = math.normalizeVector(\r\n rayDirectionControlPoint1ToPoint2Vector\r\n )\r\n\r\n const medianRayDirectionPointToRayDirectionControlPoint1Distance = math.distance(\r\n medianRayDirectionPoint,\r\n rayDirectionControlPoint1\r\n )\r\n\r\n coordinates.medianRay = {\r\n P1: getRoundedObject(rayOrigin),\r\n P2: getRoundedObject(\r\n getEdgeIntersectionPoint({\r\n sides,\r\n rayOrigin,\r\n rayDirection: medianRayDirectionPoint,\r\n })\r\n ),\r\n }\r\n if (trend1.active) {\r\n const trend1Ray = getTrendRayCoordinates({\r\n trend: trend1.trend,\r\n medianToControlPointDistance: medianRayDirectionPointToRayDirectionControlPoint1Distance,\r\n normalizedControlToControlPointVector: normalizedRayDirectionControlPoint1ToPoint2Vector,\r\n rayOriginToRayDirectionVector,\r\n medianRayDirectionPoint,\r\n sides,\r\n })\r\n\r\n coordinates.trend1Ray1 = trend1Ray.trendRay1\r\n coordinates.trend1Ray2 = trend1Ray.trendRay2\r\n }\r\n if (trend2.active) {\r\n const trend2Ray = getTrendRayCoordinates({\r\n trend: trend2.trend,\r\n medianToControlPointDistance: medianRayDirectionPointToRayDirectionControlPoint1Distance,\r\n normalizedControlToControlPointVector: normalizedRayDirectionControlPoint1ToPoint2Vector,\r\n rayOriginToRayDirectionVector,\r\n medianRayDirectionPoint,\r\n sides,\r\n })\r\n\r\n coordinates.trend2Ray1 = trend2Ray.trendRay1\r\n coordinates.trend2Ray2 = trend2Ray.trendRay2\r\n }\r\n\r\n return coordinates\r\n}\r\n\r\ninterface IGetTrendRayCoordinates {\r\n trend: number\r\n medianToControlPointDistance: number\r\n normalizedControlToControlPointVector: Point\r\n rayOriginToRayDirectionVector: Point\r\n medianRayDirectionPoint: Point\r\n sides: Point[][]\r\n}\r\n\r\nconst getTrendRayCoordinates = ({\r\n trend,\r\n medianToControlPointDistance,\r\n normalizedControlToControlPointVector,\r\n rayOriginToRayDirectionVector,\r\n medianRayDirectionPoint,\r\n sides,\r\n}: IGetTrendRayCoordinates) => {\r\n const medianToTrendLineDistance = medianToControlPointDistance * trend\r\n\r\n const trendRayPoint1Origin = math.addPoints(\r\n medianRayDirectionPoint,\r\n math.multiplyVectorByScalar(normalizedControlToControlPointVector, medianToTrendLineDistance)\r\n )\r\n const trendPoint2RayOriginPoint2 = math.subtractPoints(\r\n medianRayDirectionPoint,\r\n math.multiplyVectorByScalar(normalizedControlToControlPointVector, medianToTrendLineDistance)\r\n )\r\n\r\n const trendRayPoint1DirectionPoint = {\r\n x: trendRayPoint1Origin.x + rayOriginToRayDirectionVector.x,\r\n y: trendRayPoint1Origin.y + rayOriginToRayDirectionVector.y,\r\n }\r\n const trendPoint2RayDirectionPoint = {\r\n x: trendPoint2RayOriginPoint2.x + rayOriginToRayDirectionVector.x,\r\n y: trendPoint2RayOriginPoint2.y + rayOriginToRayDirectionVector.y,\r\n }\r\n\r\n return {\r\n trendRay1: {\r\n P1: getRoundedObject(trendRayPoint1Origin),\r\n P2: getRoundedObject(\r\n getEdgeIntersectionPoint({\r\n sides,\r\n rayOrigin: trendRayPoint1Origin,\r\n rayDirection: trendRayPoint1DirectionPoint,\r\n })\r\n ),\r\n },\r\n trendRay2: {\r\n P1: getRoundedObject(trendPoint2RayOriginPoint2),\r\n P2: getRoundedObject(\r\n getEdgeIntersectionPoint({\r\n sides,\r\n rayOrigin: trendPoint2RayOriginPoint2,\r\n rayDirection: trendPoint2RayDirectionPoint,\r\n })\r\n ),\r\n },\r\n }\r\n}\r\n","import { PaneArea, ResizeByThumbWithTypeAndDifs } from '../../../types/shared'\r\nimport { CanvasElementType } from '../../constants/common'\r\nimport { getOffsetFromLineWidth } from '../../controllers/renderUtils'\r\nimport math from '../../helpers/math'\r\nimport Chart from '../../models/chart'\r\nimport PaneModel from '../../models/pane'\r\nimport { getHEXWithSpecificAplha } from '../../utils/colors'\r\nimport Element from '../element'\r\nimport Thumb from '../thumb'\r\nimport { getPitchforkCoordinates } from './pitchfork_utils'\r\n\r\nexport interface ITrendAttrs {\r\n active: boolean\r\n trend: number\r\n color: string\r\n}\r\n\r\nexport interface IPitchforkAttrs {\r\n x1: number\r\n y1: number\r\n x2: number\r\n y2: number\r\n x3: number\r\n y3: number\r\n median: { color: string; width: number }\r\n trend1: ITrendAttrs\r\n trend2: ITrendAttrs\r\n}\r\n\r\nclass Pitchfork extends Element {\r\n static type = CanvasElementType.pitchforkV1\r\n\r\n declare scaled: Pick\r\n name = 'Pitchfork'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.resize = this.resize.bind(this)\r\n\r\n this._thumbs = [\r\n new Thumb(\r\n 'medianRayOrigin',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'rayDirectionControlPoint1',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'rayDirectionControlPoint2',\r\n () => this.attrs.x3,\r\n () => this.attrs.y3,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n median: { color: '#e72f2f', width: 1 },\r\n trend1: {\r\n color: '#004ad31c',\r\n active: true,\r\n trend: 1,\r\n },\r\n trend2: {\r\n color: '#00ca4e1f',\r\n active: true,\r\n trend: 0.5,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2', 'x3'], y: ['y1', 'y2', 'y3'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, x3, y1, y2, y3 } = this.scaled\r\n\r\n const offset = getOffsetFromLineWidth(this.attrs.median.width)\r\n context.translate(offset, offset)\r\n\r\n const { medianRay, trend1Ray1, trend1Ray2, trend2Ray1, trend2Ray2 } = getPitchforkCoordinates({\r\n paneModel: this.model,\r\n rayOrigin: { x: x1, y: y1 },\r\n rayDirectionControlPoint1: { x: x2, y: y2 },\r\n rayDirectionControlPoint2: Number.isNaN(x3) || Number.isNaN(y3) ? undefined : { x: x3, y: y3 },\r\n trend1: this.attrs.trend1,\r\n trend2: this.attrs.trend2,\r\n })\r\n\r\n context.set('lineWidth', this.attrs.median.width)\r\n\r\n const trendLines = [\r\n { trend: this.attrs.trend1, line1: trend1Ray1, line2: trend1Ray2 },\r\n { trend: this.attrs.trend2, line1: trend2Ray1, line2: trend2Ray2 },\r\n ].sort((a, b) => {\r\n if (Math.abs(a.trend.trend) > Math.abs(b.trend.trend)) {\r\n return -1\r\n }\r\n if (Math.abs(a.trend.trend) < Math.abs(b.trend.trend)) {\r\n return 1\r\n }\r\n return 0\r\n })\r\n\r\n // Draw trend lines and fill\r\n trendLines.forEach((trendLine, trendLineIndex) => {\r\n if (trendLine.line1 && trendLine.line2) {\r\n const { line1, line2 } = trendLine\r\n const solidTrendColor = getHEXWithSpecificAplha(trendLine.trend.color)\r\n const nextTrendLine = trendLines[trendLineIndex + 1]\r\n\r\n context.beginPath()\r\n context.moveTo(line1.P1.x, line1.P1.y)\r\n context.lineTo(line1.P2.x, line1.P2.y)\r\n if (trendLineIndex !== trendLines.length - 1 && nextTrendLine.line1 && nextTrendLine.line2) {\r\n context.lineTo(nextTrendLine.line1.P2.x, nextTrendLine.line1.P2.y)\r\n context.lineTo(nextTrendLine.line1.P1.x, nextTrendLine.line1.P1.y)\r\n context.moveTo(nextTrendLine.line2.P1.x, nextTrendLine.line2.P1.y)\r\n context.lineTo(nextTrendLine.line2.P2.x, nextTrendLine.line2.P2.y)\r\n }\r\n context.lineTo(line2.P2.x, line2.P2.y)\r\n context.lineTo(line2.P1.x, line2.P1.y)\r\n context.closePath()\r\n context.set('fillStyle', trendLine.trend.color)\r\n context.fill()\r\n\r\n context.beginPath()\r\n context.moveTo(line1.P1.x, line1.P1.y)\r\n context.lineTo(line1.P2.x, line1.P2.y)\r\n context.moveTo(line2.P1.x, line2.P1.y)\r\n context.lineTo(line2.P2.x, line2.P2.y)\r\n context.set('strokeStyle', solidTrendColor)\r\n context.stroke()\r\n }\r\n })\r\n\r\n // Draw median ray line\r\n context.beginPath()\r\n context.moveTo(medianRay.P1.x, medianRay.P1.y)\r\n context.lineTo(medianRay.P2.x, medianRay.P2.y)\r\n\r\n // Draw line between outer trend lines origin points or if smaller than 1 between direction control points\r\n const outerTrendLines =\r\n trendLines.filter(\r\n (item) => item.line1 && item.line2 && item.trend.active && Math.abs(item.trend.trend) >= 1\r\n )[0] ?? {}\r\n\r\n if (outerTrendLines.line1 && outerTrendLines.line2) {\r\n context.moveTo(outerTrendLines.line1.P1.x, outerTrendLines.line1.P1.y)\r\n context.lineTo(outerTrendLines.line2.P1.x, outerTrendLines.line2.P1.y)\r\n } else if (!Number.isNaN(x3) && !Number.isNaN(y3)) {\r\n context.moveTo(x2, y2)\r\n context.lineTo(x3, y3)\r\n }\r\n\r\n context.set('strokeStyle', this.attrs.median.color)\r\n context.stroke()\r\n\r\n context.translate(offset * -1, offset * -1)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n this.attrs.x3 += x\r\n this.attrs.y3 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'medianRayOrigin':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'rayDirectionControlPoint1':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'rayDirectionControlPoint2':\r\n this.attrs.x3 += difX\r\n this.attrs.y3 += difY\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const { x1, x2, x3, y1, y2, y3 } = this.scaled\r\n const { medianRay, trend1Ray1, trend1Ray2, trend2Ray1, trend2Ray2 } = getPitchforkCoordinates({\r\n paneModel: this.model,\r\n rayOrigin: { x: x1, y: y1 },\r\n rayDirectionControlPoint1: { x: x2, y: y2 },\r\n rayDirectionControlPoint2: Number.isNaN(x3) || Number.isNaN(y3) ? undefined : { x: x3, y: y3 },\r\n trend1: this.attrs.trend1,\r\n trend2: this.attrs.trend2,\r\n })\r\n const outerTrendLines =\r\n Math.abs(this.attrs.trend1.trend) > Math.abs(this.attrs.trend2.trend)\r\n ? { line1: trend1Ray1, line2: trend1Ray2 }\r\n : { line1: trend2Ray1, line2: trend2Ray2 }\r\n\r\n if (\r\n math.distanceToSegment(area.scaled, {\r\n x1: medianRay.P1.x,\r\n y1: medianRay.P1.y,\r\n x2: medianRay.P2.x,\r\n y2: medianRay.P2.y,\r\n }) <= 10\r\n ) {\r\n // cursor is near median ray\r\n return true\r\n } else if (\r\n !Number.isNaN(x3) &&\r\n !Number.isNaN(y3) &&\r\n math.distanceToSegment(area.scaled, {\r\n x1: x2,\r\n y1: y2,\r\n x2: x3,\r\n y2: y3,\r\n }) <= 10\r\n ) {\r\n // cursor is near line connecting direction control points\r\n return true\r\n } else if (\r\n outerTrendLines.line1 &&\r\n outerTrendLines.line2 &&\r\n math.pointInPolygon(area.scaled, [\r\n outerTrendLines.line1.P1,\r\n outerTrendLines.line1.P2,\r\n outerTrendLines.line2.P2,\r\n outerTrendLines.line2.P1,\r\n ])\r\n ) {\r\n // cursor is on polygon created by outer trend lines\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getIsInChartView(_: Chart) {\r\n return true\r\n }\r\n}\r\n\r\nPitchfork.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'line', name: 'median' },\r\n { type: 'trend', name: 'trend1' },\r\n { type: 'trend', name: 'trend2' },\r\n ],\r\n}\r\n\r\nexport default Pitchfork\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getOffsetFromLineWidth } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element, { EdgeValues } from './element'\r\nimport Thumb from './thumb'\r\n\r\ntype Points = Array<{ x: number; y: number }>\r\n\r\nexport interface IPolygonAttrs {\r\n points: Points\r\n fill: string\r\n border: DrawingBorder\r\n positionPointsTimestamps?: Points\r\n}\r\n\r\nclass Polygon extends Element {\r\n static type = CanvasElementType.polygon\r\n\r\n name = 'Polygon'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this.attrs.fill = this.attrs.fill || 'rgba(50, 60, 70, 0.8)'\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n context.set('fillStyle', this.attrs.fill)\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n\r\n const offset = getOffsetFromLineWidth(this.attrs.border.width)\r\n context.translate(offset, offset)\r\n\r\n const { points } = this.attrs\r\n context.beginPath()\r\n context.moveTo(this.fx(points[0].x), this.fy(points[0].y))\r\n for (const p of points.slice(1)) {\r\n context.lineTo(this.fx(p.x), this.fy(p.y))\r\n }\r\n\r\n if (this.isPolygon()) {\r\n context.closePath()\r\n context.fill()\r\n }\r\n context.translate(offset * -1, offset * -1)\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.stroke()\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getThumbs() {\r\n return this.attrs.points.map(\r\n (point, index) =>\r\n new Thumb(\r\n `${index}`,\r\n () => point.x,\r\n () => point.y,\r\n this.resize,\r\n this.model\r\n )\r\n )\r\n }\r\n\r\n cachePointPositionTimestamp = () => {\r\n const quote = this.model?.chart()?.quote()\r\n if (quote) {\r\n const positionPointsTimestamps = this.attrs.points.map((point) => ({\r\n ...point,\r\n x: quote.getTimestampFomPositionX(point.x),\r\n }))\r\n\r\n this.set({ positionPointsTimestamps } as Partial)\r\n }\r\n }\r\n\r\n updateScales() {\r\n const quote = this.model.chart().quote()\r\n const { positionPointsTimestamps } = this.attrs\r\n if (!quote || !positionPointsTimestamps) {\r\n // positionWavesTimestamps check is temporary to prevent app from crashing\r\n // caused by corrupted drawings - https://github.com/finvizhq/charts/pull/1386/files\r\n return\r\n }\r\n const points = positionPointsTimestamps.map((point) => ({\r\n ...point,\r\n x: quote.getPositionXFromTimestamp(point.x),\r\n }))\r\n this.set({ points } as Partial)\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n for (const point of this.attrs.points) {\r\n point.x += x\r\n point.y += y\r\n }\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n const last = this.attrs.points.length - 1\r\n if (this.isPolygon() && (+type === 0 || +type === last)) {\r\n this.attrs.points[0].x += difX\r\n this.attrs.points[0].y += difY\r\n this.attrs.points[last].x += difX\r\n this.attrs.points[last].y += difY\r\n } else {\r\n this.attrs.points[+type].x += difX\r\n this.attrs.points[+type].y += difY\r\n }\r\n }\r\n\r\n isPolygon() {\r\n return (\r\n this.attrs.points[0].x === this.attrs.points.last()?.x && this.attrs.points[0].y === this.attrs.points.last()?.y\r\n )\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const scaledPoints = this.attrs.points.map((p) => ({\r\n x: this.fx(p.x),\r\n y: this.fy(p.y),\r\n }))\r\n if (this.isPolygon()) {\r\n if (math.pointInPolygon(area.scaled, scaledPoints)) {\r\n return true\r\n }\r\n } else {\r\n for (let i = 0; i < scaledPoints.length - 1; i++) {\r\n if (\r\n math.distanceToSegment(area.scaled, {\r\n x1: scaledPoints[i].x,\r\n y1: scaledPoints[i].y,\r\n x2: scaledPoints[i + 1].x,\r\n y2: scaledPoints[i + 1].y,\r\n }) <= 10\r\n ) {\r\n return true\r\n }\r\n }\r\n }\r\n\r\n return super.isInArea(area)\r\n }\r\n\r\n getAutosaveOmittedProperties() {\r\n return ['points']\r\n }\r\n\r\n getEdgeXYValues() {\r\n if (this.edgeXYValues === null) {\r\n const edgeXYValues = {} as EdgeValues\r\n this.attrs.points.forEach(({ x, y }) => {\r\n const xPoint = x\r\n const yPoint = y\r\n edgeXYValues.minX = Math.min(xPoint, edgeXYValues.minX ?? xPoint)\r\n edgeXYValues.minY = Math.min(yPoint, edgeXYValues.minY ?? yPoint)\r\n edgeXYValues.maxX = Math.max(xPoint, edgeXYValues.maxX ?? xPoint)\r\n edgeXYValues.maxY = Math.max(yPoint, edgeXYValues.maxY ?? yPoint)\r\n })\r\n\r\n this.edgeXYValues = edgeXYValues\r\n }\r\n\r\n return this.edgeXYValues\r\n }\r\n}\r\n\r\nPolygon.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default Polygon\r\n","import { PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType, TextBaseline } from '../constants/common'\r\nimport { getRoundedObject } from '../controllers/renderUtils'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Text, { ITextAttrs } from './text'\r\nimport Thumb from './thumb'\r\n\r\ninterface Coordinates {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n}\r\n\r\nexport interface IPositionAttrs extends Coordinates {\r\n targetColor: string\r\n stopColor: string\r\n targetY: number\r\n centerY: number\r\n stopY: number\r\n}\r\n\r\nclass Position extends Element {\r\n static type = CanvasElementType.position\r\n\r\n name = 'Position'\r\n\r\n declare scaled: Pick\r\n\r\n x1Dif: number\r\n x2Dif: number\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 't1',\r\n () => this.attrs.x1,\r\n () => this.attrs.targetY,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 't2',\r\n () => this.attrs.x2,\r\n () => this.attrs.targetY,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 's1',\r\n () => this.attrs.x1,\r\n () => this.attrs.stopY,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 's2',\r\n () => this.attrs.x2,\r\n () => this.attrs.stopY,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c1',\r\n () => this.attrs.x1,\r\n () => this.attrs.centerY,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c2',\r\n () => this.attrs.x2,\r\n () => this.attrs.centerY,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n this.x1Dif = this.x2Dif = 0\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['targetY', 'centerY', 'stopY'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, targetY, centerY, stopY } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, targetY, centerY, stopY })\r\n let sign, stopBaseline, targetBaseline\r\n const width = roundedXY.x2 - roundedXY.x1\r\n\r\n context.set('fillStyle', this.attrs.targetColor)\r\n context.fillRect(roundedXY.x1, roundedXY.targetY, width, roundedXY.centerY - roundedXY.targetY)\r\n\r\n context.set('fillStyle', this.attrs.stopColor)\r\n context.fillRect(roundedXY.x1, roundedXY.centerY, width, roundedXY.stopY - roundedXY.centerY)\r\n\r\n const targetDif = Math.abs(this.attrs.targetY - this.attrs.centerY)\r\n const targetPerc = (100 / this.attrs.centerY) * targetDif\r\n const targetStr = `Target: ${targetDif.toFixed(2)} (${targetPerc.toFixed(2)}%)`\r\n\r\n const stopDif = Math.abs(this.attrs.stopY - this.attrs.centerY)\r\n const stopPerc = (100 / this.attrs.centerY) * stopDif\r\n const stopStr = `Stop: ${stopDif.toFixed(2)} (${stopPerc.toFixed(2)}%)`\r\n\r\n if (this.attrs.targetY > this.attrs.centerY) {\r\n sign = 1\r\n targetBaseline = TextBaseline.bottom\r\n stopBaseline = TextBaseline.top\r\n } else {\r\n sign = -1\r\n targetBaseline = TextBaseline.top\r\n stopBaseline = TextBaseline.bottom\r\n }\r\n\r\n const text = new Text(\r\n {\r\n text: targetStr,\r\n fillStyle: this.getChartLayoutSettings().ElementSettings.Colors.textWithoutBackground,\r\n font: { size: 10, family: 'Arial', weight: 'bold' },\r\n y: roundedXY.targetY - sign * 4,\r\n textBaseline: targetBaseline,\r\n },\r\n this.model\r\n )\r\n let textWidth = text.measure(context)\r\n text.set({ x: roundedXY.x1 + width / 2 - textWidth / 2 } as Partial)\r\n text.render(context)\r\n\r\n text.set({\r\n text: stopStr,\r\n y: roundedXY.stopY + sign * 4,\r\n textBaseline: stopBaseline,\r\n })\r\n textWidth = text.measure(context)\r\n text.set({ x: roundedXY.x1 + width / 2 - textWidth / 2 } as Partial)\r\n text.render(context)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n addToCoordinates(difs: Partial) {\r\n let middle, middle1, result\r\n if (difs.targetY) {\r\n result = this.attrs.targetY + difs.targetY\r\n if (\r\n (this.attrs.targetY > this.attrs.centerY && result < this.attrs.centerY) ||\r\n (this.attrs.targetY < this.attrs.centerY && result > this.attrs.centerY)\r\n ) {\r\n this.attrs.stopY = this.attrs.centerY - (this.attrs.stopY - this.attrs.centerY) // swap target&stop\r\n }\r\n this.attrs.targetY = result\r\n }\r\n\r\n if (difs.stopY) {\r\n result = this.attrs.stopY + difs.stopY\r\n if (\r\n (this.attrs.stopY > this.attrs.centerY && result < this.attrs.centerY) ||\r\n (this.attrs.stopY < this.attrs.centerY && result > this.attrs.centerY)\r\n ) {\r\n this.attrs.targetY = this.attrs.centerY - (this.attrs.targetY - this.attrs.centerY) // swap target&stop\r\n }\r\n this.attrs.stopY = result\r\n }\r\n\r\n if (\r\n difs.centerY &&\r\n ((this.attrs.stopY < (middle = this.attrs.centerY + difs.centerY) && middle < this.attrs.targetY) ||\r\n (this.attrs.stopY > (middle1 = this.attrs.centerY + difs.centerY) && middle1 > this.attrs.targetY))\r\n ) {\r\n this.attrs.centerY += difs.centerY\r\n }\r\n\r\n this.x1Dif += difs.x1 || 0\r\n this.x2Dif += difs.x2 || 0\r\n const roundDif = ~~this.x1Dif || ~~this.x2Dif\r\n if (roundDif !== 0) {\r\n if (difs.x1 != null) {\r\n this.attrs.x1 += roundDif\r\n }\r\n if (difs.x2 != null) {\r\n this.attrs.x2 += roundDif\r\n }\r\n this.x1Dif = this.x2Dif = 0\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n return this.addToCoordinates({\r\n x1: x,\r\n x2: x,\r\n targetY: y,\r\n centerY: y,\r\n stopY: y,\r\n })\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n const [coordType, coordIndex] = (type as string).split('')\r\n const yPoints: Record = { t: 'targetY', c: 'centerY', s: 'stopY' }\r\n const obj: Partial = {\r\n [`x${coordIndex}`]: difX,\r\n [yPoints[coordType]]: difY,\r\n }\r\n return this.addToCoordinates(obj)\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const x1 = Math.round(this.attrs.x1)\r\n const x2 = Math.round(this.attrs.x2)\r\n const left = Math.min(x1, x2)\r\n const right = Math.max(x1, x2)\r\n const top = Math.min(this.attrs.targetY, this.attrs.stopY)\r\n const bottom = Math.max(this.attrs.targetY, this.attrs.stopY)\r\n if (left < area.x && area.x < right && top < area.y && area.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nPosition.prototype.defaults = {\r\n targetColor: 'rgba(0,200,0,0.3)',\r\n stopColor: 'rgba(200,0,0,0.3)',\r\n}\r\n\r\nPosition.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'targetColor' },\r\n { type: 'background', name: 'stopColor' },\r\n ],\r\n}\r\n\r\nexport default Position\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getOffsetFromLineWidth, getRoundedObject } from '../controllers/renderUtils'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface IRectangleAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n fill: string\r\n border: DrawingBorder\r\n}\r\n\r\nclass Rectangle extends Element {\r\n static type = CanvasElementType.rectangle\r\n\r\n name = 'Rectangle'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'br',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'tl',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, y1, y2 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, y1, y2 })\r\n const width = roundedXY.x2 - roundedXY.x1\r\n const height = roundedXY.y2 - roundedXY.y1\r\n\r\n context.set('fillStyle', this.attrs.fill)\r\n\r\n context.fillRect(roundedXY.x1, roundedXY.y1, width, height)\r\n\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n const offset = getOffsetFromLineWidth(this.attrs.border.width)\r\n context.strokeRect(roundedXY.x1 + offset, roundedXY.y1 + offset, width, height)\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.x2 += x\r\n this.attrs.y1 += y\r\n this.attrs.y2 += y\r\n\r\n // @todo - Live sync of elements while they are being moved around\r\n // In order to have live sync across charts we need to trigger change so listeners can update other charts with new values\r\n // this.set(this.attrs)\r\n // this.trigger('change', this)\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n if (type === 'tl') {\r\n this.attrs.x1 += difX\r\n return (this.attrs.y1 += difY)\r\n } else {\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const left = Math.min(this.attrs.x1, this.attrs.x2)\r\n const right = Math.max(this.attrs.x1, this.attrs.x2)\r\n const top = Math.min(this.attrs.y1, this.attrs.y2)\r\n const bottom = Math.max(this.attrs.y1, this.attrs.y2)\r\n if (left < area.x && area.x < right && top < area.y && area.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nRectangle.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default Rectangle\r\n","import { DrawingBorder, PaneArea, Point, ResizeByThumbWithTypeAndDifs } from '../../../types/shared'\r\nimport { CanvasElementType } from '../../constants/common'\r\nimport { getOffsetFromLineWidth, getRoundedObject } from '../../controllers/renderUtils'\r\nimport math from '../../helpers/math'\r\nimport PaneModel from '../../models/pane'\r\nimport Element from '../element'\r\nimport Thumb from '../thumb'\r\n\r\nexport interface IRotatedRectangleV1Attrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n cursorTargetX: number\r\n cursorTargetY: number\r\n fill: string\r\n border: DrawingBorder\r\n}\r\n\r\nclass RotatedRectangleV1 extends Element {\r\n static type = CanvasElementType.rotatedRectangleV1\r\n\r\n name = 'New Rotated Rectangle'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'middleLeft',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'middleRight',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'topRight',\r\n () => this.getRectCoordinates(true).P1.x || this.attrs.x2,\r\n () => this.getRectCoordinates(true).P1.y || this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'topLeft',\r\n () => this.getRectCoordinates(true).P2.x || this.attrs.x2,\r\n () => this.getRectCoordinates(true).P2.y || this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'bottomLeft',\r\n () => this.getRectCoordinates(true).P3.x || this.attrs.x1,\r\n () => this.getRectCoordinates(true).P3.y || this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'bottomRight',\r\n () => this.getRectCoordinates(true).P4.x || this.attrs.x1,\r\n () => this.getRectCoordinates(true).P4.y || this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2', 'cursorTargetX'], y: ['y1', 'y2', 'cursorTargetY'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { P1, P2, P3, P4 } = this.getRectCoordinates()\r\n const roundedXY = {\r\n P1: getRoundedObject(P1),\r\n P2: getRoundedObject(P2),\r\n P3: getRoundedObject(P3),\r\n P4: getRoundedObject(P4),\r\n }\r\n const offset = getOffsetFromLineWidth(this.attrs.border.width)\r\n context.set('fillStyle', this.attrs.fill)\r\n\r\n context.translate(offset, offset)\r\n context.beginPath()\r\n if (roundedXY.P1.x === roundedXY.P4.x && roundedXY.P1.y === roundedXY.P4.y) {\r\n context.lineTo(roundedXY.P1.x, roundedXY.P1.y)\r\n context.lineTo(roundedXY.P2.x, roundedXY.P2.y)\r\n } else {\r\n context.lineTo(roundedXY.P1.x, roundedXY.P1.y)\r\n context.lineTo(roundedXY.P2.x, roundedXY.P2.y)\r\n context.lineTo(roundedXY.P3.x, roundedXY.P3.y)\r\n context.lineTo(roundedXY.P4.x, roundedXY.P4.y)\r\n context.closePath()\r\n context.fill()\r\n }\r\n context.translate(offset * -1, offset * -1)\r\n\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n context.stroke()\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getRectCoordinates(inverted = false) {\r\n const { x1, x2, y1, y2, cursorTargetX, cursorTargetY } = this.scaled\r\n let perpendicularPoint\r\n if (!isNaN(cursorTargetX) && !isNaN(cursorTargetY)) {\r\n const cursor = { x: cursorTargetX, y: cursorTargetY }\r\n const line = { x1, y1, x2, y2 }\r\n const distance = math.distanceToLine(cursor, line)\r\n perpendicularPoint = math.perpendicularPointToLine({\r\n distance,\r\n line,\r\n })\r\n } else {\r\n return {\r\n P1: { x: x2, y: y2 },\r\n P2: { x: x1, y: y1 },\r\n P3: { x: x1, y: y1 },\r\n P4: { x: x2, y: y2 },\r\n }\r\n }\r\n\r\n const pointOffsetX = perpendicularPoint.x - x2\r\n const pointOffsetY = perpendicularPoint.y - y2\r\n\r\n const P1 = { x: x2 + pointOffsetX, y: y2 + pointOffsetY }\r\n const P2 = { x: x1 + pointOffsetX, y: y1 + pointOffsetY }\r\n const P3 = { x: x1 + -1 * pointOffsetX, y: y1 + -1 * pointOffsetY }\r\n const P4 = { x: x2 + -1 * pointOffsetX, y: y2 + -1 * pointOffsetY }\r\n\r\n const invertX = this.model.scale.x.invert\r\n const invertY = this.model.scale.y.invert\r\n if (inverted) {\r\n return {\r\n P1: { x: invertX(P1.x), y: invertY(P1.y) },\r\n P2: { x: invertX(P2.x), y: invertY(P2.y) },\r\n P3: { x: invertX(P3.x), y: invertY(P3.y) },\r\n P4: { x: invertX(P4.x), y: invertY(P4.y) },\r\n }\r\n }\r\n return { P1, P2, P3, P4 }\r\n }\r\n\r\n getRotatedPointCoordinates = ({\r\n rotationAxisPoint,\r\n pointToRotate,\r\n oldLinePoint,\r\n newLinePoint,\r\n }: {\r\n rotationAxisPoint: Point\r\n pointToRotate: Point\r\n oldLinePoint: Point\r\n newLinePoint: Point\r\n }) => {\r\n const angle = math.sharedPointLinesAngle({\r\n sharedPoint: rotationAxisPoint,\r\n oldLinePoint,\r\n newLinePoint,\r\n })\r\n const rotatedPoinCoordinates = math.rotatedPointCoordinates({\r\n rotationAxisPoint,\r\n angle,\r\n pointToRotate,\r\n })\r\n return {\r\n x: this.model.scale.x.invert(rotatedPoinCoordinates.x),\r\n y: this.model.scale.y.invert(rotatedPoinCoordinates.y),\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n this.attrs.cursorTargetX += x\r\n this.attrs.cursorTargetY += y\r\n }\r\n\r\n resize({ type, difX, difY, area }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'middleLeft':\r\n const newMiddleLeftPoint = {\r\n x: this.attrs.x1 + difX,\r\n y: this.attrs.y1 + difY,\r\n }\r\n const middleLeftRotatedCursorPoint = this.getRotatedPointCoordinates({\r\n rotationAxisPoint: { x: this.scaled.x2, y: this.scaled.y2 },\r\n pointToRotate: {\r\n x: this.scaled.cursorTargetX,\r\n y: this.scaled.cursorTargetY,\r\n },\r\n oldLinePoint: { x: this.scaled.x1, y: this.scaled.y1 },\r\n newLinePoint: { x: this.model.scale.x(newMiddleLeftPoint.x), y: this.model.scale.y(newMiddleLeftPoint.y) },\r\n })\r\n this.attrs = {\r\n ...this.attrs,\r\n x1: newMiddleLeftPoint.x,\r\n y1: newMiddleLeftPoint.y,\r\n cursorTargetX: middleLeftRotatedCursorPoint.x,\r\n cursorTargetY: middleLeftRotatedCursorPoint.y,\r\n }\r\n break\r\n case 'middleRight':\r\n const newMiddleRightPoint = {\r\n x: this.attrs.x2 + difX,\r\n y: this.attrs.y2 + difY,\r\n }\r\n const middleRightRotatedCursorPoint = this.getRotatedPointCoordinates({\r\n rotationAxisPoint: { x: this.scaled.x1, y: this.scaled.y1 },\r\n pointToRotate: {\r\n x: this.scaled.cursorTargetX,\r\n y: this.scaled.cursorTargetY,\r\n },\r\n oldLinePoint: { x: this.scaled.x2, y: this.scaled.y2 },\r\n newLinePoint: { x: this.model.scale.x(newMiddleRightPoint.x), y: this.model.scale.y(newMiddleRightPoint.y) },\r\n })\r\n this.attrs = {\r\n ...this.attrs,\r\n x2: newMiddleRightPoint.x,\r\n y2: newMiddleRightPoint.y,\r\n cursorTargetX: middleRightRotatedCursorPoint.x,\r\n cursorTargetY: middleRightRotatedCursorPoint.y,\r\n }\r\n break\r\n case 'topRight':\r\n case 'topLeft':\r\n case 'bottomLeft':\r\n case 'bottomRight':\r\n this.attrs = {\r\n ...this.attrs,\r\n cursorTargetX: area.x,\r\n cursorTargetY: area.y,\r\n }\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const coordinates = this.getRectCoordinates()\r\n const polygon = Object.keys(coordinates).map((point) => ({\r\n x: coordinates[point as 'P1' | 'P2' | 'P3' | 'P4'].x,\r\n y: coordinates[point as 'P1' | 'P2' | 'P3' | 'P4'].y,\r\n }))\r\n if (math.pointInPolygon(area.scaled, polygon)) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getIsInChartView() {\r\n return true\r\n }\r\n}\r\n\r\nRotatedRectangleV1.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default RotatedRectangleV1\r\n","import { DrawingBorder, PaneArea } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Line from './line'\r\n\r\nexport interface IScaledLineAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n dashLength: number\r\n lineWidth: number\r\n strokeStyle: string\r\n border: DrawingBorder\r\n}\r\n\r\nclass ScaledLine extends Line {\r\n static type = CanvasElementType.scaledLine\r\n\r\n name = 'Line'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.renderContent = this.renderContent.bind(this)\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n border: {\r\n width: 1,\r\n color: this.getChartLayoutSettings().ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, y1, y2 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, y1, y2 })\r\n const translateXY = getXYOffsetFromLine({ lineWidth: this.attrs.border.width, ...roundedXY })\r\n\r\n context.translate(translateXY.x, translateXY.y)\r\n context.beginPath()\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n\r\n context.moveTo(roundedXY.x1, roundedXY.y1)\r\n if (this.attrs.dashLength) {\r\n context.setLineDash([this.attrs.dashLength])\r\n }\r\n context.lineTo(roundedXY.x2, roundedXY.y2)\r\n context.stroke()\r\n context.translate(translateXY.x * -1, translateXY.y * -1)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n if (math.distanceToSegment(area.scaled, this.scaled) <= 10) {\r\n return true\r\n }\r\n return this.thumbsAreInArea(area)\r\n }\r\n}\r\n\r\nScaledLine.prototype.modalConfig = {\r\n inputs: [{ type: 'line', name: 'border' }],\r\n}\r\n\r\nexport default ScaledLine\r\n","import merge from 'lodash.merge'\r\n\r\nimport { PaneArea } from '../../types/shared'\r\nimport { PADDING } from '../constants/common'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport PaneModel from '../models/pane'\r\nimport Text, { ITextAttrs } from './text'\r\n\r\ninterface FontFamilyHeightCoefficient {\r\n Arial: {\r\n firstLine: number\r\n otherLines: number\r\n }\r\n Verdana: {\r\n firstLine: number\r\n otherLines: number\r\n }\r\n}\r\n\r\nclass ScaledText extends Text {\r\n static type = CanvasElementType.scaledText\r\n\r\n name = 'Text'\r\n declare fontFamilyHeightCoeficient: FontFamilyHeightCoefficient\r\n declare lastAttrs: Attrs\r\n declare scaled: Partial\r\n declare measuredHeight: number\r\n\r\n declare font: string\r\n declare context?: CanvasRenderingContext2D\r\n declare lines: {\r\n text: string\r\n metrics: TextMetrics\r\n }[]\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.scale({ x: ['x'], y: ['y'] })\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x'], y: ['y'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n this.render(context)\r\n }\r\n\r\n setupTextMetricsCache() {\r\n const ctx = this.context\r\n\r\n if (\r\n (this.attrs.text !== this.lastAttrs?.text ||\r\n JSON.stringify(this.attrs.font) !== JSON.stringify(this.lastAttrs?.font)) &&\r\n ctx\r\n ) {\r\n this.lastAttrs = merge({}, this.attrs)\r\n this.lines = this.getLines().map((line) => ({\r\n text: line,\r\n metrics: ctx.measureText(line),\r\n }))\r\n this.measuredHeight = this.lines.reduce((acc, current, currentIndex) => {\r\n const lineHeight =\r\n current.metrics.actualBoundingBoxAscent +\r\n current.metrics.actualBoundingBoxDescent +\r\n (currentIndex !== this.lines.length - 1 ? PADDING.XXXS : 0)\r\n return acc + lineHeight\r\n }, 0)\r\n }\r\n }\r\n\r\n // private\r\n setupContext(context: CanvasRenderingContext2D) {\r\n this.context = context\r\n context.set('font', this.font)\r\n context.set('fillStyle', this.attrs.fillStyle!)\r\n context.set('textAlign', this.attrs.textAlign!)\r\n context.set('textBaseline', this.attrs.textBaseline)\r\n this.setupTextMetricsCache()\r\n }\r\n\r\n // private\r\n renderText() {\r\n if (!this.context) return\r\n let y = this.scaled.y! + this.attrs.padding.top\r\n let previousDescent = 0\r\n for (let i = 0; i < this.lines.length; i++) {\r\n y += i === 0 ? 0 : this.lines[i].metrics.actualBoundingBoxAscent + previousDescent + PADDING.XXXS\r\n this.context.fillText(this.lines[i].text, this.scaled.x! + this.attrs.padding.left, y)\r\n previousDescent = this.lines[i].metrics.actualBoundingBoxDescent\r\n }\r\n }\r\n\r\n // private\r\n renderBackground() {\r\n if (!this.attrs.background || !this.context) {\r\n return\r\n }\r\n const padding = this.attrs.border!.width / 2 + PADDING.XXS\r\n\r\n this.context.beginPath()\r\n this.context.rect(\r\n this.scaled.x! - padding,\r\n this.scaled.y! - this.lines[0].metrics.actualBoundingBoxAscent - padding,\r\n this.width + padding * 2,\r\n this.measuredHeight + padding * 2\r\n )\r\n this.context.set('fillStyle', this.attrs.background)\r\n this.context.fill()\r\n this.context.set('fillStyle', this.attrs.fillStyle!)\r\n this.renderBorder()\r\n this.context.closePath()\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n // TODO\r\n // if @attrs.textBaseline == 'middle'\r\n // rect.y = @attrs.y - rect.height/2\r\n if (\r\n this.lines &&\r\n this.scaled.x! < area.scaled.x &&\r\n area.scaled.x < this.scaled.x! + this.width &&\r\n this.scaled.y! - this.lines[0].metrics.actualBoundingBoxAscent < area.scaled.y &&\r\n area.scaled.y < this.scaled.y! - this.lines[0].metrics.actualBoundingBoxAscent + this.measuredHeight\r\n ) {\r\n return true\r\n }\r\n return this.thumbsAreInArea(area)\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n if (this.getIsCreator()) {\r\n return true\r\n }\r\n\r\n if (!this.lines) {\r\n return true\r\n }\r\n\r\n const padding = this.attrs.border!.width / 2 + PADDING.XXS\r\n const textBoxX = this.scaled.x! - padding\r\n const textBoxY = this.scaled.y! - this.lines[0].metrics.actualBoundingBoxAscent - padding\r\n const textBoxWidth = this.width + padding * 2\r\n const textBoxHeight = this.measuredHeight + padding * 2\r\n\r\n if (\r\n textBoxX <= -chart.leftOffset + chart.width &&\r\n textBoxX + textBoxWidth >= -chart.leftOffset &&\r\n textBoxY <= this.model.height &&\r\n textBoxY + textBoxHeight >= 0\r\n ) {\r\n return true\r\n }\r\n\r\n return false\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x! += x\r\n this.attrs.y! += y\r\n }\r\n}\r\n\r\nexport default ScaledText\r\n","import { PaneArea, RequireByKey, TextAttrs } from '../../types/shared'\r\nimport { CanvasElementType, TextAlign, TextBaseline } from '../constants/common'\r\nimport Element, { TodoModalConfig } from './element'\r\n\r\nexport interface Area {\r\n x: number\r\n y: number\r\n}\r\n\r\nexport type ITextAttrs = RequireByKey & Partial\r\n\r\nconst DEFAULTS: Partial = {\r\n text: '',\r\n font: {\r\n size: 20,\r\n family: 'Arial',\r\n style: 'normal',\r\n weight: 'normal',\r\n },\r\n lineHeight: 20,\r\n // left | right | center | start | end\r\n textAlign: TextAlign.left,\r\n // top | hanging | middle | alphabetic | ideographic | bottom\r\n textBaseline: TextBaseline.alphabetic,\r\n padding: {\r\n top: 0,\r\n right: 0,\r\n bottom: 0,\r\n left: 0,\r\n },\r\n}\r\n\r\nclass Text extends Element {\r\n static type = CanvasElementType.text\r\n\r\n static getMergedPropsWithDefaults>(\r\n propKey: T,\r\n props: Partial = {}\r\n ) {\r\n return {\r\n ...DEFAULTS[propKey],\r\n ...Object.entries(props).reduce((acc, [key, value]) => (value ? { ...acc, [key]: value } : acc), {}),\r\n }\r\n }\r\n\r\n name = 'Anchored text'\r\n declare context?: CanvasRenderingContext2D\r\n declare width: number\r\n declare height: number\r\n declare font: string\r\n\r\n static initClass() {\r\n Object.defineProperty(this.prototype, 'width', {\r\n get() {\r\n // TODO: revisit this getter, when you call `this.width` you don't expect/want context change\r\n if (this.context) {\r\n this.setupContext(this.context)\r\n }\r\n return this.measure() + this.attrs.padding.left + this.attrs.padding.right\r\n },\r\n })\r\n\r\n Object.defineProperty(this.prototype, 'height', {\r\n get() {\r\n const count = this.getLines().length\r\n return this.attrs.lineHeight * count + this.attrs.padding.top + this.attrs.padding.bottom\r\n },\r\n })\r\n\r\n Object.defineProperty(this.prototype, 'font', {\r\n get() {\r\n const f = this.attrs.font\r\n return `${f.style} ${f.weight} ${f.size}pt ${f.family}`\r\n },\r\n })\r\n }\r\n\r\n getModalConfigBase() {\r\n return {\r\n inputs: [\r\n { type: 'multiline_string', name: 'text', required: true },\r\n { type: 'font', name: 'font' },\r\n {\r\n type: 'background',\r\n name: 'fillStyle',\r\n label: 'Color',\r\n default: this.getChartLayoutSettings().ElementSettings.Colors.textWithoutBackground,\r\n },\r\n {\r\n type: 'background',\r\n name: 'background',\r\n label: 'Background',\r\n default: 'rgba(0,0,0,0)',\r\n },\r\n {\r\n type: 'border',\r\n name: 'border',\r\n min: 0,\r\n default: { color: 'rgba(0,0,0)', width: 0 },\r\n },\r\n ],\r\n } as unknown as TodoModalConfig\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n ...DEFAULTS,\r\n fillStyle: this.getChartLayoutSettings().ElementSettings.Colors.textWithoutBackground,\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x'], y: ['y'] })\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (obj.font?.size && !obj.lineHeight) {\r\n this.attrs.lineHeight = Math.max(obj.font.size, this.attrs.lineHeight)\r\n }\r\n return this\r\n }\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n this.setupContext(context)\r\n if (this.attrs.angle && this.context) {\r\n // TODO background & multiline text\r\n this.context.save()\r\n this.context.translate(this.attrs.x!, this.attrs.y!)\r\n this.context.rotate((this.attrs.angle * Math.PI) / 180)\r\n this.context.fillText(this.attrs.text, 0, 0)\r\n this.context.restore()\r\n } else {\r\n this.renderBackground()\r\n this.renderText()\r\n }\r\n }\r\n\r\n measure(context?: CanvasRenderingContext2D) {\r\n if (context) {\r\n this.setupContext(context)\r\n }\r\n const lines = this.getLines()\r\n let max = 0\r\n for (const line of lines) {\r\n max = Math.max(this.context?.measureText(line).width ?? Number.MIN_SAFE_INTEGER, max)\r\n }\r\n return ~~max\r\n }\r\n\r\n isInArea(testArea: PaneArea) {\r\n const area = this.convertArea(testArea)\r\n // TODO iny align\r\n if (\r\n this.attrs.x! < area.x &&\r\n area.x < this.attrs.x! + this.width &&\r\n this.attrs.y! - this.attrs.font.size < area.y &&\r\n area.y < this.attrs.y! - this.attrs.font.size + this.height\r\n ) {\r\n return true\r\n }\r\n return super.isInArea(testArea)\r\n }\r\n\r\n setupContext(context: CanvasRenderingContext2D) {\r\n this.context = context\r\n context.set('font', this.font)\r\n context.set('fillStyle', this.attrs.fillStyle)\r\n context.set('textAlign', this.attrs.textAlign)\r\n context.set('textBaseline', this.attrs.textBaseline)\r\n }\r\n\r\n getLines() {\r\n return this.attrs.text.toString().split('\\n')\r\n }\r\n\r\n renderText() {\r\n if (!this.context) return\r\n let { y } = this.attrs // + @attrs.padding.top\r\n for (const line of this.getLines()) {\r\n this.context.fillText(line, this.attrs.x! + this.attrs.padding.left, y!)\r\n y! += this.attrs.lineHeight\r\n }\r\n }\r\n\r\n renderBackground() {\r\n if (!this.attrs.background || !this.context) {\r\n return\r\n }\r\n\r\n const { width } = this\r\n const { height } = this\r\n const rawHight = height - this.attrs.padding.top - this.attrs.padding.bottom\r\n const { x } = this.attrs\r\n let y = this.attrs.y! - height\r\n\r\n const getFontHeight = () => {\r\n // @todo - This is needed to be able to verticaly center background behind the text, the better would be to always use TextBaseline.middle and in case of options having different TextBaseline we should move text manually on y axis\r\n const { fontBoundingBoxAscent = 0, fontBoundingBoxDescent = 0 } = this.context?.measureText(this.attrs.text) ?? {}\r\n return fontBoundingBoxAscent + fontBoundingBoxDescent\r\n }\r\n\r\n if (this.attrs.textBaseline === TextBaseline.bottom) {\r\n y = this.attrs.y! - (height - (height - getFontHeight()) / 2)\r\n } else if (this.attrs.textBaseline === TextBaseline.top) {\r\n y = this.attrs.y! - this.attrs.padding.top - 1 - (height - getFontHeight()) / 2\r\n } else if (this.attrs.textBaseline === TextBaseline.middle) {\r\n y = this.attrs.y! - rawHight / 2 - this.attrs.padding.top - 1\r\n } else if (this.attrs.textBaseline === TextBaseline.alphabetic) {\r\n y = this.attrs.y! - this.attrs.lineHeight\r\n }\r\n\r\n this.context.beginPath()\r\n this.context.set('fillStyle', this.attrs.background)\r\n this.context.rect(x!, y, width, height)\r\n this.context.fill()\r\n this.context.set('fillStyle', this.attrs.fillStyle)\r\n this.renderBorder()\r\n this.context.closePath()\r\n }\r\n\r\n renderBorder() {\r\n const { lineWidth = 0, strokeStyle, border } = this.attrs\r\n const borderWidth = border?.width ?? 0\r\n\r\n if ((lineWidth || this.attrs.strokeStyle || borderWidth > 0) && this.context) {\r\n this.context.set('strokeStyle', strokeStyle ?? border?.color ?? '')\r\n this.context.set('lineWidth', Math.max(lineWidth, borderWidth))\r\n this.context.stroke()\r\n }\r\n }\r\n\r\n private convertArea(area: PaneArea) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n return {\r\n x: this.model.scale.x(area.x) + this.model.chart().leftOffset + ChartSettings.left.width,\r\n y: this.model.scale.y(area.y) + ChartSettings.top.height,\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x! += this.model.scale.x(x) + 1\r\n this.attrs.y! += this.model.scale.y(y) - this.model.scale.y(0)\r\n }\r\n\r\n getHeight() {\r\n return this.height\r\n }\r\n}\r\n\r\nText.initClass()\r\n\r\nexport default Text\r\n","import { PaneArea, ResizeByThumbFuncProps, ThumbType } from '../../types/shared'\r\nimport { getOffsetFromLineWidth } from '../controllers/renderUtils'\r\nimport PaneModel from '../models/pane'\r\n\r\ntype Area = PaneArea\r\ntype ResizeFunc = (props: ResizeByThumbFuncProps) => void\r\ntype ScaleFunc = () => number\r\n\r\nclass Thumb {\r\n type: ThumbType\r\n lastX = 0\r\n lastY = 0\r\n fx: ScaleFunc\r\n fy: ScaleFunc\r\n resize: ResizeFunc\r\n model: PaneModel\r\n\r\n constructor(type: ThumbType, fx: ScaleFunc, fy: ScaleFunc, resize: ResizeFunc, model: PaneModel) {\r\n this.type = type\r\n this.fx = fx\r\n this.fy = fy\r\n this.resize = resize\r\n this.model = model\r\n }\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n const { ThumbSettings } = this.model.getChartLayoutSettings()\r\n context.set('fillStyle', ThumbSettings.color)\r\n context.set('strokeStyle', ThumbSettings.borderColor)\r\n context.set('lineWidth', ThumbSettings.borderWidth)\r\n const x = ~~this.x()\r\n const y = ~~this.y()\r\n const thumbWidth = this.getThumbWidth()\r\n const offset = getOffsetFromLineWidth(ThumbSettings.borderWidth)\r\n context.beginPath()\r\n context.rect(x + offset, y + offset, thumbWidth, thumbWidth)\r\n context.fill()\r\n context.stroke()\r\n }\r\n\r\n startEditing(area: Area) {\r\n this.lastX = area.x\r\n return (this.lastY = area.y)\r\n }\r\n\r\n moveTo(area: Area) {\r\n const difX = area.x - this.lastX\r\n const difY = area.y - this.lastY\r\n this.resize({ type: this.type, difX, difY, area })\r\n this.lastX = area.x\r\n this.lastY = area.y\r\n }\r\n\r\n isInArea(area: Area) {\r\n const width = this.model.scale.x.invert(this.getThumbWidth())\r\n const height = this.model.scale.y.invert(0) - this.model.scale.y.invert(this.getThumbWidth())\r\n // +- width/2 because we have coordinates of a center\r\n if (\r\n this.fx() + width / 2 >= area.x &&\r\n this.fx() - width / 2 <= area.x &&\r\n this.fy() + height / 2 > area.y &&\r\n this.fy() - height / 2 < area.y\r\n ) {\r\n return true\r\n }\r\n return false\r\n }\r\n\r\n getThumbWidth() {\r\n const { ThumbSettings } = this.model.getChartLayoutSettings()\r\n return ThumbSettings.size + ThumbSettings.borderWidth * 2\r\n }\r\n\r\n x() {\r\n const { ThumbSettings } = this.model.getChartLayoutSettings()\r\n return this.model.scale.x(this.fx()) - ThumbSettings.size / 2\r\n }\r\n\r\n y() {\r\n const { ThumbSettings } = this.model.getChartLayoutSettings()\r\n return this.model.scale.y(this.fy()) - ThumbSettings.size / 2\r\n }\r\n}\r\n\r\nexport default Thumb\r\n","import { PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getOffsetFromLineWidth, getRoundedObject } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface ITriangleAttrs {\r\n x1: number\r\n x2: number\r\n x3: number\r\n y1: number\r\n y2: number\r\n y3: number\r\n fill: string\r\n border: string\r\n}\r\n\r\nclass Triangle extends Element {\r\n static type = CanvasElementType.triangle\r\n\r\n declare scaled: Pick\r\n name = 'Triangle'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.resize = this.resize.bind(this)\r\n\r\n this._thumbs = [\r\n new Thumb(\r\n 'a',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'b',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c',\r\n () => this.attrs.x3,\r\n () => this.attrs.y3,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return { fill: ElementSettings.defaultFill, border: ElementSettings.Colors.border } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2', 'x3'], y: ['y1', 'y2', 'y3'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, x3, y1, y2, y3 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, x3, y1, y2, y3 })\r\n\r\n context.set('fillStyle', this.attrs.fill)\r\n\r\n const offset = this.getShouldRenderThumbs() ? getOffsetFromLineWidth(1) : 0\r\n\r\n context.translate(offset, offset)\r\n context.beginPath()\r\n context.moveTo(roundedXY.x1, roundedXY.y1)\r\n context.lineTo(roundedXY.x2, roundedXY.y2)\r\n context.lineTo(roundedXY.x3, roundedXY.y3)\r\n context.lineTo(roundedXY.x1, roundedXY.y1)\r\n context.fill()\r\n context.translate(offset * -1, offset * -1)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n context.set('strokeStyle', this.attrs.border)\r\n context.stroke()\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n this.attrs.x3 += x\r\n this.attrs.y3 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'a':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'b':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'c':\r\n this.attrs.x3 += difX\r\n this.attrs.y3 += difY\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const polygon = [1, 2, 3].map((i) => ({\r\n x: this.scaled[`x${i}` as 'x1' | 'x2' | 'x3'],\r\n y: this.scaled[`y${i}` as 'y1' | 'y2' | 'y3'],\r\n }))\r\n if (math.pointInPolygon(area.scaled, polygon)) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nTriangle.prototype.modalConfig = {\r\n inputs: [{ type: 'background', name: 'fill' }],\r\n}\r\n\r\nexport default Triangle\r\n","import { RequireByKey, ResizeByThumbFuncProps } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport PaneModel from '../models/pane'\r\nimport ScaledLine, { IScaledLineAttrs } from './scaled_line'\r\n\r\nclass VerticalLine extends ScaledLine {\r\n static type = CanvasElementType.verticalLine\r\n\r\n name = 'Vertical line'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.renderContent = this.renderContent.bind(this)\r\n\r\n this.attrs.x2 = this.attrs.x1\r\n this._thumbs = [this._thumbs[0]]\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const domain = this.model.scale.y.domain()\r\n this.attrs.y1 = domain[0]\r\n this.attrs.y2 = domain[1]\r\n this._thumbs[0].fy = () => (this.attrs.y1 + this.attrs.y2) / 2\r\n super.renderContent(context)\r\n }\r\n\r\n moveBy(x: number) {\r\n return (this.attrs.x1 = this.attrs.x2 += x)\r\n }\r\n\r\n resize({ difX }: RequireByKey) {\r\n return this.moveBy(difX)\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n return super.getIsInChartView(chart, { omitY: true })\r\n }\r\n}\r\n\r\nexport default VerticalLine\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getOffsetFromLineWidth, getRoundedObject } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Text, { ITextAttrs } from './text'\r\nimport Thumb from './thumb'\r\n\r\nexport interface IXABCDPositionAttrs {\r\n xx: number\r\n xy: number\r\n ax: number\r\n ay: number\r\n bx: number\r\n by: number\r\n cx: number\r\n cy: number\r\n dx: number\r\n dy: number\r\n}\r\n\r\ntype xPoints = 'xx' | 'ax' | 'bx' | 'cx' | 'dx'\r\ntype yPoints = 'xy' | 'ay' | 'by' | 'cy' | 'dy'\r\n\r\nexport interface IXABCDAttrs extends IXABCDPositionAttrs {\r\n fill: string\r\n border: DrawingBorder\r\n lineWidth: number\r\n}\r\n\r\nclass XABCD extends Element {\r\n static type = CanvasElementType.xabcd\r\n\r\n name = 'XABCD pattern'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.resize = this.resize.bind(this)\r\n\r\n this._thumbs = [\r\n new Thumb(\r\n 'x',\r\n () => this.attrs.xx,\r\n () => this.attrs.xy,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'a',\r\n () => this.attrs.ax,\r\n () => this.attrs.ay,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'b',\r\n () => this.attrs.bx,\r\n () => this.attrs.by,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c',\r\n () => this.attrs.cx,\r\n () => this.attrs.cy,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'd',\r\n () => this.attrs.dx,\r\n () => this.attrs.dy,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n if (this.attrs.lineWidth == null) {\r\n this.attrs.lineWidth = 1\r\n }\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({\r\n x: ['xx', 'ax', 'bx', 'cx', 'dx'],\r\n y: ['xy', 'ay', 'by', 'cy', 'dy'],\r\n })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { xx, xy, ax, ay, bx, by, cx, cy, dx, dy } = this.scaled\r\n const roundedXY = getRoundedObject({ xx, xy, ax, ay, bx, by, cx, cy, dx, dy })\r\n\r\n context.set('fillStyle', this.attrs.fill)\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n\r\n const offset = getOffsetFromLineWidth(this.attrs.border.width)\r\n context.translate(offset, offset)\r\n\r\n context.beginPath()\r\n context.moveTo(roundedXY.xx, roundedXY.xy)\r\n context.lineTo(roundedXY.ax, roundedXY.ay)\r\n context.lineTo(roundedXY.bx, roundedXY.by)\r\n context.lineTo(roundedXY.xx, roundedXY.xy)\r\n context.fill()\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.stroke()\r\n }\r\n\r\n context.beginPath()\r\n context.moveTo(roundedXY.bx, roundedXY.by)\r\n context.lineTo(roundedXY.cx, roundedXY.cy)\r\n context.lineTo(roundedXY.dx, roundedXY.dy)\r\n context.lineTo(roundedXY.bx, roundedXY.by)\r\n context.fill()\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.stroke()\r\n }\r\n\r\n context.beginPath()\r\n context.moveTo(roundedXY.ax, roundedXY.ay)\r\n context.lineTo(roundedXY.cx, roundedXY.cy)\r\n context.moveTo(roundedXY.xx, roundedXY.xy)\r\n context.lineTo(roundedXY.dx, roundedXY.dy)\r\n context.stroke()\r\n\r\n const text = new Text(\r\n {\r\n font: { size: 8, style: 'bold' },\r\n lineHeight: 8,\r\n padding: {\r\n top: 2,\r\n right: 2,\r\n bottom: 2,\r\n left: 2,\r\n },\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.start,\r\n fillStyle: '#ffffff',\r\n background: this.attrs.fill || '#000000',\r\n },\r\n this.model\r\n )\r\n\r\n for (const t of Array.from('xabcd')) {\r\n text\r\n .set({\r\n text: t.toUpperCase(),\r\n x: roundedXY[(t + 'x') as xPoints] - 6,\r\n y: roundedXY[(t + 'y') as yPoints] + 12,\r\n } as Partial)\r\n .render(context)\r\n }\r\n\r\n const retLabel = (y1: string, y2: string, y3: string) => {\r\n const len = Math.abs(this.attrs[(y1 + 'y') as yPoints] - this.attrs[(y2 + 'y') as yPoints])\r\n const ret = Math.abs(this.attrs[(y3 + 'y') as yPoints] - this.attrs[(y2 + 'y') as yPoints]) / len\r\n const x = (roundedXY[(y1 + 'x') as xPoints] + roundedXY[(y3 + 'x') as xPoints]) / 2\r\n const y = (roundedXY[(y1 + 'y') as yPoints] + roundedXY[(y3 + 'y') as yPoints]) / 2\r\n return text\r\n .set({\r\n text: ret.toFixed(3),\r\n x,\r\n y,\r\n })\r\n .render(context)\r\n }\r\n\r\n retLabel('x', 'a', 'b')\r\n retLabel('a', 'b', 'c')\r\n retLabel('b', 'c', 'd')\r\n retLabel('x', 'a', 'd')\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n context.translate(offset * -1, offset * -1)\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n for (const t of Array.from('xabcd')) {\r\n this.attrs[(t + 'x') as xPoints] += x\r\n this.attrs[(t + 'y') as yPoints] += y\r\n }\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n this.attrs[(type + 'x') as xPoints] += difX\r\n return (this.attrs[(type + 'y') as yPoints] += difY)\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n let t\r\n const xab = (() => {\r\n const result = []\r\n for (t of Array.from('xab')) {\r\n result.push({ x: this.scaled[(t + 'x') as xPoints], y: this.scaled[(t + 'y') as yPoints] })\r\n }\r\n return result\r\n })()\r\n const bcd = (() => {\r\n const result1 = []\r\n for (t of Array.from('bcd')) {\r\n result1.push({ x: this.scaled[(t + 'x') as xPoints], y: this.scaled[(t + 'y') as yPoints] })\r\n }\r\n return result1\r\n })()\r\n if (math.pointInPolygon(area.scaled, xab) || math.pointInPolygon(area.scaled, bcd)) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nXABCD.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1 },\r\n ],\r\n}\r\n\r\nexport default XABCD\r\n","import Utils from '../utils'\r\nimport { getContextWithCache } from '../utils/canvas'\r\nimport { captureException, getIsSSr } from '../utils/helpers'\r\n\r\nclass Cache {\r\n constructor() {\r\n this.canvas = getIsSSr() ? null : document.createElement('canvas')\r\n }\r\n\r\n set(callback, width, height) {\r\n this.callback = callback\r\n this.width = width\r\n this.height = height\r\n this.rendered = false\r\n }\r\n\r\n render(context, x, y) {\r\n if (x == null) {\r\n x = 0\r\n }\r\n if (y == null) {\r\n y = 0\r\n }\r\n if (!this.rendered) {\r\n this.refresh()\r\n }\r\n if (this.width < 1 || this.height < 1) {\r\n return\r\n }\r\n\r\n try {\r\n if (this.ratio >= 1 && this.canvas) {\r\n context.drawImage(\r\n this.canvas,\r\n 0,\r\n 0,\r\n ~~(this.width * this.ratio),\r\n ~~(this.height * this.ratio),\r\n x,\r\n y,\r\n this.width,\r\n this.height\r\n )\r\n } else {\r\n context.save()\r\n context.translate(x, y)\r\n this.callback(context)\r\n context.restore()\r\n }\r\n } catch (e) {\r\n captureException(\r\n e,\r\n this.canvas\r\n ? {\r\n extra: {\r\n width: this.width,\r\n height: this.height,\r\n ratio: this.ratio,\r\n cWidth: this.canvas.width,\r\n cHeight: this.canvas.height,\r\n sWidth: window.screen.width,\r\n sHeight: window.screen.height,\r\n },\r\n }\r\n : {}\r\n )\r\n }\r\n }\r\n\r\n refresh() {\r\n if (getIsSSr()) {\r\n return\r\n }\r\n this.canvas.width = this.width\r\n this.canvas.height = this.height\r\n this.context = getContextWithCache(this.canvas)\r\n this.ratio = Utils.getScaleRatio()\r\n Utils.setSizeOnCanvasElement({ canvasElement: this.canvas, width: this.width, height: this.height })\r\n this.context.scale(this.ratio, this.ratio)\r\n\r\n this.callback(this.context)\r\n this.rendered = true\r\n }\r\n}\r\n\r\nexport default Cache\r\n","import { ObjectHash, Theme } from '../../../types/shared'\r\nimport { TextAlign, TextBaseline } from '../../constants/common'\r\nimport { IChartThemeColors, IElementThemeColors, IIndicatorThemeColors } from '../constants'\r\n\r\nexport enum OHLCType {\r\n singleLine = 'singleLine',\r\n dateOnly = 'dateOnly',\r\n timeOnly = 'timeOnly',\r\n}\r\n\r\nexport interface IMargin {\r\n top?: number\r\n right?: number\r\n bottom?: number\r\n left?: number\r\n}\r\n\r\ninterface IPadding {\r\n top?: number\r\n right?: number\r\n bottom?: number\r\n left?: number\r\n}\r\n\r\ninterface IGenericText {\r\n margin: IMargin\r\n font: IFont\r\n}\r\n\r\ninterface IFont {\r\n size?: number\r\n style?: string\r\n weight?: string\r\n family?: string\r\n lineHeight?: number\r\n padding?: IPadding\r\n baseline?: TextBaseline\r\n textAlign?: TextAlign\r\n}\r\n\r\ninterface ISettingsGeneralBase {\r\n Colors: IChartThemeColors\r\n}\r\n\r\nexport interface ISettingsCenterBase {\r\n barWidth: number\r\n barMargin: number\r\n border: number\r\n volumeHeight?: number\r\n}\r\n\r\ninterface ISettingsTopBase {\r\n height: number\r\n}\r\n\r\ninterface ISettingsBottomBase {\r\n height: number\r\n}\r\n\r\ninterface ISettingsLeftBase {\r\n width: number\r\n}\r\n\r\ninterface ISettingsRightBase {\r\n width: number\r\n}\r\n\r\nexport interface ISettings {\r\n ChartSettings: IChartSettings\r\n IndicatorSettings: IIndicatorSettings\r\n MarketSentimentSettings: IMarketSentimentChartSettings\r\n ColorsSettings: Array\r\n ThumbSettings: IThumbSettings\r\n ElementSettings: IElementSettings\r\n isOurSiteRequest?: boolean\r\n}\r\n\r\nexport interface IChartSettings {\r\n general: IChartGeneral\r\n center: ISettingsCenterBase\r\n top: IChartTop\r\n bottom: IChartBottom\r\n left: IChartLeft\r\n right: IChartRight\r\n}\r\n\r\ninterface IChartGeneral {\r\n settingsHeight: number\r\n tickerTimeframeChangeHeight: number\r\n Colors: IChartThemeColors & ObjectHash\r\n}\r\n\r\ninterface IChartTop extends ISettingsTopBase {\r\n baseline: TextBaseline\r\n ticker: IGenericText\r\n ohlc: IOHLC\r\n change: IGenericText\r\n}\r\n\r\ninterface IOHLC extends IGenericText {\r\n type?: OHLCType\r\n}\r\n\r\ninterface IChartBottom extends ISettingsBottomBase {\r\n baseline: TextBaseline\r\n axis: IGenericText\r\n}\r\n\r\ninterface IChartLeft extends ISettingsLeftBase {\r\n overlayLabel: IOverlayLabel\r\n timeframe: IGenericText\r\n volumeAxis: IGenericText\r\n}\r\n\r\ninterface IOverlayLabel extends IGenericText {\r\n labelSpacing: number\r\n}\r\n\r\ninterface IChartRight extends ISettingsRightBase {\r\n axis: IGenericText\r\n}\r\n\r\nexport interface IIndicatorSettings {\r\n general: IIndicatorGeneral\r\n center: ISettingsCenterBase\r\n top: ISettingsTopBase\r\n bottom: ISettingsBottomBase\r\n left: IIndicatorLeft\r\n right: IIndicatorRight\r\n}\r\n\r\ninterface IIndicatorRight extends ISettingsRightBase {\r\n axis: IGenericText\r\n}\r\n\r\ninterface IIndicatorLeft extends ISettingsLeftBase {\r\n indicatorLabel: IIndicatorLabel\r\n}\r\n\r\ninterface IIndicatorLabel extends IGenericText {\r\n labelSpacing: number\r\n}\r\n\r\ninterface IIndicatorGeneral {\r\n Colors: IIndicatorThemeColors\r\n height: number\r\n}\r\n\r\ninterface IMarketSentimentChartSettings {\r\n general: ISettingsGeneralBase\r\n center: ISettingsCenterBase\r\n top: ISettingsTopBase\r\n bottom: ISettingsBottomBase\r\n left: ISettingsLeftBase\r\n right: ISettingsRightBase\r\n}\r\n\r\ninterface IThumbSettings {\r\n size: number\r\n touchSize: number\r\n color: string\r\n borderWidth: number\r\n borderColor: string\r\n}\r\n\r\ninterface IElementSettings {\r\n Colors: IElementThemeColors\r\n defaultFill: string\r\n defaultTransparentFill: string\r\n}\r\n","export enum ChartMinWidthBreakpoints {\r\n xs = 0,\r\n s = 480,\r\n m = 768,\r\n l = 1024,\r\n}\r\n\r\nexport function getChartBreakpoints(chartWidthInPx: number) {\r\n return {\r\n isXs: chartWidthInPx >= ChartMinWidthBreakpoints.xs,\r\n isS: chartWidthInPx >= ChartMinWidthBreakpoints.s,\r\n isM: chartWidthInPx >= ChartMinWidthBreakpoints.m,\r\n isL: chartWidthInPx >= ChartMinWidthBreakpoints.l,\r\n }\r\n}\r\n","import * as d3 from 'd3'\r\nimport merge from 'lodash.merge'\r\n\r\nimport {\r\n ChartConfigChartPaneElement,\r\n CustomSpineEvents,\r\n Instrument,\r\n Maybe,\r\n RequireByKey,\r\n Theme,\r\n} from '../../types/shared'\r\nimport Cache from '../canvas/cache'\r\nimport Element from '../canvas/element'\r\nimport Line from '../canvas/line'\r\nimport Text from '../canvas/text'\r\nimport tailwindColors from '../constants/colors'\r\nimport {\r\n CHART_MARGIN,\r\n FONT_SIZE,\r\n IndicatorType,\r\n LINE_HEIGHT,\r\n MONTHS,\r\n OFFSET,\r\n PADDING,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n TIMEFRAMES_WITH_PRE_MARKET,\r\n TextAlign,\r\n TextBaseline,\r\n getTimeframeLabel,\r\n} from '../constants/common'\r\nimport {\r\n getIsSmallIndexChart,\r\n getPercentageFromValue,\r\n getTranslate,\r\n getValueFromPercentage,\r\n} from '../controllers/renderUtils'\r\nimport Chart from '../models/chart'\r\nimport { getColorOverwrites } from '../models/chart_settings'\r\nimport { ISettings, OHLCType } from '../models/chart_settings/interfaces'\r\nimport { darkerWickColors, thinBarColorsOverride } from '../models/constants'\r\nimport mouseModel from '../models/mouse'\r\nimport PaneModel, { ScaleAxis } from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport Overlay from '../overlays/overlay'\r\nimport { overlaysByType } from '../overlays/overlays'\r\nimport utils, { isRedesignedPage, numberToStringWithUnitsSuffix } from '../utils'\r\nimport {\r\n ITickerChange,\r\n getBarWithoutMarginWidth,\r\n getChangeColor,\r\n getHalfBarWidth,\r\n getShouldUseDarkerWickColors,\r\n getTickerChange,\r\n getTickerChangeFromCloseValues,\r\n getVirtualTimeframeTradedDates,\r\n renderCross,\r\n round,\r\n unmountCanvas,\r\n} from '../utils/chart'\r\nimport { renderFadeExtendedHours, renderXAxis } from '../utils/chart-grid-render-utils'\r\nimport { convertColorToHEX, getHEXWithSpecificAplha, getHSVAFromColor, stringifyHSVAColor } from '../utils/colors'\r\nimport { setElementCursor } from '../utils/cursor'\r\nimport { drawInVisibleArea, getAreNoBarsVisible, getVisibleBarToRenderIndex } from '../utils/draw_in_visible_area'\r\nimport { getChartBreakpoints } from './utils'\r\n\r\nexport interface BaseChartAttrs {\r\n overlays: Required['overlays']\r\n}\r\n\r\ntype OhlcLineElements = Array<{ text: string; color: string } | 'space'>\r\n\r\ninterface LastOHLCAttrs {\r\n text: string\r\n x: number\r\n y: number\r\n width: number\r\n textBaseline: TextBaseline\r\n textAlign: TextAlign\r\n}\r\n\r\ninterface IRenderOHLCParameters {\r\n context: CanvasRenderingContext2D\r\n date: Maybe\r\n open?: Maybe\r\n high?: Maybe\r\n low?: Maybe\r\n close?: Maybe\r\n volume?: Maybe\r\n afterHour?: string\r\n isSmallIndexChart?: boolean\r\n isNewestOHLC?: boolean\r\n directRender?: boolean\r\n time?: string\r\n changePercentage?: Maybe\r\n}\r\n\r\nconst getDateString = ({ date, timeframe }: { date: Date; timeframe: TIMEFRAME }) => {\r\n let dateString = ''\r\n const month = date.getMonth() // 20141126\r\n const year = date.getFullYear()\r\n const day = date.getDate()\r\n switch (timeframe) {\r\n case TIMEFRAME.i1:\r\n case TIMEFRAME.i2:\r\n case TIMEFRAME.i3:\r\n case TIMEFRAME.i5:\r\n case TIMEFRAME.i10:\r\n case TIMEFRAME.i15:\r\n case TIMEFRAME.i30:\r\n case TIMEFRAME.h:\r\n case TIMEFRAME.h2:\r\n case TIMEFRAME.h4:\r\n const t =\r\n (((date.getHours() + 11) % 12) + 1).toString().padLeft('00') +\r\n ':' +\r\n date.getMinutes().toString().padLeft('00') +\r\n (date.getHours() < 12 ? 'AM' : 'PM')\r\n dateString = `${MONTHS[month]} ${day} ${t}`\r\n break\r\n case TIMEFRAME.d:\r\n case TIMEFRAME.w:\r\n dateString = `${MONTHS[month]} ${day}`\r\n break\r\n case TIMEFRAME.m:\r\n dateString = `${MONTHS[month]} ${year}`\r\n break\r\n default:\r\n break\r\n }\r\n\r\n return dateString\r\n}\r\n\r\nfunction getClosestDifferentMinMaxValueIndices(\r\n currentMinIndex: number,\r\n currentMaxIndex: number,\r\n high: number[],\r\n low: number[]\r\n): { minIndex: number; maxIndex: number } {\r\n const hasPreviousIndex = currentMinIndex > 0\r\n const hasNextIndex = currentMaxIndex < high.length - 1\r\n let minIndex = currentMinIndex\r\n let maxIndex = currentMaxIndex\r\n if (hasPreviousIndex) {\r\n minIndex -= 1\r\n }\r\n if (hasNextIndex) {\r\n maxIndex += 1\r\n }\r\n\r\n if (low[minIndex] === high[maxIndex] && (hasPreviousIndex || hasNextIndex)) {\r\n return getClosestDifferentMinMaxValueIndices(minIndex, maxIndex, high, low)\r\n }\r\n\r\n return low[minIndex] < high[maxIndex] ? { minIndex, maxIndex } : { minIndex: maxIndex, maxIndex: minIndex }\r\n}\r\n\r\nconst gray300 = tailwindColors.gray[300]\r\n\r\nclass BaseChart extends Element {\r\n static initClass() {\r\n Object.defineProperty(this.prototype, 'width', {\r\n get() {\r\n const { ChartSettings } = this.getChartLayoutSettings() as ISettings\r\n if (!this.model.width) return 0\r\n return this.model.width - ChartSettings.left.width - ChartSettings.right.width\r\n },\r\n })\r\n\r\n Object.defineProperty(this.prototype, 'height', {\r\n get() {\r\n const { ChartSettings } = this.getChartLayoutSettings() as ISettings\r\n if (!this.paneModel.height) return 0\r\n return this.paneModel.height - ChartSettings.top.height - ChartSettings.bottom.height\r\n },\r\n })\r\n }\r\n\r\n static getNumOfBarsBuffer({ overlays }: RequireByKey) {\r\n return Math.max(0, ...overlays.map((overlay) => overlaysByType[overlay.type].getNumOfBarsBuffer(overlay)))\r\n }\r\n\r\n static label = 'Chart'\r\n static iconName = ''\r\n\r\n paneModel: PaneModel\r\n model: Chart\r\n data: Quote\r\n specificChartFunctionality: SpecificChartFunctionality\r\n tickerWidth = 0\r\n changeWidth = 0\r\n lastOhlc: Array> = []\r\n overlays: Overlay[] = []\r\n isLargeChart?: boolean\r\n shouldRenderVolume = true\r\n afterChange: {\r\n x: number\r\n y: number\r\n width: number\r\n } | null = null\r\n\r\n declare setupAxisTimeFrame: string\r\n declare volumeFY: d3.ScaleLinear\r\n declare tickerText: Text\r\n declare baseCache: Cache\r\n declare leftOffset: number\r\n declare context: CanvasRenderingContext2D\r\n declare width: number\r\n declare height: number\r\n declare isMobile: boolean\r\n\r\n constructor(values: Partial, paneModel: PaneModel) {\r\n super(values, paneModel)\r\n\r\n this.paneModel = paneModel\r\n this.model = this.paneModel.chart()\r\n this.data = this.model.quote()\r\n const chartLayoutModel = this.model.chart_layout()\r\n this.specificChartFunctionality = chartLayoutModel.specificChartFunctionality\r\n this.isLargeChart = chartLayoutModel.isLargeChart\r\n this.isMobile = utils.isMobile(true)\r\n\r\n this.overlays = []\r\n if (values.overlays) {\r\n for (const overlayDefinition of values.overlays) {\r\n // overlayDefinition.color coming from DB is always string however overlays\r\n // internaly didn't use format as in db (type, color, period) but rather\r\n // more overlay specific parameters eg. (BB: topColor, bottomColor, etc.)\r\n // thus overlayDefinition.color might be undefined\r\n // approach could be reworked in https://github.com/finvizhq/charts/issues/770\r\n // but for now (!overlayDefinition.color) check solve issue as well\r\n const overlay = overlaysByType[overlayDefinition.type].fromObject(\r\n {\r\n ...overlayDefinition,\r\n color:\r\n !overlayDefinition.color || overlayDefinition.color.includes('|')\r\n ? ''\r\n : convertColorToHEX(overlayDefinition.color),\r\n },\r\n this.paneModel\r\n )\r\n this.addOverlay(overlay)\r\n }\r\n delete values.overlays\r\n }\r\n\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n this.renderText = this.renderText.bind(this)\r\n this.renderCrossText = this.renderCrossText.bind(this)\r\n this.setupCache = this.setupCache.bind(this)\r\n this.renderOverlaysLabels = this.renderOverlaysLabels.bind(this)\r\n\r\n // this.paneModel.bind('update', this.setupAxis.bind(this))\r\n this.paneModel.bind('update', this.setupCache)\r\n this.paneModel.bind('change', this.trigger.bind(this, 'change'))\r\n this.model = this.paneModel.chart()\r\n // this.model.bind('change', this.setupAxis.bind(this))\r\n this.model.bind('change', this.setupCache)\r\n this.model.bind('change', this.trigger.bind(this, 'change'))\r\n this.model.bind(CustomSpineEvents.IndicatorsChange, this.handleIndicatorsChange.bind(this))\r\n const mouseModelChangeHandler = this.trigger.bind(this, 'change', 'cross')\r\n this.model.bind('destroy', () => {\r\n this.model.unbind('change', this.setupCache)\r\n this.model.unbind(CustomSpineEvents.IndicatorsChange, this.handleIndicatorsChange.bind(this))\r\n mouseModel.unbind('change', mouseModelChangeHandler)\r\n unmountCanvas(this.baseCache.canvas)\r\n })\r\n mouseModel.bind('change', mouseModelChangeHandler)\r\n\r\n this.model.chart_layout().bind('theme', this.setupCache)\r\n this.model.chart_layout().bind('update', this.updateShouldRenderVolume.bind(this))\r\n\r\n this.setupCache()\r\n }\r\n\r\n renderChart() {\r\n throw Error('Implement renderChart')\r\n }\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n this.data = this.model.quote()\r\n this.leftOffset = this.model.leftOffset\r\n this.context = context\r\n\r\n if (this.data.close.length === 0) {\r\n this.renderChartNotAvailable()\r\n if (!this.getIsRedesignedChart()) this.renderTicker(context)\r\n return\r\n }\r\n\r\n this.context.save()\r\n this.clip()\r\n this.renderVolume()\r\n this.renderChart()\r\n this.renderOverlays()\r\n this.renderPrevClose()\r\n renderFadeExtendedHours({ context: this.context, paneModel: this.paneModel, quote: this.data })\r\n this.context.restore()\r\n if (!this.getIsRedesignedChart()) this.renderTicker(context)\r\n }\r\n\r\n renderGrid(context: CanvasRenderingContext2D) {\r\n this.data = this.model.quote()\r\n this.leftOffset = this.model.leftOffset\r\n this.context = context\r\n // text, xAxis, volumeAxis\r\n this.renderXAxis()\r\n this.baseCache.render(context)\r\n }\r\n\r\n renderTicker(context: CanvasRenderingContext2D) {\r\n if (this.tickerText) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n context.translate(ChartSettings.left.width, 0)\r\n this.tickerText.render(context)\r\n\r\n if (getIsSmallIndexChart(this.specificChartFunctionality) && this.data.ticker === 'RUSSELL 2000') {\r\n const { Colors } = ChartSettings.general\r\n new Text(\r\n {\r\n text: 'ETF',\r\n x: ChartSettings.top.ticker.margin.left,\r\n y: ChartSettings.top.ticker.margin.top! + FONT_SIZE.XXS + OFFSET.XXS,\r\n font: { size: FONT_SIZE.XXS },\r\n fillStyle: Colors.text,\r\n textBaseline: ChartSettings.top.baseline,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n\r\n context.translate(-ChartSettings.left.width, 0)\r\n }\r\n }\r\n\r\n renderTimeframe(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const quote = this.model.quote()\r\n const y = (this.height - this.volumeFY.range()[1] - 4) / 2\r\n\r\n return new Text(\r\n {\r\n text: quote.instrument === Instrument.Group ? 'YEAR PERFORMANCE %' : getTimeframeLabel(quote.timeframe),\r\n x: ChartSettings.left.timeframe.margin.left,\r\n y: ChartSettings.top.height + y + (ChartSettings.left.timeframe.margin.top ?? 0),\r\n angle: -90,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.left.timeframe.font),\r\n fillStyle: Colors.textSecondary,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.alphabetic,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n\r\n renderText(context: CanvasRenderingContext2D) {\r\n const { ChartSettings, isOurSiteRequest } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n context.save()\r\n context.translate(ChartSettings.left.width, 0)\r\n\r\n if (!getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n this.tickerText = new Text(\r\n {\r\n text: this.data.name || this.data.ticker,\r\n x: ChartSettings.top.ticker.margin.left,\r\n y: ChartSettings.top.ticker.margin.top,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.top.ticker.font),\r\n textBaseline: ChartSettings.top.baseline,\r\n fillStyle: Colors.text,\r\n },\r\n this.paneModel\r\n )\r\n } else {\r\n this.tickerText = new Text(\r\n {\r\n text: this.data.name || this.data.ticker,\r\n x: ChartSettings.top.ticker.margin.left,\r\n y: ChartSettings.top.ticker.margin.top,\r\n font: { size: FONT_SIZE.L, style: 'bold' },\r\n fillStyle: Colors.text,\r\n },\r\n this.paneModel\r\n )\r\n }\r\n this.tickerWidth = this.tickerText.measure(context)\r\n\r\n // render watermark on backend chart\r\n if (this.specificChartFunctionality === SpecificChartFunctionality.offScreen) {\r\n let yOffset = 0\r\n if (!isOurSiteRequest) {\r\n yOffset = this.isLargeChart ? -2 : -3\r\n }\r\n new Text(\r\n {\r\n text: '© finviz.com',\r\n x: this.width + ChartSettings.right.width - 2,\r\n y: 1 + yOffset,\r\n font: { size: isOurSiteRequest ? FONT_SIZE.XS : FONT_SIZE.M },\r\n textAlign: TextAlign.right,\r\n textBaseline: TextBaseline.top,\r\n fillStyle: isOurSiteRequest ? 'rgb(136, 193, 233)' : tailwindColors.finviz.blue,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n\r\n if (!this.getIsRedesignedChart()) {\r\n this.renderChange({ context })\r\n if (!this.lastOhlc[0]) {\r\n this.getOHLC({ context, directRender: false })\r\n }\r\n this.getOHLC({ context })\r\n }\r\n\r\n context.restore()\r\n if (!this.getIsRedesignedChart() && !getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n this.renderTimeframe(context)\r\n }\r\n }\r\n\r\n getOHLC({\r\n context,\r\n directRender = true,\r\n data,\r\n date,\r\n dateString = null,\r\n changePercentage = null,\r\n }: {\r\n context: CanvasRenderingContext2D\r\n directRender?: boolean\r\n data?: {\r\n open?: string\r\n high?: string\r\n low?: string\r\n close?: string\r\n volume?: string\r\n }\r\n date?: Date\r\n dateString?: string | null\r\n changePercentage?: ITickerChange | null\r\n }) {\r\n if (!this.data.lastDate) return\r\n\r\n // modulo \"parsing\" is 100% faster than with str.slice()\r\n const lastDate = `${MONTHS[(~~(this.data.lastDate / 100) % 100) - 1]} ${this.data.lastDate % 100}` // YYYYMMDD / 20211118 => Nov 18\r\n if (getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n this.renderOHLC({\r\n context,\r\n date: lastDate,\r\n isSmallIndexChart: true,\r\n isNewestOHLC: true,\r\n directRender,\r\n })\r\n } else if (data && date) {\r\n this.renderOHLC({\r\n context,\r\n date: getDateString({ date, timeframe: this.data.timeframe }),\r\n open: data.open,\r\n high: data.high,\r\n low: data.low,\r\n close: data.close,\r\n volume: numberToStringWithUnitsSuffix(Number(data.volume)),\r\n directRender,\r\n changePercentage,\r\n })\r\n } else if (dateString !== null) {\r\n this.renderOHLC({\r\n context,\r\n date: dateString,\r\n open: null,\r\n high: null,\r\n low: null,\r\n close: null,\r\n volume: null,\r\n directRender,\r\n })\r\n } else {\r\n this.renderOHLC({\r\n context,\r\n date: lastDate,\r\n afterHour:\r\n Number.isFinite(this.data.afterClose) && this.data.afterClose !== this.data.lastClose\r\n ? this.roundOhlc(this.data.afterClose)\r\n : undefined,\r\n volume: numberToStringWithUnitsSuffix(this.data.lastVolume),\r\n isNewestOHLC: true,\r\n time: utils.dateFromUnixTimestamp(this.data.date.last()!).toLocaleTimeString('en-US', {\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n }),\r\n directRender,\r\n ...this.getRoundedLastData(),\r\n })\r\n }\r\n }\r\n\r\n getRoundedLastData() {\r\n return {\r\n open: this.roundOhlc(this.data.lastOpen),\r\n high: this.roundOhlc(this.data.lastHigh),\r\n low: this.roundOhlc(this.data.lastLow),\r\n close: this.roundOhlc(this.data.lastClose),\r\n }\r\n }\r\n\r\n renderOverlaysLabels(context: CanvasRenderingContext2D) {\r\n if (!this.getIsRedesignedChart()) {\r\n this.renderOverlaysLabelsQuotePage(context)\r\n } else if (this.data.close.length !== 0) {\r\n this.renderOverlaysLabelsChartsPage(context)\r\n }\r\n }\r\n\r\n renderOverlaysLabelsQuotePage(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const text = new Text(\r\n {\r\n x: ChartSettings.left.overlayLabel.margin.left,\r\n y: ChartSettings.top.height + ChartSettings.left.overlayLabel.margin.top!,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.left.overlayLabel.font),\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.paneModel\r\n )\r\n for (const overlay of this.overlays) {\r\n if (!overlay.isRenderedOverlaysLabel()) {\r\n continue\r\n }\r\n text\r\n .set({\r\n text: overlay.toString(),\r\n y: text.get('y')! + ChartSettings.left.overlayLabel.labelSpacing,\r\n fillStyle: overlay.getLabelColor(),\r\n })\r\n .render(context)\r\n }\r\n }\r\n\r\n getYAxisLeftMargin() {\r\n if (this.data.instrument === Instrument.Crypto && this.data.lastClose <= 0.001) {\r\n return 3\r\n }\r\n return 8\r\n }\r\n\r\n getYAxisLastCloseLabel({ lastClose, firstVisibleClose }: { lastClose: number; firstVisibleClose?: number | null }) {\r\n if (typeof firstVisibleClose === 'number' && this.model.scale === ScaleType.Percentage) {\r\n return `${this.round(getPercentageFromValue({ number: lastClose, base: firstVisibleClose }), 2)}%`\r\n }\r\n return this.round(lastClose)\r\n }\r\n\r\n renderYAxis(\r\n context: CanvasRenderingContext2D,\r\n { lastClose }: RequireByKey, 'lastClose'> = this.data,\r\n renderLabels = true\r\n ) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n let y, lineTicks, textTicks, lastCloseLabel\r\n const translate = getTranslate({ context, xOffset: ChartSettings.left.width, yOffset: ChartSettings.top.height })\r\n translate.do()\r\n const tickCount = Math.floor(this.paneModel.height / 35)\r\n const minMax = this.getMinMax()\r\n const { firstVisibleClose } = minMax\r\n const height = this.height\r\n let stepPrice = 0\r\n let placesAxis\r\n\r\n switch (this.model.scale) {\r\n case ScaleType.Percentage: {\r\n if (!firstVisibleClose) return\r\n\r\n const scaleRange = this.paneModel.scaleRange\r\n const { min, max } = scaleRange || minMax\r\n\r\n this.model.updateAttribute('firstBarClose', firstVisibleClose)\r\n\r\n const minPerc = getPercentageFromValue({ number: min, base: firstVisibleClose })\r\n const maxPerc = getPercentageFromValue({ number: max, base: firstVisibleClose })\r\n\r\n const percScale = d3.scaleLinear().range([0, this.height]).domain([maxPerc, minPerc]).nice(10)\r\n textTicks = percScale.ticks(Math.min(tickCount, 9))\r\n lineTicks = textTicks.map((tick) => getValueFromPercentage({ number: tick, base: firstVisibleClose }))\r\n lastCloseLabel = this.getYAxisLastCloseLabel({ lastClose, firstVisibleClose })\r\n break\r\n }\r\n case ScaleType.Logarithmic: {\r\n if (!firstVisibleClose) return\r\n\r\n const scaleRange = this.paneModel.scaleRange\r\n const { min, max } = scaleRange || minMax\r\n lineTicks = [Math.floor(min)]\r\n const pixelGap = 30\r\n\r\n const negativeScale = []\r\n if (min < 0) {\r\n let previousNegativeTick = Math.min(0, max)\r\n while (this.paneModel.scale.y(previousNegativeTick) + pixelGap < this.paneModel.scale.y(min)) {\r\n const tick = this.paneModel.scale.y.invert(this.paneModel.scale.y(previousNegativeTick) + pixelGap)\r\n if (previousNegativeTick === tick) {\r\n break\r\n }\r\n const range = d3.nice(-previousNegativeTick, -tick, 2)\r\n previousNegativeTick = -range[range.length - 1]\r\n negativeScale.unshift(previousNegativeTick)\r\n }\r\n }\r\n\r\n const positiveScale = []\r\n if (max > 0) {\r\n positiveScale.push(Math.max(this.paneModel.scale.y.invert(this.paneModel.scale.y(min) + pixelGap), 0))\r\n }\r\n while (this.paneModel.scale.y(positiveScale[positiveScale.length - 1]) - pixelGap > 0) {\r\n const previousTick = positiveScale[positiveScale.length - 1]\r\n const positiveScaleY = this.paneModel.scale.y(positiveScale[positiveScale.length - 1])\r\n const tick = this.paneModel.scale.y.invert(positiveScaleY - pixelGap)\r\n if (previousTick === tick) {\r\n break\r\n }\r\n\r\n const range = d3.nice(previousTick, tick, 2)\r\n positiveScale.push(range[range.length - 1])\r\n }\r\n lineTicks = [...negativeScale, ...positiveScale]\r\n textTicks = lineTicks\r\n lastCloseLabel = this.getYAxisLastCloseLabel({ lastClose })\r\n break\r\n }\r\n default:\r\n // default to linear scale type\r\n lineTicks = this.paneModel.scale.y.ticks(Math.min(tickCount, 9))\r\n textTicks = lineTicks\r\n lastCloseLabel = this.getYAxisLastCloseLabel({ lastClose })\r\n }\r\n\r\n if (textTicks.length >= 2) {\r\n stepPrice = Math.abs(textTicks[1] - textTicks[0])\r\n }\r\n if (\r\n stepPrice > 10 ||\r\n (getIsSmallIndexChart(this.specificChartFunctionality) && Math.round(textTicks[0]).toString().length > 3) // if small index chart max tick is less than 999 (3 digits) allow for decimals in axis labels\r\n ) {\r\n placesAxis = 0\r\n }\r\n\r\n const getYLineText = (val: number, places?: number) => {\r\n switch (this.model.scale) {\r\n case ScaleType.Percentage:\r\n return `${val}%`\r\n default:\r\n return this.round(val, places)\r\n }\r\n }\r\n\r\n const yTickText = new Text(\r\n {\r\n x: this.width + this.getYAxisLeftMargin() + ChartSettings.right.axis.margin.left!,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.right.axis.font),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.paneModel\r\n )\r\n\r\n let yTickLine = this.getYLine()\r\n const resetYTicksStyles = () => {\r\n yTickText.set({\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.right.axis.font),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n })\r\n yTickLine = this.getYLine()\r\n }\r\n for (let i = 0; i < lineTicks.length; i++) {\r\n y = Math.round(this.fy(lineTicks[i]))\r\n if (y < 0 || y > height) continue\r\n yTickLine.set({ y1: y, y2: y })\r\n yTickText.set({\r\n text: getYLineText(textTicks[i], placesAxis),\r\n y,\r\n })\r\n if (this.model.scale === ScaleType.Percentage && textTicks[i] === 0) {\r\n yTickLine.set({ strokeStyle: Colors.text })\r\n yTickText.set({\r\n font: { weight: 'bold', size: yTickText.attrs.font.size },\r\n fillStyle: Colors.percentageZeroLineText,\r\n })\r\n yTickLine.render(context)\r\n yTickText.render(context)\r\n resetYTicksStyles()\r\n } else {\r\n yTickLine.render(context)\r\n yTickText.render(context)\r\n }\r\n }\r\n translate.undo()\r\n\r\n if (renderLabels) {\r\n this.renderYAxisLabel({ context, yCoordinate: Math.round(this.fy(lastClose)), label: lastCloseLabel })\r\n // if (typeof this.data.afterClose === 'number') {\r\n // this.renderYAxisLabel({\r\n // context,\r\n // yCoordinate: this.getYAxisSecondaryLabelYCoordinate({\r\n // mainLabelValue: lastClose,\r\n // secondaryLabelValue: this.data.afterClose,\r\n // }),\r\n // label: this.getYAxisLastCloseLabel({ lastClose: this.data.afterClose, firstVisibleClose }),\r\n // background: this.getSecondaryLabelBackgroundColor(),\r\n // })\r\n // }\r\n }\r\n }\r\n\r\n getSecondaryLabelBackgroundColor() {\r\n return stringifyHSVAColor(\r\n {\r\n ...getHSVAFromColor(this.getChartLayoutSettings().ChartSettings.general.Colors.currentBackground),\r\n s: 0.3,\r\n },\r\n 'hex'\r\n )\r\n }\r\n\r\n getYAxisSecondaryLabelYCoordinate({\r\n mainLabelValue,\r\n secondaryLabelValue,\r\n }: {\r\n mainLabelValue: number\r\n secondaryLabelValue: number\r\n }) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { lineHeight } = ChartSettings.right.axis.font\r\n const padding = Text.getMergedPropsWithDefaults('padding', ChartSettings.right.axis.font.padding)\r\n\r\n const direction = Math.sign(mainLabelValue - secondaryLabelValue) || 1\r\n const offset = (lineHeight ?? LINE_HEIGHT.S) + (padding.top ?? PADDING.XXS) + (padding.bottom ?? PADDING.XXS)\r\n const mainLabelValuePosition = Math.round(this.fy(mainLabelValue))\r\n const secondaryLabelValuePosition = Math.round(this.fy(secondaryLabelValue))\r\n const offsetedY = mainLabelValuePosition + offset * direction\r\n\r\n return Math.abs(secondaryLabelValuePosition - mainLabelValuePosition) > offset\r\n ? secondaryLabelValuePosition\r\n : offsetedY\r\n }\r\n\r\n renderYAxisLabel({\r\n context,\r\n yCoordinate,\r\n label,\r\n background,\r\n }: {\r\n context: CanvasRenderingContext2D\r\n yCoordinate: number\r\n label: string\r\n background?: string\r\n }) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({ context, xOffset: ChartSettings.left.width, yOffset: ChartSettings.top.height })\r\n const { Colors } = ChartSettings.general\r\n const { size, lineHeight } = ChartSettings.right.axis.font\r\n const padding = Text.getMergedPropsWithDefaults('padding', ChartSettings.right.axis.font.padding)\r\n\r\n translate.do()\r\n new Text(\r\n {\r\n text: label,\r\n x: this.width + this.getYAxisLeftMargin() - padding.left + ChartSettings.right.axis.margin.left!,\r\n y: yCoordinate,\r\n font: Text.getMergedPropsWithDefaults('font', { size, style: 'bold' }),\r\n lineHeight,\r\n padding,\r\n textBaseline: TextBaseline.middle,\r\n fillStyle:\r\n this.specificChartFunctionality === SpecificChartFunctionality.offScreen ? 'black' : Colors.currentText,\r\n background: background || Colors.currentBackground,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n translate.undo()\r\n }\r\n\r\n renderXAxis() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n\r\n this.context.save()\r\n if (\r\n this.data.getDrawDays() !== 1 &&\r\n !getIsSmallIndexChart(this.specificChartFunctionality) &&\r\n this.data.instrument !== Instrument.MarketSentiment\r\n ) {\r\n this.clip(true)\r\n }\r\n this.context.translate(ChartSettings.left.width, ChartSettings.top.height)\r\n const textRenderer = new Text(\r\n {\r\n y: this.height + ChartSettings.bottom.axis.margin.top!,\r\n font: Text.getMergedPropsWithDefaults('font', { size: ChartSettings.bottom.axis.font.size }),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.top,\r\n textAlign: TextAlign.center,\r\n },\r\n this.paneModel\r\n )\r\n\r\n renderXAxis({ context: this.context, quote: this.data, paneModel: this.paneModel, textRenderer, type: this.type })\r\n\r\n this.context.restore()\r\n }\r\n\r\n handleIndicatorsChange() {\r\n this.updateShouldRenderVolume()\r\n this.setupCache()\r\n this.trigger('change')\r\n }\r\n\r\n updateShouldRenderVolume() {\r\n this.shouldRenderVolume = !this.model.chart_layout().getIsIndicatorPresent(IndicatorType.Vol)\r\n }\r\n\r\n getVolumeTicks(count: number, maxHeight: number, fontHeight: number): number[] {\r\n const maxCount = 5\r\n const minCount = 1\r\n if (count > maxCount) {\r\n count = maxCount\r\n }\r\n const ticks = this.volumeFY.ticks(count).filter((tick) => tick !== 0)\r\n if (count <= minCount) {\r\n return [ticks[ticks.length - 1]]\r\n }\r\n // ticks are rendered on middle line so we have +- 1/2 of font size above and below range[min,max]\r\n // so we already have +-1 fontsize space, but in some cases that wouldn't be enough so we need to scale\r\n // dynamically, we add 3px of space per tick gap\r\n if (ticks.length * fontHeight + (ticks.length - 1) * 3 > maxHeight) {\r\n return this.getVolumeTicks(count - 1, maxHeight, fontHeight)\r\n }\r\n return ticks\r\n }\r\n\r\n renderVolumeAxis(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n if (getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n context.save()\r\n const relativeVolume = Math.max(0, Math.min(2, this.data.relativeVolume))\r\n\r\n const x = 20\r\n const fy = (y: number) => ChartSettings.top.height + this.height - this.height * (0.5 * y)\r\n const height = this.height * (0.5 * relativeVolume)\r\n\r\n const label = new Text(\r\n {\r\n x: 15,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.right,\r\n },\r\n this.paneModel\r\n )\r\n for (let i = 0.5; i <= 2; i += 0.5) {\r\n const y = Math.round(fy(i))\r\n label\r\n .set({\r\n text: i.toFixed(1),\r\n y: y,\r\n })\r\n .render(context)\r\n\r\n context.set('strokeStyle', 'rgb(130, 130, 130)')\r\n context.beginPath()\r\n context.setLineDash([2, 3])\r\n context.translate(0, 0.5)\r\n context.moveTo(x, y)\r\n context.lineTo(x + 7, y)\r\n context.translate(0, -0.5)\r\n context.stroke()\r\n }\r\n\r\n context.set('fillStyle', 'rgba(0, 135, 255, 0.58)')\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', Colors.grid)\r\n context.setLineDash([])\r\n\r\n context.fillRect(x, Math.round(ChartSettings.top.height + this.height - height), 7, Math.round(height))\r\n context.translate(0.5, 0.5)\r\n context.strokeRect(x, ChartSettings.top.height, 7, this.height)\r\n context.translate(-0.5, -0.5)\r\n\r\n new Text(\r\n {\r\n text: 'RELATIVE\\nVOLUME',\r\n x: 33,\r\n y: ChartSettings.top.height + this.height + 6,\r\n font: { size: FONT_SIZE.XXS },\r\n lineHeight: LINE_HEIGHT.XS,\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.top,\r\n textAlign: TextAlign.right,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n context.restore()\r\n return\r\n }\r\n const rangeMax = this.volumeFY.range()[1]\r\n const volumeAxisFontSize = ChartSettings.left.volumeAxis.font.size!\r\n const tickCount = Math.floor(rangeMax / volumeAxisFontSize)\r\n const ticks = this.getVolumeTicks(tickCount, rangeMax, volumeAxisFontSize)\r\n const format = this.volumeFY.tickFormat(4, 's')\r\n const text = new Text(\r\n {\r\n x: ChartSettings.left.volumeAxis.margin.left,\r\n font: Text.getMergedPropsWithDefaults('font', { size: ChartSettings.left.volumeAxis.font.size }),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.right,\r\n },\r\n this.paneModel\r\n )\r\n ticks.forEach((tick) =>\r\n text\r\n .set({\r\n text: format(tick).replace(/G/, 'B'), // https://github.com/d3/d3-format/blob/master/README.md#locale_formatPrefix\r\n y: ChartSettings.top.height + this.height - this.volumeFY(tick),\r\n })\r\n .render(context)\r\n )\r\n }\r\n\r\n renderVolume() {\r\n if (!this.shouldRenderVolume) return\r\n\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n // Return if the domain bounds are equal, this would put any value in the middle\r\n const [domainFrom, domainTo] = this.volumeFY.domain()\r\n if (this.setupAxisTimeFrame !== this.data.timeframe || domainFrom === domainTo) {\r\n return\r\n }\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height + this.height - 59,\r\n })\r\n translate.do()\r\n const halfBarWidth = getHalfBarWidth(this.model)\r\n const barWidthWithoutMargin = getBarWithoutMarginWidth(this.model)\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.paneModel,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i, x) => {\r\n // Skip render if the value is <= 0\r\n if (this.data.volume[i] <= 0) {\r\n return\r\n }\r\n\r\n this.context.fillStyle = this.data.close[i] < this.data.open[i] ? Colors.volumeTrendDown : Colors.volumeTrendUp\r\n const y = Math.round(this.volumeFY(this.data.volume[i]))\r\n this.context.fillRect(x - halfBarWidth, 60, barWidthWithoutMargin, -y)\r\n },\r\n })\r\n translate.undo()\r\n }\r\n\r\n renderOverlays() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n for (const overlay of this.overlays) {\r\n overlay.renderContent(this.context)\r\n }\r\n translate.undo()\r\n }\r\n\r\n renderCross(context: CanvasRenderingContext2D) {\r\n const isRendered = renderCross({\r\n context,\r\n mouseModel,\r\n paneModel: this.paneModel,\r\n contentWidth: this.width,\r\n contentHeight: this.height,\r\n quote: this.data,\r\n getRoundDecimalPlaces: (price) => this.getPlacesLastClose(price),\r\n onRenderCrossText: !this.getIsRedesignedChart() ? this.renderCrossText : undefined,\r\n })\r\n if (this.getIsRedesignedChart()) {\r\n this.renderCrossText(context, mouseModel.getCrossIndexForPane(this.paneModel))\r\n }\r\n\r\n if (isRendered !== undefined) {\r\n setElementCursor({\r\n elementId: this.model.chart_layout().getHTMLElementId(),\r\n cursor: isRendered ? 'crosshair' : 'default',\r\n conditionalCursor: 'grabbing',\r\n })\r\n }\r\n }\r\n\r\n getDataByCrossIndex(crossIndex: number, key: keyof Quote, shouldReturnRoundedString = true) {\r\n const n = this.data.getDataByBarIndex(key, crossIndex)\r\n if (n !== null) {\r\n return shouldReturnRoundedString ? this.roundOhlc(n) : `${n}`\r\n }\r\n }\r\n\r\n getCrossIndexChange(crossIndex: number) {\r\n const crossDataIndex = this.data.getDataIndexByBarIndex(crossIndex)\r\n const crossClose = this.data.close[crossDataIndex] ?? null\r\n const previousClose = this.data.close[crossDataIndex - 1] ?? null\r\n if (crossClose !== null && previousClose !== null) {\r\n return getTickerChangeFromCloseValues({ data: this.data, anchorClose: crossClose, prevClose: previousClose })\r\n }\r\n\r\n return null\r\n }\r\n\r\n renderCrossText(context: CanvasRenderingContext2D, crossIndex: number) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n context.save()\r\n context.translate(ChartSettings.left.width, 0)\r\n\r\n if (this.getIsRedesignedChart()) {\r\n this.renderOverlaysLabels(context)\r\n if (Number.isNaN(crossIndex)) {\r\n this.getOHLC({ context })\r\n context.restore()\r\n return\r\n }\r\n }\r\n\r\n const dateByBarIndex = this.data.getDataByBarIndex('date', crossIndex)\r\n const date = dateByBarIndex ? utils.dateFromUnixTimestamp(dateByBarIndex) : null\r\n\r\n if (date === null) {\r\n const virtualTradedDates =\r\n this.data.date.length > 0\r\n ? getVirtualTimeframeTradedDates({\r\n dateStart: this.data.date[0],\r\n dateEnd: this.data.date[this.data.date.length - 1],\r\n quote: this.data,\r\n })\r\n : []\r\n this.getOHLC({\r\n context,\r\n dateString: virtualTradedDates[crossIndex]\r\n ? getDateString({\r\n date: utils.dateFromUnixTimestamp(virtualTradedDates[crossIndex]),\r\n timeframe: this.data.timeframe,\r\n })\r\n : null,\r\n })\r\n context.restore()\r\n return\r\n }\r\n\r\n this.getOHLC({\r\n context,\r\n date,\r\n data: {\r\n open: this.getDataByCrossIndex(crossIndex, 'open'),\r\n high: this.getDataByCrossIndex(crossIndex, 'high'),\r\n low: this.getDataByCrossIndex(crossIndex, 'low'),\r\n close: this.getDataByCrossIndex(crossIndex, 'close'),\r\n volume: this.getDataByCrossIndex(crossIndex, 'volume', false),\r\n },\r\n changePercentage: this.getCrossIndexChange(crossIndex),\r\n })\r\n\r\n context.restore()\r\n }\r\n\r\n renderChange({ context }: { context: CanvasRenderingContext2D }) {\r\n const CHANGE_SPACER = 10\r\n const { ChartSettings, isOurSiteRequest } = this.getChartLayoutSettings()\r\n const { ticker, change, ohlc } = ChartSettings.top\r\n const { tickerChange, tickerAfterChange } = getTickerChange({ data: this.data })\r\n\r\n if (!tickerChange) {\r\n return\r\n }\r\n\r\n const isOffscreen = this.specificChartFunctionality === SpecificChartFunctionality.offScreen\r\n const isGroupInstrument = this.data.instrument === Instrument.Group\r\n const finvizWatermarkOffset = !isOffscreen || isOurSiteRequest || this.isLargeChart ? 0 : 15\r\n const changeText = new Text(\r\n {\r\n text: isOffscreen && isGroupInstrument ? tickerChange.percentString : tickerChange.string,\r\n x: !getIsSmallIndexChart(this.specificChartFunctionality)\r\n ? this.width - ChartSettings.top.change.margin.right! - finvizWatermarkOffset\r\n : this.width,\r\n y: ChartSettings.top.change.margin.top,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.top.change.font),\r\n textAlign: TextAlign.right,\r\n textBaseline: ChartSettings.top.baseline,\r\n fillStyle: getChangeColor({ change: tickerChange.points, ChartSettings }),\r\n },\r\n this.paneModel\r\n )\r\n this.changeWidth = changeText.measure(context)\r\n changeText.render(context)\r\n\r\n if (isOffscreen && (!this.isLargeChart || isGroupInstrument)) {\r\n return\r\n }\r\n if (tickerAfterChange) {\r\n const afterChangeText = new Text(\r\n {\r\n text: tickerAfterChange?.string,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.top.change.font),\r\n textAlign: TextAlign.right,\r\n textBaseline: ChartSettings.top.baseline,\r\n fillStyle: getChangeColor({ change: tickerAfterChange.points, ChartSettings }),\r\n },\r\n this.paneModel\r\n )\r\n const afterChangeTextWidth = afterChangeText.measure(context)\r\n const oneLineAHChangeWidth = this.changeWidth + CHANGE_SPACER + afterChangeTextWidth\r\n\r\n if (\r\n ChartSettings.left.width + this.tickerWidth + ticker.margin.left! + OFFSET.S <\r\n ChartSettings.left.width + this.width - oneLineAHChangeWidth - change.margin.right!\r\n ) {\r\n afterChangeText\r\n .set({\r\n x: this.width - ChartSettings.top.change.margin.right! - this.changeWidth - CHANGE_SPACER,\r\n y: ChartSettings.top.change.margin.top,\r\n })\r\n .render(context)\r\n this.afterChange = null\r\n this.changeWidth = oneLineAHChangeWidth\r\n } else if (\r\n this.lastOhlc[0] &&\r\n ChartSettings.left.width +\r\n this.tickerWidth +\r\n ticker.margin.left! +\r\n this.lastOhlc[0].width! +\r\n ohlc.margin.left! +\r\n ohlc.margin.right! <\r\n ChartSettings.left.width + this.width - afterChangeTextWidth - change.margin.right!\r\n ) {\r\n afterChangeText\r\n .set({\r\n x: this.width - ChartSettings.top.change.margin.right!,\r\n y: ChartSettings.top.change.margin.top! - ChartSettings.top.change.font.size! - OFFSET.S,\r\n })\r\n .render(context)\r\n this.changeWidth = Math.max(this.changeWidth, afterChangeTextWidth)\r\n this.afterChange = {\r\n x: this.width - ChartSettings.top.change.margin.right!,\r\n y: ChartSettings.top.change.margin.top! - ChartSettings.top.change.font.size! - OFFSET.S,\r\n width: afterChangeTextWidth,\r\n }\r\n }\r\n }\r\n }\r\n\r\n renderOHLC(parameters: IRenderOHLCParameters) {\r\n if (!this.getIsRedesignedChart()) {\r\n this.renderOHLCQuotePage(parameters)\r\n } else {\r\n this.renderOHLCChartsPage(parameters)\r\n }\r\n }\r\n\r\n renderOHLCChartsPage({ context, date, open, high, low, close, volume, changePercentage }: IRenderOHLCParameters) {\r\n const chartBreakpoints = getChartBreakpoints(this.width)\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n\r\n const OhlcText = new Text(\r\n {\r\n font: { size: FONT_SIZE.S },\r\n lineHeight: 18,\r\n fillStyle: Colors.text,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.middle,\r\n background: getHEXWithSpecificAplha(Colors.canvasFill, 0.8),\r\n },\r\n this.paneModel\r\n )\r\n\r\n const dateElements = date ? [{ text: date, color: gray300 }] : []\r\n const trendColor = (open ?? 0) > (close ?? 0) ? tailwindColors.red[400] : tailwindColors.green[400]\r\n const oElements = open\r\n ? [\r\n { text: 'O', color: gray300 },\r\n { text: open, color: trendColor },\r\n ]\r\n : []\r\n const hElements = high\r\n ? [\r\n { text: 'H', color: gray300 },\r\n { text: high, color: trendColor },\r\n ]\r\n : []\r\n const lElements = low\r\n ? [\r\n { text: 'L', color: gray300 },\r\n { text: low, color: trendColor },\r\n ]\r\n : []\r\n const cElements = close\r\n ? [\r\n { text: 'C', color: gray300 },\r\n { text: close, color: trendColor },\r\n ]\r\n : []\r\n const volElements = volume\r\n ? [\r\n { text: 'Vol', color: gray300 },\r\n { text: volume, color: trendColor },\r\n ]\r\n : []\r\n const changeElements = changePercentage != null ? [{ text: changePercentage.string, color: trendColor }] : []\r\n\r\n const lines: OhlcLineElements[] = []\r\n\r\n const getFlatLineArrayWithSpaces = (lineElements: OhlcLineElements[]) =>\r\n lineElements.flatMap((elements, index) =>\r\n index > 0 ? ([...(elements.length > 0 ? ['space'] : []), ...elements] as OhlcLineElements) : elements\r\n )\r\n if (chartBreakpoints.isM) {\r\n lines.push(\r\n getFlatLineArrayWithSpaces([\r\n dateElements,\r\n oElements,\r\n hElements,\r\n lElements,\r\n cElements,\r\n volElements,\r\n changeElements,\r\n ])\r\n )\r\n } else if (chartBreakpoints.isS) {\r\n lines.push(getFlatLineArrayWithSpaces([dateElements, changeElements]))\r\n lines.push(getFlatLineArrayWithSpaces([oElements, hElements, lElements, cElements, volElements]))\r\n } else {\r\n lines.push(getFlatLineArrayWithSpaces([dateElements, volElements, changeElements]))\r\n lines.push(getFlatLineArrayWithSpaces([oElements, hElements, lElements, cElements]))\r\n }\r\n\r\n const startX = OFFSET.M - ChartSettings.left.width\r\n let x = startX\r\n let y = OFFSET.M + OhlcText.attrs.lineHeight / 2\r\n\r\n lines.forEach((line) => {\r\n x = startX\r\n line.forEach((lineElement, index, lineElements) => {\r\n const padding = { left: 1, right: 1, top: 0, bottom: 0 }\r\n const { text = '', color = undefined } = lineElement === 'space' ? {} : lineElement\r\n if (index === 0) {\r\n padding.left = 5\r\n } else if (index === lineElements.length - 1) {\r\n padding.right = 5\r\n } else if (lineElement === 'space') {\r\n padding.left = 7\r\n padding.right = 7\r\n if (!chartBreakpoints.isS) {\r\n padding.left = 5\r\n padding.right = 5\r\n }\r\n }\r\n OhlcText.set({ text, fillStyle: color, x, y, padding })\r\n OhlcText.render(context)\r\n x += OhlcText.width\r\n })\r\n y += OhlcText.attrs.lineHeight\r\n })\r\n }\r\n\r\n renderOverlaysLabelsChartsPage(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const chartBreakpoints = getChartBreakpoints(this.width)\r\n const LabelsText = new Text(\r\n {\r\n font: { size: FONT_SIZE.S },\r\n lineHeight: 18,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.middle,\r\n background: getHEXWithSpecificAplha(ChartSettings.general.Colors.canvasFill, 0.8),\r\n // this function gets (indirectly) called from renderCrossText which is already \"translateX\" by ChartSettings.left.width\r\n x: OFFSET.M - ChartSettings.left.width,\r\n padding: { left: PADDING.S, right: PADDING.S, top: 0, bottom: 0 },\r\n },\r\n this.paneModel\r\n )\r\n\r\n let numberOfNewOhlcLines = 2\r\n if (chartBreakpoints.isM) {\r\n numberOfNewOhlcLines = 1\r\n } else if (chartBreakpoints.isS) {\r\n numberOfNewOhlcLines = 2\r\n }\r\n\r\n // We assume lineheight is the same as OHLC text\r\n const { lineHeight } = LabelsText.attrs\r\n let y = lineHeight * numberOfNewOhlcLines + lineHeight / 2 + OFFSET.M\r\n\r\n for (const overlay of this.overlays) {\r\n if (!overlay.isRenderedOverlaysLabel()) {\r\n continue\r\n }\r\n LabelsText.set({\r\n text: overlay.toString(),\r\n y,\r\n fillStyle: overlay.getLabelColor(),\r\n }).render(context)\r\n y += lineHeight\r\n }\r\n }\r\n\r\n renderOHLCQuotePage({\r\n context,\r\n date,\r\n open,\r\n high,\r\n low,\r\n close,\r\n volume,\r\n afterHour,\r\n isSmallIndexChart = false,\r\n isNewestOHLC = false,\r\n time,\r\n directRender = false,\r\n changePercentage,\r\n }: IRenderOHLCParameters) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const { ohlc } = ChartSettings.top\r\n const isOffscreen = this.specificChartFunctionality === SpecificChartFunctionality.offScreen\r\n const isGroupInstrument = this.data.instrument === Instrument.Group\r\n if (isOffscreen && isGroupInstrument) {\r\n ohlc.type = OHLCType.dateOnly\r\n } else if (isOffscreen && this.data.instrument !== Instrument.Stock && time) {\r\n ohlc.type = OHLCType.timeOnly\r\n }\r\n\r\n const lineTopY = ohlc.type ? ohlc.margin.top : ohlc.margin.top! - ChartSettings.top.ticker.font.size!\r\n const OHLCFontSize = ohlc.font.size!\r\n const centerXOffset =\r\n this.tickerWidth +\r\n ChartSettings.top.ticker.margin.left! +\r\n (this.width -\r\n (this.tickerWidth +\r\n ChartSettings.top.ticker.margin.left! +\r\n this.changeWidth +\r\n (isSmallIndexChart ? 0 : ChartSettings.top.change.margin.right!))) / // smallIndexChart don't have change.margin.right\r\n 2\r\n const leftXOffset = this.tickerWidth + ChartSettings.top.ticker.margin.left! + ohlc.margin.left!\r\n const hasOhlc = ![open, high, low, close, volume].some((ohlcString) => !ohlcString)\r\n const OHLC = hasOhlc\r\n ? {\r\n date: [date ?? ''],\r\n singleLine: [\r\n `${date} O:${open} H:${high} L:${low} C:${close}${\r\n afterHour ? ` AH:${afterHour}` : ''\r\n } Vol:${volume} `,\r\n /*\r\n * this is needed because of the way we render ohlc text down below in renderOHLCToCanvas\r\n * undefined is used instead of null because TS had some issues with `null` even if it is filtered out\r\n * */\r\n changePercentage ? changePercentage.string : undefined,\r\n ].filter((value) => value !== undefined),\r\n }\r\n : {\r\n date: [date ?? ''],\r\n singleLine: [`${date ?? ''}`],\r\n }\r\n\r\n const OHLC_TEXT = new Text(\r\n {\r\n font: { size: OHLCFontSize },\r\n },\r\n this.paneModel\r\n )\r\n\r\n const getOHLCType = () => {\r\n if (!isSmallIndexChart) {\r\n return OHLCType.singleLine\r\n }\r\n return OHLCType.dateOnly\r\n }\r\n\r\n const getOHLCSettings = () => {\r\n switch (ohlc.type || getOHLCType()) {\r\n case OHLCType.singleLine:\r\n return {\r\n text: OHLC.singleLine,\r\n x: [leftXOffset, leftXOffset],\r\n y: [ohlc.margin.top],\r\n textAlign: TextAlign.left,\r\n textBaseline: [TextBaseline.alphabetic],\r\n }\r\n case OHLCType.dateOnly:\r\n if (isOffscreen && isGroupInstrument) {\r\n const text = `${OHLC.date} Volume: ${volume}`\r\n const textWidth = OHLC_TEXT.set({ text }).measure(context)\r\n return {\r\n text: [text],\r\n x: [\r\n this.width - ChartSettings.top.change.margin.right! - this.changeWidth - textWidth - CHART_MARGIN.XXL,\r\n ],\r\n y: [ohlc.margin.top],\r\n textAlign: TextAlign.center,\r\n textBaseline: [TextBaseline.alphabetic],\r\n }\r\n } else if (isSmallIndexChart) {\r\n return {\r\n text: OHLC.date,\r\n x: [centerXOffset],\r\n y: [ohlc.margin.top],\r\n textAlign: TextAlign.center,\r\n textBaseline: [TextBaseline.alphabetic],\r\n }\r\n } else {\r\n const isEnoughSpace =\r\n this.width -\r\n (this.tickerWidth +\r\n ChartSettings.top.ticker.margin.left! +\r\n ohlc.margin.left! +\r\n ohlc.margin.right! +\r\n this.changeWidth +\r\n ChartSettings.top.change.margin.right!) >\r\n OHLC_TEXT.set({ text: OHLC.date[0] }).measure(context)\r\n const alignTop = !isEnoughSpace || ohlc.font.baseline === TextBaseline.top\r\n return {\r\n text: OHLC.date,\r\n x: [leftXOffset],\r\n y: alignTop ? [lineTopY] : [ohlc.margin.top],\r\n textAlign: TextAlign.left,\r\n textBaseline: alignTop ? [TextBaseline.top] : [TextBaseline.alphabetic],\r\n }\r\n }\r\n case OHLCType.timeOnly:\r\n return {\r\n text: [time],\r\n x: [centerXOffset - OHLC_TEXT.set({ text: time }).measure(context) / 2],\r\n y: [lineTopY],\r\n textAlign: TextAlign.center,\r\n textBaseline: [ohlc.font.baseline],\r\n }\r\n default:\r\n return\r\n }\r\n }\r\n\r\n if (!isNewestOHLC) {\r\n context.fillStyle = Colors.canvasFill\r\n this.lastOhlc.forEach((line) => {\r\n const x = (line.textAlign === TextAlign.left ? line.x : line.x! - line.width! / 2)!\r\n const y = (line.textBaseline === TextBaseline.top ? line.y : line.y! - OHLCFontSize)!\r\n context.fillRect(\r\n x - PADDING.XXS,\r\n y - PADDING.XXS,\r\n PADDING.XXS + line.width! + PADDING.XXS,\r\n PADDING.XXS + OHLCFontSize + PADDING.XXS\r\n )\r\n })\r\n\r\n if (this.afterChange) {\r\n context.fillRect(\r\n this.afterChange.x - this.afterChange.width - PADDING.XXS,\r\n this.afterChange.y - ChartSettings.top.change.font.size! - PADDING.XXS,\r\n PADDING.XXS + this.afterChange.width + PADDING.XXS,\r\n PADDING.XXS + ChartSettings.top.change.font.size! + PADDING.XS\r\n )\r\n }\r\n } else {\r\n this.lastOhlc = []\r\n }\r\n\r\n const ohlcSettings = getOHLCSettings()\r\n\r\n const renderOHLCToCanvas = ({\r\n ohlcSet,\r\n render = true,\r\n }: {\r\n ohlcSet?: {\r\n text: (string | undefined)[]\r\n x: number[]\r\n y: (number | undefined)[]\r\n textAlign: TextAlign\r\n textBaseline: (TextBaseline | undefined)[]\r\n }\r\n render?: boolean\r\n }) => {\r\n const isSingleLineWithChange = (ohlc.type || getOHLCType()) === OHLCType.singleLine && changePercentage\r\n ohlcSet?.text.forEach((line: string | undefined, index: number) => {\r\n let i = index\r\n let leftOffset = 0\r\n let fillStyle = Colors.text\r\n let text = line\r\n if (index > 0 && isSingleLineWithChange) {\r\n i -= 1\r\n leftOffset = OHLC_TEXT.measure(context)\r\n text = line\r\n\r\n fillStyle = getChangeColor({ change: changePercentage.points, ChartSettings })\r\n }\r\n const options = {\r\n text,\r\n x: ohlcSet.x[i] + leftOffset,\r\n y: ohlcSet.y[i],\r\n textBaseline: ohlc.font.baseline ? ohlc.font.baseline : ohlcSet.textBaseline[i],\r\n textAlign: ohlc.font.textAlign ? ohlc.font.textAlign : ohlcSet.textAlign,\r\n fillStyle,\r\n }\r\n OHLC_TEXT.set(options)\r\n if (isNewestOHLC) {\r\n this.lastOhlc[i] = { width: OHLC_TEXT.measure(context), ...options }\r\n }\r\n if (render) {\r\n OHLC_TEXT.render(context)\r\n }\r\n })\r\n }\r\n renderOHLCToCanvas({ ohlcSet: ohlcSettings, render: directRender })\r\n\r\n return {\r\n ohlcSettings,\r\n renderOHLCToCanvas,\r\n }\r\n }\r\n\r\n shouldShowPrevClose() {\r\n const quote = this.model.quote()\r\n const isStock = quote.instrument === Instrument.Stock\r\n const isIntradayWithPreMarket = TIMEFRAMES_WITH_PRE_MARKET.includes(quote.timeframe)\r\n const isIndexChart = this.specificChartFunctionality === SpecificChartFunctionality.smallIndex\r\n\r\n return isStock && (isIntradayWithPreMarket || isIndexChart)\r\n }\r\n\r\n renderPrevClose() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n if (!this.shouldShowPrevClose()) {\r\n return\r\n }\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n\r\n let y = Math.round(this.fy(this.model.quote().prevClose))\r\n if (y === this.height) y -= 1 // due pixel perfect rendering of lines, line on bottom edge is moved outside of \"chart area\" because of 0.5px translate, to compensate for this we subtract 1px\r\n\r\n new Line(\r\n {\r\n x1: 0,\r\n x2: this.width,\r\n y1: y,\r\n y2: y,\r\n strokeStyle: Colors.prevClose,\r\n dashLength: 3,\r\n },\r\n this.paneModel\r\n ).render(this.context)\r\n translate.undo()\r\n }\r\n\r\n renderChartNotAvailable() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const x = ~~((ChartSettings.left.width + ChartSettings.right.width + this.width) / 2)\r\n const y = ~~((ChartSettings.top.height + ChartSettings.bottom.height + this.height) / 2)\r\n new Text(\r\n {\r\n text: 'Chart not available',\r\n x,\r\n y,\r\n font: { size: FONT_SIZE.M, style: 'bold' },\r\n fillStyle: Colors.text,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.paneModel\r\n ).render(this.context)\r\n }\r\n\r\n // private\r\n setupCache() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n /*\r\n * Don't create new Cache instances, because Safari takes too long to free up memory\r\n * leading to canvas.getContext returning null. https://stackoverflow.com/questions/52532614/total-canvas-memory-use-exceeds-the-maximum-limit-safari-12\r\n *\r\n * To further improve performance, cache.set shouldn't be called when unnecessary,\r\n * because setupCache is called for many model updates. The same applies for indicators/indicator.js.\r\n */\r\n this.baseCache = this.baseCache || new Cache()\r\n\r\n this.baseCache.set(\r\n (context: CanvasRenderingContext2D) => {\r\n if (this.data.close.length === 0) {\r\n this.renderText(context)\r\n return\r\n }\r\n this.renderYAxis(context)\r\n this.renderText(context)\r\n if (!this.getIsMobileChartPage() && this.shouldRenderVolume) {\r\n this.renderVolumeAxis(context)\r\n }\r\n if (!this.getIsRedesignedChart()) {\r\n this.renderOverlaysLabels(context)\r\n }\r\n },\r\n this.width + ChartSettings.left.width + ChartSettings.right.width,\r\n this.height + ChartSettings.top.height + ChartSettings.bottom.height\r\n )\r\n }\r\n\r\n // called by controllers/pane on recountScale\r\n setupAxis(fx: ScaleAxis) {\r\n this.data = this.model.quote()\r\n const { volumeHeight } = this.getChartLayoutSettings().ChartSettings.center\r\n\r\n if (typeof fx !== 'function') {\r\n return\r\n }\r\n\r\n const firstBarToRenderIndex = getVisibleBarToRenderIndex({\r\n leftOffset: this.model.leftOffset,\r\n paneModel: this.paneModel,\r\n quote: this.data,\r\n })\r\n\r\n const lastBarToRenderIndex = getVisibleBarToRenderIndex({\r\n leftOffset: this.model.leftOffset,\r\n paneModel: this.paneModel,\r\n quote: this.data,\r\n chartWidth: this.width,\r\n })\r\n\r\n const areNoBarsVisible = getAreNoBarsVisible(firstBarToRenderIndex, lastBarToRenderIndex)\r\n\r\n const volumes = []\r\n if (areNoBarsVisible) {\r\n volumes.push(\r\n this.data.volume[firstBarToRenderIndex.index],\r\n Math.min(lastBarToRenderIndex.index, this.data.barIndex.length - 1)\r\n )\r\n } else {\r\n for (let i = firstBarToRenderIndex.index; i <= lastBarToRenderIndex.index; i++) {\r\n volumes.push(this.data.volume[i])\r\n }\r\n }\r\n\r\n const max = utils.max(volumes) ?? 0\r\n const rangeMax = volumeHeight || 60\r\n this.volumeFY = d3.scaleLinear().range([0, rangeMax]).domain([0, max]).nice(4)\r\n this.setupAxisTimeFrame = this.data.timeframe\r\n }\r\n\r\n // private\r\n clip(addMarginBottom?: boolean) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n if (addMarginBottom == null) {\r\n addMarginBottom = false\r\n }\r\n this.context.beginPath()\r\n let marginBottom = 0\r\n if (addMarginBottom) {\r\n marginBottom = ChartSettings.bottom.height\r\n }\r\n // due pixel perfect rendering of lines, line on bottom edge is moved outside of \"chart area\" because of 0.5px translate,\r\n // to compensate for this we clip canvas 1px taller than chart height\r\n this.context.rect(ChartSettings.left.width, ChartSettings.top.height, this.width, this.height + marginBottom + 1)\r\n this.context.clip()\r\n }\r\n\r\n addOverlay(overlay: Overlay) {\r\n overlay.chart = this\r\n this.overlays.push(overlay)\r\n return this.trigger('change')\r\n }\r\n\r\n setOverlays(overlays: Overlay[]) {\r\n this.overlays = overlays\r\n return this.trigger('change')\r\n }\r\n\r\n removeOverlay(overlay: Overlay) {\r\n for (let index = 0; index < this.overlays.length; index++) {\r\n const el = this.overlays[index]\r\n if (el === overlay) {\r\n this.attrs.overlays.splice(index, 1)\r\n this.overlays.splice(index, 1)\r\n this.trigger('change')\r\n break\r\n }\r\n }\r\n }\r\n\r\n getMinMax(): { min: number; max: number; firstVisibleClose?: number | null } {\r\n this.data = this.model.quote()\r\n let min = Number.MAX_VALUE\r\n let max = Number.MIN_VALUE\r\n let minIndex = -1\r\n let maxIndex = -1\r\n let firstVisibleClose = null\r\n\r\n const firstBarToRenderIndex = getVisibleBarToRenderIndex({\r\n leftOffset: this.model.leftOffset,\r\n paneModel: this.paneModel,\r\n quote: this.data,\r\n })\r\n const lastBarToRenderIndex = getVisibleBarToRenderIndex({\r\n leftOffset: this.model.leftOffset,\r\n paneModel: this.paneModel,\r\n quote: this.data,\r\n chartWidth: this.width,\r\n })\r\n\r\n const areNoBarsVisible = getAreNoBarsVisible(firstBarToRenderIndex, lastBarToRenderIndex)\r\n\r\n // If no bars are visible min/max are first available bar before visible and first after\r\n if (areNoBarsVisible) {\r\n min = this.data.low[firstBarToRenderIndex.index]\r\n max = this.data.high[Math.min(lastBarToRenderIndex.index, this.data.barIndex.length - 1)]\r\n if (min > max) {\r\n const prevMin = min\r\n min = max\r\n max = prevMin\r\n }\r\n firstVisibleClose = this.data.close[firstBarToRenderIndex.index]\r\n } else {\r\n for (let i = firstBarToRenderIndex.index; i <= lastBarToRenderIndex.index; i++) {\r\n if (minIndex === -1 || this.data.low[minIndex] > this.data.low[i]) {\r\n minIndex = i\r\n }\r\n if (maxIndex === -1 || this.data.high[maxIndex] < this.data.high[i]) {\r\n maxIndex = i\r\n }\r\n }\r\n\r\n // If only a single bar is visible get min/max index range from closes values outside of visible area\r\n if (this.data.low[minIndex] === this.data.high[maxIndex]) {\r\n const closestMinMaxIndices = getClosestDifferentMinMaxValueIndices(\r\n minIndex,\r\n maxIndex,\r\n this.data.high,\r\n this.data.low\r\n )\r\n minIndex = closestMinMaxIndices.minIndex\r\n maxIndex = closestMinMaxIndices.maxIndex\r\n }\r\n\r\n min = this.data.low[minIndex]\r\n max = this.data.high[maxIndex]\r\n\r\n firstVisibleClose = this.data.close[firstBarToRenderIndex.index]\r\n }\r\n\r\n // Apply scale min & max buffer if min/max is the same\r\n if (min === max) {\r\n min *= 0.99\r\n max *= 1.01\r\n }\r\n\r\n // Update min/max so prevClose is in range and can be rendered if it should\r\n if (this.shouldShowPrevClose() && this.data.prevClose !== null) {\r\n min = Math.min(min, this.data.prevClose)\r\n max = Math.max(max, this.data.prevClose)\r\n }\r\n\r\n // Update min/max so lastClose is in range and can be rendered if it should\r\n if (this.specificChartFunctionality === SpecificChartFunctionality.offScreen && !this.model.dateRange) {\r\n min = Math.min(min, this.data.lastClose)\r\n max = Math.max(max, this.data.lastClose)\r\n }\r\n\r\n return { min, max, firstVisibleClose }\r\n }\r\n\r\n moveBy() {}\r\n\r\n isInArea() {\r\n return false\r\n }\r\n\r\n fx = (x: number) => this.paneModel.scale.x(this.data.barIndex[x])\r\n\r\n fy = (y: number) => this.paneModel.scale.y(y)\r\n\r\n round(n: number, overridePlaces?: number) {\r\n return round({ data: this.data, num: n, overridePlaces: overridePlaces ?? this.getPlacesLastClose() })\r\n }\r\n\r\n roundOhlc(n: number) {\r\n const placesLastClose = this.getPlacesLastClose()\r\n return round({\r\n data: this.data,\r\n num: n,\r\n overridePlaces: placesLastClose ? Math.max(placesLastClose, 2) : undefined,\r\n })\r\n }\r\n\r\n toObject() {\r\n const overlays = this.overlays.map((overlay) => overlay.toObject())\r\n return merge({}, this.attrs, { type: this.type, overlays })\r\n }\r\n\r\n toConfig() {\r\n const overlays = this.overlays.map((overlay) => overlay.toConfig())\r\n return merge({}, this.attrs, { type: this.type, overlays })\r\n }\r\n\r\n getPlacesLastClose(price?: number) {\r\n const { lastClose, instrument } = this.data\r\n const priceAbs = price && Math.abs(price)\r\n if (lastClose >= 100000) {\r\n return 0\r\n } else if (lastClose >= 10000) {\r\n return 1\r\n } else if (instrument === Instrument.Stock && (priceAbs ?? lastClose) < 1) {\r\n return 4\r\n } else if (lastClose === undefined) {\r\n // if lastClose is not defined we'll always display 2 decimpal places, e.g. backtests, screener stats\r\n return 2\r\n }\r\n\r\n return undefined\r\n }\r\n\r\n hasOverlay(type: string) {\r\n return this.overlays.some((x) => x.type === 'overlays/' + type)\r\n }\r\n\r\n getXLine(): Line {\r\n return new Line(\r\n {\r\n y1: 0,\r\n y2: this.height,\r\n strokeStyle: this.getChartLayoutSettings().ChartSettings.general.Colors.grid,\r\n dashLength: 3,\r\n },\r\n this.paneModel\r\n )\r\n }\r\n\r\n getYLine(): Line {\r\n return new Line(\r\n {\r\n x1: 0,\r\n x2: this.width,\r\n strokeStyle: this.getChartLayoutSettings().ChartSettings.general.Colors.grid,\r\n dashLength: 3,\r\n },\r\n this.paneModel\r\n )\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.model.chart_layout())\r\n }\r\n\r\n getIsMobileChartPage() {\r\n return (\r\n this.isMobile && this.model.chart_layout().specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n )\r\n }\r\n\r\n getCandleLikeChartsRenderingColors() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const { theme, specificChartFunctionality } = this.model.chart_layout()\r\n let colors = Colors\r\n const overwrittenColors = getColorOverwrites({\r\n colors,\r\n theme,\r\n })\r\n const overwrittenColorKeys = Object.keys(overwrittenColors)\r\n const hasOverwrittenCandleColor = ['borderUp', 'wickUp', 'borderDown', 'wickDown', 'trendUp', 'trendDown'].some(\r\n (colorKey) => overwrittenColorKeys.includes(colorKey)\r\n )\r\n\r\n const shouldUseDarkerColors =\r\n theme === Theme.light &&\r\n getShouldUseDarkerWickColors({\r\n specificChartFunctionality: specificChartFunctionality,\r\n totalBarWidth: ChartSettings.center.barWidth + ChartSettings.center.border * 2,\r\n })\r\n\r\n if (shouldUseDarkerColors && !hasOverwrittenCandleColor) {\r\n colors = { ...colors, ...darkerWickColors }\r\n }\r\n const isNodeChartWithThinBars =\r\n specificChartFunctionality === SpecificChartFunctionality.offScreen && ChartSettings.center.border === 0\r\n if (isNodeChartWithThinBars && !hasOverwrittenCandleColor) {\r\n colors = { ...colors, ...thinBarColorsOverride, ...overwrittenColors }\r\n }\r\n\r\n return colors\r\n }\r\n\r\n getIsRedesignedChart() {\r\n return this.specificChartFunctionality === SpecificChartFunctionality.chartPage || isRedesignedPage(this)\r\n }\r\n}\r\n\r\nBaseChart.initClass()\r\n\r\nexport default BaseChart\r\n","import { RendererChartBarProps } from '../../types/shared'\r\nimport { ChartElementType } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport utils from '../utils'\r\nimport { getBarWidthWithMarginByParts } from '../utils/chart'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { getIsSSr } from '../utils/helpers'\r\nimport Chart from './base_chart'\r\n\r\nconst WICK_WIDTH = 1\r\n\r\nclass CandleStick extends Chart {\r\n static type = ChartElementType.CandleStick\r\n static label = 'Candle'\r\n static iconName = 'candleBarBasic'\r\n\r\n getRenderChartBarProps({ index, chartSettingsColors, hasFillAndBorder }: RendererChartBarProps) {\r\n const { trendDown, trendUp, borderDown, borderUp, wickDown, wickUp } = chartSettingsColors\r\n const open = this.data.open[index]\r\n const close = this.data.close[index]\r\n const trendColor = close < open ? trendDown : trendUp\r\n const wickColor = close < open ? wickDown : wickUp\r\n return {\r\n open,\r\n close,\r\n high: this.data.high[index],\r\n low: this.data.low[index],\r\n barFillColor: trendColor,\r\n borderColor: close < open ? borderDown : borderUp,\r\n wickColor: hasFillAndBorder ? wickColor : trendColor,\r\n }\r\n }\r\n\r\n renderChart() {\r\n if (this.setupAxisTimeFrame !== this.data.timeframe) {\r\n return\r\n }\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const Colors = this.getCandleLikeChartsRenderingColors()\r\n const { barFillWidth, barBorderWidth } = getBarWidthWithMarginByParts({\r\n chartLayout: this.model.chart_layout(),\r\n zoomFactor: this.model.zoomFactor,\r\n })\r\n const shouldRenderFillAndBorder =\r\n barFillWidth + barBorderWidth * 2 >= 2 &&\r\n !(this.type === ChartElementType.HollowCandleStick && barBorderWidth === 0)\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n const translateForWick = getTranslate({\r\n context: this.context,\r\n xOffset: WICK_WIDTH / 2,\r\n yOffset: 0,\r\n })\r\n\r\n translate.do()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.paneModel,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, center: number) => {\r\n const { open, close, high, low, wickColor, borderColor, barFillColor } = this.getRenderChartBarProps({\r\n index: i,\r\n chartSettingsColors: Colors,\r\n hasFillAndBorder: shouldRenderFillAndBorder,\r\n })\r\n\r\n const candleBodyHigh = Math.round(this.fy(utils.max(open, close)))\r\n const candleBodyLow = Math.round(this.fy(utils.min(open, close)))\r\n const candleWickHigh = Math.round(this.fy(high))\r\n const candleWickLow = Math.round(this.fy(low))\r\n\r\n const candleBodyHeight = candleBodyLow - candleBodyHigh\r\n const candleBodyLeftX = center - Math.floor(barBorderWidth + barFillWidth / 2)\r\n const halfBorderWidth = barBorderWidth / 2\r\n\r\n // TODO: revisit for better approach, this solve issue with candlesticks\r\n // with even width are shifted 1px to the left and thus first candle is vertically sliced\r\n if (getIsSSr() && candleBodyLeftX + this.leftOffset < 0) {\r\n return\r\n }\r\n\r\n const isBodyHeightGreaterOrEqualBorders = candleBodyHeight >= barBorderWidth * 2\r\n const isWickLineCandleLessThanOnePixel = !shouldRenderFillAndBorder && candleWickLow - candleWickHigh < 1\r\n\r\n translateForWick.do()\r\n this.context.set('strokeStyle', wickColor)\r\n this.context.beginPath()\r\n this.context.moveTo(center, candleWickHigh)\r\n if (shouldRenderFillAndBorder) {\r\n this.context.lineTo(center, candleBodyHigh)\r\n this.context.moveTo(\r\n center,\r\n candleBodyHigh + (isBodyHeightGreaterOrEqualBorders ? candleBodyHeight : WICK_WIDTH)\r\n )\r\n }\r\n this.context.lineTo(center, isWickLineCandleLessThanOnePixel ? candleWickHigh + 1 : candleWickLow)\r\n this.context.stroke()\r\n translateForWick.undo()\r\n\r\n if (shouldRenderFillAndBorder) {\r\n const hasBorder = barBorderWidth > 0\r\n if (hasBorder) {\r\n this.context.set('strokeStyle', borderColor)\r\n if (isBodyHeightGreaterOrEqualBorders) {\r\n this.context.set('lineWidth', barBorderWidth)\r\n this.context.strokeRect(\r\n candleBodyLeftX + halfBorderWidth,\r\n candleBodyHigh + halfBorderWidth,\r\n barFillWidth + 2 * halfBorderWidth,\r\n candleBodyHeight - 2 * halfBorderWidth\r\n )\r\n this.context.set('lineWidth', WICK_WIDTH)\r\n } else {\r\n this.context.beginPath()\r\n this.context.moveTo(candleBodyLeftX, candleBodyHigh + WICK_WIDTH / 2)\r\n this.context.lineTo(candleBodyLeftX + barFillWidth + 2 * barBorderWidth, candleBodyHigh + WICK_WIDTH / 2)\r\n this.context.stroke()\r\n }\r\n }\r\n\r\n const fillHeight = candleBodyHeight - 2 * barBorderWidth\r\n const hasFill = fillHeight > 0\r\n if (hasFill || !hasBorder) {\r\n this.context.set('fillStyle', hasFill ? barFillColor : borderColor)\r\n this.context.fillRect(\r\n candleBodyLeftX + barBorderWidth,\r\n candleBodyHigh + barBorderWidth,\r\n barFillWidth,\r\n hasFill ? fillHeight : WICK_WIDTH\r\n )\r\n }\r\n }\r\n },\r\n })\r\n translate.undo()\r\n }\r\n\r\n toString() {\r\n return `Candle stick ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default CandleStick\r\n","import { ChartConfigChartPaneElement, RendererChartBarProps, RequireByKey } from '../../types/shared'\r\nimport { ChartElementType } from '../constants/common'\r\nimport CandleStick from './candle_stick'\r\n\r\nclass HollowCandleStick extends CandleStick {\r\n static type = ChartElementType.HollowCandleStick\r\n static label = 'Hollow Candle'\r\n static iconName = 'candleBarHollow'\r\n\r\n static getNumOfBarsBuffer(element: RequireByKey) {\r\n return Math.max(1, super.getNumOfBarsBuffer(element))\r\n }\r\n\r\n getRenderChartBarProps({ index, chartSettingsColors }: RendererChartBarProps) {\r\n const open = this.data.open[index]\r\n const close = this.data.close[index]\r\n const isHollow = close > open\r\n const generalTrendColor =\r\n close > this.data.close[index - 1] ? chartSettingsColors.ohlcTrendUp : chartSettingsColors.ohlcTrendDown\r\n const trendColor = index === 0 ? chartSettingsColors.zeroChange : generalTrendColor\r\n return {\r\n open,\r\n close,\r\n high: this.data.high[index],\r\n low: this.data.low[index],\r\n // hollow candles have transparend bodies that's why rgba is here\r\n barFillColor: isHollow ? 'rgba(0, 0, 0, 0)' : trendColor,\r\n borderColor: trendColor,\r\n wickColor: trendColor,\r\n }\r\n }\r\n\r\n toString() {\r\n return `Hollow Candle stick ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default HollowCandleStick\r\n","import { ChartConfigChartPaneElement, RendererChartBarProps, RequireByKey } from '../../types/shared'\r\nimport { ChartElementType, ScaleType } from '../constants/common'\r\nimport Quote from '../models/quote'\r\nimport { getTickerChangeFromCloseValues } from '../utils/chart'\r\nimport CandleStick from './candle_stick'\r\n\r\ntype OhlcKeys = 'high' | 'low' | 'open' | 'close'\r\n\r\nclass HeikinAshi extends CandleStick {\r\n static type = ChartElementType.HeikinAshi\r\n static label = 'Heikin Ashi'\r\n static iconName = 'candleBarHeikinAshi'\r\n\r\n static getNumOfBarsBuffer(element: RequireByKey) {\r\n return Math.max(1, super.getNumOfBarsBuffer(element))\r\n }\r\n\r\n getRenderChartBarProps = ({ index, chartSettingsColors, hasFillAndBorder }: RendererChartBarProps) => {\r\n const haData = this.data.getHeikinAshiData()\r\n\r\n const open = haData.open[index]\r\n const close = haData.close[index]\r\n const trendColor = close < open ? chartSettingsColors.trendDown : chartSettingsColors.trendUp\r\n const wickColor = close < open ? chartSettingsColors.wickDown : chartSettingsColors.wickUp\r\n return {\r\n open,\r\n close,\r\n high: Math.max(this.data.high[index], open, close),\r\n low: Math.min(open, close, this.data.low[index]),\r\n barFillColor: trendColor,\r\n borderColor: close < open ? chartSettingsColors.borderDown : chartSettingsColors.borderUp,\r\n wickColor: hasFillAndBorder ? wickColor : trendColor,\r\n }\r\n }\r\n\r\n getLastValues = () => {\r\n const Colors = this.getCandleLikeChartsRenderingColors()\r\n const {\r\n open: lastOpen,\r\n close: lastClose,\r\n high: lastHigh,\r\n low: lastLow,\r\n } = this.getRenderChartBarProps({\r\n index: this.data.date.length - 1,\r\n chartSettingsColors: Colors,\r\n })\r\n\r\n return { lastOpen, lastClose, lastHigh, lastLow }\r\n }\r\n\r\n getRoundedLastData() {\r\n const lastOhlc = this.getLastValues()\r\n return {\r\n open: this.roundOhlc(lastOhlc.lastOpen),\r\n high: this.roundOhlc(lastOhlc.lastHigh),\r\n low: this.roundOhlc(lastOhlc.lastLow),\r\n close: this.roundOhlc(lastOhlc.lastClose),\r\n }\r\n }\r\n\r\n renderYAxis = (context: CanvasRenderingContext2D) => {\r\n const { lastClose } = this.getLastValues()\r\n super.renderYAxis(context, { lastClose }, false)\r\n\r\n const { firstVisibleClose } = this.getMinMax()\r\n if (this.model.scale === ScaleType.Percentage && !firstVisibleClose) return\r\n\r\n const originalLatestClose = this.data.close[this.data.close.length - 1]\r\n const heikinLatestCloseLabel = this.getYAxisLastCloseLabel({ lastClose, firstVisibleClose })\r\n const originalLatestCloseLabel = this.getYAxisLastCloseLabel({ lastClose: originalLatestClose, firstVisibleClose })\r\n\r\n this.renderYAxisLabel({ context, yCoordinate: Math.round(this.fy(lastClose)), label: heikinLatestCloseLabel })\r\n\r\n if (heikinLatestCloseLabel === originalLatestCloseLabel) return\r\n\r\n this.renderYAxisLabel({\r\n context,\r\n yCoordinate: this.getYAxisSecondaryLabelYCoordinate({\r\n mainLabelValue: lastClose,\r\n secondaryLabelValue: originalLatestClose,\r\n }),\r\n label: originalLatestCloseLabel,\r\n background: this.getSecondaryLabelBackgroundColor(),\r\n })\r\n }\r\n\r\n getDataByCrossIndex(crossIndex: number, key: keyof Quote, shouldReturnRoundedString = true) {\r\n const Colors = this.getCandleLikeChartsRenderingColors()\r\n const barIndex = this.data.getDataIndexByBarIndex(crossIndex)\r\n if (barIndex > -1) {\r\n let value = null\r\n if (['high', 'low', 'open', 'close'].includes(key)) {\r\n const data = this.getRenderChartBarProps({ index: barIndex, chartSettingsColors: Colors })\r\n value = data[key as OhlcKeys]\r\n }\r\n value = value === null ? this.data.getDataByBarIndex(key, crossIndex) : value\r\n if (value !== null) {\r\n return shouldReturnRoundedString ? this.roundOhlc(value) : `${value}`\r\n }\r\n }\r\n }\r\n\r\n getCrossIndexChange(crossIndex: number) {\r\n const barIndex = this.data.getDataIndexByBarIndex(crossIndex)\r\n const haData = this.data.getHeikinAshiData()\r\n const crossClose = haData.close[barIndex] ?? null\r\n const previousClose = haData.close[barIndex - 1] ?? null\r\n if (crossClose !== null && previousClose !== null) {\r\n return getTickerChangeFromCloseValues({ data: this.data, anchorClose: crossClose, prevClose: previousClose })\r\n }\r\n\r\n return null\r\n }\r\n\r\n toString() {\r\n return `HA Candle stick ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default HeikinAshi\r\n","import { ChartElementType } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Chart from './base_chart'\r\n\r\nclass LineChart extends Chart {\r\n static type = ChartElementType.LineChart\r\n static label = 'Line'\r\n static iconName = 'lineChartType'\r\n\r\n renderChart() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n let first: number | undefined, last: number | undefined\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width + 0.5,\r\n yOffset: ChartSettings.top.height + 0.5,\r\n })\r\n translate.do()\r\n this.context.beginPath()\r\n this.context.set('lineWidth', 1)\r\n this.context.set('strokeStyle', Colors.line)\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.paneModel,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n const y = Math.round(this.fy(this.data.close[i]))\r\n this.context.lineTo(x, y)\r\n last = x\r\n if (first === undefined) {\r\n first = x\r\n }\r\n },\r\n })\r\n if (first !== undefined && last !== undefined) {\r\n this.context.stroke()\r\n this.context.set('fillStyle', Colors.background)\r\n this.context.lineTo(last!, this.height)\r\n this.context.lineTo(first!, this.height)\r\n this.context.fill()\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n toString() {\r\n return `Line chart ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default LineChart\r\n","import Text from '../canvas/text'\r\nimport { ChartElementType, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport { isRedesignEnabled } from '../utils'\r\nimport Chart, { BaseChartAttrs } from './base_chart'\r\n\r\nconst interval = 3\r\nconst domainMin = -1\r\nconst domainMax = 1\r\nconst red = 'rgba(200, 0, 0, 0.392)'\r\nconst redLine = 'rgb(120, 0, 0)'\r\nconst green = 'rgba(0, 180, 0, 0.392)'\r\nconst greenLine = 'rgb(0, 100, 0)'\r\n\r\nclass MarketSentiment extends Chart {\r\n static type = ChartElementType.MarketSentiment\r\n\r\n static initClass() {\r\n Object.defineProperty(this.prototype, 'width', {\r\n get() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n return this.model.width - MarketSentimentSettings.left.width - MarketSentimentSettings.right.width\r\n },\r\n })\r\n\r\n Object.defineProperty(this.prototype, 'height', {\r\n get() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n return this.paneModel.height - MarketSentimentSettings.top.height - MarketSentimentSettings.bottom.height\r\n },\r\n })\r\n }\r\n\r\n declare _data: number[]\r\n declare _dataLastIndex: number | null\r\n\r\n constructor(values: Partial, model: Pane) {\r\n super(values, model)\r\n this.renderText = this.renderText.bind(this)\r\n this.renderOverlaysLabels = this.renderOverlaysLabels.bind(this)\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n this.setupCache = this.setupCache.bind(this)\r\n }\r\n\r\n setupCache() {\r\n super.setupCache()\r\n if (!this.data) {\r\n return\r\n }\r\n const arr: number[] = []\r\n this.data.close.forEach((sum, i) => {\r\n arr[i] = sum / this.data.volume[i]\r\n })\r\n this._data = arr\r\n\r\n let lastIndex = null\r\n for (let i = this.data.volume.length - 1; i >= 0; i--) {\r\n if (this.data.volume[i] !== 0) {\r\n lastIndex = i\r\n break\r\n }\r\n }\r\n this._dataLastIndex =\r\n lastIndex === null\r\n ? null\r\n : Math.min(lastIndex, Math.round((this.data.drawMinutesPerDay - this.data.marketStartMinutes) / interval))\r\n }\r\n\r\n renderChart() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + MarketSentimentSettings.left.width + 0.5,\r\n yOffset: MarketSentimentSettings.top.height + 0.5,\r\n })\r\n translate.do()\r\n this.renderLineBullBear(this.context, this._data, 0, 0, 0)\r\n translate.undo()\r\n }\r\n\r\n renderLineBullBear(\r\n context: CanvasRenderingContext2D,\r\n array: number[],\r\n from: number,\r\n oversold: number,\r\n overbought: number\r\n ) {\r\n if (this._dataLastIndex === null) {\r\n return\r\n }\r\n const isRedesign = isRedesignEnabled()\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n\r\n const domain = [domainMax, domainMin]\r\n\r\n context.save()\r\n context.beginPath()\r\n context.rect(\r\n -this.leftOffset,\r\n this.fy(domain[1]),\r\n this.fx(this._dataLastIndex),\r\n Math.round(this.fy(oversold) - this.fy(domain[1])) - 0.5\r\n )\r\n context.clip()\r\n context.set('fillStyle', red)\r\n context.set('strokeStyle', isRedesign ? Colors.marketDown : redLine)\r\n context.beginPath()\r\n context.moveTo(this.fx(0), Math.round(this.fy(domain[0])))\r\n for (let i = from; i < this.data.close.length; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(array[i])))\r\n }\r\n context.lineTo(this.fx(this.data.close.length - 1), Math.round(this.fy(domain[0])))\r\n context.fill()\r\n context.stroke()\r\n context.restore()\r\n\r\n context.save()\r\n context.beginPath()\r\n context.rect(\r\n -this.leftOffset,\r\n this.fy(domain[0]),\r\n this.fx(this._dataLastIndex),\r\n Math.round(this.fy(overbought)) - 0.5\r\n )\r\n context.clip()\r\n context.set('fillStyle', green)\r\n context.set('strokeStyle', isRedesign ? Colors.marketUp : greenLine)\r\n context.beginPath()\r\n context.moveTo(this.fx(0), Math.round(this.fy(domain[1])))\r\n for (let i = from; i < this.data.close.length; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(array[i])))\r\n }\r\n context.lineTo(this.fx(this.data.close.length - 1), Math.round(this.fy(domain[1])))\r\n context.fill()\r\n context.stroke()\r\n context.restore()\r\n }\r\n\r\n renderXAxis() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n const { Colors } = MarketSentimentSettings.general\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + MarketSentimentSettings.left.width,\r\n yOffset: MarketSentimentSettings.top.height,\r\n })\r\n translate.do()\r\n\r\n const xLine = this.getXLine()\r\n const text = new Text(\r\n {\r\n y: this.height + 12,\r\n font: { size: 7 },\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.bottom,\r\n textAlign: TextAlign.center,\r\n },\r\n this.paneModel\r\n )\r\n let x\r\n\r\n x = this.fx(0)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10) + 2 /* remove overflow */\r\n text.set({ text: '10AM', x }).render(this.context)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 20)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 40)\r\n text.set({ text: '12PM', x }).render(this.context)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 60)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 80)\r\n text.set({ text: '2PM', x }).render(this.context)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 100)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 120 - 1)\r\n text.set({ text: '4PM', x }).render(this.context)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n translate.undo()\r\n }\r\n\r\n renderText() {}\r\n\r\n renderCrossText() {}\r\n\r\n renderOverlaysLabels() {}\r\n\r\n _compute() {\r\n return { min: domainMin, max: domainMax }\r\n }\r\n\r\n computeVisibleMinMax() {\r\n return this._compute()\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n const { MarketSentimentSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const isRedesign = isRedesignEnabled()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: MarketSentimentSettings.left.width,\r\n yOffset: MarketSentimentSettings.top.height,\r\n })\r\n translate.do()\r\n\r\n const yLine = this.getYLine()\r\n for (const tick of [domainMin, 0, domainMax]) {\r\n const y = Math.round(this.fy(tick))\r\n yLine.set({ y1: y, y2: y }).render(context)\r\n }\r\n\r\n const text = new Text(\r\n {\r\n x: this.width + 27,\r\n font: { size: 8 },\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.right,\r\n },\r\n this.paneModel\r\n )\r\n\r\n const fillUp = isRedesign ? Colors.marketUp : greenLine\r\n const fillDown = isRedesign ? Colors.marketDown : redLine\r\n const last = this._data[this._dataLastIndex!]\r\n const percent = this._dataLastIndex !== null ? Math.floor(last * 50 + 50) : 50\r\n text.set({ y: this.fy(0) - 5, fillStyle: fillUp, text: `${percent}%` }).render(context)\r\n text.set({ y: this.fy(0) + 7, fillStyle: fillDown, text: `${100 - percent}%` }).render(context)\r\n\r\n translate.undo()\r\n }\r\n\r\n clip() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n this.context.beginPath()\r\n this.context.rect(MarketSentimentSettings.left.width, MarketSentimentSettings.top.height, this.width, this.height)\r\n this.context.clip()\r\n }\r\n\r\n getMinMax() {\r\n return this._compute()\r\n }\r\n\r\n renderVolumeAxis() {}\r\n\r\n renderVolume() {}\r\n\r\n toString() {\r\n return `Market sentiment chart`\r\n }\r\n}\r\nMarketSentiment.initClass()\r\n\r\nexport default MarketSentiment\r\n","import { ObjectHash } from '../../types/shared'\r\nimport Text from '../canvas/text'\r\nimport { ChartElementType, FONT_SIZE, LINE_HEIGHT, PADDING, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport utils from '../utils'\r\nimport Chart, { BaseChartAttrs } from './base_chart'\r\n\r\ninterface MultiLineChartAttrs extends BaseChartAttrs {\r\n tickers: string[]\r\n label?: string\r\n min?: number\r\n max?: number\r\n}\r\n\r\nconst months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\r\n\r\nclass MultiLineChart extends Chart {\r\n static type = ChartElementType.MultiLineChart\r\n tickersDimensions: number[] = []\r\n\r\n constructor(values: Partial, model: Pane) {\r\n super(values, model)\r\n this.renderText = this.renderText.bind(this)\r\n }\r\n\r\n renderChart() {\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width + 0.5,\r\n yOffset: ChartSettings.top.height + 0.5,\r\n })\r\n translate.do()\r\n\r\n this.context.set('lineWidth', 1)\r\n\r\n const quotes: ObjectHash = {}\r\n for (const quote of this.getQuotes()) {\r\n quotes[quote.ticker] = quote\r\n }\r\n\r\n for (let index = this.attrs.tickers.length - 1; index >= 0; index--) {\r\n const ticker = this.attrs.tickers[index]\r\n const quote = quotes[ticker]\r\n this.context.set('strokeStyle', ColorsSettings[index % ColorsSettings.length])\r\n this.context.beginPath()\r\n for (let i = 0, end = quote.close.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n const x = this.fx(i)\r\n if (x + this.leftOffset < -10 || x + this.leftOffset > this.model.width + 10) {\r\n // margin?\r\n continue\r\n }\r\n const y = Math.round(this.fy(quote.close[i]))\r\n this.context.lineTo(x, y)\r\n }\r\n this.context.stroke()\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n renderText(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const text = this.attrs.label || ''\r\n const y = (this.height - 4) / 2\r\n new Text(\r\n {\r\n text,\r\n x: 28,\r\n y: ChartSettings.top.height + y,\r\n angle: -90,\r\n font: { size: 10, weight: '900', family: 'Lato, sans-serif' },\r\n fillStyle: Colors.textSecondary,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.alphabetic,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n return this.renderCrossText(context, this.data.barToDataIndex.length - 1)\r\n }\r\n\r\n renderCrossText(context: CanvasRenderingContext2D, crossIndex: number) {\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const maxTickerLength = utils.max(this.attrs.tickers.map((t) => t.length))\r\n\r\n const date = utils.dateFromUnixTimestamp(this.data.getDataByBarIndex('date', crossIndex) ?? 0)\r\n const month = date.getMonth() // 20141126\r\n const year = date.getFullYear()\r\n const day = date.getDate()\r\n const isLastDate = crossIndex === this.data.close.length - 1\r\n\r\n new Text(\r\n {\r\n text: `${months[month]} ${day} ${year} `,\r\n x: ChartSettings.left.width + (maxTickerLength > 15 ? 200 : 132),\r\n y: 30,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n background: Colors.canvasFill,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n\r\n const quotes: ObjectHash = {}\r\n for (const quote of this.getQuotes()) {\r\n quotes[quote.ticker] = quote\r\n }\r\n for (let index = 0; index < this.attrs.tickers.length; index++) {\r\n const y = PADDING.S + (PADDING.S + LINE_HEIGHT.M) * index\r\n const ticker = this.attrs.tickers[index]\r\n const closeValue = quotes[ticker].close[crossIndex]\r\n const text = new Text(\r\n {\r\n text: `${ticker} ${typeof closeValue === 'number' ? closeValue.toFixed(2) : NaN} `,\r\n x: ChartSettings.left.width,\r\n y,\r\n font: { size: FONT_SIZE.M, style: 'bold' },\r\n lineHeight: LINE_HEIGHT.M,\r\n fillStyle: ColorsSettings[index % ColorsSettings.length],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.paneModel\r\n )\r\n\r\n if (!this.tickersDimensions[index] && isLastDate) {\r\n this.tickersDimensions[index] = text.measure(context)\r\n }\r\n\r\n if (this.tickersDimensions[index]) {\r\n context.set('fillStyle', Colors.canvasFill)\r\n context.fillRect(\r\n ChartSettings.left.width - PADDING.XXXS,\r\n y - PADDING.XXXS,\r\n PADDING.XXXS + this.tickersDimensions[index] + PADDING.XXXS,\r\n PADDING.XXXS + FONT_SIZE.M + PADDING.XXXS\r\n )\r\n }\r\n\r\n text.render(context)\r\n }\r\n }\r\n\r\n computeVisibleMinMax(...arrays: Array) {\r\n let min = Number.MAX_VALUE\r\n let max = Number.MIN_VALUE\r\n\r\n const { leftOffset } = this.model\r\n for (const arr of arrays) {\r\n for (let i = 0, end = arr.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n const center = this.fx(i)\r\n if (center + leftOffset < 0 || center + leftOffset > this.width) {\r\n // margin?\r\n continue\r\n }\r\n\r\n if (min > arr[i]) {\r\n min = arr[i]\r\n }\r\n if (max < arr[i]) {\r\n max = arr[i]\r\n }\r\n }\r\n }\r\n\r\n return { min, max }\r\n }\r\n\r\n getMinMax() {\r\n const quotes = this.getQuotes()\r\n let { min, max } = this.computeVisibleMinMax(...quotes.map((q) => q.close))\r\n if (typeof this.attrs.min !== 'undefined') {\r\n min = this.attrs.min\r\n }\r\n if (typeof this.attrs.max !== 'undefined') {\r\n max = this.attrs.max\r\n }\r\n return { min, max }\r\n }\r\n\r\n renderVolumeAxis() {}\r\n\r\n renderVolume() {}\r\n\r\n getQuotes() {\r\n return Quote.select(\r\n (q: Quote) =>\r\n this.attrs.tickers.includes(q.ticker) &&\r\n q.timeframe === this.data?.timeframe &&\r\n this.model.chart_layout().isIdeaId(q.ideaID)\r\n )\r\n }\r\n\r\n toString() {\r\n return `Line chart ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default MultiLineChart\r\n","import { ChartElementType } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport { getBarWithoutMarginWidth } from '../utils/chart'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Chart from './base_chart'\r\n\r\nclass OHLCChart extends Chart {\r\n static type = ChartElementType.OhlcChart\r\n static label = 'OHLC'\r\n static iconName = 'ohlcChartType'\r\n\r\n renderChart() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n\r\n const barWithoutMarginWidth = getBarWithoutMarginWidth(this.model)\r\n\r\n let lineWidth = 1\r\n if (barWithoutMarginWidth >= 40) {\r\n lineWidth = 4\r\n } else if (barWithoutMarginWidth >= 30) {\r\n lineWidth = 3\r\n } else if (barWithoutMarginWidth >= 15) {\r\n lineWidth = 2\r\n }\r\n const lineThickness = lineWidth / 2\r\n const handleLengthFromWick = Math.round(barWithoutMarginWidth / 2 - lineThickness)\r\n const lineOffset = lineWidth % 2 === 0 ? 0 : 0.5\r\n this.context.set('lineWidth', lineWidth)\r\n\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.paneModel,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n const barX = ~~(x - 1) + lineOffset // move 1px to left so cursor don't cover bar of ohlc-chart & round for pixel perfect render on zoom\r\n\r\n this.context.beginPath()\r\n this.context.set(\r\n 'strokeStyle',\r\n this.data.close[i] < this.data.open[i] ? Colors.ohlcTrendDown : Colors.ohlcTrendUp\r\n )\r\n\r\n this.context.moveTo(barX, Math.round(this.fy(this.data.high[i])))\r\n this.context.lineTo(barX, Math.round(this.fy(this.data.low[i])))\r\n\r\n if (handleLengthFromWick >= 1) {\r\n const open = Math.round(this.fy(this.data.open[i]))\r\n this.context.moveTo(barX + lineThickness, open + lineOffset) // move to right edge of wick\r\n this.context.lineTo(barX - lineThickness - handleLengthFromWick, open + lineOffset) // draw line to the left\r\n\r\n const close = Math.round(this.fy(this.data.close[i]))\r\n this.context.moveTo(barX - lineThickness, close + lineOffset) // move to left edge of wick\r\n this.context.lineTo(barX + lineThickness + handleLengthFromWick, close + lineOffset) // draw line to the right\r\n }\r\n\r\n this.context.stroke()\r\n },\r\n })\r\n\r\n translate.undo()\r\n }\r\n\r\n toString() {\r\n return `OHLC ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default OHLCChart\r\n","import { ObjectHash } from '../../types/shared'\r\nimport Text from '../canvas/text'\r\nimport { ChartElementType, FONT_SIZE, MARGIN, OFFSET, PADDING, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport utils from '../utils'\r\nimport Chart, { BaseChartAttrs } from './base_chart'\r\n\r\nconst months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\r\nconst NO_VALUE = ' - '\r\n\r\ninterface PerfChartAttrs extends BaseChartAttrs {\r\n tickers: string[]\r\n label?: string\r\n fromDate: string\r\n toDate: string\r\n min?: number\r\n max?: number\r\n}\r\n\r\nclass PerfChart extends Chart {\r\n static type = ChartElementType.PerfChart\r\n\r\n overlayLabelWidth: ObjectHash\r\n perf: ObjectHash> = {}\r\n dates: number[] = []\r\n\r\n constructor(values: Partial, model: Pane) {\r\n super(values, model)\r\n this.renderText = this.renderText.bind(this)\r\n this.renderOverlaysLabels = this.renderOverlaysLabels.bind(this)\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n this.overlayLabelWidth = {}\r\n }\r\n\r\n fx = (i: number) => this.paneModel.scale.x(i)\r\n\r\n getCompleteChartNumOfBars() {\r\n return this.dates.length\r\n }\r\n\r\n renderChart() {\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width + 0.5,\r\n yOffset: ChartSettings.top.height + 0.5,\r\n })\r\n translate.do()\r\n\r\n this.context.beginPath()\r\n this.context.set('lineWidth', 1)\r\n for (let index = 0; index < this.attrs.tickers.length; index++) {\r\n const ticker = this.attrs.tickers[index]\r\n if ((this.perf[ticker] != null ? this.perf[ticker].length : 0) > 0) {\r\n this.context.set('strokeStyle', ColorsSettings[index % ColorsSettings.length])\r\n this.context.beginPath()\r\n // We don't need to calculate first/last visible bars because the data is already cropped\r\n for (let i = 0; i < this.perf[ticker].length; i++) {\r\n const value = this.perf[ticker][i]\r\n if (value !== null && Number.isFinite(value)) {\r\n this.context.lineTo(this.fx(i), Math.round(this.fy(value)))\r\n }\r\n }\r\n this.context.stroke()\r\n }\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n renderText(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const period = (() => {\r\n switch (this.model.quote().timeframe) {\r\n case 'd':\r\n return 'DAILY'\r\n case 'w':\r\n return 'WEEKLY'\r\n case 'm':\r\n return 'MONTHLY'\r\n default:\r\n return\r\n }\r\n })()\r\n const y = (this.height - 4) / 2\r\n new Text(\r\n {\r\n text: period,\r\n x: 28,\r\n y: ChartSettings.top.height + y,\r\n angle: -90,\r\n font: { size: 10, weight: '900', family: 'Lato, sans-serif' },\r\n fillStyle: Colors.textSecondary,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.alphabetic,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n\r\n renderCrossText(context: CanvasRenderingContext2D, crossIndex: number) {\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const date = utils.dateFromUnixTimestamp(this.dates[crossIndex] ?? 0)\r\n let dateString = ''\r\n const month = date.getMonth() // 20141126\r\n const year = date.getFullYear()\r\n const day = date.getDate()\r\n switch (this.data.timeframe) {\r\n case 'd':\r\n case 'w':\r\n dateString = `${months[month]} ${day}`\r\n break\r\n case 'm':\r\n dateString = `${months[month]} ${year}`\r\n break\r\n default:\r\n return\r\n }\r\n\r\n let shouldRenderDate = false\r\n for (let index = 0; index < this.attrs.tickers.length; index++) {\r\n const ticker = this.attrs.tickers[index]\r\n const tickerData = this.perf[ticker]\r\n if (tickerData?.length) {\r\n context.fillStyle = Colors.canvasFill\r\n context.fillRect(\r\n ChartSettings.left.width - PADDING.XXXS,\r\n OFFSET.M + (FONT_SIZE.M + MARGIN.XS) * index - PADDING.XXXS,\r\n PADDING.XXXS + this.overlayLabelWidth[ticker] + PADDING.XXXS,\r\n PADDING.XXXS + FONT_SIZE.M + PADDING.XXXS\r\n )\r\n const value = tickerData[crossIndex] ?? null\r\n const percentageText = value !== null ? `${value.toFixed(2)}%` : NO_VALUE\r\n shouldRenderDate = shouldRenderDate || value !== null\r\n new Text(\r\n {\r\n text: `${ticker} ${percentageText}`,\r\n x: ChartSettings.left.width,\r\n y: OFFSET.M + (FONT_SIZE.M + MARGIN.XS) * index,\r\n font: { size: FONT_SIZE.M, style: 'bold' },\r\n fillStyle: ColorsSettings[index % ColorsSettings.length],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n }\r\n\r\n if (shouldRenderDate) {\r\n new Text(\r\n {\r\n text: `${dateString} `,\r\n x: ChartSettings.left.width + 132,\r\n y: 30,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n background: Colors.canvasFill,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n }\r\n\r\n renderOverlaysLabels(context: CanvasRenderingContext2D) {\r\n super.renderOverlaysLabels(context)\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n\r\n for (let index = 0; index < this.attrs.tickers.length; index++) {\r\n const ticker = this.attrs.tickers[index]\r\n const tickerData = this.perf[ticker]\r\n if (tickerData?.length) {\r\n const lastCrossIndex = this.perf[ticker].findLastIndex((value) => value !== null)\r\n const value = tickerData[lastCrossIndex] ?? null\r\n const percentageText = value !== null ? `${value.toFixed(2)}%` : NO_VALUE\r\n\r\n const text = new Text(\r\n {\r\n text: `${ticker} ${percentageText}`,\r\n x: ChartSettings.left.width,\r\n y: OFFSET.M + (FONT_SIZE.M + MARGIN.XS) * index,\r\n font: { size: FONT_SIZE.M, style: 'bold' },\r\n fillStyle: ColorsSettings[index % ColorsSettings.length],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.paneModel\r\n )\r\n this.overlayLabelWidth = { ...this.overlayLabelWidth, [ticker]: text.measure(context) }\r\n text.render(context)\r\n }\r\n }\r\n }\r\n\r\n _compute() {\r\n let min = Number.MAX_VALUE\r\n let max = Number.MIN_VALUE\r\n this.perf = {}\r\n const quotes = this.getQuotes()\r\n\r\n const fromDate = new Date(this.attrs.fromDate + ' 00:00')\r\n const toDate = new Date(this.attrs.toDate + ' 23:59')\r\n this.dates = []\r\n for (const quote of quotes) {\r\n for (let i = 0; i < quote.date.length; i++) {\r\n const timestampe = quote.date[i]\r\n const date = utils.dateFromUnixTimestamp(timestampe)\r\n if (fromDate <= date && date <= toDate && this.dates.indexOf(timestampe) === -1) {\r\n this.dates.push(timestampe)\r\n }\r\n }\r\n }\r\n\r\n this.dates.sort((a, b) => a - b)\r\n\r\n for (const quote of quotes) {\r\n const ticker = quote.ticker\r\n this.perf[ticker] = []\r\n\r\n const dateToIndex = quote.getDateToIndex()\r\n let first = null\r\n let lastValue = null\r\n let dataIndex = -1\r\n for (let i = 0; i < this.dates.length; i++) {\r\n const timestamp = this.dates[i]\r\n dataIndex = dateToIndex[timestamp]\r\n\r\n if (typeof dataIndex === 'number') {\r\n first = first === null ? quote.close[dataIndex] : first\r\n const value = (quote.close[dataIndex] * 100) / (first ?? 0) - 100\r\n lastValue = Number.isFinite(value) ? value : null\r\n }\r\n\r\n this.perf[ticker][i] = lastValue\r\n\r\n if (lastValue !== null && min > lastValue) {\r\n min = lastValue\r\n }\r\n if (lastValue !== null && max < lastValue) {\r\n max = lastValue\r\n }\r\n }\r\n }\r\n\r\n return { min, max }\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const translate = getTranslate({\r\n context,\r\n xOffset: ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n const ticks = this.paneModel.scale.y.ticks(10)\r\n const yLine = this.getYLine()\r\n const text = new Text(\r\n {\r\n x: this.width + 8,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.paneModel\r\n )\r\n for (const tick of ticks) {\r\n const y = Math.round(this.fy(tick))\r\n yLine.set({ y1: y, y2: y }).render(context)\r\n text.set({ text: tick.toFixed(2), y }).render(context)\r\n }\r\n translate.undo()\r\n }\r\n\r\n renderXAxis() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n const text = new Text(\r\n {\r\n y: this.height + 18,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.bottom,\r\n textAlign: TextAlign.center,\r\n },\r\n this.paneModel\r\n )\r\n const textWidth = text.set({ text: '2020' }).measure(this.context)\r\n\r\n let date = new Date(this.dates[0] * 1000)\r\n let lastMonth = date.getMonth() + '-' + date.getFullYear()\r\n\r\n let monthsInData = 0\r\n this.dates.forEach((d, index) => {\r\n if (index < 1) {\r\n return\r\n }\r\n\r\n const date = new Date(d * 1000)\r\n const month = date.getMonth() + '-' + date.getFullYear()\r\n if (month !== lastMonth) {\r\n monthsInData++\r\n }\r\n lastMonth = month\r\n })\r\n\r\n const availableTickSpots = ~~(this.width / textWidth)\r\n const monthsToAvail = monthsInData / availableTickSpots\r\n let renderMonth\r\n if (monthsToAvail <= 1) {\r\n renderMonth = () => true\r\n } else if (monthsToAvail <= 2) {\r\n renderMonth = (x: number) => x % 2 === 0\r\n } else if (monthsToAvail <= 3) {\r\n renderMonth = (x: number) => x % 3 === 0\r\n } else if (monthsToAvail <= 4) {\r\n renderMonth = (x: number) => x % 4 === 0\r\n } else if (monthsToAvail <= 6) {\r\n renderMonth = (x: number) => x % 6 === 0\r\n } else {\r\n renderMonth = (x: number) => x === 0\r\n }\r\n\r\n date = new Date(this.dates[0] * 1000)\r\n lastMonth = date.getMonth() + '-' + date.getFullYear()\r\n\r\n const xLine = this.getXLine()\r\n\r\n for (let i = 0; i < this.dates.length; i++) {\r\n date = new Date(this.dates[i] * 1000)\r\n const month = date.getMonth() + '-' + date.getFullYear()\r\n if (month !== lastMonth) {\r\n lastMonth = month\r\n const x = this.fx(i)\r\n if (x + this.leftOffset < -15 || x + this.leftOffset > this.width + 15) {\r\n // margin?\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n if (!renderMonth(date.getMonth())) {\r\n continue\r\n }\r\n\r\n text\r\n .set({\r\n text: date.getMonth() === 0 ? date.getFullYear().toString() : months[date.getMonth()],\r\n x: x,\r\n })\r\n .render(this.context)\r\n }\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n getMinMax() {\r\n return this._compute()\r\n }\r\n\r\n renderVolumeAxis() {}\r\n\r\n renderVolume() {}\r\n\r\n getQuotes() {\r\n return Quote.select(\r\n (q: Quote) =>\r\n this.attrs.tickers.includes(q.ticker) &&\r\n q.timeframe === this.data?.timeframe &&\r\n this.model.chart_layout().isIdeaId(q.ideaID)\r\n )\r\n }\r\n\r\n toString() {\r\n return `Perf chart ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default PerfChart\r\n","import { ChartElementType } from '../constants/common'\r\nimport candleStick from './candle_stick'\r\nimport hollowCandleStick from './candle_stick_hollow'\r\nimport heikinAshi from './heikin_ashi'\r\nimport lineChart from './line_chart'\r\nimport marketSentiment from './market_sentiment'\r\nimport multiLineCharts from './multi_line_chart'\r\nimport ohlcChart from './ohlc_chart'\r\nimport perfChart from './perf_chart'\r\n\r\nexport const chartsByType = Object.freeze({\r\n [ChartElementType.CandleStick]: candleStick,\r\n [ChartElementType.HeikinAshi]: heikinAshi,\r\n [ChartElementType.HollowCandleStick]: hollowCandleStick,\r\n [ChartElementType.LineChart]: lineChart,\r\n [ChartElementType.MarketSentiment]: marketSentiment,\r\n [ChartElementType.MultiLineChart]: multiLineCharts,\r\n [ChartElementType.OhlcChart]: ohlcChart,\r\n [ChartElementType.PerfChart]: perfChart,\r\n})\r\n","export const FONT_SIZE = {\r\n XXS: 5,\r\n XS: 7,\r\n S: 8,\r\n M: 10,\r\n L: 11,\r\n XXL: 18,\r\n XXXL: 23,\r\n}\r\nexport const LINE_HEIGHT = {\r\n XS: 7,\r\n S: 8,\r\n M: 10,\r\n}\r\nexport const PADDING = {\r\n XXXS: 1,\r\n XXS: 2,\r\n XS: 3,\r\n S: 5,\r\n}\r\nexport const MARGIN = {\r\n XS: 4,\r\n}\r\nexport const CHART_MARGIN = {\r\n S: 15,\r\n M: 30,\r\n L: 35,\r\n XL: 38,\r\n XXL: 48,\r\n}\r\nexport const SETTINGS_HEIGHT = 44\r\nexport const TICKER_TIMEFRAME_CHANGE_HEIGHT = 20\r\nexport const OFFSET = {\r\n XXS: 2,\r\n XS: 4,\r\n S: 6,\r\n M: 8,\r\n XXL: 20,\r\n}\r\nexport const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\r\n\r\nexport enum ChartEditorEnum {\r\n publish = 'publish',\r\n tools = 'tools',\r\n ideas = 'ideas',\r\n settings = 'settings',\r\n timeframe = 'timeframe',\r\n}\r\n\r\nexport enum LayoutType {\r\n '1h1v' = '1h1v',\r\n '1h2v' = '1h2v',\r\n '1h3v' = '1h3v',\r\n '2h1v' = '2h1v',\r\n '2h2v' = '2h2v',\r\n '3h1v' = '3h1v',\r\n '3h2v' = '3h2v',\r\n '1l2r' = '1l2r',\r\n '1t2b' = '1t2b',\r\n}\r\n\r\nexport enum CanvasElementType {\r\n element = 'canvas/element',\r\n arrow = 'canvas/arrow',\r\n brushV1 = 'canvas/brush/brush_v1',\r\n curve = 'canvas/curve',\r\n ellipse = 'canvas/ellipse',\r\n fibonacciRetracements = 'canvas/fibonacci_retracements',\r\n horizontalLine = 'canvas/horizontal_line',\r\n line = 'canvas/line',\r\n measure = 'canvas/measure',\r\n pitchforkV1 = 'canvas/pitchfork/pitchfork_v1',\r\n polygon = 'canvas/polygon',\r\n position = 'canvas/position',\r\n rectangle = 'canvas/rectangle',\r\n rotatedRectangle = 'canvas/rotated_rectangle',\r\n scaledLine = 'canvas/scaled_line',\r\n scaledText = 'canvas/scaled_text',\r\n symbol = 'canvas/symbol',\r\n text = 'canvas/text',\r\n triangle = 'canvas/triangle',\r\n verticalLine = 'canvas/vertical_line',\r\n xabcd = 'canvas/xabcd',\r\n calloutV1 = 'canvas/callout/callout_v1',\r\n elliottWaves = 'canvas/elliott_waves/elliott_waves',\r\n ellipseV1 = 'canvas/ellipse/ellipse_v1',\r\n rotatedRectangleV1 = 'canvas/rotated_rectangle/rotated_rectangle_v1',\r\n}\r\n\r\nexport enum ChartElementType {\r\n CandleStick = 'charts/candle_stick',\r\n HeikinAshi = 'charts/heikin_ashi',\r\n HollowCandleStick = 'charts/candle_stick_hollow',\r\n LineChart = 'charts/line_chart',\r\n OhlcChart = 'charts/ohlc_chart',\r\n MarketSentiment = 'charts/market_sentiment',\r\n MultiLineChart = 'charts/multi_line_chart',\r\n PerfChart = 'charts/perf_chart',\r\n}\r\n\r\nexport enum IndicatorType {\r\n Indicator = 'indicators/indicator',\r\n None = 'indicators/none',\r\n Adx = 'indicators/adx',\r\n Aro = 'indicators/aro',\r\n Aroosc = 'indicators/aroosc',\r\n Atr = 'indicators/atr',\r\n Cci = 'indicators/cci',\r\n Cot = 'indicators/cot',\r\n Fi = 'indicators/fi',\r\n Macd = 'indicators/macd',\r\n Mfi = 'indicators/mfi',\r\n Obv = 'indicators/obv',\r\n Perf = 'indicators/perf',\r\n Rmi = 'indicators/rmi',\r\n Roc = 'indicators/roc',\r\n Rsi = 'indicators/rsi',\r\n Rvol = 'indicators/rvol',\r\n Rwi = 'indicators/rwi',\r\n Stofa = 'indicators/stofa',\r\n Stofu = 'indicators/stofu',\r\n Stosl = 'indicators/stosl',\r\n Trix = 'indicators/trix',\r\n Ult = 'indicators/ult',\r\n Vol = 'indicators/vol',\r\n Wr = 'indicators/wr',\r\n Shrtfl = 'indicators/shrtfl',\r\n Shrtra = 'indicators/shrtra',\r\n}\r\n\r\nexport enum OverlayType {\r\n Overlay = 'overlays/overlay',\r\n None = 'overlays/none',\r\n Bb = 'overlays/bb',\r\n Dch = 'overlays/dch',\r\n Ema = 'overlays/ema',\r\n Ema2 = 'overlays/ema2',\r\n Hilo = 'overlays/hilo',\r\n Hline = 'overlays/hline',\r\n Ic = 'overlays/ic',\r\n Icf = 'overlays/icf',\r\n Kch = 'overlays/kch',\r\n Patterns = 'overlays/patterns',\r\n Pp = 'overlays/pp',\r\n Sar = 'overlays/sar',\r\n Sma = 'overlays/sma',\r\n Sma2 = 'overlays/sma2',\r\n Str = 'overlays/str',\r\n Vp = 'overlays/vp',\r\n Vwap = 'overlays/vwap',\r\n}\r\n\r\nexport enum ChartEventDbType {\r\n Dividends = 'chartEvent/dividends',\r\n Split = 'chartEvent/split',\r\n Earnings = 'chartEvent/earnings',\r\n}\r\n\r\nexport enum ChartEventType {\r\n ChartEvent = 'chartEvent/chartEvent',\r\n Dividends = 'chartEvent/dividends',\r\n Split = 'chartEvent/split',\r\n Earnings = 'chartEvent/earnings',\r\n}\r\n\r\nexport enum ChartEventBadgeType {\r\n Dividends = 'chartEvent/dividends',\r\n Split = 'chartEvent/split',\r\n EarningsPositive = 'chartEvent/earnings',\r\n EarningsNegative = 'chartEvent/earningsNegative',\r\n EarningsNeutral = 'chartEvent/earningsNeutral',\r\n EarningsFuture = 'chartEvent/earningsFuture',\r\n}\r\n\r\nexport const ChartEventLabels: Record = {\r\n [ChartEventBadgeType.Dividends]: 'Dividends',\r\n [ChartEventBadgeType.Split]: 'Split',\r\n [ChartEventBadgeType.EarningsPositive]: 'Earnings & Revenue',\r\n [ChartEventBadgeType.EarningsNegative]: 'Earnings & Revenue',\r\n [ChartEventBadgeType.EarningsNeutral]: 'Earnings & Revenue',\r\n [ChartEventBadgeType.EarningsFuture]: 'Earnings & Revenue',\r\n}\r\n\r\ninterface LayoutRule {\r\n columns: number\r\n rows: number\r\n count: number\r\n gridAreas?: string[]\r\n}\r\n\r\nexport const LAYOUTS: Record = {\r\n '1h1v': { columns: 1, rows: 1, count: 1 },\r\n '1h2v': { columns: 1, rows: 2, count: 2 },\r\n '1h3v': { columns: 1, rows: 3, count: 3 },\r\n '2h1v': { columns: 2, rows: 1, count: 2 },\r\n '2h2v': { columns: 2, rows: 2, count: 4 },\r\n '3h1v': { columns: 3, rows: 1, count: 3 },\r\n '3h2v': { columns: 3, rows: 2, count: 6 },\r\n '1l2r': {\r\n columns: 2,\r\n rows: 2,\r\n count: 3,\r\n gridAreas: ['1 / 1 / 3 / 2', '1 / 2 / 2 / 3', '2 / 2 / 3 / 3'],\r\n },\r\n '1t2b': {\r\n columns: 2,\r\n rows: 2,\r\n count: 3,\r\n gridAreas: ['1 / 1 / 2 / 3', '2 / 1 / 3 / 2', '2 / 2 / 3 / 3'],\r\n },\r\n}\r\n\r\nexport const SORT_DIRECTION = {\r\n ASC: 'ASC',\r\n DESC: 'DESC',\r\n}\r\n\r\nexport const ICON_SIZE = {\r\n L: 32,\r\n}\r\n\r\n// Keep in sync with the copy in Website repo - Website/js/main/constants.ts\r\nexport enum TIMEFRAME {\r\n i1 = 'i1',\r\n i2 = 'i2',\r\n i3 = 'i3',\r\n i5 = 'i5',\r\n i10 = 'i10',\r\n i15 = 'i15',\r\n i30 = 'i30',\r\n h = 'h',\r\n h2 = 'h2',\r\n h4 = 'h4',\r\n d = 'd',\r\n w = 'w',\r\n m = 'm',\r\n}\r\n\r\nexport type TimeframeAndIntradayType = TIMEFRAME | 'intraday'\r\n\r\nexport const TIMEFRAMES_WITH_PRE_MARKET = [TIMEFRAME.i1, TIMEFRAME.i2, TIMEFRAME.i3, TIMEFRAME.i5]\r\n\r\nexport const IntradayTimeframeInterval = {\r\n [TIMEFRAME.i1]: 1,\r\n [TIMEFRAME.i2]: 2,\r\n [TIMEFRAME.i3]: 3,\r\n [TIMEFRAME.i5]: 5,\r\n [TIMEFRAME.i10]: 10,\r\n [TIMEFRAME.i15]: 15,\r\n [TIMEFRAME.i30]: 30,\r\n [TIMEFRAME.h]: 60,\r\n [TIMEFRAME.h2]: 120,\r\n [TIMEFRAME.h4]: 240,\r\n}\r\n\r\nexport const TimeframeLabelShort = {\r\n [TIMEFRAME.i1]: '1M',\r\n [TIMEFRAME.i2]: '2M',\r\n [TIMEFRAME.i3]: '3M',\r\n [TIMEFRAME.i5]: '5M',\r\n [TIMEFRAME.i10]: '10M',\r\n [TIMEFRAME.i15]: '15M',\r\n [TIMEFRAME.i30]: '30M',\r\n [TIMEFRAME.h]: '1H',\r\n [TIMEFRAME.h2]: '2H',\r\n [TIMEFRAME.h4]: '4H',\r\n [TIMEFRAME.d]: 'D',\r\n [TIMEFRAME.w]: 'W',\r\n [TIMEFRAME.m]: 'M',\r\n}\r\n\r\nexport enum DateRangeType {\r\n d1 = 'd1',\r\n d5 = 'd5',\r\n m1 = 'm1',\r\n m3 = 'm3',\r\n m6 = 'm6',\r\n ytd = 'ytd',\r\n y1 = 'y1',\r\n y2 = 'y2',\r\n y5 = 'y5',\r\n max = 'max',\r\n}\r\n\r\nexport enum QuoteFinancialAttachment {\r\n shortInterest = 'shortInterest',\r\n}\r\n\r\nexport const TIMEFRAME_SECONDS = {\r\n [TIMEFRAME.i1]: 60,\r\n [TIMEFRAME.i2]: 120,\r\n [TIMEFRAME.i3]: 180,\r\n [TIMEFRAME.i5]: 300,\r\n [TIMEFRAME.i10]: 600,\r\n [TIMEFRAME.i15]: 900,\r\n [TIMEFRAME.i30]: 1800,\r\n [TIMEFRAME.h]: 3600,\r\n [TIMEFRAME.h2]: 7200,\r\n [TIMEFRAME.h4]: 14400,\r\n [TIMEFRAME.d]: 86400,\r\n [TIMEFRAME.w]: 604800,\r\n [TIMEFRAME.m]: 2592000,\r\n}\r\n\r\nexport const CRYPTOS = {\r\n BTCUSD: 'BTCUSD',\r\n LTCUSD: 'LTCUSD',\r\n ETHUSD: 'ETHUSD',\r\n XRPUSD: 'XRPUSD',\r\n BCHUSD: 'BCHUSD',\r\n BTCEUR: 'BTCEUR',\r\n LTCEUR: 'LTCEUR',\r\n ETHEUR: 'ETHEUR',\r\n XRPEUR: 'XRPEUR',\r\n BCHEUR: 'BCHEUR',\r\n LTCBTC: 'LTCBTC',\r\n ETHBTC: 'ETHBTC',\r\n XRPBTC: 'XRPBTC',\r\n BCHBTC: 'BCHBTC',\r\n}\r\n\r\nexport enum SpecificChartFunctionality {\r\n default = 'default',\r\n quotePage = 'quotePage',\r\n quotePerf = 'quotePerf',\r\n quoteFinancials = 'quoteFinancials',\r\n chartPage = 'chartPage',\r\n smallIndex = 'smallIndex',\r\n offScreen = 'offScreen',\r\n forexPage = 'forexPage',\r\n futuresPage = 'futuresPage',\r\n cryptoPage = 'cryptoPage',\r\n}\r\n\r\nexport enum TextAlign {\r\n left = 'left',\r\n right = 'right',\r\n center = 'center',\r\n start = 'start',\r\n end = 'end',\r\n}\r\n\r\nexport enum TextBaseline {\r\n top = 'top',\r\n hanging_dont_use = 'hanging', // not supported - https://github.com/Automattic/node-canvas/wiki/Compatibility-Status#text-styles\r\n middle = 'middle',\r\n alphabetic = 'alphabetic',\r\n ideographic_dont_use = 'ideographic', // not supported - https://github.com/Automattic/node-canvas/wiki/Compatibility-Status#text-styles\r\n bottom = 'bottom',\r\n}\r\n\r\nexport enum ScaleType {\r\n Linear = 'linear',\r\n Percentage = 'percentage',\r\n Logarithmic = 'logarithmic',\r\n}\r\n\r\nexport enum QuotePollingIntervalInMs {\r\n Default = 2000,\r\n Free = 180000,\r\n Elite = Default,\r\n EliteStocksReduced = 60000,\r\n}\r\n\r\nexport const EXTRA_MARKET_BUFFER_MINUTES = 30\r\n\r\nexport const ScaleLabel = {\r\n [ScaleType.Linear]: 'Linear',\r\n [ScaleType.Percentage]: 'Percentage',\r\n [ScaleType.Logarithmic]: 'Logarithmic',\r\n}\r\n\r\nexport const PANE_HEIGHT_DEFAULT = {\r\n chart: 400,\r\n indicator: 120,\r\n}\r\n\r\nexport const INDICATOR_LABEL_HEIGHT = 24\r\n\r\nexport const MOBILE_BARS_TO_VIEW = 150 // 5 months of daily bars\r\n\r\nexport const MOBILE_VIEW_BREAKPOINT_WIDTH = 768\r\n\r\nexport const FREE_DATE_RANGES = ['m1', 'm3', 'm6', 'ytd', 'y1', 'y2', 'y5', 'max']\r\n\r\nexport const getTimeframeLabel = (timeframe: string) => {\r\n switch (timeframe) {\r\n case TIMEFRAME.i1:\r\n return '1 MIN'\r\n case TIMEFRAME.i2:\r\n return '2 MIN'\r\n case TIMEFRAME.i3:\r\n return '3 MIN'\r\n case TIMEFRAME.i5:\r\n return '5 MIN'\r\n case TIMEFRAME.i10:\r\n return '10 MIN'\r\n case TIMEFRAME.i15:\r\n return '15 MIN'\r\n case TIMEFRAME.i30:\r\n return '30 MIN'\r\n case TIMEFRAME.h:\r\n return '1 HR'\r\n case TIMEFRAME.h2:\r\n return '2 HR'\r\n case TIMEFRAME.h4:\r\n return '4 HR'\r\n case TIMEFRAME.d:\r\n return 'DAILY'\r\n case TIMEFRAME.w:\r\n return 'WEEKLY'\r\n case TIMEFRAME.m:\r\n return 'MONTHLY'\r\n default:\r\n return ''\r\n }\r\n}\r\n\r\nexport type ChartsPageQueryParams = {\r\n p: string\r\n t: string\r\n l: string\r\n r?: string\r\n i?: string\r\n sidebar?: string\r\n}\r\n\r\nexport type QuotePageQueryParams = {\r\n p?: string\r\n t: string\r\n r?: string\r\n i?: string\r\n ty?: QuotePageQueryChartTypes\r\n}\r\n\r\nexport enum QuotePageQueryChartTypes {\r\n l = 'l',\r\n c = 'c',\r\n cs = 'cs',\r\n hc = 'hc',\r\n ha = 'ha',\r\n o = 'o',\r\n p = 'p',\r\n}\r\n\r\nexport type ChartsOrQuotePageQueryParams = ChartsPageQueryParams | QuotePageQueryParams\r\n\r\nexport enum MacroTimeframe {\r\n // seconds = 'seconds',\r\n minutes = 'minutes',\r\n hours = 'hours',\r\n days = 'days',\r\n weeks = 'weeks',\r\n months = 'months',\r\n}\r\n\r\nexport const MicroMacroTimeframe = {\r\n [TIMEFRAME.i1]: {\r\n micro: 1,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i2]: {\r\n micro: 2,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i3]: {\r\n micro: 3,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i5]: {\r\n micro: 5,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i10]: {\r\n micro: 10,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i15]: {\r\n micro: 15,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i30]: {\r\n micro: 30,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.h]: {\r\n micro: 1,\r\n macro: MacroTimeframe.hours,\r\n },\r\n [TIMEFRAME.h2]: {\r\n micro: 2,\r\n macro: MacroTimeframe.hours,\r\n },\r\n [TIMEFRAME.h4]: {\r\n micro: 4,\r\n macro: MacroTimeframe.hours,\r\n },\r\n [TIMEFRAME.d]: {\r\n micro: 1,\r\n macro: MacroTimeframe.days,\r\n },\r\n [TIMEFRAME.w]: {\r\n micro: 1,\r\n macro: MacroTimeframe.weeks,\r\n },\r\n [TIMEFRAME.m]: {\r\n micro: 1,\r\n macro: MacroTimeframe.months,\r\n },\r\n}\r\n\r\nexport const MicroTimeframeRange = (Object.keys(MicroMacroTimeframe) as TIMEFRAME[]).reduce(\r\n (prev, curr) => ({\r\n ...prev,\r\n [MicroMacroTimeframe[curr].macro]: prev[MicroMacroTimeframe[curr].macro]\r\n ? [...prev[MicroMacroTimeframe[curr].macro], MicroMacroTimeframe[curr].micro]\r\n : [MicroMacroTimeframe[curr].micro],\r\n }),\r\n {} as { [key in MacroTimeframe]: number[] }\r\n)\r\n\r\ntype IRange = {\r\n from?: number\r\n to?: number\r\n}\r\n\r\nexport type IVisibility = {\r\n [key in MacroTimeframe]?: IRange\r\n}\r\n\r\nexport enum SetVisibilityTo {\r\n currentAndAbove,\r\n currentAndBelow,\r\n currentOnly,\r\n all,\r\n}\r\n\r\nexport const QUOTE_FETCH_EVENT = 'quoteFetchEvent'\r\n\r\n// Keep in sync with the clone in Website repo in shared/is-stock-fast-refresh-available.ts\r\nexport const PREMARKET_AFTERMARKET_HOURS = 2.5\r\n\r\nexport const CHART_ELEMENT_ID = 'chart'\r\n\r\nexport const CHART_SETTINGS_DIALOG_TEST_ID = 'chart-settings-dialog'\r\n","import { ChartConfigChartPane } from '../../../types/shared'\r\nimport { IndicatorType } from '../../constants/common'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport Element from '../../models/element'\r\nimport PaneModel from '../../models/pane'\r\nimport { HLC, compareHlc, incrementHlc, receiveHlc } from '../../utils/hlc'\r\nimport {\r\n AutoSaveChangeType,\r\n AutoSaveElement,\r\n AutoSaveElementDBRecord,\r\n DrawingChangeTimestamp,\r\n DrawingContainerType,\r\n} from './constants'\r\n\r\nexport function getContainerTypeFromPaneConfig(pane: ChartConfigChartPane) {\r\n const indicatorElement = pane.elements.find((el) => el.type.startsWith('indicators/'))\r\n if (indicatorElement) {\r\n return indicatorElement.type as DrawingContainerType\r\n }\r\n const chartElement = pane.elements.find((el) => el.type.startsWith('charts/'))\r\n if (chartElement) {\r\n return 'chart'\r\n }\r\n return null\r\n}\r\n\r\nexport function getContainerType(model: PaneModel) {\r\n const mainElement = model.mainElement()\r\n const indicatorType = mainElement?.instance?.type ?? null\r\n if (mainElement?.isIndicator() && indicatorType !== IndicatorType.None) {\r\n return indicatorType as DrawingContainerType\r\n }\r\n if (mainElement?.isChart()) {\r\n return 'chart'\r\n }\r\n return null\r\n}\r\n\r\nexport function updateInternalStoreWithChangedElement({\r\n element,\r\n changeType,\r\n currentInternalStore,\r\n lastUpdateTimestamp,\r\n}: {\r\n element: Element\r\n changeType: AutoSaveChangeType\r\n currentInternalStore: AutoSaveElement[]\r\n lastUpdateTimestamp: HLC\r\n}) {\r\n const paneModel = element.pane()\r\n const ticker = paneModel.getQuoteRawTicker()\r\n const containerType = getContainerType(paneModel)\r\n if (ticker && paneModel && containerType && (!element.destroyed || changeType === 'destroy')) {\r\n const instanceJson = element.instance.toAutosaveConfig()\r\n const newDrawing: AutoSaveElement = {\r\n elementId: element.elementId!,\r\n zIndex: element.zIndex,\r\n ticker,\r\n lastChange: lastUpdateTimestamp,\r\n changeType,\r\n containerType,\r\n elementAttrs: JSON.stringify(instanceJson),\r\n }\r\n\r\n const newInternalStore = [...currentInternalStore]\r\n const updateDrawingIndex = newInternalStore.findIndex(\r\n (drawingElement) => drawingElement.elementId === newDrawing.elementId\r\n )\r\n\r\n let shouldSyncAndSave = false\r\n if (updateDrawingIndex > -1) {\r\n const updatedRecord = newInternalStore[updateDrawingIndex]\r\n const hasChangedZIndex = updatedRecord.zIndex !== newDrawing.zIndex\r\n const hasChangedType = updatedRecord.changeType !== newDrawing.changeType\r\n const hasChangedAttrs = updatedRecord.elementAttrs !== newDrawing.elementAttrs\r\n const hasChange = hasChangedType || hasChangedAttrs || hasChangedZIndex\r\n if (\r\n !element.instance.isEditInProgress &&\r\n updatedRecord.ticker === ticker &&\r\n hasChange &&\r\n updatedRecord.changeType !== 'destroy'\r\n ) {\r\n newInternalStore[updateDrawingIndex] = newDrawing\r\n shouldSyncAndSave = true\r\n }\r\n } else {\r\n newInternalStore.push(newDrawing)\r\n shouldSyncAndSave = true\r\n }\r\n\r\n return {\r\n newInternalStore,\r\n shouldSyncAndSave,\r\n newDrawing,\r\n }\r\n }\r\n}\r\n\r\nexport function getTickersAndContainerTypesInLayoutModel(chartLayout: ChartLayout) {\r\n const tickers: string[] = []\r\n const containerTypes: Array = ['note']\r\n\r\n chartLayout.getAllPanes().forEach((paneModel) => {\r\n const ticker = paneModel.getQuoteRawTicker()\r\n const containerType = getContainerType(paneModel)\r\n if (ticker && !tickers.includes(ticker)) {\r\n tickers.push(ticker)\r\n }\r\n if (containerType && !containerTypes.includes(containerType)) {\r\n containerTypes.push(containerType)\r\n }\r\n })\r\n return { tickers, containerTypes }\r\n}\r\n\r\nexport function mergeUpdatedDrawingsToInternalStore({\r\n updatedDrawings,\r\n currentInternalStore,\r\n lastUpdateTimestamp,\r\n isRefetchAll,\r\n}: {\r\n updatedDrawings: AutoSaveElement[]\r\n currentInternalStore: AutoSaveElement[]\r\n lastUpdateTimestamp: DrawingChangeTimestamp\r\n isRefetchAll: boolean\r\n}) {\r\n let newLastUpdateTimestamp = lastUpdateTimestamp\r\n const newInternalStore = [...currentInternalStore]\r\n const updatedElementIds: string[] = []\r\n\r\n updatedDrawings.forEach((drawing) => {\r\n newLastUpdateTimestamp = receiveHlc(newLastUpdateTimestamp, drawing.lastChange)\r\n const drawingIndex = newInternalStore.findIndex(({ elementId }) => drawing.elementId === elementId)\r\n const currentDrawing = drawingIndex > -1 ? newInternalStore[drawingIndex] : null\r\n if (currentDrawing === null) {\r\n newInternalStore.push(drawing)\r\n updatedElementIds.push(drawing.elementId)\r\n } else if (currentDrawing.containerType === 'note' && isRefetchAll) {\r\n const currentNote = getElementNoteText(currentDrawing)\r\n const autoSavedNote = getElementNoteText(drawing)\r\n if (currentNote !== autoSavedNote) {\r\n newInternalStore[drawingIndex] = {\r\n ...drawing,\r\n lastChange: incrementHlc(receiveHlc(currentDrawing.lastChange, drawing.lastChange), Date.now()),\r\n elementAttrs: JSON.stringify({\r\n ...JSON.parse(drawing.elementAttrs),\r\n text: `${currentNote}\\r\\n${autoSavedNote}`,\r\n }),\r\n }\r\n }\r\n updatedElementIds.push(drawing.elementId)\r\n } else if (compareHlc(newInternalStore[drawingIndex].lastChange, drawing.lastChange) < 0) {\r\n newInternalStore[drawingIndex] = drawing\r\n updatedElementIds.push(drawing.elementId)\r\n }\r\n })\r\n return { newLastUpdateTimestamp, newInternalStore, updatedElementIds }\r\n}\r\n\r\nexport function getInitialStoreDrawings(): null | AutoSaveElement[] {\r\n const initialDrawings = (\r\n window.FinvizSettings?.initialDrawingsStore ?? window.FinvizChartsSettings?.initialDrawingsStore\r\n )?.drawings as null | AutoSaveElementDBRecord[]\r\n\r\n return initialDrawings?.map((item) => getAutosaveElementFromDBRecord(item)) ?? null\r\n}\r\n\r\nexport function handleCallMethodOnAllDrawings({\r\n chartLayoutModel,\r\n elementMethod,\r\n}: {\r\n chartLayoutModel: ChartLayout\r\n elementMethod: keyof Pick\r\n}) {\r\n chartLayoutModel.getAllElements().forEach((element) => {\r\n if (element.isDrawing()) {\r\n element[elementMethod]()\r\n }\r\n })\r\n}\r\n\r\nexport function getNoteElementId(ticker: string) {\r\n return `note-${ticker}`\r\n}\r\n\r\nexport function getElementNoteText(noteElement?: AutoSaveElement) {\r\n return (noteElement ? JSON.parse(noteElement.elementAttrs)?.text : '') ?? ''\r\n}\r\n\r\nexport function getTickerNoteText({ ticker, elements }: { ticker: string; elements: AutoSaveElement[] }) {\r\n const noteElement = elements.find(({ elementId }) => elementId === getNoteElementId(ticker))\r\n return getElementNoteText(noteElement)\r\n}\r\n\r\nexport function getAutosaveElementFromDBRecord(item: AutoSaveElementDBRecord): AutoSaveElement {\r\n return {\r\n elementId: item.elementId,\r\n ticker: item.ticker,\r\n zIndex: item.zIndex,\r\n changeType: item.changeType,\r\n containerType: item.containerType,\r\n elementAttrs: item.elementAttrs,\r\n lastChange: {\r\n ts: item.lastChangeTimestamp,\r\n count: item.lastChangeCounter,\r\n uuid: item.lastChangeNodeUUID,\r\n },\r\n }\r\n}\r\n\r\nexport function getDBRecordFromAutosaveElement(item: AutoSaveElement): Omit {\r\n return {\r\n elementId: item.elementId,\r\n ticker: item.ticker,\r\n zIndex: item.zIndex,\r\n changeType: item.changeType,\r\n containerType: item.containerType,\r\n elementAttrs: JSON.stringify(item.elementAttrs),\r\n lastChangeTimestamp: item.lastChange.ts,\r\n lastChangeCounter: item.lastChange.count,\r\n lastChangeNodeUUID: item.lastChange.uuid,\r\n }\r\n}\r\n","import { ButtonComponentProps, Icon, Select, SelectListProps } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport { useChartTypes } from './use-chart-types'\r\n\r\ninterface Props extends Pick {\r\n isPremium: boolean\r\n specificFunctionality: SpecificChartFunctionality\r\n rounding: SelectListProps['rounding']\r\n}\r\n\r\nexport function ChartTypesSelect({ isPremium, specificFunctionality, ...props }: Props) {\r\n const { chartTypes, currentType, setSelectedChartTypeOverwrite } = useChartTypes({ isPremium, specificFunctionality })\r\n\r\n return (\r\n \r\n }\r\n nativeSelect=\"mobile\"\r\n onChange={(item) => setSelectedChartTypeOverwrite(item.value)}\r\n />\r\n )\r\n}\r\n","import * as React from 'react'\r\nimport { useLocation } from 'react-router-dom'\r\n\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\nimport {\r\n DEFAULT_TYPES,\r\n FREE_TYPES_QUOTE,\r\n FREE_TYPES_QUOTE_VALUES,\r\n QuoteLongToShortType,\r\n QuoteNodeChartTypes,\r\n QuoteShortToLongType,\r\n QuoteUrlChartTypes,\r\n TypeBaseOption,\r\n} from './utils'\r\n\r\nexport function useChartTypes({\r\n isPremium,\r\n specificFunctionality,\r\n}: {\r\n isPremium: boolean\r\n specificFunctionality: SpecificChartFunctionality\r\n}) {\r\n const [selectedChartTypeOverwrite, setSelectedChartTypeOverwrite] = React.useState()\r\n const location = useLocation()\r\n const { b, t, ta, ty, p = 'd', r } = decodeQueryString(location.search)\r\n const taInt = ta ? Number.parseInt(ta) : 1\r\n const isQuoteOrQuoteFinancials = [\r\n SpecificChartFunctionality.quotePage,\r\n SpecificChartFunctionality.quoteFinancials,\r\n ].includes(specificFunctionality)\r\n\r\n const generateRouterPath = React.useCallback(\r\n (type: QuoteNodeChartTypes) => {\r\n if (isPremium || FREE_TYPES_QUOTE_VALUES.includes(type)) {\r\n return `${location.pathname}?${encodeQueryString({\r\n b,\r\n t,\r\n r,\r\n ty:\r\n type === QuoteNodeChartTypes.candlesticksimple\r\n ? QuoteLongToShortType.candlestick\r\n : QuoteLongToShortType[type],\r\n ta: type === QuoteNodeChartTypes.candlestick ? '1' : '0',\r\n p,\r\n })}`\r\n }\r\n return `/elite.ashx?${encodeQueryString({\r\n utm_source: 'finviz',\r\n utm_medium: 'banner',\r\n utm_campaign: 'quote-chart-type-select',\r\n })}`\r\n },\r\n [isPremium, location.pathname, b, t, r, p]\r\n )\r\n\r\n const chartTypes = React.useMemo(() => {\r\n const options = isPremium || !isQuoteOrQuoteFinancials ? DEFAULT_TYPES : FREE_TYPES_QUOTE\r\n\r\n return options.map((item) => ({\r\n ...item,\r\n href: generateRouterPath(item.value as QuoteNodeChartTypes),\r\n reloadDocument: !isPremium,\r\n })) as TypeBaseOption[]\r\n }, [generateRouterPath, isPremium, isQuoteOrQuoteFinancials])\r\n\r\n const currentType = React.useMemo(\r\n () =>\r\n chartTypes.find((type) => {\r\n if (selectedChartTypeOverwrite) return type.value === selectedChartTypeOverwrite\r\n\r\n const defaultType =\r\n ((ty as QuoteUrlChartTypes | undefined) && QuoteShortToLongType[ty as QuoteUrlChartTypes]) ??\r\n (FinvizQuoteTypeCurrent as QuoteNodeChartTypes)\r\n\r\n return !isPremium && defaultType === QuoteNodeChartTypes.candlestick && taInt === 0\r\n ? type.value === QuoteNodeChartTypes.candlesticksimple\r\n : type.value === defaultType\r\n }),\r\n [chartTypes, selectedChartTypeOverwrite, ty, isPremium, taInt]\r\n )\r\n\r\n return { currentType, chartTypes, setSelectedChartTypeOverwrite }\r\n}\r\n","import {\r\n Button,\r\n ButtonComponentProps,\r\n ConfirmationDialog,\r\n Delayed,\r\n DialogDismiss,\r\n Popover,\r\n PopoverPlacement,\r\n PopoverRounding,\r\n PopoverStateReturn,\r\n PopoverTheme,\r\n PopoverTrigger,\r\n Spinner,\r\n ZIndexContext,\r\n usePopoverState,\r\n} from '@finviz/website'\r\nimport classNames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { CHART_ELEMENT_ID, CHART_SETTINGS_DIALOG_TEST_ID, SpecificChartFunctionality } from '../../constants/common'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\nimport { encodeQueryString } from '../../utils/query_string'\r\nimport { useChartLayoutGlobalModelAsync } from '../../utils/useChartLayoutGlobalModelAsync'\r\nimport { chartSettingsAsyncModule } from '../chart-settings/async-modules'\r\n\r\nconst utmCampaign: Partial> = {\r\n [SpecificChartFunctionality.quotePage]: 'quote-settings-button',\r\n [SpecificChartFunctionality.futuresPage]: 'futures-settings-button',\r\n [SpecificChartFunctionality.forexPage]: 'forex-settings-button',\r\n [SpecificChartFunctionality.cryptoPage]: 'crypto-settings-button',\r\n}\r\n\r\ninterface ScrollableChartSettingsPopoverProps {\r\n isOpen: boolean\r\n state: PopoverStateReturn\r\n}\r\n\r\nexport function PopoverInner({ hidePopover }: { hidePopover: () => void }) {\r\n const [chartSettingsModule] = useAsyncModule({\r\n ...chartSettingsAsyncModule,\r\n isSuspenseMode: true,\r\n errorSeverity: 'medium',\r\n onError: () => hidePopover(),\r\n })\r\n\r\n const { ChartSettings } = chartSettingsModule ?? {}\r\n\r\n return \r\n}\r\n\r\nexport const ScrollableChartSettingsPopover = React.memo(function ScrollableChartSettingsPopover({\r\n state,\r\n isOpen,\r\n}: ScrollableChartSettingsPopoverProps) {\r\n const { forceGlobalRerender, getIsConfigChanged, chartLayoutModel } = useChartLayoutGlobalModelAsync()\r\n const confirmationDialogState = usePopoverState()\r\n const hidePopover = state.hide\r\n\r\n const checkChangesAndOpenDiscard = React.useCallback(\r\n (ev: Event | React.MouseEvent) => {\r\n if (getIsConfigChanged()) {\r\n ev.preventDefault()\r\n confirmationDialogState.show()\r\n return\r\n }\r\n hidePopover()\r\n },\r\n [confirmationDialogState, getIsConfigChanged, hidePopover]\r\n )\r\n\r\n const discardChangesAndHide = React.useCallback(() => {\r\n forceGlobalRerender()\r\n // We need to defer the hide so that the rerender finishes first\r\n setTimeout(hidePopover)\r\n }, [forceGlobalRerender, hidePopover])\r\n\r\n const buttonPosition = React.useMemo(() => {\r\n const popoverContentElement = state.getState().disclosureElement\r\n const { top = 0, height = 32 } = popoverContentElement?.getBoundingClientRect() ?? {}\r\n return top + height + window.scrollY\r\n // Only recount on open\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [isOpen])\r\n\r\n const chartHeight = React.useMemo(() => {\r\n const chartElement = document.getElementById(CHART_ELEMENT_ID)\r\n return chartElement?.clientHeight ?? 0\r\n // Only recount on open\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [isOpen])\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n }\r\n >\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n Discard changes\r\n \r\n \r\n }\r\n >\r\n Are you sure you want to discard changes?\r\n \r\n \r\n )\r\n})\r\n\r\ninterface ChartSettingsButtonProps extends ButtonComponentProps {\r\n isPremium: boolean\r\n placement?: PopoverPlacement\r\n model: ChartLayout\r\n}\r\n\r\nexport function ChartSettingsButton({\r\n isPremium,\r\n model,\r\n placement,\r\n ...props\r\n}: React.PropsWithChildren) {\r\n const settingsPopoverState = usePopoverState({ placement: placement ?? 'bottom' })\r\n const isOpen = settingsPopoverState.useState('open')\r\n\r\n const buttonProps = React.useMemo(() => {\r\n if (model.specificChartFunctionality !== SpecificChartFunctionality.quotePage && !isPremium) {\r\n return {\r\n as: 'a',\r\n href: `/elite.ashx?${encodeQueryString({\r\n utm_source: 'finviz',\r\n utm_medium: 'banner',\r\n utm_campaign: utmCampaign[model.specificChartFunctionality],\r\n })}`,\r\n } as ButtonComponentProps<'a'>\r\n }\r\n\r\n return {\r\n as: PopoverTrigger,\r\n state: settingsPopoverState,\r\n active: isOpen,\r\n } as ButtonComponentProps\r\n }, [model.specificChartFunctionality, isPremium, settingsPopoverState, isOpen])\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n )\r\n}\r\n","import * as React from 'react'\r\nimport { useLocation, useNavigate } from 'react-router-dom'\r\n\r\nimport { ChartsOrQuotePageQueryParams, SpecificChartFunctionality } from '../../constants/common'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { useModelRef } from '../../model-hooks/useModelRef'\r\nimport Chart from '../../models/chart'\r\nimport Quote from '../../models/quote'\r\nimport { QuoteFetchType } from '../../models/quote/constants'\r\nimport { createRequestAbortController, removeFromAbortCache } from '../../utils/abort_controller'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\nimport { getLeftOffset } from '../renderUtils'\r\n\r\nconst getQuoteRequestKey = (chartModel: Chart) =>\r\n `quoteReq-${chartModel.ticker}-${chartModel.instrument}-${chartModel.id}`\r\n\r\nexport function useChartControls({\r\n chartModel: unwatchedChartModel,\r\n isInteractive,\r\n}: {\r\n chartModel: Chart | null\r\n isInteractive: boolean\r\n}) {\r\n const location = useLocation()\r\n const navigate = useNavigate()\r\n const chartModel = useModelState(unwatchedChartModel, {\r\n watchProperties: ['ticker', 'timeframe', 'dateRange'],\r\n })\r\n const chartLayoutModel = useModelState(chartModel?.chart_layout() ?? null, {\r\n watchProperties: ['idea', 'settings'],\r\n })\r\n const chartModelRef = useModelRef(chartModel)\r\n const [isLoading, setIsLoading] = React.useState(false)\r\n const abortControllerKeyRef = React.useRef('')\r\n const isIdeaChart = !!chartLayoutModel?.idea?.id\r\n\r\n const updateChartModelWithNewQuote = React.useCallback((quote: Quote) => {\r\n const chart = chartModelRef.current\r\n if (!chart) {\r\n return\r\n }\r\n\r\n const chartLayoutModel = chart.chart_layout()\r\n const isSameTicker = chart.getQuoteRawTicker() === quote.getRawTicker()\r\n\r\n chart.getAllPanes().forEach((pane) => {\r\n if (!!pane.getChartOrIndicatorElement()) {\r\n pane.updateAttribute('scaleRange', null)\r\n }\r\n })\r\n\r\n chart.updateAttributes({ leftOffset: getLeftOffset({ quote, chartModel: chart }), quote, isScrolled: true })\r\n\r\n // Refetch all other chart quotes as the main one is already refetched so we can filter it out but other quotes (from perf for example) should be refetched as well\r\n chart\r\n .getAllQuotes()\r\n .filter((chartQuote) => !chartQuote.eql(quote))\r\n .forEach((quote) => {\r\n quote.fetchData({ fetchType: QuoteFetchType.NewerData })\r\n })\r\n\r\n const chartPane = chart.getChartPane()\r\n chartLayoutModel.activeChartEvent?.instance.toggleIsOpen(false)\r\n\r\n const elements = [...chart.getAllElements(), ...(chartPane?.getAllChartEvents(false) ?? [])]\r\n for (const element of elements) {\r\n const isDrawing = element.isDrawing()\r\n const isChartEvent = element.isChartEvent()\r\n if (isDrawing || isChartEvent) {\r\n // We want to remove all drawings on ticker change but if autosave is enabled we let the autosave hook take care of that\r\n if (isSameTicker && (isChartEvent || chartLayoutModel.isPreserveDrawingsActive)) {\r\n element.instance.updateScales()\r\n } else {\r\n element.destroyCascade()\r\n }\r\n }\r\n }\r\n\r\n chart.setChartEvents(quote.chartEvents, true)\r\n\r\n chartPane?.updateChartEventsZIndexes()\r\n\r\n // The only dependency here is a ref , so no need to add it to dependencies\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n const fetchQuote = React.useCallback(async () => {\r\n if (!isInteractive || !chartModel || isIdeaChart) {\r\n return\r\n }\r\n\r\n const { ticker, instrument, timeframe, hasChartEvents } = chartModel\r\n const { premarket, aftermarket } = Quote.first()\r\n const patterns = chartModel.getHasPatterns()\r\n const currentQuote = chartModel.quote()\r\n if (currentQuote.getRawTicker() !== ticker || currentQuote.timeframe !== timeframe) {\r\n setIsLoading(true)\r\n abortControllerKeyRef.current = getQuoteRequestKey(chartModel)\r\n const abortController = createRequestAbortController({\r\n key: abortControllerKeyRef.current,\r\n shouldAbortRunningRequest: !Quote.select(\r\n (quote) =>\r\n quote.ticker === ticker &&\r\n quote.timeframe === timeframe &&\r\n quote.isFetching &&\r\n chartModel.chart_layout().isIdeaId(quote.ideaID)\r\n ),\r\n })\r\n\r\n const quote = await Quote.get({\r\n ticker,\r\n instrument,\r\n timeframe,\r\n options: {\r\n premarket,\r\n aftermarket,\r\n events: hasChartEvents,\r\n financialAttachments: chartModel.getQuoteFinancialAttachments(),\r\n patterns,\r\n cachePredicate: (quote) => quote.ideaID === undefined,\r\n fetchNewDataOnCachedQuote: true,\r\n },\r\n abortController,\r\n })\r\n\r\n if (quote.wasFetchAborted) {\r\n // Check if the quote is also used in other chars, as the quote may be reused if we already have a quote with the same options\r\n const isQuoteUsedInOtherCharts = chartModel\r\n .chart_layout()\r\n .getAllCharts()\r\n .filter((chart) => !chartModel.eql(chart))\r\n .some((chart) => quote.eql(chart.quote()))\r\n\r\n // If the quote hasn't been fetched yet and is not anywhere else we can destroy the model\r\n if (quote.fetchedAt === -1 && !isQuoteUsedInOtherCharts) {\r\n quote.destroy()\r\n }\r\n } else if (quote.timeframe === chartModel.timeframe && quote.getRawTicker() === chartModel.ticker) {\r\n removeFromAbortCache(abortControllerKeyRef.current)\r\n updateChartModelWithNewQuote(quote)\r\n setIsLoading(false)\r\n }\r\n }\r\n\r\n // We don't want to create new function on any chartModel change as it may be the same chart with different object instance\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [\r\n chartModel?.id,\r\n chartModel?.ticker,\r\n chartModel?.timeframe,\r\n chartModel?.instrument,\r\n isIdeaChart,\r\n updateChartModelWithNewQuote,\r\n isInteractive,\r\n ])\r\n\r\n React.useEffect(() => {\r\n fetchQuote()\r\n }, [fetchQuote])\r\n\r\n // There are several ways how to turn off dateRange, e.g. moving the charts\r\n // This effect listens to dateRange changes on chartmodel and updates the url if there's a change\r\n // Consider refactoring this part so we only update chart models on route changes not the other way around\r\n React.useEffect(() => {\r\n if (chartModel) {\r\n const decodedQueryString = decodeQueryString(location.search)\r\n const rangesArray = chartModel\r\n .chart_layout()\r\n .getAllCharts()\r\n .map((chart) => chart.dateRange)\r\n const ranges = rangesArray.every((i) => !i) ? undefined : rangesArray.join(',')\r\n\r\n if (decodedQueryString.r !== ranges) {\r\n navigate({\r\n search: `?${encodeQueryString({\r\n ...decodedQueryString,\r\n r: ranges,\r\n })}`,\r\n })\r\n }\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [chartModel?.dateRange])\r\n\r\n // https://github.com/finvizhq/charts/pull/1253/files#r1052266805\r\n // React.useEffect(\r\n // () => () => {\r\n // if (isInteractive && abortControllerKeyRef.current !== '') {\r\n // abortRequest(abortControllerKeyRef.current)\r\n // }\r\n // },\r\n // [isInteractive]\r\n // )\r\n\r\n React.useEffect(() => {\r\n const chart = chartModelRef.current\r\n const quote = chart?.quote()\r\n\r\n let shouldRecalculateOnCharts = false\r\n if (chartLayoutModel?.specificChartFunctionality === SpecificChartFunctionality.chartPage && !isIdeaChart) {\r\n const settings = chartLayoutModel?.settings\r\n const barWidth = 3\r\n const barMargin = 1\r\n if (settings) {\r\n const hasSameBarWidth = [\r\n settings.ChartSettings.center.barWidth,\r\n settings.IndicatorSettings.center.barWidth,\r\n ].every((value) => value === barWidth)\r\n const hasSameBarMargin = [\r\n settings.ChartSettings.center.barMargin,\r\n settings.IndicatorSettings.center.barMargin,\r\n ].every((value) => value === barMargin)\r\n\r\n shouldRecalculateOnCharts = !hasSameBarWidth || !hasSameBarMargin\r\n if (shouldRecalculateOnCharts) {\r\n settings.ChartSettings.center.barWidth = barWidth\r\n settings.IndicatorSettings.center.barWidth = barWidth\r\n settings.ChartSettings.center.barMargin = barMargin\r\n settings.IndicatorSettings.center.barMargin = barMargin\r\n\r\n chartLayoutModel.updateAttributes({ settings })\r\n }\r\n }\r\n }\r\n\r\n const isQuoteOrQuoteFinancials =\r\n chartLayoutModel &&\r\n [SpecificChartFunctionality.quotePage, SpecificChartFunctionality.quoteFinancials].includes(\r\n chartLayoutModel.specificChartFunctionality\r\n )\r\n\r\n if (chart && quote && (isQuoteOrQuoteFinancials || shouldRecalculateOnCharts) && !isIdeaChart) {\r\n const leftOffset = getLeftOffset({ quote, chartModel: chart })\r\n chart.updateAttributes({ leftOffset })\r\n }\r\n // This effect should run only on timeframe change & idea change\r\n // The reason we need to recalculate the left offset is that quote timeframe change changes chart and chart bars sizes\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [chartModel?.quote()?.timeframe, chartLayoutModel?.settings, isIdeaChart])\r\n\r\n return { isLoading }\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport * as React from 'react'\r\n\r\nexport function useModelRef(model: Model | null) {\r\n const modelRef = React.useRef(model)\r\n\r\n React.useEffect(() => {\r\n modelRef.current = model\r\n }, [model])\r\n\r\n return modelRef\r\n}\r\n","import {\r\n Notification,\r\n Paragraph,\r\n generatePathForTimeframeDateRange,\r\n getDateRangeGroupsWithHref,\r\n timeframeUtm,\r\n useNotification,\r\n} from '@finviz/website'\r\nimport React from 'react'\r\nimport { useLocation } from 'react-router-dom'\r\n\r\nimport { Instrument } from '../../../types/shared'\r\nimport { SpecificChartFunctionality, TIMEFRAME, TimeframeAndIntradayType } from '../../constants/common'\r\nimport Chart from '../../models/chart'\r\nimport Quote from '../../models/quote'\r\nimport { dateFromUnixTimestamp } from '../../utils'\r\nimport { getChartStartEndDates, getVisibleBarsNumber } from '../renderUtils'\r\nimport { useChartsPathLocation } from './use-charts-path-location'\r\nimport { getTimeframeGroupsWithHref } from './utils'\r\n\r\ninterface IPathForTimeframeDateRangeProps {\r\n timeframe: TimeframeAndIntradayType\r\n dateRange?: string | null\r\n ticker?: string\r\n}\r\n\r\nexport interface IDateRange {\r\n value: string\r\n timeframe: TIMEFRAME\r\n}\r\n\r\nexport function useChartModelCustomDateRangeValues({\r\n chartModel,\r\n isPremium,\r\n}: {\r\n chartModel: Chart | null\r\n isPremium: boolean\r\n}) {\r\n const notificationContext = useNotification()\r\n const location = useLocation()\r\n const [isFetching, setIsFetching] = React.useState(false)\r\n const chartLayoutModel = chartModel?.chart_layout() || null\r\n const chartIndex = chartLayoutModel?.getAllCharts().findIndex((chart) => chartModel!.eql(chart)) ?? -1\r\n const { getChartsToPath } = useChartsPathLocation({ chartLayoutModel, chartIndex })\r\n const specificChartFunctionality = chartLayoutModel?.specificChartFunctionality ?? SpecificChartFunctionality.default\r\n\r\n const anchorDate = React.useMemo(() => {\r\n if (!chartModel) return new Date()\r\n const quote = chartModel.quote()\r\n return dateFromUnixTimestamp(quote.date[quote.date.length - 1])\r\n }, [chartModel])\r\n\r\n const generateChartLayoutRouterPath = React.useCallback(\r\n ({ ticker, timeframe, dateRange }: IPathForTimeframeDateRangeProps) => {\r\n if (specificChartFunctionality === SpecificChartFunctionality.chartPage) {\r\n return getChartsToPath({\r\n ticker: ticker,\r\n timeframe: timeframe as TIMEFRAME,\r\n dateRange: dateRange,\r\n })\r\n }\r\n\r\n return generatePathForTimeframeDateRange({\r\n isPremium,\r\n pathname: location.pathname,\r\n timeframe: timeframe,\r\n dateRange: dateRange,\r\n utmCampaign: timeframeUtm[specificChartFunctionality],\r\n })\r\n },\r\n [getChartsToPath, isPremium, specificChartFunctionality, location.pathname]\r\n )\r\n\r\n const timeframeGroupsWithHref = (isPremium: boolean) =>\r\n getTimeframeGroupsWithHref({\r\n isPremium,\r\n generatePath: (timeFrame) => generateChartLayoutRouterPath({ timeframe: timeFrame.value, dateRange: null }),\r\n })\r\n\r\n const dateRangeGroupsWithHref = ({\r\n isPremium,\r\n customRange,\r\n instrument,\r\n }: {\r\n isPremium: boolean\r\n customRange?: string\r\n instrument: Instrument\r\n }) =>\r\n getDateRangeGroupsWithHref({\r\n isPremium,\r\n customRange,\r\n instrument,\r\n generatePath: (dateRange: { timeframe?: TIMEFRAME; value: string }) =>\r\n generateChartLayoutRouterPath({ timeframe: dateRange.timeframe!, dateRange: dateRange.value }),\r\n })\r\n\r\n const handleCustomDateRangeValidation = async (dateRangeState: { value: string | null; timeframe: TIMEFRAME }) => {\r\n if (dateRangeState.value !== null) {\r\n const { timeframe, ticker, instrument, premarket, aftermarket } = chartModel?.quote() || {}\r\n const patterns = !!chartModel?.getHasPatterns()\r\n if (!anchorDate || !instrument || !ticker || !timeframe || !dateRangeState.value) return false\r\n setIsFetching(true)\r\n const quote = await Quote.get({\r\n ticker,\r\n instrument,\r\n timeframe: dateRangeState.timeframe,\r\n options: {\r\n premarket,\r\n aftermarket,\r\n patterns,\r\n cachePredicate: (quote) => quote.ideaID === undefined,\r\n fetchNewDataOnCachedQuote: true,\r\n },\r\n })\r\n setIsFetching(false)\r\n\r\n const { numOfVisibleBars } = getVisibleBarsNumber({\r\n ...getChartStartEndDates({ dateRange: dateRangeState.value, quote }),\r\n quote,\r\n dateRange: dateRangeState.value,\r\n })\r\n if (numOfVisibleBars === 0) {\r\n notificationContext.show(\r\n } timeoutInMs={6000}>\r\n \r\n There are no data for the selected date range. Try selecting different dates.\r\n \r\n \r\n )\r\n\r\n return false\r\n }\r\n }\r\n return true\r\n }\r\n\r\n return {\r\n anchorDate,\r\n generateChartLayoutRouterPath,\r\n timeframeGroupsWithHref,\r\n dateRangeGroupsWithHref,\r\n isFetching,\r\n handleCustomDateRangeValidation,\r\n }\r\n}\r\n","import * as React from 'react'\r\nimport { useLocation } from 'react-router-dom'\r\n\r\nimport { ChartsPageQueryParams, LAYOUTS, LayoutType, TIMEFRAME } from '../../constants/common'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { ChartSyncablePart } from '../../models/chart/contstants'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { getIsMobilePortrait } from '../../utils'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\n\r\nexport function useChartsPathLocation({\r\n chartLayoutModel: unwatchedChartLayoutModel,\r\n chartIndex = -1,\r\n}: {\r\n chartLayoutModel: ChartLayout | null\r\n chartIndex?: number\r\n}) {\r\n const location = useLocation()\r\n const chartLayoutModel = useModelState(unwatchedChartLayoutModel, {\r\n watchProperties: ['syncChartParts'],\r\n })\r\n const hasSyncedTimeframe = React.useMemo(\r\n () => !!chartLayoutModel?.getIsChartPartInSync(ChartSyncablePart.Timeframe),\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [chartLayoutModel?.syncChartParts]\r\n )\r\n const hasSyncedTicker = React.useMemo(\r\n () => !!chartLayoutModel?.getIsChartPartInSync(ChartSyncablePart.Ticker),\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [chartLayoutModel?.syncChartParts]\r\n )\r\n\r\n const getChartsToPath = React.useCallback(\r\n ({\r\n ticker,\r\n timeframe,\r\n dateRange,\r\n layout,\r\n }: {\r\n timeframe?: TIMEFRAME\r\n dateRange?: string | null\r\n ticker?: string\r\n layout?: LayoutType\r\n }) => {\r\n if (!chartLayoutModel) {\r\n return {\r\n pathname: location.pathname,\r\n search: '',\r\n }\r\n }\r\n\r\n const decodedSearch = decodeQueryString(location.search)\r\n const { count } = LAYOUTS[(layout ?? chartLayoutModel.layout) as LayoutType]\r\n const urlTickers = decodedSearch.t?.split(',') ?? []\r\n const urlTimeframes = decodedSearch.p?.split(',') ?? []\r\n const urlDateRanges = decodedSearch.r?.split(',')\r\n\r\n const chartsArrayPlaceholder = Array.from({ length: count })\r\n const tickers = chartsArrayPlaceholder\r\n .map((_, index) => {\r\n const currentTicker = urlTickers[index] ?? urlTickers[urlTickers.length - 1]\r\n return (chartIndex === index || hasSyncedTicker) && ticker ? ticker : currentTicker\r\n })\r\n .join(',')\r\n const timeframes = chartsArrayPlaceholder\r\n .map((_, index) => {\r\n const currentTimeframe = urlTimeframes[index] ?? urlTimeframes[urlTimeframes.length - 1]\r\n return (chartIndex === index || hasSyncedTimeframe) && timeframe ? timeframe : currentTimeframe\r\n })\r\n .join(',')\r\n const ranges = chartsArrayPlaceholder\r\n .map((_, index) => {\r\n const currentDaterange = urlDateRanges\r\n ? (urlDateRanges[index] ?? urlDateRanges[urlDateRanges.length - 1])\r\n : undefined\r\n return (chartIndex === index || hasSyncedTimeframe) && dateRange !== undefined ? dateRange : currentDaterange\r\n })\r\n .join(',')\r\n\r\n return {\r\n pathname: location.pathname,\r\n search: `?${encodeQueryString({\r\n t: tickers,\r\n p: timeframes,\r\n r: ranges.split(',').some(Boolean) ? ranges : undefined,\r\n l: layout ?? chartLayoutModel.layout,\r\n sidebar: getIsMobilePortrait() ? undefined : decodedSearch.sidebar,\r\n })}`,\r\n }\r\n },\r\n [chartLayoutModel, chartIndex, location, hasSyncedTicker, hasSyncedTimeframe]\r\n )\r\n\r\n return { getChartsToPath }\r\n}\r\n","import { IconNameType, getTimeframeGroups } from '@finviz/website'\r\nimport { type To } from 'react-router-dom'\r\n\r\nimport { TimeframeAndIntradayType } from '../../constants/common'\r\n\r\ninterface ITimeFrame {\r\n value: TimeframeAndIntradayType\r\n label: string\r\n labelShort: string\r\n labelPageTitle?: string\r\n}\r\n\r\ninterface ITimeframeGroup {\r\n label: string\r\n timeframes: ITimeFrame[]\r\n}\r\n\r\nexport function getTimeframeGroupsWithHref({\r\n isPremium,\r\n generatePath,\r\n}: {\r\n isPremium: boolean\r\n generatePath: (timeframe: ITimeFrame) => To\r\n}) {\r\n return getTimeframeGroups(isPremium).map((timeFrameGroup: ITimeframeGroup) => ({\r\n label: timeFrameGroup.label,\r\n timeframes: timeFrameGroup.timeframes.map((timeFrame) => ({\r\n ...timeFrame,\r\n href: generatePath(timeFrame),\r\n })),\r\n }))\r\n}\r\n\r\nexport enum QuoteNodeChartTypes {\r\n candlesticksimple = 'candlesticksimple',\r\n candlestick = 'candlestick',\r\n line = 'line',\r\n ohlc = 'ohlc',\r\n heikinashi = 'heikinashi',\r\n hollowcandlestick = 'hollowcandlestick',\r\n}\r\n\r\nexport enum QuoteUrlChartTypes {\r\n cs = 'cs',\r\n c = 'c',\r\n l = 'l',\r\n o = 'o',\r\n ha = 'ha',\r\n hc = 'hc',\r\n}\r\n\r\nexport const QuoteShortToLongType = {\r\n [QuoteUrlChartTypes.cs]: QuoteNodeChartTypes.candlesticksimple,\r\n [QuoteUrlChartTypes.c]: QuoteNodeChartTypes.candlestick,\r\n [QuoteUrlChartTypes.l]: QuoteNodeChartTypes.line,\r\n [QuoteUrlChartTypes.o]: QuoteNodeChartTypes.ohlc,\r\n [QuoteUrlChartTypes.ha]: QuoteNodeChartTypes.heikinashi,\r\n [QuoteUrlChartTypes.hc]: QuoteNodeChartTypes.hollowcandlestick,\r\n} as const\r\n\r\nexport const QuoteLongToShortType = {\r\n [QuoteNodeChartTypes.candlesticksimple]: QuoteUrlChartTypes.cs,\r\n [QuoteNodeChartTypes.candlestick]: QuoteUrlChartTypes.c,\r\n [QuoteNodeChartTypes.line]: QuoteUrlChartTypes.l,\r\n [QuoteNodeChartTypes.ohlc]: QuoteUrlChartTypes.o,\r\n [QuoteNodeChartTypes.heikinashi]: QuoteUrlChartTypes.ha,\r\n [QuoteNodeChartTypes.hollowcandlestick]: QuoteUrlChartTypes.hc,\r\n} as const\r\n\r\nexport type TypeBaseOption = {\r\n label: string\r\n value: QuoteNodeChartTypes\r\n icon: IconNameType\r\n href?: string\r\n}\r\nexport const DEFAULT_TYPES: TypeBaseOption[] = [\r\n { icon: 'candleBarBasic', value: QuoteNodeChartTypes.candlestick, label: 'Candle' },\r\n { icon: 'lineChartType', value: QuoteNodeChartTypes.line, label: 'Line' },\r\n { icon: 'ohlcChartType', value: QuoteNodeChartTypes.ohlc, label: 'OHLC' },\r\n { icon: 'candleBarHollow', value: QuoteNodeChartTypes.hollowcandlestick, label: 'Hollow Candle' },\r\n { icon: 'candleBarHeikinAshi', value: QuoteNodeChartTypes.heikinashi, label: 'Heikin Ashi' },\r\n]\r\n\r\nexport const FREE_TYPES_QUOTE: TypeBaseOption[] = [\r\n { icon: 'candleBarBasic', value: QuoteNodeChartTypes.candlesticksimple, label: 'Candle - simple' },\r\n { icon: 'candleBarBasic', value: QuoteNodeChartTypes.candlestick, label: 'Candle - advanced' },\r\n // Filter out the candle from DEFAULT_TYPES, we’re naming it differently\r\n ...DEFAULT_TYPES.filter((type) => type.value !== QuoteNodeChartTypes.candlestick),\r\n]\r\n\r\nexport const FREE_TYPES_QUOTE_VALUES = ['candlesticksimple', 'candlestick', 'line']\r\n","export const chartEventsAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"chart-events\" */ './module-entry'),\r\n cacheKey: 'chart-events',\r\n}\r\n","export const chartSettingsAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"chart-settings\" */ './module-entry'),\r\n cacheKey: 'chart-settings',\r\n}\r\n\r\nexport const useChartLayoutGlobalModelAsyncModule = {\r\n importFn: () =>\r\n import(/* webpackChunkName: \"use-chart-layout-global-model\" */ './useChartLayoutGlobalModel/module-entry'),\r\n cacheKey: 'use-chart-layout-global-model',\r\n}\r\n\r\nexport const preventClosingUnsavedChangesAsyncModule = {\r\n importFn: () =>\r\n import(/* webpackChunkName: \"prevent-closing-unsaved-changes\" */ './PreventClosingUnsavedChanges/module-entry'),\r\n cacheKey: 'prevent-closing-unsaved-changes',\r\n}\r\n","import { InputColorPicker, convertColorToHEX } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\ninterface BackgroundInputProps {\r\n label: string\r\n value: string\r\n onChange: (color: string) => void\r\n}\r\n\r\nexport function BackgroundInput({ label = 'Background', value, onChange }: BackgroundInputProps) {\r\n return (\r\n \r\n )\r\n}\r\n","import { InputColorPicker, Paragraph, RangeSlider } from '@finviz/website'\r\nimport React, { useCallback } from 'react'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\n\r\ninterface ColorRangeRowInputProps {\r\n label: string\r\n colorValue: string\r\n colorTestId: string\r\n rangeValue: string\r\n rangeTestId: string\r\n rangeLabel: string\r\n rangeProps: ObjectHash\r\n onChange: (colorValue: string, value: string) => void\r\n}\r\n\r\nexport function ColorRangeRowInput({\r\n label,\r\n colorValue,\r\n colorTestId,\r\n rangeValue,\r\n rangeTestId,\r\n rangeLabel,\r\n rangeProps,\r\n onChange,\r\n}: ColorRangeRowInputProps) {\r\n const handleRangeChange = useCallback(\r\n (ev: React.ChangeEvent) => {\r\n const value = ev.currentTarget.value\r\n onChange(colorValue, value)\r\n },\r\n [onChange, colorValue]\r\n )\r\n const handleColorChange = useCallback(\r\n (color: string) => {\r\n onChange(color, rangeValue)\r\n },\r\n [onChange, rangeValue]\r\n )\r\n return (\r\n

\r\n
\r\n \r\n
\r\n
\r\n \r\n {rangeValue}\r\n \r\n }\r\n onChange={handleRangeChange}\r\n value={Number(rangeValue)}\r\n data-testid={rangeTestId}\r\n />\r\n
\r\n
\r\n )\r\n}\r\n","import { convertColorToHEX } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { ColorRangeRowInput } from './color_range_row'\r\n\r\ninterface Value {\r\n color: string\r\n width: string\r\n}\r\n\r\ninterface BorderInputProps {\r\n label: string\r\n value: Value\r\n min: number\r\n max: number\r\n onChange: (value: Value) => void\r\n}\r\n\r\nexport function BorderInput({ label = 'Border', value, onChange, min, max }: BorderInputProps) {\r\n return (\r\n onChange({ color, width })}\r\n />\r\n )\r\n}\r\n","import { Checkbox } from '@finviz/website'\r\nimport React from 'react'\r\n\r\ninterface CheckBoxProps {\r\n label: string\r\n value: boolean\r\n onChange: (isChecked: boolean) => void\r\n}\r\n\r\nexport function CheckBox({ label, value, onChange }: CheckBoxProps) {\r\n return (\r\n ) => onChange(ev.currentTarget.checked)}\r\n data-testid=\"chart-modal-checkbox\"\r\n >\r\n {label}\r\n \r\n )\r\n}\r\n","import { Checkbox, Input, Label, Select } from '@finviz/website'\r\nimport React, { useCallback, useState } from 'react'\r\n\r\nconst FONT_VALUES = [\r\n { value: 'Arial', label: 'Arial' },\r\n { value: 'Verdana', label: 'Verdana' },\r\n]\r\n\r\ninterface InputProps {\r\n family: string\r\n size: string\r\n style: 'italic' | 'normal'\r\n weight: 'bold' | 'normal'\r\n}\r\n\r\ninterface FontInputProps {\r\n value: InputProps\r\n onChange: (values: InputProps) => void\r\n}\r\n\r\nexport function FontInput({ value, onChange }: FontInputProps) {\r\n const [family, setFamily] = useState(value.family)\r\n const [size, setSize] = useState(value.size)\r\n const [style, setStyle] = useState(value.style)\r\n const [weight, setWeight] = useState(value.weight)\r\n\r\n const setValue = useCallback(\r\n function setValue(\r\n key: string,\r\n valueSetter: React.Dispatch>,\r\n value: ValueType\r\n ) {\r\n valueSetter(value)\r\n onChange({ family, size, style, weight, [key]: value })\r\n },\r\n [family, size, style, weight, onChange]\r\n )\r\n\r\n return (\r\n
\r\n
\r\n \r\n ) => setValue('size', setSize, ev.currentTarget.value)}\r\n value={size}\r\n data-testid=\"chart-modal-font-size\"\r\n />\r\n\r\n ) =>\r\n setValue('weight', setWeight, ev.currentTarget.checked ? 'bold' : 'normal')\r\n }\r\n data-testid=\"chart-modal-font-weight\"\r\n >\r\n Bold\r\n \r\n ) =>\r\n setValue('style', setStyle, ev.currentTarget.checked ? 'italic' : 'normal')\r\n }\r\n data-testid=\"chart-modal-font-style\"\r\n >\r\n Italic\r\n \r\n
\r\n
\r\n )\r\n}\r\n","import { convertColorToHEX } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { ColorRangeRowInput } from './color_range_row'\r\n\r\ninterface LineInputValue {\r\n color: string\r\n width: string\r\n}\r\n\r\ninterface LineInputProps {\r\n label: string\r\n value: LineInputValue\r\n onChange: (value: LineInputValue) => void\r\n}\r\n\r\nexport function LineInput({ label = 'Line', value, onChange }: LineInputProps) {\r\n return (\r\n onChange({ color, width })}\r\n />\r\n )\r\n}\r\n","import { Textarea } from '@finviz/website'\r\nimport React from 'react'\r\n\r\ninterface MultilineStringInputProps {\r\n label: string\r\n value: string\r\n required: boolean\r\n onChange: (value: string) => void\r\n}\r\n\r\nexport function MultilineStringInput({ label, value, required, onChange }: MultilineStringInputProps) {\r\n return (\r\n ) => onChange(e.target.value)}\r\n value={value}\r\n autoFocus\r\n data-testid=\"chart-modal-multiline-string-textarea\"\r\n />\r\n )\r\n}\r\n","import { Input } from '@finviz/website'\r\nimport React from 'react'\r\n\r\ninterface NumberInputProps {\r\n label: string\r\n name: string\r\n value: number\r\n required: boolean\r\n min?: number\r\n max?: number\r\n allowDecimal?: boolean\r\n step?: number\r\n onChange: (value: number) => void\r\n}\r\n\r\nexport function NumberInput(props: NumberInputProps) {\r\n const { label, name, value, required, min, max, step, allowDecimal = false } = props\r\n\r\n return (\r\n ) =>\r\n props.onChange(allowDecimal ? parseFloat(e.target.value) : parseInt(e.target.value, 10))\r\n }\r\n data-testid=\"chart-modal-number-input\"\r\n />\r\n )\r\n}\r\n","import { Input } from '@finviz/website'\r\nimport React from 'react'\r\n\r\ninterface StringInputProps {\r\n label: string\r\n name: string\r\n value: string\r\n required: boolean\r\n onChange: (value: string) => void\r\n}\r\n\r\nexport function StringInput(props: StringInputProps) {\r\n const { label, name, value, required } = props\r\n\r\n return (\r\n ) => props.onChange(e.target.value)}\r\n data-testid=\"chart-modal-string-textinput\"\r\n />\r\n )\r\n}\r\n","import { Checkbox, Input, InputColorPicker, convertColorToHEX } from '@finviz/website'\r\nimport React from 'react'\r\n\r\ninterface InputProps {\r\n active: boolean\r\n trend: number\r\n color: string\r\n}\r\n\r\ninterface trendInputProps {\r\n value: InputProps\r\n onChange: (values: InputProps) => void\r\n}\r\n\r\nexport function Trend({ value, onChange }: trendInputProps) {\r\n return (\r\n
\r\n ) => onChange({ ...value, active: ev.currentTarget.checked })}\r\n data-testid=\"chart-modal-trend-active\"\r\n />\r\n ) =>\r\n onChange({ ...value, trend: ev.currentTarget.valueAsNumber })\r\n }\r\n value={value.trend}\r\n data-testid=\"chart-modal-trend-value\"\r\n />\r\n onChange({ ...value, color: color })}\r\n inputDataTestId=\"chart-modal-trend-color\"\r\n />\r\n
\r\n )\r\n}\r\n","import { Checkbox, Input, Paragraph } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { MacroTimeframe } from '../../constants/common'\r\nimport { DEFAULTS } from './index'\r\n\r\nexport interface InputProps {\r\n macroKey: MacroTimeframe\r\n isOff: boolean\r\n from: number\r\n to: number\r\n}\r\n\r\ninterface VisibilityInputProps {\r\n value: InputProps\r\n onChange: (value: InputProps) => void\r\n isCheckboxOnly: boolean\r\n}\r\n\r\nexport function VisibilityInput({ value, onChange, isCheckboxOnly }: VisibilityInputProps) {\r\n const [isOff, setIsOff] = React.useState(value.isOff)\r\n const [from, setFrom] = React.useState(value.from)\r\n const [to, setTo] = React.useState(value.to)\r\n const { macroKey } = value\r\n const macroLabel = macroKey.charAt(0).toUpperCase() + macroKey.slice(1)\r\n\r\n const setValue = React.useCallback(\r\n function (key: string, valueSetter: React.Dispatch>, value: ValueType) {\r\n valueSetter(value)\r\n onChange({ macroKey, isOff, from, to, [key]: value })\r\n },\r\n [macroKey, isOff, from, to, onChange]\r\n )\r\n return (\r\n
\r\n
\r\n ) => setValue('isOff', setIsOff, !e.target.checked)}\r\n >\r\n {isCheckboxOnly && macroLabel}\r\n \r\n {!isCheckboxOnly && (\r\n <>\r\n ) =>\r\n setValue('from', setFrom, Number(ev.currentTarget.value))\r\n }\r\n data-testid={`visibility-input-${macroKey}-from`}\r\n />\r\n -\r\n ) =>\r\n setValue('to', setTo, Number(ev.currentTarget.value))\r\n }\r\n data-testid={`visibility-input-${macroKey}-to`}\r\n />\r\n {macroLabel}\r\n \r\n )}\r\n
\r\n
\r\n )\r\n}\r\n","import merge from 'lodash.merge'\r\nimport React from 'react'\r\n\r\nimport { IVisibility, MacroTimeframe, MicroTimeframeRange } from '../../constants/common'\r\nimport { isInRange } from '../../utils/helpers'\r\nimport { InputProps, VisibilityInput } from './visibility-input'\r\n\r\ninterface VisibilityProps {\r\n label: string\r\n name: string\r\n value: IVisibility\r\n onChange: (value: IVisibility) => void\r\n handleDisableSubmit: (value: string | false) => void\r\n}\r\n\r\ntype Micro = { isOff: boolean; from: number; to: number }\r\nexport type DEFAULTS_TYPE = { [key in MacroTimeframe]: Micro }\r\n\r\nexport const DEFAULTS: DEFAULTS_TYPE = {\r\n // [MacroTimeframe.seconds]: { isOff: false, from: 1, to: 59 },\r\n [MacroTimeframe.minutes]: { isOff: false, from: 1, to: 59 },\r\n [MacroTimeframe.hours]: { isOff: false, from: 1, to: 24 },\r\n [MacroTimeframe.days]: { isOff: false, from: 1, to: 366 },\r\n [MacroTimeframe.weeks]: { isOff: false, from: 1, to: 52 },\r\n [MacroTimeframe.months]: { isOff: false, from: 1, to: 12 },\r\n}\r\n\r\nconst INPUTS_AVAILABLE = [MacroTimeframe.minutes, MacroTimeframe.hours]\r\n\r\nconst getInitialState = (value: IVisibility) => {\r\n const visibilities = merge({}, DEFAULTS)\r\n for (const visibility in visibilities) {\r\n const macroTimeframe = visibility as MacroTimeframe\r\n const valueMacroTimeframe = value?.[macroTimeframe]\r\n if (!valueMacroTimeframe) continue\r\n if (Object.keys(valueMacroTimeframe).length === 0) {\r\n visibilities[macroTimeframe] = { ...visibilities[macroTimeframe], isOff: true }\r\n } else {\r\n visibilities[macroTimeframe] = { ...visibilities[macroTimeframe], ...valueMacroTimeframe }\r\n }\r\n }\r\n return visibilities\r\n}\r\n\r\nconst getIsVisibilityOutsideAvailableTimeframes = (value: IVisibility) => {\r\n const result = Object.keys(MacroTimeframe).every((macrotimeframe) => {\r\n const macroRange = value[macrotimeframe as MacroTimeframe]\r\n\r\n return (\r\n macroRange &&\r\n (Object.keys(macroRange).length === 0 ||\r\n !MicroTimeframeRange[macrotimeframe as MacroTimeframe].some((item) =>\r\n isInRange({\r\n value: item,\r\n min: macroRange?.from ?? DEFAULTS[macrotimeframe as MacroTimeframe].from,\r\n max: macroRange?.to ?? DEFAULTS[macrotimeframe as MacroTimeframe].to,\r\n })\r\n ))\r\n )\r\n })\r\n return result\r\n}\r\n\r\nexport function Visibility(props: VisibilityProps) {\r\n const initialVisibilityRef = React.useRef(getInitialState(props.value))\r\n\r\n const handleChange = (value: InputProps) => {\r\n const result: IVisibility = props.value ? merge({}, props.value) : {}\r\n result[value.macroKey] = {}\r\n\r\n if (value.isOff) {\r\n props.onChange(result)\r\n } else if (value.from === DEFAULTS[value.macroKey].from && value.to === DEFAULTS[value.macroKey].to) {\r\n delete result[value.macroKey]\r\n props.onChange(result)\r\n } else {\r\n if (value.from !== DEFAULTS[value.macroKey].from) {\r\n result[value.macroKey]!.from = value.from\r\n }\r\n if (value.to !== DEFAULTS[value.macroKey].to) {\r\n result[value.macroKey]!.to = value.to\r\n }\r\n props.onChange(result)\r\n }\r\n\r\n props.handleDisableSubmit(\r\n getIsVisibilityOutsideAvailableTimeframes(result)\r\n ? 'The chosen timeframes would make the drawing invisible on all supported timeframes.'\r\n : false\r\n )\r\n }\r\n\r\n return Object.keys(initialVisibilityRef.current).map((macroKey) => (\r\n \r\n ))\r\n}\r\n","import {\r\n Button,\r\n ButtonGroup,\r\n Dialog,\r\n DialogBody,\r\n DialogFooter,\r\n DialogHeader,\r\n DialogStateReturn,\r\n useDialogState,\r\n} from '@finviz/website'\r\nimport debounce from 'lodash.debounce'\r\nimport * as React from 'react'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\nimport CanvasElement from '../canvas/element'\r\nimport Pane from '../models/pane'\r\nimport { BackgroundInput } from './background'\r\nimport { BorderInput } from './border'\r\nimport { CheckBox } from './checkbox'\r\nimport { FontInput } from './font'\r\nimport { LineInput } from './line'\r\nimport { MultilineStringInput } from './multiline_string'\r\nimport { NumberInput } from './number'\r\nimport { StringInput } from './string'\r\nimport { Trend } from './trend'\r\nimport { Visibility } from './visibility'\r\n\r\nfunction getInputForType(type: string) {\r\n switch (type) {\r\n case 'number':\r\n return NumberInput\r\n case 'string':\r\n return StringInput\r\n case 'text':\r\n return StringInput\r\n case 'background':\r\n return BackgroundInput\r\n case 'border':\r\n return BorderInput\r\n case 'line':\r\n return LineInput\r\n case 'multiline_string':\r\n return MultilineStringInput\r\n case 'font':\r\n return FontInput\r\n case 'checkbox':\r\n return CheckBox\r\n case 'trend':\r\n return Trend\r\n case 'visibility':\r\n return Visibility\r\n default:\r\n return () =>
ERROR: Unknown input type
\r\n }\r\n}\r\n\r\nconst TAB_BUTTON_COMMON_PROPS = { type: 'button' as const, className: 'flex-1', contentClass: 'text-center' }\r\n\r\ntype OnSubmitType = ((value: ObjectHash) => void) | null\r\ntype OnDismissType = (() => void) | null\r\n\r\nexport interface ElementStyleDialogProps {\r\n state: DialogStateReturn\r\n element: ElementType\r\n onSubmit: ((values: ElementType['attrs']) => void) | null\r\n onDismiss: (() => void) | null\r\n onHide: () => void\r\n}\r\n\r\nexport type StyleDialogOpener = (\r\n element: ElementType,\r\n onSubmit: ElementStyleDialogProps['onSubmit'],\r\n onDismiss: ElementStyleDialogProps['onDismiss']\r\n) => void\r\n\r\nfunction getValuesFromFormState(formState: ObjectHash) {\r\n return formState.reduce((acc: ObjectHash, cur: ObjectHash) => {\r\n acc[cur.name] = cur.value\r\n return acc\r\n }, {} as ObjectHash)\r\n}\r\n\r\nenum DialogTabs {\r\n Style,\r\n Visibility,\r\n}\r\n\r\nexport function ElementStyleDialog(props: ElementStyleDialogProps) {\r\n const config = props.element.getModalConfig()\r\n const initialFormStateRef = React.useRef[]>(JSON.parse(JSON.stringify(config.inputs)))\r\n const [formState, setFormState] = React.useState[]>(config.inputs)\r\n const [selectedTab, setSelectedTab] = React.useState(DialogTabs.Style)\r\n const [isSubmitDisabled, setIsSubmitDisabled] = React.useState(false) // If string, the value is used as title for disabled button.\r\n\r\n const isDrawingElement = props.element.getIsDrawing()\r\n\r\n const handleFullyOpen = React.useCallback(() => {\r\n if (props.element instanceof CanvasElement && props.element.model instanceof Pane) {\r\n props.element.setIsSelected(true)\r\n props.element.model.updateAttribute('selection', props.element)\r\n props.element.setIsEditInProgress(true)\r\n }\r\n }, [props.element])\r\n\r\n const handleFullyClosed = React.useCallback(() => {\r\n if (props.element instanceof CanvasElement) {\r\n props.element.setIsEditInProgress(false)\r\n }\r\n props.onHide()\r\n }, [props])\r\n\r\n const handleValuesChange = React.useCallback(\r\n ({\r\n values,\r\n shouldSubmit = false,\r\n shouldDismiss = false,\r\n }: {\r\n values: ObjectHash\r\n shouldSubmit?: boolean\r\n shouldDismiss?: boolean\r\n }) => {\r\n const hasOnSubmit = typeof props.onSubmit === 'function'\r\n const hasOnDismiss = typeof props.onDismiss === 'function'\r\n\r\n props.element.set(values)\r\n if (shouldSubmit && hasOnSubmit) {\r\n props.onSubmit!(values)\r\n } else if (shouldDismiss && hasOnDismiss) {\r\n props.onDismiss!()\r\n }\r\n\r\n if (shouldSubmit || shouldDismiss) {\r\n props.state.hide()\r\n }\r\n },\r\n [props]\r\n )\r\n\r\n const handleValuesChangeDebounceRef = React.useRef(\r\n debounce(\r\n (newFormState) => {\r\n const values = getValuesFromFormState(newFormState)\r\n handleValuesChange({ values })\r\n },\r\n 50,\r\n { maxWait: 100 }\r\n )\r\n )\r\n\r\n React.useEffect(\r\n () => () => {\r\n handleValuesChangeDebounceRef.current.cancel()\r\n },\r\n []\r\n )\r\n\r\n const onSubmit: React.FormEventHandler = React.useCallback(\r\n (ev: React.FormEvent) => {\r\n ev.preventDefault()\r\n if (ev.currentTarget.checkValidity()) {\r\n const values = getValuesFromFormState(formState)\r\n handleValuesChange({ values, shouldSubmit: true })\r\n }\r\n },\r\n [formState, handleValuesChange]\r\n )\r\n\r\n const handleCloseDialog = React.useCallback(() => {\r\n const values = getValuesFromFormState(initialFormStateRef.current)\r\n handleValuesChange({ values, shouldDismiss: true })\r\n\r\n // Ariakit hideOnEscape expects a bool as return value\r\n return true\r\n }, [handleValuesChange])\r\n\r\n const getShouldRenderInputForTab = (inputType: string) => {\r\n if (selectedTab === DialogTabs.Visibility && inputType === 'visibility') return true\r\n if (selectedTab !== DialogTabs.Visibility && inputType !== 'visibility') return true\r\n return false\r\n }\r\n\r\n return (\r\n }\r\n onFullyOpen={handleFullyOpen}\r\n onFullyClosed={handleFullyClosed}\r\n hideOnEsc={handleCloseDialog}\r\n >\r\n {config.title}\r\n {formState.length > 0 ? (\r\n
\r\n \r\n {isDrawingElement && (\r\n \r\n setSelectedTab(DialogTabs.Style)}\r\n data-testid=\"dialog-tab-button-style\"\r\n >\r\n Style\r\n \r\n setSelectedTab(DialogTabs.Visibility)}\r\n data-testid=\"dialog-tab-button-visibility\"\r\n >\r\n Visibility\r\n \r\n \r\n )}\r\n\r\n {formState.map((input) => {\r\n const InputComponent = getInputForType(input.type) as React.FC<{\r\n onChange: (value: string) => void\r\n handleDisableSubmit?: typeof setIsSubmitDisabled\r\n }>\r\n return (\r\n getShouldRenderInputForTab(input.type) && (\r\n {\r\n setFormState((prevState) => {\r\n const newFormState = prevState.map((stateInput) => {\r\n if (stateInput.name === input.name) {\r\n return { ...stateInput, value }\r\n }\r\n return stateInput\r\n })\r\n handleValuesChangeDebounceRef.current(newFormState)\r\n return newFormState\r\n })\r\n }}\r\n handleDisableSubmit={setIsSubmitDisabled}\r\n />\r\n )\r\n )\r\n })}\r\n \r\n \r\n \r\n \r\n Save\r\n \r\n \r\n
\r\n ) : (\r\n <>\r\n This indicator doesn't offer any configuration options.\r\n \r\n \r\n \r\n \r\n )}\r\n \r\n )\r\n}\r\n\r\nexport const ElementStyleDialogContext = React.createContext>(() => {})\r\n\r\nexport function withElementStyleDialogState

(Component: React.ComponentType

) {\r\n return function WrappedComponent(props: P) {\r\n const context = React.useContext(ElementStyleDialogContext)\r\n\r\n return \r\n }\r\n}\r\n\r\nexport function ElementStyleDialogWrapper(props: { children: React.ReactNode }) {\r\n const [element, setElement] = React.useState(null)\r\n const [onSubmit, setOnSubmit] = React.useState(null)\r\n const [onDismiss, setOnDismiss] = React.useState(null)\r\n const dialog = useDialogState()\r\n\r\n const openDialog = (element: CanvasElement, onSubmit?: OnSubmitType, onDismiss?: OnDismissType) => {\r\n if (onSubmit) {\r\n setOnSubmit(() => onSubmit)\r\n }\r\n if (onDismiss) {\r\n setOnDismiss(() => onDismiss)\r\n }\r\n\r\n setElement(element)\r\n dialog.show()\r\n }\r\n\r\n const onHide = () => {\r\n setElement(null)\r\n setOnSubmit(null)\r\n setOnDismiss(null)\r\n }\r\n\r\n return (\r\n \r\n {props.children}\r\n {element && (\r\n \r\n )}\r\n \r\n )\r\n}\r\n","import { IndicatorType } from '../../constants/common'\r\nimport { HLC } from '../../utils/hlc'\r\n\r\nexport type DrawingChangeTimestamp = HLC\r\nexport type DrawingContainerType = IndicatorType | 'chart' | 'note' | null\r\nexport type AutoSaveChangeType = 'update' | 'destroy'\r\n\r\nexport interface AutoSaveElement {\r\n elementId: string\r\n ticker: string\r\n zIndex: number\r\n lastChange: DrawingChangeTimestamp\r\n changeType: AutoSaveChangeType\r\n containerType: DrawingContainerType\r\n elementAttrs: string\r\n}\r\n\r\nexport type AutoSaveElementDBRecord = Omit & { lastChange: string } & {\r\n lastChangeTimestamp: number\r\n lastChangeCounter: number\r\n lastChangeNodeUUID: string\r\n}\r\n\r\nexport const DRAWINGS_UPDATE_INTERVAL_MS = process.env.IS_E2E_TESTING ? 3000 : 15000\r\nexport const DRAWINGS_SAVE_INTERVAL_MS = 250\r\n","import { Notification, Paragraph, useNotification } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport fetchApi, {\r\n ContentType,\r\n ForbiddenError,\r\n GenericStatusCodeError,\r\n GoneError,\r\n InternalServerError,\r\n} from '../../utils/fetch_api'\r\nimport { HLC, compareHlc, incrementHlc } from '../../utils/hlc'\r\nimport { getByteLengthOfString } from '../../utils/string-byte-length'\r\nimport { AutoSaveElement, AutoSaveElementDBRecord, DrawingContainerType } from './constants'\r\nimport { getAutosaveElementFromDBRecord, getDBRecordFromAutosaveElement } from './utils'\r\n\r\nconst RETRY_LIMIT = 5\r\n\r\nexport function useDrawingAutoSaveApi() {\r\n const postRetryCountRef = React.useRef(0)\r\n const deleteRetryCountRef = React.useRef(0)\r\n const notificationContext = useNotification()\r\n\r\n const fetchDrawings = React.useCallback(\r\n async ({\r\n tickers,\r\n containerTypes,\r\n lastChange,\r\n }: {\r\n tickers: string[]\r\n containerTypes: DrawingContainerType[]\r\n lastChange: HLC\r\n }) => {\r\n try {\r\n const data = await fetchApi<{\r\n drawings: AutoSaveElementDBRecord[]\r\n }>({\r\n location: '/api/auto_save.ashx',\r\n queryParameters: {\r\n ticker: tickers.join(','),\r\n containerTypes: containerTypes.join(',') || undefined,\r\n lastChangeTimestamp: lastChange.ts,\r\n lastChangeCounter: lastChange.count,\r\n lastChangeNodeUUID: lastChange.uuid,\r\n },\r\n throwOnStatusCodes: [403, 404],\r\n })\r\n return data.drawings.map((drawing) => getAutosaveElementFromDBRecord(drawing))\r\n } catch {\r\n // ignore error\r\n }\r\n\r\n return []\r\n },\r\n []\r\n )\r\n\r\n const saveDrawings = React.useCallback(\r\n async (drawings: AutoSaveElement[]): Promise => {\r\n if (drawings.length === 0) {\r\n return undefined\r\n }\r\n\r\n try {\r\n const bodyJsonString = JSON.stringify(drawings.map((item) => getDBRecordFromAutosaveElement(item)))\r\n let keepalive = false\r\n try {\r\n keepalive = getByteLengthOfString(bodyJsonString) < 64000\r\n } catch (error: any) {\r\n window.Sentry?.captureException(error)\r\n }\r\n await fetchApi({\r\n location: '/api/auto_save.ashx',\r\n method: 'POST',\r\n throwOnStatusCodes: [400, 403, 404, 410, 500],\r\n contentType: ContentType.ApplicationJson,\r\n body: bodyJsonString,\r\n keepalive,\r\n })\r\n const [latestChangeHlc] = [...drawings].sort((a, b) => compareHlc(b.lastChange, a.lastChange))\r\n postRetryCountRef.current = 0\r\n return latestChangeHlc.lastChange\r\n } catch (error) {\r\n if (error instanceof InternalServerError) {\r\n // try again\r\n if (postRetryCountRef.current < RETRY_LIMIT) {\r\n postRetryCountRef.current = postRetryCountRef.current + 1\r\n await new Promise((r) => setTimeout(r, 1000))\r\n return saveDrawings(drawings)\r\n } else {\r\n // continue to report to Sentry\r\n postRetryCountRef.current = 0\r\n }\r\n } else if (error instanceof ForbiddenError) {\r\n // ignore error\r\n return undefined\r\n } else if (error instanceof GoneError) {\r\n const newTicker = (error.response as ObjectHash).newTicker\r\n const message = newTicker\r\n ? `Ticker \"${drawings[0].ticker}\" was renamed to \"${newTicker}\"`\r\n : `Ticker \"${drawings[0].ticker}\" no longer exists.`\r\n notificationContext.show(\r\n } timeoutInMs={6000}>\r\n {message}\r\n \r\n )\r\n return undefined\r\n }\r\n\r\n // report error to Sentry\r\n window.Sentry?.captureException(error, {\r\n extra: (error instanceof GenericStatusCodeError\r\n ? (error.response as ObjectHash).invalidItems\r\n : drawings\r\n ).reduce(\r\n (acc: ObjectHash, cur: ObjectHash, index: number) => ({ ...acc, [`item-${index}`]: JSON.stringify(cur) }),\r\n {} as ObjectHash\r\n ),\r\n })\r\n\r\n return undefined\r\n }\r\n },\r\n [notificationContext]\r\n )\r\n\r\n const deleteAllDrawings = React.useCallback(\r\n async ({ tickers, lastLocalChange }: { tickers: string[]; lastLocalChange: HLC }): Promise => {\r\n try {\r\n const newHlc = incrementHlc(lastLocalChange, Date.now())\r\n await fetchApi({\r\n location: `/api/auto_save.ashx?ticker=${tickers.join(',')}&lastChangeTimestamp=${\r\n newHlc.ts\r\n }&lastChangeCounter=${newHlc.count}&lastChangeNodeUUID=${newHlc.uuid}`,\r\n method: 'DELETE',\r\n throwOnStatusCodes: [403, 404, 500],\r\n keepalive: true,\r\n })\r\n deleteRetryCountRef.current = 0\r\n } catch (error) {\r\n if (error instanceof InternalServerError) {\r\n // try again\r\n if (deleteRetryCountRef.current < RETRY_LIMIT) {\r\n deleteRetryCountRef.current = deleteRetryCountRef.current + 1\r\n await new Promise((r) => setTimeout(r, 1000))\r\n return deleteAllDrawings({ tickers, lastLocalChange })\r\n } else {\r\n // continue to report to Sentry\r\n deleteRetryCountRef.current = 0\r\n }\r\n } else if (error instanceof ForbiddenError) {\r\n // ignore error\r\n return\r\n }\r\n\r\n // report error to Sentry\r\n window.Sentry?.captureException(error)\r\n }\r\n },\r\n []\r\n )\r\n\r\n return { fetchDrawings, saveDrawings, deleteAllDrawings }\r\n}\r\n","// byteLengthCharCode2 from https://stackoverflow.com/a/63893237\r\n\r\nexport function getByteLengthOfString(s: string) {\r\n //assuming the String is UCS-2(aka UTF-16) encoded\r\n let n = 0\r\n for (let i = 0, l = s.length; i < l; i++) {\r\n const hi = s.charCodeAt(i)\r\n if (hi < 0x0080) {\r\n n += 1\r\n } else if (hi < 0x0800) {\r\n n += 2\r\n } else if (hi < 0xd800) {\r\n n += 3\r\n } else if (hi < 0xdc00) {\r\n const lo = s.charCodeAt(++i)\r\n if (i < l && lo >= 0xdc00 && lo <= 0xdfff) {\r\n n += 4\r\n } else {\r\n throw new Error('UCS-2 String malformed')\r\n }\r\n } else if (hi < 0xe000) {\r\n throw new Error('UCS-2 String malformed')\r\n } else {\r\n n += 3\r\n }\r\n }\r\n return n\r\n}\r\n","import React from 'react'\r\n\r\nimport { DrawingSpineOptions, DrawingSpineOptionsEvent } from '../../../types/shared'\r\nimport ElementCanvas from '../../canvas/element'\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport { getCanvasElementByType } from '../../helpers/get-canvas-element-by-type'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { AutoSaveState } from '../../models/constants'\r\nimport Element from '../../models/element'\r\nimport { compareHlc, incrementHlc, initHlc, receiveHlc } from '../../utils/hlc'\r\nimport { AutoSaveChangeType, AutoSaveElement, DRAWINGS_SAVE_INTERVAL_MS } from './constants'\r\nimport { useDrawingAutoSaveApi } from './use-drawing-autosave-api'\r\nimport { useIsAutoSaveActive } from './use-is-auto-save-active'\r\nimport {\r\n getContainerType,\r\n getNoteElementId,\r\n getTickerNoteText,\r\n getTickersAndContainerTypesInLayoutModel,\r\n mergeUpdatedDrawingsToInternalStore,\r\n updateInternalStoreWithChangedElement,\r\n} from './utils'\r\n\r\nexport function useDrawingAutoSaveControls(chartLayout: ChartLayout) {\r\n const { fetchDrawings, saveDrawings, deleteAllDrawings } = useDrawingAutoSaveApi()\r\n const isAutoSaveActive = useIsAutoSaveActive(chartLayout)\r\n const drawingsInternalStore = React.useMemo(() => chartLayout.drawingsInternalStore(), [chartLayout])\r\n const saveTimeoutRef = React.useRef()\r\n\r\n React.useEffect(\r\n () => () => {\r\n if (saveTimeoutRef.current) {\r\n clearTimeout(saveTimeoutRef.current)\r\n }\r\n },\r\n []\r\n )\r\n\r\n const saveLatestChanges = React.useCallback(\r\n (\r\n withDelayInMs = DRAWINGS_SAVE_INTERVAL_MS,\r\n saveQueueExtraFilterCallback: ((item: AutoSaveElement) => boolean) | null = null\r\n ) => {\r\n if (saveTimeoutRef.current) {\r\n clearTimeout(saveTimeoutRef.current)\r\n }\r\n const saveQueue = drawingsInternalStore.elements.filter(\r\n (item) =>\r\n compareHlc(item.lastChange, drawingsInternalStore.latestLocalUpdateTimestamp) > 0 &&\r\n item.lastChange.uuid === drawingsInternalStore.instanceUUID &&\r\n (saveQueueExtraFilterCallback === null || saveQueueExtraFilterCallback(item))\r\n )\r\n if (saveQueue.length === 0) {\r\n return\r\n }\r\n\r\n drawingsInternalStore.setAutoSaveState(AutoSaveState.Unsaved)\r\n\r\n const save = async () => {\r\n drawingsInternalStore.setAutoSaveState(AutoSaveState.Saving)\r\n const result = await saveDrawings(saveQueue)\r\n if (result) {\r\n drawingsInternalStore.updateAttributes({\r\n latestLocalUpdateTimestamp: receiveHlc(drawingsInternalStore.latestLocalUpdateTimestamp, result),\r\n })\r\n }\r\n drawingsInternalStore.setAutoSaveState(AutoSaveState.Saved)\r\n\r\n return result\r\n }\r\n\r\n if (withDelayInMs === 0) {\r\n return save()\r\n }\r\n\r\n saveTimeoutRef.current = window.setTimeout(save, withDelayInMs)\r\n },\r\n [saveDrawings, drawingsInternalStore]\r\n )\r\n\r\n const syncChartLayoutDrawings = React.useCallback(\r\n (drawing: AutoSaveElement) => {\r\n if (drawing.containerType === 'note') {\r\n return\r\n }\r\n const isRemove = drawing.changeType === 'destroy'\r\n\r\n chartLayout.getAllPanes().forEach((paneModel) => {\r\n const ticker = paneModel.getQuoteRawTicker()\r\n const paneContainerType = getContainerType(paneModel)\r\n if (!paneContainerType || drawing.ticker !== ticker) {\r\n return\r\n }\r\n const paneInternalStoreElements = drawingsInternalStore.elements.filter(\r\n (autoSaveElement) => autoSaveElement.ticker === ticker && autoSaveElement.containerType === paneContainerType\r\n )\r\n const paneElements = paneModel.getAllElements()\r\n let element: Element | undefined\r\n paneElements.forEach((paneElement) => {\r\n if (paneElement.isDrawing() && !paneElement.instance.isCreator) {\r\n const paneDrawing = paneInternalStoreElements.find(({ elementId }) => elementId === paneElement.elementId)\r\n if (!paneDrawing || paneDrawing.changeType === 'destroy') {\r\n paneElement.destroyCascade()\r\n } else if (paneElement.elementId && paneElement.elementId === drawing.elementId) {\r\n element = paneElement\r\n }\r\n }\r\n })\r\n\r\n const parsedElementAttrs = JSON.parse(drawing.elementAttrs)\r\n if (element) {\r\n if (drawing.elementAttrs !== JSON.stringify(element.instance.toAutosaveConfig())) {\r\n if (element.pane().selection !== element.instance && !element.hasOngoingInteraction()) {\r\n element.instance.set(parsedElementAttrs)\r\n element.instance.updateScales()\r\n }\r\n }\r\n if (drawing.zIndex !== element.zIndex) {\r\n element.updateAttributes({ zIndex: drawing.zIndex })\r\n }\r\n if (isRemove || paneContainerType !== drawing.containerType) {\r\n element.destroyCascade()\r\n }\r\n } else if (!isRemove && paneContainerType === drawing.containerType) {\r\n const instance = getCanvasElementByType(parsedElementAttrs.type).fromObject(\r\n parsedElementAttrs,\r\n paneModel\r\n ) as ElementCanvas\r\n paneModel.elements().create({ elementId: drawing.elementId, instance, zIndex: drawing.zIndex })\r\n instance.updateScales()\r\n }\r\n })\r\n },\r\n [chartLayout, drawingsInternalStore]\r\n )\r\n\r\n const handleAutoSaveNoteChange = React.useCallback(\r\n (note: string, ticker?: string) => {\r\n if (ticker) {\r\n const newNoteElement: AutoSaveElement = {\r\n elementId: getNoteElementId(ticker),\r\n zIndex: 0,\r\n ticker: ticker,\r\n lastChange: incrementHlc(drawingsInternalStore.latestLocalUpdateTimestamp, Date.now()),\r\n changeType: 'update',\r\n containerType: 'note',\r\n elementAttrs: JSON.stringify({ text: note }),\r\n }\r\n\r\n drawingsInternalStore.updateAttributes({\r\n elements: [\r\n ...drawingsInternalStore.elements.filter(({ elementId }) => elementId !== newNoteElement.elementId),\r\n newNoteElement,\r\n ],\r\n })\r\n }\r\n },\r\n [drawingsInternalStore]\r\n )\r\n\r\n const handleIdeaNoteChange = React.useCallback(\r\n (note: string) => {\r\n if (chartLayout.idea?.note !== note && (chartLayout.idea || note)) {\r\n chartLayout.updateAttribute('idea', { ...chartLayout.idea, note })\r\n handleAutoSaveNoteChange(note, chartLayout.activeChart?.getQuoteRawTicker() ?? undefined)\r\n }\r\n },\r\n [chartLayout, handleAutoSaveNoteChange]\r\n )\r\n\r\n const checkDrawingUpdate = React.useCallback(\r\n async (isRefetchAll = false) => {\r\n const { tickers, containerTypes } = getTickersAndContainerTypesInLayoutModel(chartLayout)\r\n if (isRefetchAll) {\r\n drawingsInternalStore.updateAttributes({\r\n latestRemoteUpdateTimestamp: initHlc(drawingsInternalStore.instanceUUID, 0),\r\n })\r\n }\r\n\r\n const updatedDrawings = await fetchDrawings({\r\n tickers,\r\n containerTypes,\r\n lastChange: drawingsInternalStore.latestRemoteUpdateTimestamp,\r\n })\r\n const { newLastUpdateTimestamp, updatedElementIds, newInternalStore } = mergeUpdatedDrawingsToInternalStore({\r\n updatedDrawings,\r\n currentInternalStore: drawingsInternalStore.elements,\r\n lastUpdateTimestamp: drawingsInternalStore.latestRemoteUpdateTimestamp,\r\n isRefetchAll,\r\n })\r\n\r\n drawingsInternalStore.updateAttributes({\r\n // Even if there are no changes in elements, newInternalStore is new array with the same content which may cause unnecessary rerenders\r\n ...(updatedElementIds.length > 0 ? { elements: newInternalStore } : {}),\r\n latestRemoteUpdateTimestamp: newLastUpdateTimestamp,\r\n latestLocalUpdateTimestamp:\r\n isRefetchAll && newInternalStore.length > 0\r\n ? receiveHlc(drawingsInternalStore.latestLocalUpdateTimestamp, newLastUpdateTimestamp)\r\n : drawingsInternalStore.latestLocalUpdateTimestamp,\r\n })\r\n\r\n if (updatedElementIds.length > 0 || isRefetchAll) {\r\n saveLatestChanges(0)\r\n const allElements = chartLayout.getAllElements()\r\n updatedElementIds.forEach((elementId) => {\r\n const element = allElements.find((element) => element.elementId === elementId)\r\n\r\n if (element && element.isDrawing() && !element.hasOngoingInteraction()) {\r\n element.destroyCascade()\r\n }\r\n })\r\n\r\n drawingsInternalStore.elements.forEach(syncChartLayoutDrawings)\r\n chartLayout.getAllPanes().forEach((paneModel) => {\r\n paneModel.normalizeZIndexes()\r\n })\r\n\r\n if (chartLayout.specificChartFunctionality === SpecificChartFunctionality.quotePage) {\r\n const activeTicker = chartLayout.activeChart?.getQuoteRawTicker() ?? ''\r\n handleIdeaNoteChange(getTickerNoteText({ ticker: activeTicker, elements: newInternalStore }))\r\n }\r\n }\r\n },\r\n [\r\n chartLayout,\r\n drawingsInternalStore,\r\n syncChartLayoutDrawings,\r\n fetchDrawings,\r\n handleIdeaNoteChange,\r\n saveLatestChanges,\r\n ]\r\n )\r\n\r\n const updateInternalStoreWithElement = React.useCallback(\r\n (element: Element, changeType: AutoSaveChangeType) => {\r\n const updateResult = updateInternalStoreWithChangedElement({\r\n element,\r\n changeType,\r\n currentInternalStore: drawingsInternalStore.elements,\r\n lastUpdateTimestamp: incrementHlc(\r\n receiveHlc(\r\n drawingsInternalStore.latestLocalUpdateTimestamp,\r\n drawingsInternalStore.latestRemoteUpdateTimestamp\r\n ),\r\n Date.now()\r\n ),\r\n })\r\n\r\n if (updateResult) {\r\n const { shouldSyncAndSave, newInternalStore, newDrawing } = updateResult\r\n if (shouldSyncAndSave) {\r\n drawingsInternalStore.updateAttributes({ elements: newInternalStore })\r\n syncChartLayoutDrawings(newDrawing)\r\n }\r\n }\r\n },\r\n [syncChartLayoutDrawings, drawingsInternalStore]\r\n )\r\n\r\n const deleteAllAutoSavedElements = React.useCallback(async () => {\r\n const { tickers } = getTickersAndContainerTypesInLayoutModel(chartLayout)\r\n\r\n await deleteAllDrawings({ tickers, lastLocalChange: drawingsInternalStore.latestLocalUpdateTimestamp })\r\n await checkDrawingUpdate()\r\n }, [chartLayout, deleteAllDrawings, drawingsInternalStore, checkDrawingUpdate])\r\n\r\n const onElementChange = React.useCallback(\r\n (element: Element, _?: any, options?: DrawingSpineOptions) => {\r\n const elementPane = element.pane()\r\n // This may happen if pane had been removed already, in most cases \"element.destroyed\" should be true,\r\n // but we would need to check if it was destroyed by delete drawing action or not, and checking if pane exists covers all cases\r\n if (!element.isDrawing() || element.instance.isCreator || !elementPane) {\r\n return\r\n }\r\n const elementContainerType = getContainerType(elementPane)\r\n const elementPaneTicker = elementPane.getQuoteRawTicker()\r\n const isElementInCurrentChartLayout = chartLayout\r\n .getAllPanes()\r\n .some(\r\n (model) => getContainerType(model) === elementContainerType && model.getQuoteRawTicker() === elementPaneTicker\r\n )\r\n if (isElementInCurrentChartLayout) {\r\n const isRemove = options?.eventType === DrawingSpineOptionsEvent.Remove\r\n updateInternalStoreWithElement(element, isRemove ? 'destroy' : 'update')\r\n }\r\n },\r\n [updateInternalStoreWithElement, chartLayout]\r\n )\r\n\r\n return {\r\n drawingsInternalStore,\r\n onElementChange,\r\n handleIdeaNoteChange,\r\n deleteAllAutoSavedElements,\r\n isAutoSaveActive,\r\n handleAutoSaveNoteChange,\r\n syncChartLayoutDrawings,\r\n saveLatestChanges,\r\n checkDrawingUpdate,\r\n }\r\n}\r\n","import React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { getIsPreserveDrawingsAndAutosaveAvailable } from '../../utils/chart'\r\n\r\nexport function useIsAutoSaveActive(chartLayout: ChartLayout) {\r\n const chartLayoutModel = useModelState(chartLayout, {\r\n watchProperties: ['isInit', 'isPreserveDrawingsActive', 'idea'],\r\n })\r\n const { idea, isInit, isPreserveDrawingsActive } = chartLayoutModel\r\n return React.useMemo(\r\n () =>\r\n getIsPreserveDrawingsAndAutosaveAvailable(chartLayoutModel) && isPreserveDrawingsActive && !!isInit && !idea?.id,\r\n [isPreserveDrawingsActive, isInit, idea?.id, chartLayoutModel]\r\n )\r\n}\r\n","import { intervalCallbackOnWindowVisible } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { CustomSpineEvents } from '../../../types/shared'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartModel from '../../models/chart'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { AutoSaveState } from '../../models/constants'\r\nimport Element from '../../models/element'\r\nimport { usePrevious } from '../../utils/use-prev-state'\r\nimport { DRAWINGS_UPDATE_INTERVAL_MS } from './constants'\r\nimport { useDrawingAutoSaveControls } from './use-drawing-auto-save-controls'\r\nimport { getTickersAndContainerTypesInLayoutModel } from './utils'\r\n\r\nfunction useDrawingAutoSave(chartLayout: ChartLayout) {\r\n const {\r\n onElementChange,\r\n deleteAllAutoSavedElements,\r\n checkDrawingUpdate,\r\n syncChartLayoutDrawings,\r\n saveLatestChanges,\r\n isAutoSaveActive,\r\n } = useDrawingAutoSaveControls(chartLayout)\r\n\r\n const drawingsInternalStoreUnwatched = React.useMemo(() => chartLayout.drawingsInternalStore(), [chartLayout])\r\n const drawingsInternalStore = useModelState(drawingsInternalStoreUnwatched, { watchProperties: ['elements'] })\r\n const prevIsAutoSaveActive = usePrevious(isAutoSaveActive)\r\n\r\n const runInitialSaveAndRefetchUpdate = React.useCallback(async () => {\r\n chartLayout.getAllElements().forEach((element) => {\r\n // Adds drawings to internal store if isAutoSaveActive and they are not in the store yet\r\n if (!drawingsInternalStore.elements.some((drawing) => drawing.elementId === element.elementId)) {\r\n onElementChange(element)\r\n }\r\n })\r\n\r\n // We want to save everything except notes because saving notes can overwrite those already saved in db. Each drawing has different id but there is only one note per ticker\r\n // Notes are merged in checkDrawingUpdate fn\r\n await saveLatestChanges(0, (item) => item.containerType !== 'note')\r\n\r\n checkDrawingUpdate(true)\r\n }, [checkDrawingUpdate, chartLayout, onElementChange, drawingsInternalStore.elements, saveLatestChanges])\r\n\r\n React.useEffect(() => {\r\n if (isAutoSaveActive) {\r\n saveLatestChanges()\r\n }\r\n }, [saveLatestChanges, drawingsInternalStore.elements, isAutoSaveActive])\r\n\r\n React.useEffect(() => {\r\n if (!isAutoSaveActive) {\r\n chartLayout.drawingsInternalStore().setAutoSaveState(AutoSaveState.Off)\r\n return\r\n }\r\n chartLayout.drawingsInternalStore().setAutoSaveState(AutoSaveState.Saved)\r\n if (!prevIsAutoSaveActive && isAutoSaveActive) {\r\n runInitialSaveAndRefetchUpdate()\r\n }\r\n\r\n let { tickers, containerTypes } = getTickersAndContainerTypesInLayoutModel(chartLayout)\r\n\r\n const onChartOrIndicatorChange = () => {\r\n const { tickers: newTickers, containerTypes: newContainerTypes } =\r\n getTickersAndContainerTypesInLayoutModel(chartLayout)\r\n if (\r\n JSON.stringify(tickers) !== JSON.stringify(newTickers) ||\r\n JSON.stringify(containerTypes) !== JSON.stringify(newContainerTypes)\r\n ) {\r\n tickers = newTickers\r\n containerTypes = newContainerTypes\r\n checkDrawingUpdate(true)\r\n }\r\n }\r\n\r\n ChartModel.bind(`${CustomSpineEvents.IndicatorsChange} change`, onChartOrIndicatorChange)\r\n Element.bind('change', onElementChange)\r\n\r\n drawingsInternalStore.elements.forEach(syncChartLayoutDrawings)\r\n const checkDrawingUpdateSubscription = intervalCallbackOnWindowVisible(\r\n { interval: DRAWINGS_UPDATE_INTERVAL_MS },\r\n checkDrawingUpdate\r\n )\r\n\r\n const unregisterListeners = () => {\r\n checkDrawingUpdateSubscription()\r\n ChartModel.unbind(`${CustomSpineEvents.IndicatorsChange} change`, onChartOrIndicatorChange)\r\n Element.unbind('change', onElementChange)\r\n }\r\n\r\n ChartLayout.bind('change', (model: ChartLayout) => {\r\n if (model.willDestroy) {\r\n unregisterListeners()\r\n }\r\n })\r\n\r\n return unregisterListeners\r\n }, [\r\n chartLayout,\r\n drawingsInternalStore,\r\n checkDrawingUpdate,\r\n onElementChange,\r\n syncChartLayoutDrawings,\r\n isAutoSaveActive,\r\n prevIsAutoSaveActive,\r\n runInitialSaveAndRefetchUpdate,\r\n ])\r\n\r\n return { deleteAllAutoSavedElements, isAutoSaveActive }\r\n}\r\n\r\ninterface Props {\r\n chartLayoutModel: ChartLayout\r\n}\r\n\r\nexport const withDrawingsAutoSave = (Component: any) => (props: Props) => {\r\n const { deleteAllAutoSavedElements, isAutoSaveActive } = useDrawingAutoSave(props.chartLayoutModel)\r\n\r\n return (\r\n \r\n )\r\n}\r\n","import React from 'react'\r\n\r\nexport function usePrevious(value: any) {\r\n const ref = React.useRef()\r\n React.useEffect(() => {\r\n ref.current = value\r\n }, [value])\r\n return ref.current\r\n}\r\n","import { Paragraph, withSuspense } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport math from '../../helpers/math'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { QuoteFetchType } from '../../models/quote/constants'\r\nimport { getTickerChange } from '../../utils/chart'\r\nimport { useChartLayoutGlobalModelAsync } from '../../utils/useChartLayoutGlobalModelAsync'\r\n\r\ninterface Props {\r\n chartIndex: number\r\n}\r\n\r\ninterface ChangeLabelProps {\r\n children: React.ReactNode\r\n changePoints: number\r\n isTiny: boolean\r\n}\r\n\r\nconst CHANGE_UPATE_EVENTS = ['change', 'update']\r\nconst QUOTE_MODEL_CHANGE_EVENTS = [...CHANGE_UPATE_EVENTS, ...Object.values(QuoteFetchType)]\r\n\r\nfunction ChangeLabel({ children, changePoints, isTiny }: ChangeLabelProps) {\r\n return (\r\n 0,\r\n 'text-red-400': changePoints < 0,\r\n })}\r\n >\r\n {children}\r\n \r\n )\r\n}\r\n\r\nexport function DailyChangeDisplayComponent({ chartIndex }: Props) {\r\n const { chartLayoutModel } = useChartLayoutGlobalModelAsync()\r\n const chartModel = useModelState(chartLayoutModel?.getAllCharts()[chartIndex] ?? null, {\r\n watchProperties: ['quote'],\r\n listenOnEvents: CHANGE_UPATE_EVENTS,\r\n })\r\n const quoteModel = useModelState(chartModel?.quote() ?? null, {\r\n watchProperties: ['lastClose', 'prevClose', 'afterClose'],\r\n listenOnEvents: QUOTE_MODEL_CHANGE_EVENTS,\r\n })\r\n\r\n const tickerChange = quoteModel && getTickerChange({ data: quoteModel })\r\n const isTiny =\r\n !!tickerChange?.tickerChange &&\r\n math.getInstrumentDecimalPlaces({\r\n instrument: quoteModel!.instrument,\r\n value: quoteModel!.lastClose,\r\n }) >= 6\r\n\r\n return (\r\n \r\n {tickerChange?.tickerChange && (\r\n <>\r\n {tickerChange.tickerAfterChange && (\r\n \r\n {tickerChange.tickerAfterChange.string}\r\n \r\n )}\r\n \r\n {tickerChange.tickerChange.string}\r\n \r\n \r\n )}\r\n \r\n )\r\n}\r\n\r\nexport const DailyChangeDisplay = React.memo(\r\n withSuspense(DailyChangeDisplayComponent),\r\n (prevProps, nextProps) => prevProps.chartIndex === nextProps.chartIndex\r\n)\r\n","import { Button, ButtonComponentProps, setCookieRequest } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport utils from '../../utils'\r\nimport { DRAWING_COOKIE_NAME, getIsDrawingEnabled } from '../../utils/chart'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\n\r\nconst utmCampaign: Partial> = {\r\n [SpecificChartFunctionality.quotePage]: 'quote-draw-button',\r\n [SpecificChartFunctionality.futuresPage]: 'futures-interactive-chart',\r\n [SpecificChartFunctionality.forexPage]: 'forex-interactive-chart',\r\n [SpecificChartFunctionality.cryptoPage]: 'crypto-interactive-chart',\r\n}\r\n\r\nconst testId: Partial> = {\r\n [SpecificChartFunctionality.quotePage]: 'quote-toggle-draw-btn',\r\n [SpecificChartFunctionality.futuresPage]: 'futures-interactive',\r\n [SpecificChartFunctionality.forexPage]: 'forex-interactive',\r\n [SpecificChartFunctionality.cryptoPage]: 'crypto-interactive',\r\n}\r\n\r\ninterface DrawButtonProps extends Pick {\r\n isPremium: boolean\r\n specificChartFunctionality: SpecificChartFunctionality\r\n active?: boolean\r\n}\r\n\r\nexport function DrawButton({\r\n isPremium,\r\n specificChartFunctionality,\r\n ...props\r\n}: React.PropsWithChildren) {\r\n const buttonProps = React.useMemo(() => {\r\n if (!isPremium) {\r\n return {\r\n as: 'a' as const,\r\n href: `/elite.ashx?${encodeQueryString({\r\n utm_source: 'finviz',\r\n utm_medium: 'banner',\r\n utm_campaign: utmCampaign[specificChartFunctionality],\r\n })}`,\r\n }\r\n }\r\n\r\n return {\r\n onClick: (ev: React.MouseEvent) => {\r\n ev.preventDefault()\r\n const newValue = getIsDrawingEnabled() ? 'off' : 'on'\r\n\r\n setCookieRequest(DRAWING_COOKIE_NAME, newValue)\r\n .catch(() => {\r\n // fallback to JS otherwise draw toggle won't work if API don't work\r\n const expires = new Date()\r\n expires.setMonth(expires.getMonth() + 1)\r\n utils.setCookie(DRAWING_COOKIE_NAME, newValue, expires)\r\n })\r\n .finally(() => {\r\n const { i: idea, ...rest } = decodeQueryString()\r\n if (idea) {\r\n document.location = `quote.ashx?${encodeQueryString(rest)}`\r\n } else {\r\n document.location.reload()\r\n }\r\n })\r\n },\r\n }\r\n }, [isPremium, specificChartFunctionality])\r\n\r\n return (\r\n \r\n )\r\n}\r\n","import { Button, ButtonComponentProps } from '@finviz/website'\r\nimport * as React from 'react'\r\nimport { useLocation } from 'react-router-dom'\r\n\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\n\r\nfunction getTickersString(tickers: string[], tickersCount: number) {\r\n return Array.from({ length: Math.min(tickersCount, 6) })\r\n .map((_, index) => tickers[index] ?? tickers[tickers.length - 1])\r\n .join(',')\r\n}\r\n\r\nfunction getLayoutType(tickersCount: number) {\r\n switch (tickersCount) {\r\n case 0: // shouldn't happen\r\n case 1:\r\n return '1h1v'\r\n case 2:\r\n return '2h1v'\r\n case 3:\r\n return '3h1v'\r\n case 4:\r\n return '2h2v'\r\n case 5:\r\n default:\r\n // 6 and more\r\n return '3h2v'\r\n }\r\n}\r\n\r\nconst utmCampaign: Partial> = {\r\n [SpecificChartFunctionality.quotePage]: 'quote-fullscreen-button',\r\n [SpecificChartFunctionality.futuresPage]: 'futures-fullscreen-button',\r\n [SpecificChartFunctionality.forexPage]: 'forex-fullscreen-button',\r\n [SpecificChartFunctionality.cryptoPage]: 'crypto-fullscreen-button',\r\n}\r\n\r\ninterface FullscreenButtonProps extends Pick {\r\n model: ChartLayout\r\n isPremium: boolean\r\n title?: string\r\n}\r\n\r\nexport function FullscreenButton({ model, isPremium, ...props }: React.PropsWithChildren) {\r\n const location = useLocation()\r\n const { i, p = 'd', r } = decodeQueryString(location.search)\r\n const urlTickers = model\r\n .charts()\r\n .all()\r\n .map((chart) => chart.quote().getRawTicker())\r\n\r\n return (\r\n p).join(','),\r\n l: getLayoutType(urlTickers.length),\r\n r,\r\n })}`\r\n : `/elite.ashx?${encodeQueryString({\r\n utm_source: 'finviz',\r\n utm_medium: 'banner',\r\n utm_campaign: utmCampaign[model.specificChartFunctionality],\r\n })}`\r\n }\r\n />\r\n )\r\n}\r\n","import {\r\n Button,\r\n Dialog,\r\n Dropdown,\r\n DropdownItem,\r\n Icon,\r\n Spinner,\r\n Search as WebsiteSearchComponent,\r\n createAlertAsyncModule,\r\n saveToPortfolioAsyncModule,\r\n useDialogState,\r\n} from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { Instrument } from '../../../types/shared'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\n\r\ninterface SearchProps {\r\n ticker: string\r\n instrument: Instrument\r\n onTickerSelected: (ticker: string) => void\r\n chartIndex: number\r\n}\r\n\r\nexport default function Search({ ticker, instrument, onTickerSelected, chartIndex }: SearchProps) {\r\n const saveToPortfolioDialogState = useDialogState()\r\n const isSaveToPortfolioVisible = saveToPortfolioDialogState.useState('open')\r\n const createAlertDialogState = useDialogState()\r\n const isCreateAlertVisible = createAlertDialogState.useState('open')\r\n const [saveToPortfolioModule, { isLoading: isLoadingSaveToPortfolio }] = useAsyncModule({\r\n ...saveToPortfolioAsyncModule,\r\n shouldLoadModule: isSaveToPortfolioVisible,\r\n onError: () => saveToPortfolioDialogState.hide(),\r\n })\r\n const [createAlertModule, { isLoading: isLoadingCreateAlert }] = useAsyncModule({\r\n ...createAlertAsyncModule,\r\n shouldLoadModule: isCreateAlertVisible,\r\n onError: () => createAlertDialogState.hide(),\r\n })\r\n const SaveToPortfolio = saveToPortfolioModule?.SaveToPortfolio\r\n const CreateAlert = createAlertModule?.CreateAlert\r\n\r\n const detailLink = React.useMemo(() => {\r\n const formattedTicker = ticker.replace('@', '')\r\n\r\n switch (instrument) {\r\n case Instrument.Stock:\r\n return `/quote.ashx?t=${formattedTicker}`\r\n case Instrument.Futures:\r\n return `/futures_charts.ashx?t=${formattedTicker}`\r\n case Instrument.Forex:\r\n return `/forex_charts.ashx?t=${formattedTicker}`\r\n case Instrument.Crypto:\r\n return `/crypto_charts.ashx?t=${formattedTicker}`\r\n }\r\n }, [ticker, instrument])\r\n\r\n return (\r\n

\r\n }\r\n />\r\n }\r\n >\r\n {\r\n window.gtag?.('event', 'click', { event_category: 'open-stock-detail' })\r\n }}\r\n >\r\n {instrument === Instrument.Stock ? 'Open Stock Detail' : 'Open Detail'}\r\n \r\n {instrument === Instrument.Stock && (\r\n {\r\n saveToPortfolioDialogState.show()\r\n window.gtag?.('event', 'click', { event_category: 'save-to-portfolio' })\r\n }}\r\n >\r\n Save to Portfolio\r\n \r\n )}\r\n {instrument === Instrument.Stock && (\r\n {\r\n createAlertDialogState.show()\r\n window.gtag?.('event', 'click', { event_category: 'create-alert' })\r\n }}\r\n >\r\n Create Alert\r\n \r\n )}\r\n \r\n }\r\n />\r\n \r\n {isLoadingSaveToPortfolio && (\r\n
\r\n \r\n
\r\n )}\r\n {SaveToPortfolio && }\r\n
\r\n \r\n {isLoadingCreateAlert && (\r\n
\r\n \r\n
\r\n )}\r\n {CreateAlert && }\r\n
\r\n
\r\n )\r\n}\r\n","import {\r\n ButtonRoundingType,\r\n ButtonSizeType,\r\n CustomDateRange,\r\n Heading,\r\n TimeframeBar,\r\n ZIndexContext,\r\n useCustomDateRangeDialog,\r\n useFavoriteTimeframes,\r\n} from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport React from 'react'\r\nimport { useNavigate } from 'react-router-dom'\r\n\r\nimport { ChartEditorEnum, SpecificChartFunctionality, TIMEFRAME } from '../../constants/common'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport Chart from '../../models/chart'\r\nimport { IdeasDropdown } from '../header/ideas_dropdown'\r\nimport { Publish } from '../header/publish'\r\nimport { TourButton } from '../header/tour_button'\r\nimport { ChartTypesSelect } from './chart-type-select'\r\nimport { DailyChangeDisplay } from './daily-change-display'\r\nimport { DrawButton } from './draw-button'\r\nimport { FullscreenButton } from './fullscreen-button'\r\nimport Search from './search'\r\nimport { ChartSettingsButton } from './settings-button'\r\nimport { useChartControls } from './use-chart-controls'\r\nimport { useChartModelCustomDateRangeValues } from './use-chart-model-custom-date-range-values'\r\n\r\ninterface SettingsComponentProps {\r\n chartModel: Chart\r\n chartIndex: number\r\n}\r\n\r\nconst isPremium = window.FinvizSettings.hasUserPremium\r\nconst hasRedesignEnabled = window.FinvizSettings.hasRedesignEnabled\r\n\r\nexport function ChartControls({ chartIndex, chartModel: unwatchedChartModel }: SettingsComponentProps) {\r\n const rounding: ButtonRoundingType | undefined = hasRedesignEnabled ? undefined : 'none'\r\n // This memo is required for publish, otherwise it ends up in a loop\r\n const chartLayout = React.useMemo(() => unwatchedChartModel.chart_layout(), [unwatchedChartModel])\r\n const chartModel = useModelState(unwatchedChartModel, {\r\n watchProperties: ['ticker', 'quote', 'dateRange'],\r\n })\r\n const { instrument } = chartModel?.quote() || {}\r\n const isQuotePage = chartLayout.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n const isQuoteFinancials = chartLayout.specificChartFunctionality === SpecificChartFunctionality.quoteFinancials\r\n\r\n const navigate = useNavigate()\r\n const { favoriteTimeframes, toggleFavoriteTimeframe } = useFavoriteTimeframes()\r\n const { isLoading } = useChartControls({\r\n chartModel,\r\n isInteractive: true,\r\n })\r\n const {\r\n anchorDate,\r\n generateChartLayoutRouterPath,\r\n timeframeGroupsWithHref,\r\n dateRangeGroupsWithHref,\r\n isFetching,\r\n handleCustomDateRangeValidation,\r\n } = useChartModelCustomDateRangeValues({ chartModel, isPremium })\r\n const { onDialogSubmit, customDateRangeDialogState, handleDateRangeSelect, getDateRangeTimeframe } =\r\n useCustomDateRangeDialog({\r\n instrument,\r\n anchorDate,\r\n pathGenerator: generateChartLayoutRouterPath,\r\n })\r\n\r\n const handleTickerSelect = React.useCallback(\r\n (ticker: string) => {\r\n const upperCaseTicker = ticker.toUpperCase()\r\n\r\n navigate(\r\n generateChartLayoutRouterPath({\r\n ticker: upperCaseTicker,\r\n timeframe: chartModel.timeframe,\r\n dateRange: chartModel.dateRange,\r\n })\r\n )\r\n },\r\n [chartModel, generateChartLayoutRouterPath, navigate]\r\n )\r\n\r\n async function handleCustomRangeSubmit(values: { dateRange: string | null }) {\r\n const dateRangeTimeframe = values.dateRange\r\n ? getDateRangeTimeframe(values.dateRange)\r\n : { value: '', timeframe: chartModel.timeframe }\r\n\r\n if (dateRangeTimeframe === null) {\r\n return\r\n } else if (dateRangeTimeframe.value) {\r\n const isValid = await handleCustomDateRangeValidation(dateRangeTimeframe)\r\n if (!isValid) {\r\n return\r\n }\r\n }\r\n\r\n onDialogSubmit(dateRangeTimeframe)\r\n }\r\n\r\n const timeframeBarProps = React.useMemo(\r\n () => ({\r\n size: 'medium' as ButtonSizeType,\r\n chartIndex: chartIndex,\r\n timeFrameGroups: timeframeGroupsWithHref(isPremium),\r\n dateRangeGroups: dateRangeGroupsWithHref({ isPremium, customRange: chartModel.dateRange, instrument }),\r\n selectedTimeframe: chartModel.timeframe,\r\n onTimeframeSelect: () => {},\r\n selectedDateRange: chartModel.dateRange,\r\n favoriteTimeframes: favoriteTimeframes,\r\n loadingTimeframe: isLoading ? chartModel.timeframe : undefined,\r\n onDateRangeSelect: handleDateRangeSelect,\r\n onCustomDateRangeClick: () => {\r\n if (isPremium) customDateRangeDialogState.show()\r\n },\r\n isFavoritesEnabled: isPremium,\r\n onFavoriteTimeframeToggle: ({ value }: { value: TIMEFRAME | 'intraday' }) => {\r\n toggleFavoriteTimeframe(value)\r\n },\r\n }),\r\n [\r\n chartIndex,\r\n chartModel.dateRange,\r\n chartModel.timeframe,\r\n customDateRangeDialogState,\r\n dateRangeGroupsWithHref,\r\n favoriteTimeframes,\r\n handleDateRangeSelect,\r\n instrument,\r\n isLoading,\r\n timeframeGroupsWithHref,\r\n toggleFavoriteTimeframe,\r\n ]\r\n )\r\n\r\n if (chartLayout.specificChartFunctionality === SpecificChartFunctionality.chartPage) {\r\n return (\r\n \r\n
\r\n {chartModel.chart_layout().canChangeTicker && (\r\n \r\n )}\r\n\r\n \r\n\r\n \r\n\r\n \r\n
\r\n
\r\n )\r\n }\r\n\r\n const hasTimeframe = chartLayout.editors.includes(ChartEditorEnum.timeframe)\r\n\r\n return (\r\n \r\n
\r\n {!isQuotePage && !isQuoteFinancials && (\r\n \r\n {chartModel.quote().name ?? chartModel.ticker}\r\n \r\n )}\r\n {chartLayout.editors.includes(ChartEditorEnum.tools) && (\r\n \r\n Draw\r\n \r\n )}\r\n {chartLayout.editors.includes(ChartEditorEnum.ideas) && (\r\n \r\n Ideas\r\n \r\n )}\r\n {!hasTimeframe && (\r\n
\r\n \r\n
\r\n )}\r\n
\r\n\r\n {hasTimeframe && (\r\n
\r\n
\r\n {!isQuoteFinancials && (\r\n
\r\n \r\n
\r\n )}\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n )}\r\n\r\n \r\n {chartLayout.editors.includes(ChartEditorEnum.publish) && (\r\n \r\n Share\r\n \r\n )}\r\n {isQuotePage && (\r\n \r\n )}\r\n {!isQuoteFinancials && (\r\n \r\n {!isQuotePage && 'Fullscreen'}\r\n \r\n )}\r\n {chartLayout.editors.includes(ChartEditorEnum.settings) && (\r\n \r\n {!isQuotePage && 'Settings'}\r\n \r\n )}\r\n {!isQuotePage && !isQuoteFinancials && (\r\n
\r\n \r\n
\r\n )}\r\n \r\n \r\n )\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport { ContextMenuItem } from '@finviz/website'\r\n\r\nexport type CallbacksType = {\r\n onFullyOpen: () => void\r\n onFullyClosed: () => void\r\n onBeforeItemClick: () => void\r\n}\r\n\r\nclass ContextMenu extends Spine.Model {\r\n static initClass() {\r\n this.configure('ContextMenu', 'shown', 'config', 'anchorRect', 'callbacks')\r\n }\r\n\r\n declare shown: boolean\r\n declare config: ContextMenuItem[]\r\n declare anchorRect: { x: number; y: number }\r\n declare callbacks: CallbacksType | undefined\r\n}\r\n\r\nContextMenu.initClass()\r\n\r\nconst contextMenu = ContextMenu.create() as ContextMenu\r\ncontextMenu.save()\r\n\r\nexport default contextMenu\r\n","import { ContextMenu as ContextMenuComponent, useDropdownState } from '@finviz/website'\r\nimport React from 'react'\r\nimport * as ReactDOM from 'react-dom/client'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\nimport { useModelState } from '../model-hooks/use-model-state'\r\nimport model, { CallbacksType } from '../models/context_menu'\r\nimport { ready } from '../utils'\r\n\r\nfunction ContextMenu() {\r\n const watchedModel = useModelState(model, {\r\n watchProperties: ['shown', 'anchorRect', 'config', 'callbacks'],\r\n })\r\n const state = useDropdownState({ open: watchedModel.shown })\r\n\r\n return (\r\n ev.type !== 'contextmenu'}\r\n state={state}\r\n items={watchedModel.config?.map((item) => ({\r\n ...item,\r\n onClick: () => {\r\n watchedModel.callbacks?.onBeforeItemClick()\r\n if ('onClick' in item) {\r\n item.onClick?.()\r\n }\r\n },\r\n }))}\r\n getAnchorRect={() => watchedModel.anchorRect}\r\n onClose={() => model.updateAttribute('shown', false)}\r\n onFullyOpen={watchedModel.callbacks?.onFullyOpen}\r\n onFullyClosed={watchedModel.callbacks?.onFullyClosed}\r\n data-testid=\"charts-context-menu-body\"\r\n backdrop={\r\n {\r\n ev.preventDefault()\r\n ev.stopPropagation()\r\n }}\r\n />\r\n }\r\n />\r\n )\r\n}\r\n\r\nready(() => {\r\n const rootEl = document.querySelector('.context-menu')\r\n if (rootEl) {\r\n const root = ReactDOM.createRoot(rootEl!)\r\n root.render()\r\n }\r\n})\r\n\r\nconst contextMenuControl = {\r\n show: (event: MouseEvent | React.MouseEvent, config: ObjectHash, callbacks: CallbacksType) => {\r\n model.updateAttributes({\r\n shown: true,\r\n config: config,\r\n callbacks,\r\n anchorRect: {\r\n x: event.clientX,\r\n y: event.clientY,\r\n },\r\n })\r\n },\r\n}\r\n\r\nexport default contextMenuControl\r\n","import { Delayed, DialogBody, Popover, PopoverAnchor, Spinner, usePopoverState } from '@finviz/website'\r\nimport classNames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartModel from '../../models/chart'\r\nimport Utils from '../../utils'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\nimport { useClickAway } from '../../utils/use-click-away'\r\nimport { chartEventsAsyncModule } from '../chart-events/async-modules'\r\n\r\nconst isMobile = Utils.isMobile()\r\n\r\ninterface ChartEventPopoverWithStateProps {\r\n chartModel: ChartModel\r\n}\r\n\r\nexport function ChartEventPopoverWithState({ chartModel }: ChartEventPopoverWithStateProps) {\r\n const unwatchedChartLayout = React.useMemo(() => chartModel.chart_layout() ?? null, [chartModel])\r\n const { activeChartEvent, theme } = useModelState(unwatchedChartLayout, { watchProperties: ['activeChartEvent'] })\r\n const lastEventId = React.useRef(activeChartEvent?.id)\r\n const popoverState = usePopoverState({ placement: 'top' })\r\n const isPopoverMounted = popoverState.useState('mounted')\r\n const [style, setStyle] = React.useState({ top: 0, left: 0 })\r\n const [chartEventsModule] = useAsyncModule({\r\n ...chartEventsAsyncModule,\r\n shouldLoadModule: isPopoverMounted,\r\n errorSeverity: 'medium',\r\n onError: () => popoverState.hide(),\r\n })\r\n const isChartEventOfThisChart = activeChartEvent?.pane().chart().eql(chartModel)\r\n const [data, setData] = React.useState(null)\r\n const clickAwayRef = useClickAway(() => {\r\n const isAnyBadgeHovered = !!chartModel\r\n .getChartPane()\r\n ?.getAllChartEvents()\r\n .some((chartEvent) => chartEvent.instance.isHovered)\r\n\r\n if (!isAnyBadgeHovered && activeChartEvent && isChartEventOfThisChart) {\r\n activeChartEvent.instance.toggleIsOpen(false)\r\n }\r\n // Due to the fact that chart events logic depends heavily on hover state which isn't really present on touch devices\r\n // we need to mimic that state for touch devices, this enables chart event closed on click outside and counterpart in\r\n // chart-events.ts allow chart event to be open\r\n if (activeChartEvent && isMobile) {\r\n activeChartEvent.instance.setIsHovered(false)\r\n }\r\n }, !!activeChartEvent && isChartEventOfThisChart)\r\n // This is intentional, it doesn't need to be in useEffect, it would just call effect function which is redundant\r\n clickAwayRef.current = popoverState.useState('popoverElement')\r\n const popoverShow = popoverState.show\r\n const popoverHide = popoverState.hide\r\n\r\n React.useEffect(() => {\r\n lastEventId.current = activeChartEvent?.id\r\n if (!activeChartEvent?.instance.isOpen || !isChartEventOfThisChart) {\r\n if (!isPopoverMounted) {\r\n return setData(null)\r\n }\r\n return popoverHide()\r\n }\r\n if (!isChartEventOfThisChart) return\r\n const { top, left } = activeChartEvent.instance\r\n const newData = activeChartEvent.getChartEventData()\r\n if (newData?.elementId !== data?.elementId) {\r\n setData({\r\n ...newData,\r\n badgeType: activeChartEvent.instance.getChartEvenBadgeType(),\r\n })\r\n }\r\n\r\n if (style.top !== top || style.left !== left) {\r\n setStyle({ top, left })\r\n }\r\n if (!isPopoverMounted) {\r\n popoverShow()\r\n }\r\n }, [\r\n activeChartEvent,\r\n data?.elementId,\r\n isChartEventOfThisChart,\r\n isPopoverMounted,\r\n popoverHide,\r\n popoverShow,\r\n popoverState,\r\n style.left,\r\n style.top,\r\n ])\r\n\r\n return (\r\n <>\r\n \r\n {data && (\r\n \r\n \r\n {chartEventsModule ? (\r\n \r\n ) : (\r\n
\r\n \r\n \r\n \r\n
\r\n )}\r\n \r\n \r\n )}\r\n \r\n )\r\n}\r\n","import React from 'react'\r\n\r\nimport Utils from '../utils'\r\n\r\nexport function useClickAway(callback: (event: MouseEvent | TouchEvent) => void, isListening = true) {\r\n const ref = React.useRef(null)\r\n const refCallback = React.useRef(callback)\r\n\r\n React.useLayoutEffect(() => {\r\n refCallback.current = callback\r\n })\r\n\r\n React.useEffect(() => {\r\n if (!isListening) {\r\n return\r\n }\r\n const isMobile = Utils.isMobile()\r\n const handler = (e: MouseEvent | TouchEvent) => {\r\n const element = ref.current\r\n if (element && e.target && !element.contains(e.target as HTMLElement)) {\r\n refCallback.current(e)\r\n }\r\n }\r\n\r\n document.addEventListener(isMobile ? 'touchstart' : 'mousedown', handler)\r\n\r\n return () => {\r\n document.removeEventListener(isMobile ? 'touchstart' : 'mousedown', handler)\r\n }\r\n }, [callback, isListening])\r\n\r\n return ref\r\n}\r\n","import { Button, ButtonGroup, Delayed, Icon, Spinner } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport Chart from '../../models/chart'\r\nimport { QuoteFetchType } from '../../models/quote/constants'\r\nimport { useIsMounted } from '../../utils/use-is-mounted'\r\n\r\ninterface LoadLatestDataButtonProps {\r\n chartModel: Chart\r\n}\r\n\r\nexport function LoadLatestDataButton({ chartModel: chartModelUnwatched }: LoadLatestDataButtonProps) {\r\n const getIsMounted = useIsMounted()\r\n const chartModel = useModelState(chartModelUnwatched, { watchProperties: ['quote'] })\r\n const quoteModel = useModelState(chartModel.quote(), { watchProperties: ['isFetching'] })\r\n const [hasNewDataAvailable, setHasNewDataAvailable] = React.useState(false)\r\n\r\n React.useEffect(() => {\r\n if (!chartModel.getRefreshInterval()) {\r\n // We will do a check here if we have correct new data\r\n chartModel\r\n .quote()\r\n .isPossibleToFetchSequentialData()\r\n .then((hasNewData) => {\r\n if (getIsMounted()) {\r\n setHasNewDataAvailable(hasNewData)\r\n }\r\n })\r\n }\r\n // We need to run it only on mount\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n const handleLoadLatestData = async () => {\r\n const promises = chartModel\r\n .getAllQuotes()\r\n .map(async (quote) => quote.fetchData({ fetchType: QuoteFetchType.NewerData }))\r\n chartModel.updateAttributes({ refreshData: true })\r\n await Promise.all(promises)\r\n if (getIsMounted()) {\r\n setHasNewDataAvailable(false)\r\n window.gtag?.('event', 'load-latest-data', { event_category: 'ideas' })\r\n }\r\n }\r\n\r\n if (!hasNewDataAvailable) {\r\n return null\r\n }\r\n\r\n return (\r\n \r\n }>\r\n \r\n \r\n ) : (\r\n 'refresh'\r\n )\r\n }\r\n disabled={quoteModel?.isFetching}\r\n title=\"Load latest data\"\r\n onClick={handleLoadLatestData}\r\n data-testid=\"load-latest-data-button\"\r\n >\r\n Load latest data\r\n \r\n \r\n )\r\n}\r\n","// Copy if this file is in Website repo in Website/js/main/hooks/ folder\r\nimport * as React from 'react'\r\n\r\nexport function useIsMounted() {\r\n const isMountedRef = React.useRef(false)\r\n const getIsMounted = React.useCallback(() => isMountedRef.current, [])\r\n\r\n React.useEffect(() => {\r\n isMountedRef.current = true\r\n return () => {\r\n isMountedRef.current = false\r\n }\r\n }, [])\r\n\r\n return getIsMounted\r\n}\r\n","import { Button, ButtonGroup, ButtonSizeType, Icon } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport debounce from 'lodash.debounce'\r\nimport React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport Chart from '../../models/chart'\r\nimport Utils from '../../utils'\r\nimport { getLeftOffset } from '../renderUtils'\r\nimport { LoadLatestDataButton } from './load-latest-data-button'\r\n\r\nexport const ZOOM_CONTROLS_ACTIVE_CLASS = 'is-active'\r\nexport const ZOOM_CONTROLS_IS_IN_AREA_CLASS = 'is-in-area'\r\n\r\nconst buttonCommonProps: { size: ButtonSizeType; className: string; contentClass: string } = {\r\n size: 'none',\r\n className: 'w-7 h-6',\r\n contentClass: 'flex justify-center',\r\n}\r\n\r\nconst isMobile = Utils.isMobile()\r\n\r\ninterface ZoomControlsProps {\r\n zoomControlsRef: React.RefObject\r\n isVisible: boolean\r\n chartModel: Chart\r\n onZoomIn: () => void\r\n onZoomOut: () => void\r\n onZoomReset: () => void\r\n}\r\n\r\nconst getDefaultLeftOffset = (chartModel: Chart) =>\r\n getLeftOffset({\r\n quote: chartModel.quote(),\r\n chartModel,\r\n config: {},\r\n })\r\n\r\nexport function ZoomControls({\r\n zoomControlsRef,\r\n chartModel,\r\n isVisible,\r\n onZoomIn,\r\n onZoomOut,\r\n onZoomReset,\r\n}: ZoomControlsProps) {\r\n const chartLayoutModel = useModelState(chartModel.chart_layout(), { watchProperties: ['idea'] })\r\n const [isGoToRecentVisible, setIsGoToRecentVisible] = React.useState(\r\n () => chartModel.leftOffset !== getDefaultLeftOffset(chartModel)\r\n )\r\n const { defaultZoomFactor } = chartLayoutModel\r\n const [isZoomResetVisible, setIsZoomResetVisible] = React.useState(chartModel.zoomFactor !== defaultZoomFactor)\r\n const handleGoToMostRecent = React.useCallback(() => {\r\n chartModel.updateAttributes({ leftOffset: getDefaultLeftOffset(chartModel), dateRange: null })\r\n }, [chartModel])\r\n\r\n React.useEffect(() => {\r\n const handleChartModelChangeDebounced = debounce(\r\n () => {\r\n setIsZoomResetVisible(chartModel.zoomFactor !== defaultZoomFactor)\r\n setIsGoToRecentVisible(chartModel.leftOffset !== getDefaultLeftOffset(chartModel))\r\n },\r\n 100,\r\n { maxWait: 333 }\r\n )\r\n chartModel.bind('change', handleChartModelChangeDebounced)\r\n return () => {\r\n handleChartModelChangeDebounced.cancel()\r\n chartModel.unbind('change', handleChartModelChangeDebounced)\r\n }\r\n }, [defaultZoomFactor, chartModel])\r\n\r\n return (\r\n \r\n {!isMobile && (\r\n
\r\n {isZoomResetVisible && (\r\n
\r\n \r\n \r\n \r\n \r\n \r\n
\r\n )}\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n
\r\n )}\r\n\r\n
\r\n {!!chartLayoutModel.idea?.id && }\r\n\r\n {isGoToRecentVisible && (\r\n \r\n \r\n \r\n \r\n \r\n )}\r\n
\r\n \r\n )\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport { Button, Notification, NotificationContextType, Paragraph, withNotificationContext } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport Hammer from 'hammerjs'\r\nimport debounce from 'lodash.debounce'\r\nimport React from 'react'\r\n\r\nimport { CustomSpineEvents, DrawingSpineOptionsEvent, EmptyObject, ObjectHash, PaneArea } from '../../../types/shared'\r\nimport CanvasElement from '../../canvas/element'\r\nimport ChartEvent from '../../chart-events/chart-event'\r\nimport { IndicatorType, ScaleType, SetVisibilityTo, SpecificChartFunctionality } from '../../constants/common'\r\nimport IndicatorElement from '../../indicators/indicator'\r\nimport { withElementStyleDialogState } from '../../modals/element_style'\r\nimport ChartModel from '../../models/chart'\r\nimport ChartEventElement from '../../models/chart-event-element'\r\nimport ElementModel from '../../models/element'\r\nimport MouseModel from '../../models/mouse'\r\nimport PaneModel from '../../models/pane'\r\nimport Quote from '../../models/quote'\r\nimport { handleRemoveIndicatorPane } from '../../models/utils'\r\nimport Utils, { isRedesignedPage } from '../../utils'\r\nimport { getContextWithCache } from '../../utils/canvas'\r\nimport { getBarWidthWithMargin, unmountCanvas } from '../../utils/chart'\r\nimport { setElementCursor } from '../../utils/cursor'\r\nimport { getValueInRange, isPrimaryClick } from '../../utils/helpers'\r\nimport { getInitialStoreDrawings } from '../autosave/utils'\r\nimport { CHART_LAYOUT_CHILD_CHANGE_EVENT } from '../chart_layout/constants'\r\nimport ContextMenu from '../context_menu'\r\nimport { getMinMaxLeftOffset, getSettings, recountScale, renderPane } from '../renderUtils'\r\nimport { DrawingTool } from '../toolbar/interfaces'\r\nimport { getChartAlt } from '../utils'\r\nimport { ChartEventPopoverWithState } from './chart-event-popover-with-state'\r\nimport { withPaneModel } from './with-pane-model'\r\nimport { ZOOM_CONTROLS_ACTIVE_CLASS, ZOOM_CONTROLS_IS_IN_AREA_CLASS, ZoomControls } from './zoom_controls'\r\n\r\n// Indicates how many time lower/higher can new scale be compared to original one\r\nconst ALLOWED_MIN_MAX_ZOOM = 10000\r\n\r\ninterface PaneProps {\r\n model: PaneModel\r\n chartModel: ChartModel\r\n activeTool: DrawingTool\r\n activeChartInteraction: string | null\r\n chartIndex: number\r\n paneIndex: number\r\n touchEventsDisabled: boolean\r\n onPaneClick?: (model: PaneModel) => void\r\n onZoomerReset: () => void\r\n onZoomerMouseDown: React.MouseEventHandler\r\n onZoomerTouchStart: React.TouchEventHandler\r\n onAddToZoomFactor: (data: { diff: number; shouldCalculateRightAlign: boolean }) => void\r\n onResizerMouseDown: (e: React.MouseEvent, model: PaneModel) => void\r\n onPaneDestroy: (paneId: string) => void\r\n setActiveChartInteraction: (value: string | null) => void\r\n openElementStyleDialog?: (element: CanvasElement | IndicatorElement) => void\r\n notificationContext: NotificationContextType\r\n}\r\n\r\ninterface PaneState {\r\n hasSeenCrossNotification: boolean\r\n}\r\n\r\nfunction toggleE2eRenderInProgress({ id, isInProgress }: { id: number; isInProgress: boolean }) {\r\n if (process.env.IS_E2E_TESTING) {\r\n window.rendersInProgress = window.rendersInProgress ?? []\r\n\r\n if (isInProgress) {\r\n window.isRenderInProgress = true\r\n window.rendersInProgress.push(id)\r\n } else {\r\n window.rendersInProgress = window.rendersInProgress.filter((progressId) => id !== progressId)\r\n\r\n if (window.rendersInProgress.length === 0) {\r\n window.isRenderInProgress = Date.now()\r\n }\r\n }\r\n }\r\n}\r\n\r\nclass Pane extends React.Component {\r\n rafId?: number | null = null\r\n crossRafId?: number | null = null\r\n quoteModel: Quote\r\n paneRef = React.createRef()\r\n scalerRef = React.createRef()\r\n zoomerRef = React.createRef()\r\n zoomControlsRef = React.createRef()\r\n canvasWrapperRef = React.createRef()\r\n canvasRef = React.createRef()\r\n crossCanvasRef = React.createRef()\r\n chartLayoutModel = this.props.chartModel.chart_layout()\r\n paneHammer!: HammerManager\r\n scalerHammer!: HammerManager\r\n zoomerHammer!: HammerManager\r\n canvasWrapperHammer!: HammerManager\r\n mouseDown = false\r\n lastClientX?: number\r\n lastClientY?: number\r\n currentViewRange: { min: number; max: number } | null = null\r\n lastX!: number\r\n lastY!: number\r\n lastActiveTool: DrawingTool\r\n scalerLastY: number | null = null\r\n isElementHovered = false\r\n hoveredElement: CanvasElement | null = null\r\n isMobile: boolean\r\n isDisableTouchCrossAvailable = true\r\n\r\n canvas: HTMLCanvasElement | null = null\r\n canvasCtx: CanvasRenderingContext2D | null = null\r\n crossCanvas: HTMLCanvasElement | null = null\r\n crossCanvasCtx: CanvasRenderingContext2D | null = null\r\n isIndicatorPane = false\r\n\r\n state: PaneState = {\r\n hasSeenCrossNotification: !!window.localStorage?.getItem('hasSeenCrossNotification'),\r\n }\r\n\r\n // expects chartModel, model, onResizerMouseDown, onPaneDestroy\r\n constructor(props: PaneProps) {\r\n super(props)\r\n\r\n this.quoteModel = this.props.chartModel.quote()\r\n props.model.updateAttribute('instance', this)\r\n props.model.bind('update', this.onModelUpdate)\r\n props.model\r\n .elements()\r\n .bind('create', this.onElementCreate)\r\n .bind('destroy', this.onElementDestroy)\r\n .bind('replace', this.onElementReplace)\r\n .bind('select', this.onElementSelect)\r\n .bind('makeClone', this.onElementClone)\r\n .bind('change', this.immediateRecountScaleOnChartIndicatorChange)\r\n .bind('change', debounce(this.recountScale, 50))\r\n props.model.bind(CustomSpineEvents.ManualChange, this.recountScale)\r\n\r\n props.model.chartEvents().bind('create', this.onElementCreate).bind('change', debounce(this.recountScale, 50))\r\n\r\n this.props.chartModel.bind('update', this.onChartUpdate)\r\n this.props.chartModel.bind(`change ${CustomSpineEvents.IndicatorsChange}`, this.recountScale)\r\n this.quoteModel.bind('change', this.recountScale)\r\n this.isMobile = !!Utils.isMobile()\r\n this.lastActiveTool = props.activeTool\r\n if (!MouseModel.pane()) {\r\n MouseModel.updateAttribute('pane', props.model)\r\n }\r\n this.isIndicatorPane = props.model.getIsIndicatorPane()\r\n this.recountScale()\r\n }\r\n\r\n componentDidMount() {\r\n const { model } = this.props\r\n this.chartLayoutModel.bind('theme', this.renderAll)\r\n this.chartLayoutModel.bind('theme', this.renderCross)\r\n\r\n const initialStoreDrawings = getInitialStoreDrawings() ?? []\r\n const elements = [...model.getAllElements(), ...model.getAllChartEvents(false)]\r\n elements.forEach((element) => {\r\n this.onElementCreate(element)\r\n if (element.isDrawing()) {\r\n const hasDrawingInInitialCache = initialStoreDrawings.some(({ elementId }) => element.elementId === elementId)\r\n if (hasDrawingInInitialCache) {\r\n element.instance?.updateScales()\r\n }\r\n element.instance.cachePointPositionTimestamp()\r\n } else if (element.isChartEvent()) {\r\n element.instance?.updateScales()\r\n }\r\n })\r\n\r\n model?.updateChartEventsZIndexes()\r\n\r\n this.canvas = this.canvasRef.current\r\n this.canvasCtx = getContextWithCache(this.canvasRef.current)\r\n this.crossCanvas = this.crossCanvasRef.current\r\n this.crossCanvasCtx = getContextWithCache(this.crossCanvasRef.current)\r\n\r\n this.paneHammer = new Hammer.Manager(this.paneRef.current!, { touchAction: 'none' })\r\n this.paneHammer.add(new Hammer.Press({ threshold: 5, time: 500 })) // chrome simulator \"long touch\" -> \"oncontextmenu\" is 680ms +- 2ms\r\n this.paneHammer.on('press', this.onPress)\r\n this.canvasWrapperHammer = new Hammer(this.canvasWrapperRef.current!, { touchAction: 'none' })\r\n this.canvasWrapperHammer.on('tap', this.onClick)\r\n this.canvasWrapperRef.current?.addEventListener('touchmove', this.onTouchMove, { passive: false })\r\n\r\n if (this.chartLayoutModel.scrollable || !this.isMobile) {\r\n if (this.scalerRef.current) {\r\n this.scalerHammer = new Hammer(this.scalerRef.current, { touchAction: 'none' })\r\n this.scalerHammer.on('doubletap', this.onScalerReset)\r\n }\r\n if (this.zoomerRef.current) {\r\n this.zoomerHammer = new Hammer(this.zoomerRef.current, { touchAction: 'none' })\r\n this.zoomerHammer.on('doubletap', this.props.onZoomerReset)\r\n }\r\n this.canvasWrapperHammer.on('doubletap', this.onDoubleClick)\r\n }\r\n\r\n this.onChartUpdate({ width: this.props.chartModel.width })\r\n this.onModelUpdate({ height: model.height })\r\n this.forceUpdate()\r\n this.chartLayoutModel.trigger(CHART_LAYOUT_CHILD_CHANGE_EVENT)\r\n }\r\n\r\n componentWillUnmount() {\r\n this.canvasWrapperRef.current?.removeEventListener('touchmove', this.onTouchMove)\r\n unmountCanvas(this.canvas)\r\n unmountCanvas(this.crossCanvas)\r\n this.props.chartModel.unbind('update', this.onChartUpdate)\r\n this.props.chartModel.unbind('change', this.recountScale)\r\n this.quoteModel.unbind('change', this.recountScale)\r\n }\r\n\r\n render() {\r\n const { activeTool, touchEventsDisabled, onPaneClick, paneIndex, chartIndex, model, chartModel } = this.props\r\n if (touchEventsDisabled) {\r\n this.paneHammer?.set({ touchAction: 'auto' })\r\n this.scalerHammer?.set({ touchAction: 'auto' })\r\n this.zoomerHammer?.set({ touchAction: 'auto' })\r\n this.canvasWrapperHammer?.set({ touchAction: 'auto' })\r\n } else {\r\n const touchAction = this.getIsHammerAllowScrollActive() ? 'auto' : 'none'\r\n this.scalerHammer?.set({ touchAction: 'none' })\r\n this.zoomerHammer?.set({ touchAction: 'none' })\r\n this.paneHammer?.set({ touchAction })\r\n this.canvasWrapperHammer?.set({ touchAction })\r\n }\r\n\r\n const isChartPane = model.getIsChartPane()\r\n\r\n return (\r\n onPaneClick?.(model)}\r\n onTouchStart={() => onPaneClick?.(model)}\r\n onContextMenu={this.onContextMenu}\r\n data-testid={`chart-${chartIndex}-pane-${paneIndex}`}\r\n >\r\n {isChartPane && }\r\n {paneIndex !== 0 && (\r\n this.props.onResizerMouseDown(e, model)}\r\n data-testid={`chart-${chartIndex}-pane-${paneIndex}-resizer`}\r\n />\r\n )}\r\n {this.chartLayoutModel.initialScrollable && (\r\n \r\n )}\r\n\r\n {this.chartLayoutModel.initialScrollable && isChartPane && (\r\n <>\r\n \r\n {\r\n this.props.onAddToZoomFactor({ diff: 0.1, shouldCalculateRightAlign: true })\r\n }}\r\n onZoomOut={() => {\r\n this.props.onAddToZoomFactor({ diff: -0.1, shouldCalculateRightAlign: true })\r\n }}\r\n onZoomReset={this.props.onZoomerReset}\r\n />\r\n \r\n )}\r\n \r\n {getChartAlt(this.quoteModel)}\r\n {this.chartLayoutModel.cross && }\r\n \r\n \r\n )\r\n }\r\n\r\n getIsHammerAllowScrollActive = () =>\r\n this.chartLayoutModel.specificChartFunctionality !== SpecificChartFunctionality.chartPage &&\r\n !this.chartLayoutModel.isTouchCrossActive &&\r\n !this.chartLayoutModel.scrollable\r\n\r\n onElementCreate = (el: ElementModel | ChartEventElement) => {\r\n el.instance.bind('change', this.renderAll)\r\n this.renderAll()\r\n }\r\n\r\n onElementReplace = (el: ElementModel, oldElementInstance: CanvasElement) => {\r\n oldElementInstance.unbind('change', this.renderAll)\r\n el.instance.bind('change', this.renderAll)\r\n if (oldElementInstance === this.props.model.selection && !this.chartLayoutModel.isDrawingModeContinuousActive) {\r\n this.setSelection(el.instance)\r\n } else {\r\n this.setSelection(null)\r\n }\r\n this.renderAll()\r\n }\r\n\r\n onElementDestroy = (el: ElementModel) => {\r\n const { type } = el.instance\r\n el.instance.unbind('change', this.renderAll)\r\n if (el.instance === this.props.model.selection) {\r\n this.setSelection(null)\r\n }\r\n if (type.startsWith('charts/') || type.startsWith('indicators/')) {\r\n this.props.onPaneDestroy(el['pane_id'])\r\n }\r\n this.renderAll()\r\n }\r\n\r\n onElementSelect = (el: ElementModel) => {\r\n this.setSelectedElement(el.instance)\r\n }\r\n\r\n onElementClone = (_: unknown, clonedElementInstance: CanvasElement) => {\r\n this.setSelectedElement(clonedElementInstance)\r\n }\r\n\r\n onModelUpdate = ({ height }: { height: number }) => {\r\n this.setCanvasSize({\r\n width: this.props.chartModel.width,\r\n height,\r\n })\r\n }\r\n\r\n onChartUpdate = ({ width }: { width: number }) => {\r\n const { model, chartModel } = this.props\r\n this.setCanvasSize({\r\n width,\r\n height: model.height,\r\n })\r\n const quote = chartModel.quote()\r\n if (!this.quoteModel.eql(quote)) {\r\n this.quoteModel.unbind('change', this.recountScale)\r\n if (quote) {\r\n this.quoteModel = quote\r\n this.quoteModel.bind('change', this.recountScale)\r\n }\r\n }\r\n }\r\n\r\n onZoomerMouseMove: React.MouseEventHandler = (e) => {\r\n if (!this.chartLayoutModel.scrollable || (this.isMobile && !this.chartLayoutModel.isTouchCrossActive)) return\r\n const area = this.getArea(e)\r\n MouseModel.updateAttributes({\r\n position: { x: area.x, y: null },\r\n pane: this.props.model,\r\n })\r\n }\r\n\r\n onMouseMoveOnScrolling = (event: TouchEvent | MouseEvent) => {\r\n if (this.props.activeChartInteraction) {\r\n return\r\n }\r\n\r\n let { clientX, clientY } = event as MouseEvent\r\n const { model } = this.props\r\n\r\n const isTouch = typeof TouchEvent !== 'undefined' && event instanceof TouchEvent\r\n if (isTouch && event.targetTouches?.length > 0) {\r\n clientX = event.targetTouches[0].clientX\r\n clientY = event.targetTouches[0].clientY\r\n }\r\n if (!model.selection && !this.chartLayoutModel.activeChartEvent) {\r\n if (this.lastClientX != null) {\r\n const dif = this.lastClientX - clientX\r\n this.addToLeftOffset(-dif)\r\n }\r\n if (model.scaleRange && this.lastClientY != null) {\r\n let { min, max } = model.scaleRange\r\n let difY\r\n switch (this.props.chartModel.scale) {\r\n case ScaleType.Logarithmic: {\r\n difY = this.lastClientY - clientY\r\n min = model.scale.y.invert(model.scale.y(min) + difY)\r\n max = model.scale.y.invert(model.scale.y(max) + difY)\r\n break\r\n }\r\n default: {\r\n difY = (this.lastClientY - clientY) * (model.scale.y.invert(0) - model.scale.y.invert(1))\r\n min -= difY\r\n max -= difY\r\n break\r\n }\r\n }\r\n\r\n model.updateAttribute('scaleRange', { min, max })\r\n this.recountScale()\r\n this.currentViewRange = this.props.model.getChartOrIndicatorElement()?.instance?.getMinMax?.() ?? null\r\n }\r\n }\r\n this.lastClientX = clientX\r\n this.lastClientY = clientY\r\n }\r\n\r\n onScalerTouchStart: React.TouchEventHandler = (e) => {\r\n if (!this.chartLayoutModel.scrollable || this.props.touchEventsDisabled) return\r\n if (this.chartLayoutModel.scrollable && e.targetTouches.length === 1) {\r\n this.onScalerMouseDown(e.targetTouches[0])\r\n }\r\n }\r\n\r\n onScalerTouchMove = (e: TouchEvent) => {\r\n if (this.chartLayoutModel.scrollable && e.targetTouches.length === 1) {\r\n this.onScalerMouseMove(e.targetTouches[0])\r\n }\r\n }\r\n\r\n onScalerTouchEnd = () => {\r\n if (this.chartLayoutModel.scrollable) {\r\n this.onScalerMouseUp()\r\n }\r\n }\r\n\r\n onScalerMouseEnter = () => {\r\n MouseModel.updateAttributes({\r\n position: null,\r\n pane: null,\r\n })\r\n }\r\n\r\n onScalerMouseDown = (event: React.MouseEvent | React.Touch) => {\r\n const { activeChartInteraction, setActiveChartInteraction, model } = this.props\r\n if ((event instanceof MouseEvent && event.button) || activeChartInteraction || !this.chartLayoutModel.scrollable) {\r\n return\r\n }\r\n setActiveChartInteraction('scaler')\r\n\r\n this.scalerLastY = event.clientY\r\n // here we need current domain scale or former \"nice\" value\r\n const [currentDomainMax, currentDomainMin] = model.scale.y.domain()\r\n this.currentViewRange = { min: currentDomainMin, max: currentDomainMax }\r\n document.addEventListener<'mousemove'>('mousemove', this.onScalerMouseMove)\r\n document.addEventListener('mouseup', this.onScalerMouseUp)\r\n document.addEventListener('touchmove', this.onScalerTouchMove)\r\n document.addEventListener('touchend', this.onScalerTouchEnd)\r\n }\r\n\r\n onScalerMouseMove = (event: MouseEvent | Touch) => {\r\n const { model, chartModel } = this.props\r\n if (model.scaleRange === null && this.currentViewRange === null) {\r\n return\r\n }\r\n let { min, max } = model.scaleRange || this.currentViewRange!\r\n let difY\r\n switch (this.props.chartModel.scale) {\r\n case ScaleType.Logarithmic: {\r\n difY = this.scalerLastY! - event.clientY\r\n min = model.scale.y.invert(model.scale.y(min) - difY)\r\n max = model.scale.y.invert(model.scale.y(max) + difY)\r\n break\r\n }\r\n default: {\r\n difY = -(this.scalerLastY! - event.clientY) * (model.scale.y.invert(0) - model.scale.y.invert(1))\r\n min -= difY\r\n max += difY\r\n break\r\n }\r\n }\r\n this.scalerLastY = event.clientY\r\n\r\n const originalMinMax = model.getChartOrIndicatorElement()?.instance?.getMinMax?.()\r\n if (originalMinMax) {\r\n const currentDiff = Math.abs(max - min)\r\n const originalDiff = Math.abs(originalMinMax.max - originalMinMax.min)\r\n\r\n if (currentDiff > originalDiff * ALLOWED_MIN_MAX_ZOOM || currentDiff < originalDiff / ALLOWED_MIN_MAX_ZOOM) {\r\n return\r\n }\r\n }\r\n\r\n model.updateAttribute('scaleRange', { min, max })\r\n chartModel.updateAttribute('dateRange', null)\r\n this.recountScale()\r\n }\r\n\r\n onScalerMouseUp = () => {\r\n this.scalerLastY = null\r\n\r\n document.removeEventListener('mousemove', this.onScalerMouseMove)\r\n document.removeEventListener('mouseup', this.onScalerMouseUp)\r\n document.removeEventListener('touchmove', this.onScalerTouchMove)\r\n document.removeEventListener('touchend', this.onScalerTouchEnd)\r\n this.props.setActiveChartInteraction(null)\r\n }\r\n\r\n onScalerReset = () => {\r\n const { model, chartModel } = this.props\r\n if (!this.chartLayoutModel.scrollable) return\r\n chartModel.updateAttribute('dateRange', null)\r\n model.updateAttribute('scaleRange', null)\r\n this.recountScale()\r\n }\r\n\r\n addToLeftOffset = (n: number) => {\r\n const quote = this.props.chartModel.quote()\r\n const barWidth = getBarWidthWithMargin({\r\n chartLayout: this.chartLayoutModel,\r\n zoomFactor: this.props.chartModel.zoomFactor,\r\n })\r\n const leftOffset = getMinMaxLeftOffset({\r\n newLeftOffset: this.props.chartModel.leftOffset + n,\r\n chartModel: this.props.chartModel,\r\n barWidth,\r\n barIndex: quote.barIndex[quote.open.length - 1],\r\n })\r\n\r\n if (leftOffset > barWidth) {\r\n quote.fetchOlderData()\r\n }\r\n this.props.chartModel.updateAttributes({\r\n leftOffset,\r\n dateRange: null,\r\n })\r\n }\r\n\r\n onDoubleClick = (event: HammerInput) => {\r\n event.preventDefault()\r\n const area = this.getArea(event)\r\n const element = this.props.model.selection || this.getElement(area)\r\n if (element && element.type !== IndicatorType.Cot && !element.isCreator) {\r\n setTimeout(() => {\r\n this.props.openElementStyleDialog!(element)\r\n }, 0)\r\n element.trigger('dblclick', event)\r\n }\r\n }\r\n\r\n onPress = (e: ObjectHash) => {\r\n if (e.pointerType !== 'touch') return\r\n\r\n e.clientX = e.center.x\r\n e.clientY = e.center.y\r\n\r\n const el = this.props.model.selection || this.getElement(this.getArea(e))\r\n if (!this.chartLayoutModel.isTouchCrossActive) {\r\n if (!el) {\r\n this.onCanvasPress(e as React.MouseEvent)\r\n } else {\r\n this.onContextMenu(e as React.MouseEvent, el)\r\n }\r\n }\r\n }\r\n\r\n onContextMenu = (e: React.MouseEvent, element?: IndicatorElement | CanvasElement) => {\r\n e.preventDefault()\r\n const area = this.getArea(e)\r\n const elementInArea = this.getElement(area)\r\n const el = element ?? elementInArea\r\n if (!el || el.thumbsAreInArea(area)) {\r\n return\r\n }\r\n const elementModel = ElementModel.findByAttribute('instance', el)\r\n if (!elementModel) return\r\n const hasProperties =\r\n ['indicator', 'canvas'].some((type) => el.type.startsWith(type)) && el.type !== IndicatorType.Cot\r\n const isElementDrawing = elementModel.isDrawing()\r\n\r\n const onContextMenuFullyOpen = () => {\r\n this.setSelectedElement(el)\r\n if (el instanceof CanvasElement) {\r\n el.setIsEditInProgress(true)\r\n }\r\n }\r\n\r\n const onContextMenuClose = () => {\r\n if (el instanceof CanvasElement) {\r\n el.setIsEditInProgress(false)\r\n }\r\n }\r\n\r\n return ContextMenu.show(\r\n e,\r\n [\r\n hasProperties && {\r\n id: 'edit',\r\n label: 'Edit style',\r\n onClick: () => this.props.openElementStyleDialog!(el),\r\n },\r\n\r\n !(elementModel.isChart() || elementModel?.isIndicator()) && {\r\n id: 'clone',\r\n label: 'Clone',\r\n onClick: () => elementModel.makeClone(),\r\n },\r\n\r\n ...(isElementDrawing\r\n ? [\r\n { type: 'divider', label: 'Visibility' },\r\n\r\n {\r\n id: 'visibility-current-and-above',\r\n label: 'Current interval and above',\r\n onClick: () => elementModel.instance.setVisibilityTo(SetVisibilityTo.currentAndAbove),\r\n },\r\n\r\n {\r\n id: 'visibility-current-and-below',\r\n label: 'Current interval and below',\r\n onClick: () => elementModel.instance.setVisibilityTo(SetVisibilityTo.currentAndBelow),\r\n },\r\n\r\n {\r\n id: 'visibility-current-only',\r\n label: 'Current interval only',\r\n onClick: () => elementModel.instance.setVisibilityTo(SetVisibilityTo.currentOnly),\r\n },\r\n\r\n {\r\n id: 'visibility-all-intervals',\r\n label: 'All intervals',\r\n onClick: () => elementModel.instance.setVisibilityTo(SetVisibilityTo.all),\r\n },\r\n ]\r\n : []),\r\n\r\n (isElementDrawing || hasProperties) && { type: 'divider' },\r\n\r\n {\r\n id: 'bring-to-front',\r\n label: 'Bring to Front',\r\n onClick: () => elementModel.bringToFront(),\r\n },\r\n {\r\n id: 'send-to-back',\r\n label: 'Send to Back',\r\n onClick: () => elementModel.sendToBack(),\r\n },\r\n {\r\n id: 'bring-forward',\r\n label: 'Bring Forward',\r\n onClick: () => elementModel.bringForward(),\r\n },\r\n {\r\n id: 'send-backward',\r\n label: 'Send Backward',\r\n onClick: () => elementModel.sendBackward(),\r\n },\r\n\r\n { type: 'divider' },\r\n\r\n {\r\n id: 'remove',\r\n label: 'Remove',\r\n onClick: () => {\r\n if (elementModel.isIndicator()) {\r\n handleRemoveIndicatorPane({ paneIndex: this.props.paneIndex, chartLayoutModel: this.chartLayoutModel })\r\n } else {\r\n elementModel.destroyCascade({ eventType: DrawingSpineOptionsEvent.Remove })\r\n this.props.model.normalizeZIndexes()\r\n }\r\n },\r\n },\r\n ]\r\n .filter(Boolean)\r\n .map((item) => ({ ...item, gtag: { element_type: el.type } })),\r\n { onFullyOpen: onContextMenuFullyOpen, onBeforeItemClick: onContextMenuClose, onFullyClosed: onContextMenuClose }\r\n )\r\n }\r\n\r\n immediateRecountScaleOnChartIndicatorChange = (element?: ElementModel) => {\r\n if (element?.isChart() || element?.isIndicator()) {\r\n this.recountScale()\r\n }\r\n }\r\n\r\n recountScale = (_?: unknown, updateType?: Spine.Event) => {\r\n const { model } = this.props\r\n const chartModel = model.chart()\r\n if (updateType === 'destroy' || !chartModel || !chartModel.quote()) {\r\n return\r\n }\r\n\r\n recountScale({ chartModel, paneModel: model })\r\n\r\n if (this.canvasCtx) {\r\n this.renderAll()\r\n }\r\n }\r\n\r\n onBlur = () => {\r\n if (this.props.model.selection?.getIsCreator?.()) {\r\n this.setSelection(null)\r\n } else {\r\n this.setSelectedElement(null)\r\n }\r\n if (this.hoveredElement) {\r\n this.hoveredElement.setIsHovered(false)\r\n this.hoveredElement = null\r\n }\r\n this.props.model.getAllElements().forEach((element) => {\r\n if (element.instance.getIsCreator?.() && !element.instance.getIsCreatorDialogOpen?.()) {\r\n element.destroyCascade()\r\n }\r\n })\r\n }\r\n\r\n renderAll = (type?: string) => {\r\n if (process.env.IS_E2E_TESTING) window.isRenderInProgress = true\r\n\r\n if (type === 'cross' && this.chartLayoutModel.cross) {\r\n if (this.crossRafId === null) {\r\n const crossRafId = window.requestAnimationFrame(() => {\r\n this.renderCross()\r\n if (process.env.IS_E2E_TESTING) {\r\n toggleE2eRenderInProgress({ id: crossRafId, isInProgress: false })\r\n }\r\n })\r\n if (process.env.IS_E2E_TESTING) {\r\n toggleE2eRenderInProgress({ id: crossRafId, isInProgress: true })\r\n }\r\n this.crossRafId = crossRafId\r\n }\r\n } else if (this.rafId == null && this.canvasCtx) {\r\n const rafId = window.requestAnimationFrame(() => {\r\n this._renderAll()\r\n if (process.env.IS_E2E_TESTING) {\r\n toggleE2eRenderInProgress({ id: rafId, isInProgress: false })\r\n }\r\n })\r\n if (process.env.IS_E2E_TESTING) {\r\n toggleE2eRenderInProgress({ id: rafId, isInProgress: true })\r\n }\r\n this.rafId = rafId\r\n }\r\n }\r\n\r\n _renderAll = () => {\r\n const { model } = this.props\r\n // _renderAll may be called after Chart was deleted because of requestAnimationFrame\r\n if (model.chart() === null || this.canvasRef.current === null || !this.canvasCtx) {\r\n return\r\n }\r\n if (this.getIsUpdatedDesign()) {\r\n if (this.crossRafId === null) {\r\n this.crossRafId = window.requestAnimationFrame(this.renderCross)\r\n }\r\n }\r\n this.rafId = undefined\r\n\r\n renderPane({\r\n chartLayoutModel: this.chartLayoutModel,\r\n chartModel: this.props.chartModel,\r\n paneModel: model,\r\n canvasCtx: this.canvasCtx,\r\n })\r\n }\r\n\r\n getIsUpdatedDesign() {\r\n const { specificChartFunctionality } = this.chartLayoutModel\r\n const isCharts = specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isRedesignedFuturesForexCrypto = isRedesignedPage({ specificChartFunctionality })\r\n\r\n return isCharts || isRedesignedFuturesForexCrypto\r\n }\r\n\r\n renderCross = () => {\r\n const { model } = this.props\r\n const isMouseInPane = MouseModel.getShouldRenderCrossInPane(model)\r\n this.crossRafId = null\r\n if (!this.crossCanvasCtx) {\r\n return\r\n }\r\n this.crossCanvasCtx.clearRect(0, 0, this.props.chartModel.width, model.height)\r\n const isCrossDisabled =\r\n PaneModel.select((p) => !!p.selection && !p.selection.type.startsWith('indicators/')).length !== 0 ||\r\n this.props.chartModel.getIsDisabled() ||\r\n !isMouseInPane\r\n\r\n for (const { instance: elementInstance } of model.getAllElements()) {\r\n if (\r\n (!isCrossDisabled && elementInstance.renderCross != null) ||\r\n (isCrossDisabled && elementInstance.renderCrossText != null)\r\n ) {\r\n this.crossCanvasCtx.save()\r\n if (isCrossDisabled) {\r\n elementInstance.renderCrossText!(this.crossCanvasCtx, Number.NaN)\r\n } else {\r\n elementInstance.renderCross!(this.crossCanvasCtx)\r\n }\r\n this.crossCanvasCtx.restore()\r\n }\r\n }\r\n }\r\n\r\n getArea = (e: ObjectHash, additionalData?: T): PaneArea => {\r\n const { model } = this.props\r\n const clientX = e.clientX || additionalData?.clientX\r\n const clientY = e.clientY || additionalData?.clientY\r\n const Settings = getSettings(model)\r\n const areaRectangle = this.canvas!.getBoundingClientRect()\r\n const areaRectangleCursorX = clientX - areaRectangle.left\r\n const areaRectangleCursorY = clientY - areaRectangle.top\r\n const x = areaRectangleCursorX - model.chart().leftOffset - Settings.left.width\r\n const y = areaRectangleCursorY - Settings.top.height\r\n const scale = model.scale\r\n const chartLeftX = areaRectangle.left + Settings.left.width\r\n const chartRightX = areaRectangle.right - Settings.right.width\r\n return {\r\n ...(additionalData as T),\r\n // TODO: rewrite if canvas uses padding/border\r\n x: scale.x.invert(x),\r\n y: scale.y.invert(y),\r\n scaled: {\r\n x,\r\n y,\r\n },\r\n width: 1,\r\n height: 1,\r\n cursorX: areaRectangleCursorX,\r\n cursorY: areaRectangleCursorY,\r\n isCursorInChartWidthBoundaries: clientX > chartLeftX && clientX < chartRightX,\r\n }\r\n }\r\n\r\n setCanvasSize = ({ width, height }: { width: number; height: number }) => {\r\n const ratio = Utils.getScaleRatio()\r\n const canvasElement = this.canvasRef.current\r\n\r\n /**\r\n * It seems that value passed into element attr (e.g. height) is ceiled down,\r\n * so if you provide canvas element with height 100.5 we'll get integer 100 from canvasElement.height\r\n * If the difference in values between \"new height\" and canvasElement.height is less than 1, I treat it as the same value\r\n */\r\n if (\r\n this.canvasCtx &&\r\n canvasElement &&\r\n (Math.abs(height * ratio - canvasElement.height) >= 1 || Math.abs(width * ratio - canvasElement.width) >= 1)\r\n ) {\r\n Utils.setSizeOnCanvasElement({ canvasElement, width, height })\r\n this.canvasCtx.scale(ratio, ratio)\r\n if (this.chartLayoutModel.cross && this.crossCanvasCtx) {\r\n Utils.setSizeOnCanvasElement({\r\n canvasElement: this.crossCanvasRef.current,\r\n width,\r\n height,\r\n })\r\n this.crossCanvasCtx.scale(ratio, ratio)\r\n }\r\n setTimeout(() => {\r\n this.recountScale()\r\n })\r\n }\r\n }\r\n\r\n onClick = (event: HammerInput) => {\r\n const area = this.getArea(event, {\r\n clientX: event.center.x,\r\n clientY: event.center.y,\r\n })\r\n const element = this.props.model.selection || this.getElement(area)\r\n element?.trigger('click', area)\r\n\r\n if (!this.isDisableTouchCrossAvailable) {\r\n this.isDisableTouchCrossAvailable = true\r\n return\r\n }\r\n\r\n if (this.chartLayoutModel.isTouchCrossActive) {\r\n MouseModel.updateAttributes({\r\n position: null,\r\n pane: null,\r\n })\r\n this.chartLayoutModel.updateAttributes({\r\n scrollable: this.chartLayoutModel.initialScrollable,\r\n isTouchCrossActive: false,\r\n })\r\n } else if (\r\n this.isMobile &&\r\n !this.state.hasSeenCrossNotification &&\r\n this.lastActiveTool === DrawingTool.Mouse &&\r\n this.chartLayoutModel.specificChartFunctionality !== SpecificChartFunctionality.smallIndex\r\n ) {\r\n const isChartsPage = this.chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n\r\n this.setState({ hasSeenCrossNotification: true })\r\n this.props.notificationContext.show(\r\n {\r\n this.props.notificationContext.hide()\r\n window.localStorage.setItem('hasSeenCrossNotification', 'true')\r\n }}\r\n theme=\"dark\"\r\n >\r\n Got it\r\n \r\n }\r\n >\r\n Long press the chart to show the crosshair.\r\n ,\r\n { inline: !isChartsPage }\r\n )\r\n }\r\n\r\n this.lastActiveTool = this.props.activeTool\r\n }\r\n\r\n onPaneMouseLeave = () => {\r\n // timout in onPaneMouseMove may cause racecondition where active class is added right after it's been removed\r\n setTimeout(() => {\r\n this.zoomControlsRef.current?.classList.remove(ZOOM_CONTROLS_ACTIVE_CLASS, ZOOM_CONTROLS_IS_IN_AREA_CLASS)\r\n })\r\n if (this.chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage) {\r\n this.renderCross()\r\n }\r\n }\r\n\r\n onPaneMouseMove = (e: React.MouseEvent | React.Touch, isMouseDownIgnored = false) => {\r\n const { model, chartModel } = this.props\r\n const zoomControls = this.zoomControlsRef.current\r\n const paneHeight = model.height\r\n if (zoomControls) {\r\n const area = this.getArea<{ mouseDown: boolean; clientX: number; clientY: number }>(e, {\r\n mouseDown: !isMouseDownIgnored && this.mouseDown,\r\n clientX: e.clientX,\r\n clientY: e.clientY,\r\n })\r\n\r\n // timeout is needed here as adding a classname on parent element of a button where we are listening on a click is not working properly if done synchrnousely\r\n setTimeout(() => {\r\n // 103 is the destance between pane bottom and zoom-controls top\r\n // zoomer bottom (8 px) + zoomer height (20px) - 13px + zoom controls height (75px) = 90px\r\n const isInArea = model.height - 90 <= area.cursorY && paneHeight > 210\r\n\r\n if (\r\n isInArea &&\r\n !zoomControls.classList.contains(ZOOM_CONTROLS_IS_IN_AREA_CLASS) &&\r\n !chartModel.getIsDisabled()\r\n ) {\r\n zoomControls.classList.add(ZOOM_CONTROLS_IS_IN_AREA_CLASS)\r\n } else if (!isInArea && zoomControls.classList.contains(ZOOM_CONTROLS_IS_IN_AREA_CLASS)) {\r\n zoomControls.classList.remove(ZOOM_CONTROLS_IS_IN_AREA_CLASS)\r\n }\r\n\r\n if (!area.mouseDown && !model.selection && isInArea && !chartModel.getIsDisabled()) {\r\n if (!zoomControls.classList.contains(ZOOM_CONTROLS_ACTIVE_CLASS)) {\r\n zoomControls.classList.add(ZOOM_CONTROLS_ACTIVE_CLASS)\r\n }\r\n } else if (zoomControls.classList.contains(ZOOM_CONTROLS_ACTIVE_CLASS)) {\r\n zoomControls.classList.remove(ZOOM_CONTROLS_ACTIVE_CLASS)\r\n }\r\n })\r\n }\r\n }\r\n\r\n onMouseLeave = () => {\r\n this.mouseDown = false\r\n }\r\n\r\n onTouchStart = (e: React.TouchEvent) => {\r\n if (!this.props.touchEventsDisabled && e.targetTouches.length === 1) {\r\n const touchEvent = e.targetTouches[0]\r\n if (this.chartLayoutModel.scrollable) {\r\n this.onCanvasInteractionStart(touchEvent)\r\n } else if (this.chartLayoutModel.isTouchCrossActive) {\r\n this.lastClientX = touchEvent.clientX\r\n this.lastClientY = touchEvent.clientY\r\n if (!MouseModel.pane()?.eql(this.props.model)) {\r\n const area = this.getArea(touchEvent, {\r\n mouseDown: this.mouseDown,\r\n clientX: touchEvent.clientX,\r\n clientY: touchEvent.clientY,\r\n })\r\n this.setMousePosition(this.getMousePositionInBoundaries(area))\r\n this.isDisableTouchCrossAvailable = false\r\n }\r\n } else {\r\n const area = this.getArea(touchEvent, { isTouch: true }) // passing isTouch is pretty confusing, it's used in Tools.jsx -> onMouseDown method\r\n const element = this.getElement(area)\r\n if (element?.getIsChartEvent?.() && this.props.activeTool === DrawingTool.Mouse) {\r\n const chartEventElement = element as ChartEvent\r\n chartEventElement.toggleIsOpen()\r\n }\r\n }\r\n this.onPaneMouseMove(touchEvent, true)\r\n }\r\n }\r\n\r\n onTouchMove = (e: TouchEvent) => {\r\n if (!this.props.touchEventsDisabled) {\r\n if (!this.getIsHammerAllowScrollActive()) {\r\n e.preventDefault()\r\n }\r\n if (!this.props.touchEventsDisabled && e.targetTouches.length === 1) {\r\n this.onCanvasInteractionMove(e.targetTouches[0])\r\n }\r\n }\r\n }\r\n\r\n onTouchEnd = (e: React.TouchEvent) => {\r\n if (!this.props.touchEventsDisabled && this.chartLayoutModel.scrollable) {\r\n this.onCanvasInteractionEnd(e)\r\n }\r\n }\r\n\r\n onCanvasPress = (e: React.MouseEvent) => {\r\n if (this.chartLayoutModel.scrollable) {\r\n this.chartLayoutModel.updateAttribute('scrollable', false)\r\n document.removeEventListener('touchmove', this.onMouseMoveOnScrolling)\r\n }\r\n if (!this.chartLayoutModel.isTouchCrossActive) {\r\n this.chartLayoutModel.updateAttribute('isTouchCrossActive', true)\r\n this.onCanvasInteractionMove(e)\r\n }\r\n }\r\n\r\n onCanvasInteractionStart = (e: React.Touch | React.MouseEvent) => {\r\n const { activeTool, activeChartInteraction, chartModel, model } = this.props\r\n const isTouch = typeof Touch !== 'undefined' && e instanceof Touch\r\n this.lastActiveTool = activeTool\r\n\r\n if (isPrimaryClick(e) && !activeChartInteraction && !chartModel.getIsDisabled()) {\r\n const area = this.getArea(e, { isTouch }) // passing isTouch is pretty confusing, it's used in Tools.jsx -> onMouseDown method\r\n const element = this.getElement(area)\r\n\r\n // if user click outside of drawable area but still inside canvas creator would hang unfinised,\r\n // it that case we want to cancel element creation, same as we do on click outside of canvas / onBlur\r\n if (model.selection?.isCreator && !area.isCursorInChartWidthBoundaries && element !== model.selection) {\r\n model.getAllElements().forEach((element) => {\r\n if (element.instance.getIsCreator?.() && !element.instance.getIsCreatorDialogOpen?.()) {\r\n element.destroyCascade()\r\n }\r\n })\r\n }\r\n if (this.chartLayoutModel.scrollable) {\r\n setElementCursor({ elementId: this.chartLayoutModel.getHTMLElementId(), cursor: 'grabbing' })\r\n if (model.scaleRange) {\r\n this.currentViewRange = model.getChartOrIndicatorElement()?.instance?.getMinMax?.() ?? null\r\n }\r\n document.addEventListener(isTouch ? 'touchmove' : 'mousemove', this.onMouseMoveOnScrolling)\r\n document.addEventListener(isTouch ? 'touchend' : 'mouseup', this.onCanvasInteractionEnd)\r\n }\r\n if (element?.getIsChartEvent?.() && activeTool === DrawingTool.Mouse) {\r\n this.setSelectedElement(null)\r\n const chartEventElement = element as ChartEvent\r\n chartEventElement.toggleIsOpen()\r\n } else if (\r\n activeTool === DrawingTool.Mouse ||\r\n model.getAllElements().some(({ instance }) => instance.isCreator)\r\n ) {\r\n element?.trigger('mousedown', area)\r\n this.setSelectedElement(element)\r\n }\r\n model.trigger('mousedown', model, area, element)\r\n this.mouseDown = true\r\n this.lastX = area.x\r\n this.lastY = area.y\r\n }\r\n\r\n this.lastClientX = e.clientX\r\n this.lastClientY = e.clientY\r\n }\r\n\r\n onCanvasInteractionMove = (e: React.MouseEvent | React.Touch) => {\r\n const area = this.getArea(e, {\r\n mouseDown: this.mouseDown,\r\n clientX: e.clientX,\r\n clientY: e.clientY,\r\n })\r\n if (!area.isCursorInChartWidthBoundaries) {\r\n MouseModel.updateAttributes({\r\n position: null,\r\n pane: null,\r\n })\r\n return\r\n }\r\n\r\n const { model } = this.props\r\n const hoveredElement = this.getElement(area)\r\n const element = model.selection || hoveredElement\r\n\r\n if (!(this.isMobile && !this.chartLayoutModel.isTouchCrossActive)) {\r\n this.isDisableTouchCrossAvailable = true\r\n this.setMousePosition(\r\n this.lastClientX && this.lastClientY && this.chartLayoutModel.isTouchCrossActive && MouseModel.position\r\n ? this.getMousePositionInBoundaries({\r\n x: MouseModel.position.x + (model.scale.x.invert(area.clientX) - model.scale.x.invert(this.lastClientX)),\r\n y: MouseModel.position.y + (model.scale.y.invert(area.clientY) - model.scale.y.invert(this.lastClientY)),\r\n })\r\n : { x: area.x, y: area.y }\r\n )\r\n }\r\n\r\n if (!this.chartLayoutModel.scrollable) {\r\n this.lastClientX = area.clientX\r\n this.lastClientY = area.clientY\r\n }\r\n\r\n element?.trigger('mousemove', area)\r\n if (\r\n this.mouseDown &&\r\n model.selection instanceof CanvasElement &&\r\n !model.selection.activeThumb &&\r\n !this.chartLayoutModel.activeChartEvent\r\n ) {\r\n if (!model.selection.getIsCreator?.()) {\r\n model.selection.moveBy(area.x - this.lastX, area.y - this.lastY)\r\n }\r\n this.lastX = area.x\r\n this.lastY = area.y\r\n this.renderAll()\r\n }\r\n const isElementHovered =\r\n this.props.activeTool === DrawingTool.Mouse &&\r\n ((element && element === hoveredElement) || hoveredElement instanceof CanvasElement)\r\n\r\n if (hoveredElement !== this.hoveredElement && this.hoveredElement instanceof CanvasElement) {\r\n this.hoveredElement.setIsHovered(false)\r\n this.hoveredElement = null\r\n }\r\n\r\n if (isElementHovered && hoveredElement instanceof CanvasElement) {\r\n if (!hoveredElement.isHovered && !hoveredElement.isSelected) {\r\n hoveredElement.setIsHovered(true)\r\n this.hoveredElement = hoveredElement\r\n }\r\n }\r\n\r\n if (isElementHovered !== this.isElementHovered && this.canvas && hoveredElement?.type !== IndicatorType.Cot) {\r\n this.canvas.className = isElementHovered ? 'hover' : ''\r\n if (this.chartLayoutModel.cross && this.crossCanvas) {\r\n this.crossCanvas.className = `second${isElementHovered ? ' hover' : ''}`\r\n }\r\n this.isElementHovered = isElementHovered\r\n }\r\n }\r\n\r\n onCanvasInteractionEnd = (event: TouchEvent | MouseEvent | React.TouchEvent) => {\r\n if (MouseModel.position) {\r\n setElementCursor({ elementId: this.chartLayoutModel.getHTMLElementId(), cursor: 'crosshair' })\r\n } else {\r\n setElementCursor({ elementId: this.chartLayoutModel.getHTMLElementId(), cursor: 'default' })\r\n }\r\n const isTouch = typeof TouchEvent !== 'undefined' && event instanceof TouchEvent\r\n this.mouseDown = false\r\n const area = this.getArea(event)\r\n const element = this.props.model.selection || this.getElement(area)\r\n element?.trigger('mouseup', area)\r\n document.removeEventListener(isTouch ? 'touchmove' : 'mousemove', this.onMouseMoveOnScrolling)\r\n document.removeEventListener(isTouch ? 'touchend' : 'mouseup', this.onCanvasInteractionEnd)\r\n }\r\n\r\n getMousePositionInBoundaries = ({ x, y }: { x: number; y: number }) => {\r\n const { model } = this.props\r\n const Settings = getSettings(model)\r\n const canvasAreaRectangle = this.canvas!.getBoundingClientRect()\r\n const chartLeft = model.scale.x.invert(-model.chart().leftOffset + 1)\r\n const chartRight = model.scale.x.invert(\r\n canvasAreaRectangle.width - Settings.right.width - Settings.left.width - model.chart().leftOffset - 1\r\n )\r\n const chartTop = model.scale.y.invert(0)\r\n const chartBottom = model.scale.y.invert(canvasAreaRectangle.height - Settings.bottom.height - Settings.top.height)\r\n\r\n return {\r\n x: getValueInRange({\r\n value: x,\r\n min: chartLeft,\r\n max: chartRight,\r\n }),\r\n y: getValueInRange({\r\n value: y,\r\n min: chartBottom,\r\n max: chartTop,\r\n }),\r\n }\r\n }\r\n\r\n setMousePosition = ({ x, y }: { x: number; y: number }) => {\r\n const isSameMouseModel = !!MouseModel.pane()?.eql(this.props.model)\r\n MouseModel.updateAttributes({\r\n position: { x, y },\r\n ...(isSameMouseModel ? {} : { pane: this.props.model }),\r\n })\r\n }\r\n\r\n setSelection = (selection: IndicatorElement | CanvasElement | null) => {\r\n if (selection instanceof CanvasElement) {\r\n selection?.setIsSelected(true)\r\n }\r\n\r\n this.props.model.updateAttribute('selection', selection)\r\n }\r\n\r\n setSelectedElement = (element: IndicatorElement | CanvasElement | null) => {\r\n const { selection } = this.props.model\r\n const isSelectionCanvas = selection instanceof CanvasElement\r\n if (element !== selection || (isSelectionCanvas && element && !selection?.isSelected)) {\r\n if (isSelectionCanvas) {\r\n selection?.setIsSelected(false)\r\n }\r\n if (isSelectionCanvas && selection?.isCreator) {\r\n this.setSelection(null)\r\n } else {\r\n this.setSelection(element)\r\n }\r\n }\r\n }\r\n\r\n getElement = (area: PaneArea) => {\r\n const chartEvents = this.props.model.getAllChartEvents(false)\r\n\r\n for (let i = chartEvents.length - 1; i >= 0; i--) {\r\n const el = chartEvents[i].instance\r\n if (el.getIsInChartView(this.props.chartModel) && el.isInArea(area)) {\r\n return el\r\n }\r\n }\r\n\r\n const elements = this.props.model.getAllElements()\r\n\r\n for (let i = elements.length - 1; i >= 0; i--) {\r\n const el = elements[i].instance\r\n if (el.getIsInChartView(this.props.chartModel) && el.isInArea(area)) {\r\n return el\r\n }\r\n }\r\n return null\r\n }\r\n\r\n getCanvasDOMNode = () =>\r\n // This is used in app/modals/publish/publish.jsx\r\n this.canvasRef.current\r\n}\r\n\r\nexport default withNotificationContext(withElementStyleDialogState(withPaneModel(Pane)))\r\n","import React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport PaneModel from '../../models/pane'\r\n\r\nexport function withPaneModel

(Component: React.ComponentType

) {\r\n return function WrappedComponent(props: P) {\r\n const model = useModelState(props.model, { watchProperties: ['selection'] })\r\n\r\n return \r\n }\r\n}\r\n","import { Spinner } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nexport function ChartSpinnerOverlay({ shouldDisplay, className }: { shouldDisplay: boolean; className: string }) {\r\n const [isVisible, setIsVisible] = React.useState(shouldDisplay)\r\n React.useEffect(() => {\r\n let timeout: number\r\n if (!shouldDisplay) {\r\n timeout = window.setTimeout(() => {\r\n setIsVisible(false)\r\n }, 400)\r\n }\r\n return () => {\r\n clearTimeout(timeout)\r\n }\r\n }, [shouldDisplay])\r\n\r\n return (\r\n <>\r\n {isVisible && (\r\n \r\n \r\n \r\n )}\r\n \r\n )\r\n}\r\n","import React from 'react'\r\n\r\nimport { RootChartConfigObjectChart } from '../../../types/shared'\r\nimport ChartModel from '../../models/chart'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { DrawingTool } from '../toolbar/interfaces'\r\n\r\nexport const CHART_CLASS_NAMES = 'chart flex-1 relative'\r\nexport const DEFAULT_WRAPPER_COMPONENT = 'div'\r\n\r\nexport interface ChartProps {\r\n chartIndex: number\r\n gridArea?: string\r\n WrapperComp?: React.ForwardRefRenderFunction\r\n config: RootChartConfigObjectChart\r\n chartModel: ChartModel\r\n layoutModel: ChartLayout\r\n setActiveChartInteraction: (interaction: string | null) => void\r\n activeChartInteraction: string | null\r\n activeTool: DrawingTool\r\n touchEventsDisabled: boolean\r\n hasOutline?: boolean\r\n shouldResize?: boolean\r\n renderChartToolbar?: () => React.ReactNode\r\n}\r\n","import classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { Instrument } from '../../../types/shared'\r\nimport { ChartEditorEnum, SpecificChartFunctionality } from '../../constants/common'\r\nimport math from '../../helpers/math'\r\nimport ChartModel from '../../models/chart'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport MouseModel from '../../models/mouse'\r\nimport PaneModel from '../../models/pane'\r\nimport Quote from '../../models/quote'\r\nimport { QuoteFetchType } from '../../models/quote/constants'\r\nimport utils, { isRedesignEnabled } from '../../utils'\r\nimport { getBarWidthWithMargin, getZoomFactorForBarsToDisplay } from '../../utils/chart'\r\nimport { ChartControls } from '../chart-controls'\r\nimport Pane from '../pane'\r\nimport {\r\n getBarIndex,\r\n getIsSmallIndexChart,\r\n getLeftOffset,\r\n getMinMaxLeftOffset,\r\n updateZoomAndLeftOffsetByDateRange,\r\n} from '../renderUtils'\r\nimport { ChartProps } from './constants'\r\nimport { withChartInit } from './with-chart-init'\r\nimport { withWatchedPanesOnChartModel } from './with-watched-panes-on-chart-model'\r\n\r\nfunction preventDefaultFunc(event: Event) {\r\n event.preventDefault()\r\n}\r\n\r\nfunction getZoomFactor({\r\n chartLayout,\r\n currentZoomFactor,\r\n diff,\r\n minBarWidthInPx = 1,\r\n maxBarWidthInPx = 66,\r\n}: {\r\n chartLayout: ChartLayout\r\n currentZoomFactor: number\r\n diff: number\r\n minBarWidthInPx?: number\r\n maxBarWidthInPx?: number\r\n}) {\r\n const minZoomFactor = getZoomFactorForBarsToDisplay({\r\n chartLayout,\r\n chartVisibleWidth: minBarWidthInPx,\r\n numOfVisibleBars: 1,\r\n })\r\n const maxZoomFactor = getZoomFactorForBarsToDisplay({\r\n chartLayout,\r\n chartVisibleWidth: maxBarWidthInPx,\r\n numOfVisibleBars: 1,\r\n })\r\n const isNegativeDirection = diff < 0\r\n const newZoomFactor = currentZoomFactor + diff\r\n const newZoomFactorInRange = Math.min(Math.max(minZoomFactor, newZoomFactor), maxZoomFactor)\r\n\r\n if (newZoomFactor > newZoomFactorInRange && currentZoomFactor > newZoomFactorInRange) {\r\n return isNegativeDirection ? newZoomFactor : currentZoomFactor\r\n }\r\n\r\n if (newZoomFactor < newZoomFactorInRange && currentZoomFactor < newZoomFactorInRange) {\r\n return !isNegativeDirection ? newZoomFactor : currentZoomFactor\r\n }\r\n\r\n return newZoomFactorInRange\r\n}\r\n\r\ninterface ChartState {\r\n panesWrapperElement: HTMLDivElement | null\r\n}\r\n\r\nclass Chart extends React.Component {\r\n lastWidth: number\r\n mouseWheelTimeout?: number\r\n setStateWithPanesTimeout?: number\r\n lastHeight = 0\r\n lastY: number | null = null\r\n lastX: number | null = null\r\n resizerPaneIndex = -1\r\n minimalPaneHeight = 0\r\n zoomerRightAlign: {\r\n barIndex?: number\r\n index: number\r\n offsetDiff: number\r\n } | null = null\r\n\r\n // expects model, config, layoutModel\r\n constructor(props: ChartProps) {\r\n super(props)\r\n\r\n this.lastWidth = props.chartModel.width\r\n this.props.layoutModel.bind('change', this.onLayoutModelChange)\r\n this.state = { panesWrapperElement: null }\r\n }\r\n\r\n componentDidMount() {\r\n const { chartModel } = this.props\r\n this.lastWidth = this.props.layoutModel.width\r\n\r\n chartModel.trigger('change', chartModel)\r\n chartModel.bind('createPane', this.onPaneCreate)\r\n\r\n this.calculateMinimalPaneHeight()\r\n this.handleQuoteChange(chartModel.quote()!)\r\n this.onModelChange()\r\n\r\n chartModel.bind('update', this.onModelChange)\r\n chartModel.bind('destroy', () => {\r\n Quote.unbind('olderData', this.onOlderDataLoaded)\r\n Quote.unbind(`${QuoteFetchType.Refetch} ${QuoteFetchType.NewerData}`, this.onDataLoaded)\r\n })\r\n\r\n Quote.bind('olderData', this.onOlderDataLoaded)\r\n Quote.bind(`${QuoteFetchType.Refetch} ${QuoteFetchType.NewerData}`, this.onDataLoaded)\r\n }\r\n\r\n componentDidUpdate(prevProps: Readonly, prevState: Readonly) {\r\n if (\r\n prevState.panesWrapperElement !== this.state.panesWrapperElement ||\r\n prevProps.layoutModel.isWheelZoomEnabled !== this.props.layoutModel.isWheelZoomEnabled\r\n ) {\r\n prevState.panesWrapperElement?.removeEventListener('wheel', preventDefaultFunc)\r\n\r\n if (this.props.layoutModel.isWheelZoomEnabled) {\r\n // can't use onWheel as it has passive: true\r\n this.state.panesWrapperElement?.addEventListener('wheel', preventDefaultFunc, { passive: false })\r\n }\r\n }\r\n }\r\n\r\n componentWillUnmount() {\r\n const { chartModel, layoutModel } = this.props\r\n if (this.setStateWithPanesTimeout) {\r\n clearTimeout(this.setStateWithPanesTimeout)\r\n }\r\n layoutModel.unbind('change', this.onLayoutModelChange)\r\n chartModel.unbind('update', this.onModelChange)\r\n\r\n this.state.panesWrapperElement?.removeEventListener('wheel', preventDefaultFunc)\r\n }\r\n\r\n handleSetPanesWrapperRef = (panesWrapperElement: HTMLDivElement | null) => {\r\n this.setState({ panesWrapperElement })\r\n }\r\n\r\n render() {\r\n const { activeTool, chartIndex, layoutModel, chartModel, renderChartToolbar } = this.props\r\n const isChartPage = layoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const panes =\r\n layoutModel.specificChartFunctionality === SpecificChartFunctionality.futuresPage\r\n ? chartModel.getAllValidPanes()\r\n : chartModel.getAllPanes()\r\n const showSettings = layoutModel.editors.includes(ChartEditorEnum.settings)\r\n const showTimeframe = showSettings || layoutModel.editors.includes(ChartEditorEnum.timeframe)\r\n\r\n return (\r\n <>\r\n this.onClick(undefined) : undefined}\r\n data-testid={`chart-${chartIndex}-settings`}\r\n onMouseEnter={this.resetMouseModel}\r\n >\r\n {showTimeframe && }\r\n \r\n {layoutModel.editable && showSettings && renderChartToolbar && (\r\n \r\n {renderChartToolbar()}\r\n \r\n )}\r\n \r\n {panes.map((pane, index) => (\r\n \r\n ))}\r\n \r\n \r\n )\r\n }\r\n\r\n onMouseWheel = (e: React.WheelEvent) => {\r\n const { chartModel, layoutModel } = this.props\r\n const isLoading = chartModel.panes().count() < 1\r\n if (!layoutModel.isWheelZoomEnabled || isLoading) {\r\n return\r\n }\r\n if (!this.zoomerRightAlign) {\r\n this.calcZoomerRightAlign()\r\n }\r\n clearTimeout(this.mouseWheelTimeout)\r\n this.mouseWheelTimeout = window.setTimeout(() => {\r\n this.zoomerRightAlign = null\r\n }, 250)\r\n this.onZoomerMouseMove(e, undefined, true)\r\n }\r\n\r\n onClick = (activePane: PaneModel | undefined) => {\r\n if (\r\n !this.props.layoutModel.activeChart.eql(this.props.chartModel) ||\r\n !(this.props.layoutModel.activePane?.eql(activePane) || this.props.layoutModel.activePane === activePane)\r\n ) {\r\n this.props.layoutModel.updateAttributes({ activeChart: this.props.chartModel, activePane })\r\n }\r\n }\r\n\r\n onPaneCreate = () => {\r\n const { chartModel } = this.props\r\n this.onModelChange()\r\n this.calculateMinimalPaneHeight()\r\n chartModel.trigger('change', chartModel)\r\n }\r\n\r\n onPaneDestroy = (paneId: string) => {\r\n const { chartModel } = this.props\r\n const pane = chartModel.panes().find(paneId)\r\n\r\n if (pane) {\r\n pane.destroyCascade()\r\n this.onModelChange()\r\n chartModel.trigger('change', chartModel)\r\n }\r\n }\r\n\r\n onModelChange = (chartModelParam?: ChartModel) => {\r\n const { chartModel, config } = this.props\r\n const panes = chartModel.getAllPanes()\r\n const quote = chartModel.quote()\r\n\r\n if (panes.length === 0 || !quote || chartModel.leftOffset === undefined) {\r\n return\r\n }\r\n\r\n const { width, height } = chartModel\r\n let panesHeight = panes.reduce((sum, pane) => sum + (pane.height ?? 0), 0)\r\n if (panesHeight !== height) {\r\n panesHeight = panes.reduce((sum, pane) => {\r\n const newPaneHeight = Math.round((pane.height / panesHeight) * height)\r\n if (!Number.isNaN(newPaneHeight)) {\r\n pane.updateAttribute('height', newPaneHeight)\r\n }\r\n return sum + newPaneHeight\r\n }, 0)\r\n const chartPane = chartModel.getChartPane()\r\n if (chartPane && panesHeight !== height) {\r\n const newChartPaneHeight = chartPane.height + height - panesHeight\r\n if (!Number.isNaN(newChartPaneHeight)) {\r\n chartPane.updateAttribute('height', newChartPaneHeight)\r\n }\r\n }\r\n }\r\n\r\n const newLeftOffset = getLeftOffset({\r\n quote,\r\n chartModel,\r\n config: config,\r\n })\r\n const newIsScrolled = chartModel.leftOffset !== newLeftOffset\r\n const isScrolled = chartModel.isScrolled\r\n if (!isScrolled && this.lastWidth !== width) {\r\n this.lastWidth = width\r\n chartModel.updateAttribute('leftOffset', newLeftOffset)\r\n } else if (isScrolled !== newIsScrolled) {\r\n chartModel.updateAttributes({ isScrolled: newIsScrolled })\r\n }\r\n\r\n if (this.lastHeight !== height) {\r\n this.lastHeight = height\r\n this.calculateMinimalPaneHeight()\r\n }\r\n\r\n if (chartModelParam) {\r\n this.handleQuoteChange(chartModelParam.quote())\r\n }\r\n }\r\n\r\n onLayoutModelChange = ({ activeChart, activePane }: { activeChart: ChartModel; activePane: PaneModel }) => {\r\n const { chartModel } = this.props\r\n if (!activeChart) {\r\n return\r\n }\r\n for (const pane of chartModel.getAllPanes()) {\r\n if (activePane?.id !== pane.id && pane.selection?.isSelected === true) {\r\n pane.selection.setIsSelected(false)\r\n pane.updateAttribute('selection', undefined)\r\n }\r\n }\r\n }\r\n\r\n onResizerMouseDown = (e: React.MouseEvent | MouseEvent, model: PaneModel) => {\r\n if (e.button !== 0) {\r\n return\r\n }\r\n this.lastY = e.clientY\r\n this.resizerPaneIndex = this.props.chartModel\r\n .panes()\r\n .all()\r\n .findIndex((pane) => pane.eql(model))\r\n document.addEventListener('mousemove', this.onResizerMouseMove)\r\n document.addEventListener('mouseup', this.onResizerMouseUp)\r\n }\r\n\r\n onResizerMouseMove = (e: MouseEvent) => {\r\n if (this.resizerPaneIndex > 0 && this.lastY !== null && this.resizePanesAccordingly(this.lastY! - e.clientY)) {\r\n this.lastY = e.clientY\r\n }\r\n }\r\n\r\n onResizerMouseUp = (e: MouseEvent) => {\r\n const { chartModel } = this.props\r\n if (this.resizerPaneIndex > 0 && this.lastY !== null) {\r\n this.resizePanesAccordingly(this.lastY - e.clientY)\r\n this.lastY = null\r\n\r\n chartModel.trigger('change', chartModel)\r\n }\r\n\r\n document.removeEventListener('mousemove', this.onResizerMouseMove)\r\n document.removeEventListener('mouseup', this.onResizerMouseUp)\r\n }\r\n\r\n calculateMinimalPaneHeight() {\r\n const { chartModel } = this.props\r\n const { minHeight, total } = chartModel\r\n .panes()\r\n .all()\r\n .reduce(\r\n ({ minHeight, total }, pane) => {\r\n if (minHeight > pane.height) {\r\n minHeight = pane.height\r\n }\r\n total += pane.getIsChartPane() ? 3 : 1\r\n return { minHeight, total }\r\n },\r\n { minHeight: chartModel.height, total: 0 }\r\n )\r\n const optiMinHeight = Math.floor(chartModel.height / total)\r\n this.minimalPaneHeight = Math.min(minHeight, optiMinHeight)\r\n }\r\n\r\n resizePanesAccordingly(difY: number) {\r\n const { chartModel } = this.props\r\n const panes = chartModel.panes().all()\r\n let basePane = this.resizerPaneIndex\r\n if (!difY) {\r\n return true\r\n } else if (difY > 0) {\r\n let i = basePane\r\n let pane = panes[i]\r\n if (pane.height + difY >= this.minimalPaneHeight) {\r\n pane.updateAttribute('height', pane.height + difY)\r\n } else {\r\n pane.updateAttribute('height', this.minimalPaneHeight)\r\n }\r\n for (--i; i >= 0; i--) {\r\n pane = panes[i]\r\n if (pane.height - difY >= this.minimalPaneHeight) {\r\n pane.updateAttribute('height', pane.height - difY)\r\n break\r\n } else {\r\n pane.updateAttribute('height', this.minimalPaneHeight)\r\n }\r\n }\r\n } else if (difY < 0) {\r\n basePane = Math.max(0, basePane - 1)\r\n let i = basePane\r\n let pane = panes[i]\r\n if (pane.height - difY >= this.minimalPaneHeight) {\r\n pane.updateAttribute('height', pane.height - difY)\r\n } else {\r\n pane.updateAttribute('height', this.minimalPaneHeight)\r\n }\r\n for (++i; i < panes.length; i++) {\r\n pane = panes[i]\r\n if (pane.height + difY >= this.minimalPaneHeight) {\r\n pane.updateAttribute('height', pane.height + difY)\r\n break\r\n } else {\r\n pane.updateAttribute('height', this.minimalPaneHeight)\r\n }\r\n }\r\n }\r\n\r\n const panesHeight = panes.reduce((sum, pane) => sum + pane.height, 0)\r\n if (panesHeight !== chartModel.height) {\r\n difY = chartModel.height - panesHeight\r\n\r\n const pane = panes[basePane]\r\n pane.updateAttribute('height', pane.height + difY)\r\n\r\n // if we exceeded total height we need to stop updating lastY - return false\r\n return false\r\n }\r\n\r\n return true\r\n }\r\n\r\n onZoomerTouchStart = (e: React.TouchEvent | TouchEvent) => {\r\n if (!this.props.layoutModel.scrollable || e.touches.length !== 1 || this.props.touchEventsDisabled) {\r\n return\r\n }\r\n this.onZoomerMouseDown(e.targetTouches[0])\r\n }\r\n\r\n onZoomerTouchMove = (e: TouchEvent) => {\r\n if (!this.props.layoutModel.scrollable || e.touches.length !== 1) {\r\n return\r\n }\r\n this.onZoomerMouseMove(e.targetTouches[0])\r\n }\r\n\r\n onZoomerTouchEnd = () => {\r\n if (!this.props.layoutModel.scrollable) {\r\n return\r\n }\r\n this.onZoomerMouseUp()\r\n }\r\n\r\n getRawDistance = (e: Pick) => {\r\n const p1 = { x: e.touches[0].clientX, y: e.touches[0].clientY }\r\n const p2 = { x: e.touches[1].clientX, y: e.touches[1].clientY }\r\n return math.distance(p1, p2)\r\n }\r\n\r\n onPinchStart = (e: React.TouchEvent) => {\r\n const { chartModel } = this.props\r\n const { activeChartInteraction, setActiveChartInteraction, touchEventsDisabled } = this.props\r\n const isLoading = chartModel.panes().count() < 1\r\n\r\n if (\r\n this.props.layoutModel.scrollable &&\r\n e.touches.length === 2 &&\r\n !activeChartInteraction &&\r\n !isLoading &&\r\n !touchEventsDisabled\r\n ) {\r\n setActiveChartInteraction('pinch')\r\n this.onZoomerMouseDown({ clientX: this.getRawDistance(e as unknown as TouchEvent) })\r\n\r\n document.addEventListener('touchmove', this.onPinchMove)\r\n document.addEventListener('touchend', this.onPinchEnd)\r\n }\r\n }\r\n\r\n onPinchMove = (e: TouchEvent) => {\r\n if (e.touches.length === 2) {\r\n this.onZoomerMouseMove({ clientX: this.getRawDistance(e) })\r\n }\r\n }\r\n\r\n onPinchEnd = (e: TouchEvent) => {\r\n if (e.touches.length === 1) {\r\n this.onZoomerMouseUp()\r\n document.removeEventListener('touchmove', this.onPinchMove)\r\n document.removeEventListener('touchend', this.onPinchEnd)\r\n }\r\n }\r\n\r\n calcZoomerRightAlign = () => {\r\n const { chartModel } = this.props\r\n const { ChartSettings } = chartModel.getChartLayoutSettings()\r\n const quote = chartModel.quote()\r\n const fx = chartModel.panes().first().scale.x\r\n const barWidth = getBarWidthWithMargin({ zoomFactor: chartModel.zoomFactor, chartLayout: this.props.layoutModel })\r\n const currentLeftOffset = getLeftOffset({ quote, chartModel, config: this.props.config, barWidth })\r\n this.zoomerRightAlign = null\r\n\r\n if (quote.isIntraday && quote.instrument === Instrument.Stock) {\r\n const barIndex = quote.getBarIndex(quote.close.length - 1)\r\n let offsetDiff =\r\n chartModel.leftOffset -\r\n getLeftOffset({\r\n quote,\r\n chartModel: chartModel,\r\n config: this.props.config,\r\n barWidth,\r\n barIndex,\r\n shouldAlignDaysToLeftApplied: false,\r\n })\r\n const offsetBars = ~~(offsetDiff / barWidth)\r\n offsetDiff -= offsetBars * barWidth\r\n this.zoomerRightAlign = {\r\n barIndex,\r\n index: barIndex - offsetBars,\r\n offsetDiff,\r\n }\r\n } else if (chartModel.leftOffset <= currentLeftOffset) {\r\n this.zoomerRightAlign = {\r\n index: quote.getBarIndex(quote.open.length - 1),\r\n offsetDiff: chartModel.leftOffset - currentLeftOffset,\r\n }\r\n } else {\r\n const offset = chartModel.leftOffset\r\n for (let i = 0; i < quote.open.length; i += 1) {\r\n const x = fx(i)\r\n if (x + offset < 0) {\r\n continue\r\n }\r\n if (x + offset > chartModel.width - ChartSettings.left.width - ChartSettings.right.width) {\r\n const barIndex = quote.getBarIndex(i - 1)\r\n let offsetDiff =\r\n offset -\r\n getLeftOffset({\r\n quote,\r\n chartModel,\r\n config: this.props.config,\r\n barWidth,\r\n barIndex,\r\n })\r\n const offsetBars = ~~(offsetDiff / barWidth)\r\n offsetDiff -= offsetBars * barWidth\r\n this.zoomerRightAlign = {\r\n barIndex,\r\n index: barIndex - offsetBars,\r\n offsetDiff,\r\n }\r\n break\r\n }\r\n }\r\n }\r\n }\r\n\r\n onZoomerMouseDown = (e: Partial) => {\r\n if ((e.button !== 0 && 'button' in e) || !this.props.layoutModel.scrollable) {\r\n return\r\n }\r\n switch (this.props.activeChartInteraction) {\r\n case 'pinch':\r\n break\r\n case null:\r\n this.props.setActiveChartInteraction('zoomer')\r\n break\r\n default:\r\n return\r\n }\r\n\r\n this.lastX = e.clientX ?? null\r\n this.calcZoomerRightAlign()\r\n\r\n document.addEventListener('mousemove', this.onZoomerMouseMove)\r\n document.addEventListener('mouseup', this.onZoomerMouseUp)\r\n document.addEventListener('touchmove', this.onZoomerTouchMove)\r\n document.addEventListener('touchend', this.onZoomerTouchEnd)\r\n }\r\n\r\n normalizeWheelDeltaY = (e: WheelEvent) => {\r\n // because wheel deltaY on mouse and touchpad is quite different we need to normalize it\r\n const abs = Math.abs(e.deltaY)\r\n if (abs === 0) return 0\r\n return Math.log(abs) * Math.sign(e.deltaY) * 10\r\n }\r\n\r\n onZoomerMouseMove = (\r\n e: React.WheelEvent | MouseEvent | Touch | { clientX: number },\r\n _?: unknown,\r\n isMouseWheel = false\r\n ) => {\r\n const { chartModel, layoutModel } = this.props\r\n let difX\r\n if (!layoutModel.scrollable) return\r\n if (!isMouseWheel && this.lastX !== null) {\r\n difX = (this.lastX - e.clientX) / chartModel.width\r\n this.lastX = e.clientX\r\n } else {\r\n // standard difX calculation result is around 0.00x, wheel deltaY is whole px\r\n // because of that we divide px with 1000\r\n difX = this.normalizeWheelDeltaY(e as WheelEvent) / 1000\r\n }\r\n\r\n this.addToZoomFactor({ diff: -difX })\r\n }\r\n\r\n addToZoomFactor = ({\r\n diff,\r\n shouldCalculateRightAlign = false,\r\n }: {\r\n diff: number\r\n shouldCalculateRightAlign?: boolean\r\n }) => {\r\n const { chartModel, layoutModel } = this.props\r\n if (shouldCalculateRightAlign) {\r\n this.calcZoomerRightAlign()\r\n }\r\n // 6 is default bar width with margin on charts page, so to get the similar feeling when zooming we're multiplying the zoom factor by the coefficient\r\n const diffCoefficient = chartModel.zoomFactor * (6 / getBarWidthWithMargin({ chartLayout: this.props.layoutModel }))\r\n const zoomFactor = getZoomFactor({\r\n chartLayout: layoutModel,\r\n currentZoomFactor: chartModel.zoomFactor,\r\n diff: diff * diffCoefficient,\r\n })\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor,\r\n chartLayout: this.props.layoutModel,\r\n })\r\n\r\n let leftOffset\r\n if (this.props.config.stretch) {\r\n leftOffset = 0\r\n } else if (getIsSmallIndexChart(this.props.layoutModel.specificChartFunctionality)) {\r\n leftOffset = barWidth\r\n } else if (this.zoomerRightAlign) {\r\n leftOffset = getMinMaxLeftOffset({\r\n newLeftOffset:\r\n getLeftOffset({\r\n quote: chartModel.quote(),\r\n chartModel: chartModel,\r\n config: this.props.config,\r\n barWidth,\r\n barIndex: this.zoomerRightAlign.index,\r\n shouldAlignDaysToLeftApplied: false,\r\n }) + this.zoomerRightAlign.offsetDiff,\r\n chartModel: chartModel,\r\n barWidth,\r\n barIndex: getBarIndex(chartModel.quote()),\r\n })\r\n } else {\r\n return\r\n }\r\n chartModel.updateAttributes({\r\n zoomFactor,\r\n leftOffset,\r\n dateRange: null,\r\n })\r\n if (shouldCalculateRightAlign) {\r\n this.zoomerRightAlign = null\r\n }\r\n }\r\n\r\n onZoomerMouseUp = () => {\r\n this.zoomerRightAlign = null\r\n document.removeEventListener('mousemove', this.onZoomerMouseMove)\r\n document.removeEventListener('mouseup', this.onZoomerMouseUp)\r\n document.removeEventListener('touchmove', this.onZoomerTouchMove)\r\n document.removeEventListener('touchend', this.onZoomerTouchEnd)\r\n this.props.setActiveChartInteraction(null)\r\n }\r\n\r\n onZoomerReset = () => {\r\n const { chartModel, layoutModel } = this.props\r\n const zoomFactor = chartModel.chart_layout().defaultZoomFactor\r\n const barWidth = getBarWidthWithMargin({ zoomFactor, chartLayout: layoutModel })\r\n const leftOffset = getLeftOffset({\r\n quote: chartModel.quote(),\r\n chartModel,\r\n config: this.props.config,\r\n barWidth,\r\n })\r\n\r\n chartModel.updateAttributes({\r\n zoomFactor,\r\n leftOffset,\r\n dateRange: null,\r\n })\r\n }\r\n\r\n onOlderDataLoaded = () => {\r\n throw new Error('onOlderDataLoaded not implemented')\r\n // TODO implement similarly to onDataLoaded\r\n }\r\n\r\n resetMouseModel = () => {\r\n const isLoading = this.props.chartModel.panes().count() < 1\r\n if (!isLoading) {\r\n MouseModel.updateAttributes({\r\n position: null,\r\n pane: null,\r\n })\r\n }\r\n }\r\n\r\n handleQuoteChange = (quote: Quote) => {\r\n const { chartModel } = this.props\r\n\r\n // Update only date range chart\r\n if (chartModel.dateRange) {\r\n if (!quote.eql(chartModel.quote()) || chartModel.timeframe !== quote.timeframe || quote.date.length === 0) {\r\n return\r\n }\r\n updateZoomAndLeftOffsetByDateRange({ chartModel, quote })\r\n }\r\n }\r\n\r\n onDataLoaded = (newQuote: Quote, fetchType: QuoteFetchType) => {\r\n const { chartModel } = this.props\r\n const quote = chartModel.quote()\r\n if (!quote?.eql(newQuote)) {\r\n return\r\n }\r\n\r\n const shouldForceLeftOffsetUpdate = fetchType === QuoteFetchType.Refetch\r\n let newLeftOffset = chartModel.leftOffset // TODO find proper fix. If this line is removed (if we don't trigger leftOffset update), the chart stops being updated for the user until they move chart around.\r\n if (\r\n (this.props.layoutModel.scrollable === false && !this.props.layoutModel.isTouchCrossActive) ||\r\n !chartModel.isScrolled ||\r\n shouldForceLeftOffsetUpdate\r\n ) {\r\n newLeftOffset = getLeftOffset({\r\n quote,\r\n chartModel: chartModel,\r\n config: this.props.config,\r\n })\r\n }\r\n\r\n chartModel.setChartEvents(quote.chartEvents, !quote.events)\r\n\r\n if (newLeftOffset !== chartModel.leftOffset) {\r\n chartModel.getAllElements().forEach((element) => {\r\n if (element.isDrawing() && !element.isMouseDown()) {\r\n element.instance.updateScales()\r\n }\r\n })\r\n }\r\n\r\n chartModel.updateAttribute('leftOffset', newLeftOffset)\r\n\r\n this.handleQuoteChange(quote)\r\n }\r\n}\r\n\r\nexport default withChartInit(withWatchedPanesOnChartModel(Chart))\r\n","import classNames from 'classnames'\r\nimport merge from 'lodash.merge'\r\nimport React from 'react'\r\n\r\nimport { ObjectHash } from '../../../types/shared'\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport Quote from '../../models/quote'\r\nimport { getChartsDimensions, isRedesignEnabled } from '../../utils'\r\nimport { getQuoteFinancialAttachmentsFromChartConfig, prefetchPerfIndicatorAllQuotes } from '../../utils/chart'\r\nimport { getLeftOffset } from '../renderUtils'\r\nimport { ChartSpinnerOverlay } from './chart-spinner-overlay'\r\nimport { CHART_CLASS_NAMES, ChartProps, DEFAULT_WRAPPER_COMPONENT } from './constants'\r\n\r\nexport function withChartInit(Component: React.ComponentType) {\r\n return function WrappedComponent(props: ChartProps) {\r\n const { WrapperComp = DEFAULT_WRAPPER_COMPONENT, gridArea } = props\r\n const isModelDestroyedRef = React.useRef(null)\r\n const model = useModelState(props.chartModel, { watchProperties: ['panes', 'quote'] })\r\n const layoutModel = useModelState(props.layoutModel, { watchProperties: ['activeChart'] })\r\n const quote = model.quote()\r\n\r\n const initChartRef = React.useRef(async () => {\r\n const { chartModel, config } = props\r\n const { premarket, hasChartEvents, aftermarket, ticker, instrument, timeframe, panes: panesConfig } = config\r\n const options = {\r\n premarket,\r\n aftermarket,\r\n events: hasChartEvents,\r\n patterns: panesConfig.some((pane) =>\r\n pane.elements?.some((element) =>\r\n element.overlays?.some((overlay: ObjectHash) => overlay.type === 'overlays/patterns')\r\n )\r\n ),\r\n }\r\n\r\n const quote = await Quote.get({\r\n ticker,\r\n instrument,\r\n timeframe,\r\n options: {\r\n ...options,\r\n financialAttachments: getQuoteFinancialAttachmentsFromChartConfig(config),\r\n },\r\n })\r\n const panesWithPerfIndicator = panesConfig.filter(({ elements }) =>\r\n elements.some(({ type }) => type === 'indicators/perf')\r\n )\r\n\r\n if (panesWithPerfIndicator) {\r\n await Promise.allSettled(\r\n panesWithPerfIndicator.map((paneWithPerfIndicator) =>\r\n prefetchPerfIndicatorAllQuotes({ paneWithPerfIndicator, timeframe, options })\r\n )\r\n )\r\n }\r\n\r\n if (isModelDestroyedRef.current) {\r\n return\r\n }\r\n\r\n config.panes.forEach((pane) => {\r\n const paneProperties = merge({}, pane)\r\n paneProperties.chart = chartModel\r\n chartModel.createPaneCascade(paneProperties)\r\n })\r\n\r\n chartModel.updateAttributes({\r\n quote,\r\n premarket: options.premarket,\r\n aftermarket: options.aftermarket,\r\n })\r\n\r\n chartModel.setChartEvents(quote.chartEvents, true)\r\n\r\n if (props.shouldResize) {\r\n const chartsDimensions = getChartsDimensions(props.layoutModel.getHTMLElementId())\r\n props.layoutModel.updateAttributes(chartsDimensions)\r\n }\r\n\r\n if (chartModel.leftOffset == null) {\r\n const leftOffset = getLeftOffset({ quote, chartModel: chartModel, config: props.config })\r\n chartModel.updateAttribute('leftOffset', leftOffset)\r\n }\r\n })\r\n\r\n React.useEffect(() => {\r\n // This prevents the being re-called on hotreload\r\n if (isModelDestroyedRef.current !== null) {\r\n return\r\n }\r\n\r\n isModelDestroyedRef.current = false\r\n\r\n const handleModelBeforeDestroy = () => {\r\n isModelDestroyedRef.current = true\r\n }\r\n\r\n model.bind('beforeDestroy', handleModelBeforeDestroy)\r\n initChartRef.current()\r\n return () => {\r\n model.unbind('beforeDestroy', handleModelBeforeDestroy)\r\n }\r\n // We want to run it only on mount\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n const isQuoteOrQuoteFinancials = [\r\n SpecificChartFunctionality.quotePage,\r\n SpecificChartFunctionality.quoteFinancials,\r\n ].includes(props.layoutModel.specificChartFunctionality)\r\n const isChartPage = props.layoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isFuturesForexCryptoPage = [\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n ].includes(props.layoutModel.specificChartFunctionality)\r\n const isModelReady =\r\n quote && ((quote.fetchedAt === undefined && quote.close.length > 0) || quote.fetchedAt > 0 || quote)\r\n const loadingStyle =\r\n !isModelReady && isQuoteOrQuoteFinancials\r\n ? // 2px is border\r\n { width: model.width ? model.width + 2 : '100%', height: model.height + 2 }\r\n : undefined\r\n\r\n return (\r\n \r\n {isChartPage && (\r\n \r\n )}\r\n {isModelReady && }\r\n \r\n )\r\n }\r\n}\r\n","import React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartModel from '../../models/chart'\r\n\r\nexport function withWatchedPanesOnChartModel

(Component: React.ComponentType

) {\r\n return function WrappedComponent(props: P) {\r\n const model = useModelState(props.chartModel, { watchProperties: ['panes'] })\r\n\r\n return \r\n }\r\n}\r\n","export const drawingCreatorsAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"drawing-creators\" */ './module-entry'),\r\n cacheKey: 'drawing-creators',\r\n}\r\n","import { DrawingActions, IToolbarDrawingAction, IToolbarDrawingActionItem } from './interfaces'\r\n\r\nexport const drawingActions: Record = {\r\n [DrawingActions.AddNote]: {\r\n id: DrawingActions.AddNote,\r\n title: 'Add note',\r\n icon: 'note',\r\n },\r\n [DrawingActions.DeleteDrawings]: {\r\n id: DrawingActions.DeleteDrawings,\r\n title: 'Remove all drawings',\r\n icon: 'drawingActionDelete',\r\n },\r\n [DrawingActions.DeleteAutoSavedDrawings]: {\r\n id: DrawingActions.DeleteAutoSavedDrawings,\r\n title: 'Remove all autosaved drawings',\r\n icon: 'drawingActionDelete',\r\n },\r\n}\r\n\r\nexport const getToolbarDrawingActions = ({\r\n isAutoSaveActive,\r\n isAddNoteAvailable = false,\r\n isIdea,\r\n}: {\r\n isAutoSaveActive: boolean\r\n isAddNoteAvailable?: boolean\r\n isIdea?: boolean\r\n}): Array => [\r\n ...(isAddNoteAvailable\r\n ? [\r\n {\r\n defaultItem: drawingActions[DrawingActions.AddNote],\r\n isDisabled: isIdea,\r\n disabledTooltip: 'Add note is not available in ideas',\r\n },\r\n ]\r\n : []),\r\n {\r\n defaultItem:\r\n drawingActions[isAutoSaveActive ? DrawingActions.DeleteAutoSavedDrawings : DrawingActions.DeleteDrawings],\r\n },\r\n]\r\n","import { DrawingSetting, IToolbarDrawingSetting, IToolbarDrawingsSettingItem } from './interfaces'\r\n\r\nconst drawingSettings: Record = {\r\n [DrawingSetting.PreserveDrawings]: {\r\n id: DrawingSetting.PreserveDrawings,\r\n icon: 'drawingSettingPreserveDrawings',\r\n iconActive: 'drawingSettingPreserveDrawingsActive',\r\n title: 'Preserve drawings: Off',\r\n titleActive: 'Preserve drawings: On',\r\n },\r\n [DrawingSetting.DrawingModeContinuous]: {\r\n id: DrawingSetting.DrawingModeContinuous,\r\n icon: 'drawingSettingDrawingMode',\r\n iconActive: 'drawingSettingDrawingModeActive',\r\n title: 'Drawing mode: Single',\r\n titleActive: 'Drawing mode: Continuous',\r\n },\r\n [DrawingSetting.HideDrawings]: {\r\n id: DrawingSetting.HideDrawings,\r\n icon: 'drawingSettingHide',\r\n iconActive: 'drawingSettingShow',\r\n title: 'Hide drawings',\r\n titleActive: 'Show drawings',\r\n },\r\n [DrawingSetting.LockDrawings]: {\r\n id: DrawingSetting.LockDrawings,\r\n icon: 'drawingSettingLock',\r\n iconActive: 'drawingSettingUnlock',\r\n title: 'Lock drawings',\r\n titleActive: 'Unlock drawings',\r\n },\r\n}\r\n\r\nconst preserveDrawingsAutosaveOverride: IToolbarDrawingSetting = {\r\n id: DrawingSetting.PreserveDrawings, // DrawingSetting.PreserveDrawings so it works with current settings sync to DB\r\n icon: 'drawingSettingAutosaveOff',\r\n iconActive: 'drawingSettingAutosaveOn',\r\n iconAction: 'drawingSettingAutosaveSaving',\r\n title: 'Drawings autosave: Off',\r\n titleActive: 'Drawings Autosave: On',\r\n titleAction: 'Drawings Autosave: Saving',\r\n}\r\n\r\nexport const getToolbarDrawingSettings = ({\r\n isPreserveDrawingsAndAutosaveAvailable,\r\n isIdea,\r\n isAutoSaveInProgress,\r\n}: {\r\n isPreserveDrawingsAndAutosaveAvailable?: boolean\r\n isIdea?: boolean\r\n isAutoSaveInProgress?: boolean\r\n}): Array => {\r\n const toolbarSettings = [\r\n {\r\n defaultItem: drawingSettings[DrawingSetting.DrawingModeContinuous],\r\n },\r\n ...(isPreserveDrawingsAndAutosaveAvailable\r\n ? [\r\n {\r\n defaultItem: preserveDrawingsAutosaveOverride,\r\n isDisabled: isIdea,\r\n isInAction: isAutoSaveInProgress,\r\n disabledTooltip: 'Autosave is not available in ideas',\r\n },\r\n ]\r\n : []),\r\n {\r\n defaultItem: drawingSettings[DrawingSetting.HideDrawings],\r\n },\r\n {\r\n defaultItem: drawingSettings[DrawingSetting.LockDrawings],\r\n },\r\n ]\r\n\r\n return toolbarSettings\r\n}\r\n","import { DrawingTool, IToolbarDrawingTool, IToolbarDrawingToolItem } from './interfaces'\r\n\r\nexport const drawingTools: Record = {\r\n [DrawingTool.Mouse]: {\r\n id: DrawingTool.Mouse,\r\n title: 'Mouse',\r\n icon: 'toolMouse',\r\n },\r\n [DrawingTool.Measure]: {\r\n id: DrawingTool.Measure,\r\n title: 'Measure',\r\n icon: 'toolMeasure',\r\n },\r\n [DrawingTool.ScaledLine]: {\r\n id: DrawingTool.ScaledLine,\r\n title: 'Line',\r\n icon: 'toolLine',\r\n },\r\n [DrawingTool.Arrow]: {\r\n id: DrawingTool.Arrow,\r\n title: 'Arrow',\r\n icon: 'toolArrow',\r\n },\r\n [DrawingTool.VerticalLine]: {\r\n id: DrawingTool.VerticalLine,\r\n title: 'Vertical line',\r\n icon: 'toolMidLineV',\r\n },\r\n [DrawingTool.HorizontalLine]: {\r\n id: DrawingTool.HorizontalLine,\r\n title: 'Horizontal line',\r\n icon: 'toolMidLineH',\r\n },\r\n [DrawingTool.Rectangle]: {\r\n id: DrawingTool.Rectangle,\r\n title: 'Rectangle',\r\n icon: 'toolRect',\r\n },\r\n [DrawingTool.RotatedRectangle]: {\r\n id: DrawingTool.RotatedRectangle,\r\n title: 'Rotated rectangle',\r\n icon: 'toolRectRotated',\r\n },\r\n [DrawingTool.Triangle]: {\r\n id: DrawingTool.Triangle,\r\n title: 'Triangle',\r\n icon: 'toolTriangle',\r\n },\r\n [DrawingTool.Ellipse]: {\r\n id: DrawingTool.Ellipse,\r\n title: 'Ellipse',\r\n icon: 'toolEllipse',\r\n },\r\n [DrawingTool.Curve]: {\r\n id: DrawingTool.Curve,\r\n title: 'Curve',\r\n icon: 'toolCurve',\r\n },\r\n [DrawingTool.Pitchfork]: {\r\n id: DrawingTool.Pitchfork,\r\n title: 'Pitchfork',\r\n icon: 'toolPitchfork',\r\n },\r\n [DrawingTool.Polygon]: {\r\n id: DrawingTool.Polygon,\r\n title: 'Polygon',\r\n icon: 'toolPolygon',\r\n },\r\n [DrawingTool.Xabcd]: {\r\n id: DrawingTool.Xabcd,\r\n title: 'XABCD',\r\n icon: 'toolXABCD',\r\n },\r\n [DrawingTool.ScaledText]: {\r\n id: DrawingTool.ScaledText,\r\n title: 'Text',\r\n icon: 'toolText',\r\n },\r\n [DrawingTool.Brush]: {\r\n id: DrawingTool.Brush,\r\n title: 'Brush',\r\n icon: 'toolBrush',\r\n },\r\n [DrawingTool.ElliottWaves]: {\r\n id: DrawingTool.ElliottWaves,\r\n title: 'Elliott waves',\r\n icon: 'toolElliottWave',\r\n },\r\n [DrawingTool.FibonacciRetracements]: {\r\n id: DrawingTool.FibonacciRetracements,\r\n title: 'Fibonacci retracements',\r\n icon: 'toolFibonacci',\r\n },\r\n [DrawingTool.Position]: {\r\n id: DrawingTool.Position,\r\n title: 'Position',\r\n icon: 'toolPosition',\r\n },\r\n [DrawingTool.Callout]: {\r\n id: DrawingTool.Callout,\r\n title: 'Callout',\r\n icon: 'toolCallout',\r\n },\r\n}\r\n\r\nexport const toolbarDrawingTools: Array = [\r\n {\r\n defaultItem: drawingTools[DrawingTool.Mouse],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Measure],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.ScaledLine],\r\n toolGroup: [\r\n drawingTools[DrawingTool.ScaledLine],\r\n drawingTools[DrawingTool.VerticalLine],\r\n drawingTools[DrawingTool.HorizontalLine],\r\n drawingTools[DrawingTool.Curve],\r\n ],\r\n toolGroupTitle: 'Line tools',\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Arrow],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Rectangle],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.RotatedRectangle],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Triangle],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Ellipse],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Polygon],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Xabcd],\r\n toolGroup: [drawingTools[DrawingTool.Xabcd], drawingTools[DrawingTool.Pitchfork]],\r\n toolGroupTitle: 'XABCD tools',\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.ScaledText],\r\n toolGroup: [drawingTools[DrawingTool.ScaledText], drawingTools[DrawingTool.Callout]],\r\n toolGroupTitle: 'Text tools',\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Brush],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.ElliottWaves],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.FibonacciRetracements],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Position],\r\n },\r\n]\r\n","import { Toolbar as ToolbarComponent, ToolbarDivider, ToolbarGroupProps, ToolbarItem } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { PaneArea } from '../../../types/shared'\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport { drawingCreatorsAsyncModule } from '../../creators/async-modules'\r\nimport { ElementStyleDialogContext } from '../../modals/element_style'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { AutoSaveState } from '../../models/constants'\r\nimport PaneModel from '../../models/pane'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\nimport { getIsPreserveDrawingsAndAutosaveAvailable } from '../../utils/chart'\r\nimport { getToolbarDrawingActions } from './drawingActions'\r\nimport { getToolbarDrawingSettings } from './drawingSettings'\r\nimport { drawingTools, toolbarDrawingTools } from './drawingTools'\r\nimport { DrawingSetting, DrawingTool, IToolBarProps } from './interfaces'\r\n\r\nexport const DISABLED_ITEM_TOOLTIP_LABEL = \"Disabled due 'lock/hide' drawings active\"\r\n\r\nexport default function Toolbar({\r\n isSidebar,\r\n isHorizontal,\r\n isMobileOverlay,\r\n activeTool,\r\n chartLayoutModel,\r\n onActiveToolChange,\r\n onDrawingActionClick,\r\n onDrawingSettingClick,\r\n onDrawingEnd,\r\n drawingSettings,\r\n isAlternativeTheme,\r\n areToolsDisabled,\r\n}: IToolBarProps) {\r\n const ignoreRowId =\r\n isHorizontal || chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const [drawingCreatorsModule, { isLoading: isDrawingCreatorsModuleLoading }] = useAsyncModule({\r\n ...drawingCreatorsAsyncModule,\r\n shouldLoadModule: true,\r\n })\r\n const { autoSaveState } = useModelState(\r\n React.useMemo(() => chartLayoutModel.drawingsInternalStore(), [chartLayoutModel]),\r\n { watchProperties: ['autoSaveState'] }\r\n )\r\n const [isDrawing, setIsDrawing] = React.useState(false)\r\n const openElementStyleDialog = React.useContext(ElementStyleDialogContext)\r\n\r\n const availableDrawingSettings = getToolbarDrawingSettings({\r\n isPreserveDrawingsAndAutosaveAvailable: getIsPreserveDrawingsAndAutosaveAvailable(chartLayoutModel),\r\n isAutoSaveInProgress: autoSaveState === AutoSaveState.Saving,\r\n isIdea: !!chartLayoutModel.idea?.id,\r\n })\r\n\r\n const availableDrawingActions = getToolbarDrawingActions({\r\n isAutoSaveActive: autoSaveState !== AutoSaveState.Off,\r\n isAddNoteAvailable: chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage,\r\n isIdea: !!chartLayoutModel.idea?.id,\r\n })\r\n\r\n React.useEffect(() => {\r\n if (!drawingCreatorsModule) {\r\n return\r\n }\r\n\r\n const onMouseDown = (model: PaneModel, area: PaneArea & { isTouch: boolean }) => {\r\n const isDrawingModeContinuous = drawingSettings[DrawingSetting.DrawingModeContinuous]\r\n const hasData = model.chart().quote().close.length > 0\r\n const hasHiddenDrawings = drawingSettings[DrawingSetting.HideDrawings]\r\n const tool = drawingTools[activeTool].id\r\n\r\n if (tool === DrawingTool.Mouse || isDrawing || hasHiddenDrawings || !hasData) {\r\n return\r\n }\r\n\r\n setIsDrawing(true)\r\n const { drawingToolsTouchCreatorsByType, drawingToolsCreatorsByType } = drawingCreatorsModule\r\n const ToolClass = area.isTouch ? drawingToolsTouchCreatorsByType[tool] : drawingToolsCreatorsByType[tool]\r\n const element = model.elements().create({\r\n instance: new ToolClass(area, {}, model, openElementStyleDialog, () => {\r\n if (!isDrawingModeContinuous) {\r\n onActiveToolChange(DrawingTool.Mouse)\r\n }\r\n setIsDrawing(false)\r\n onDrawingEnd?.()\r\n }),\r\n })\r\n element.one('destroy', ({ instance }) => {\r\n if (instance.getIsCreator()) {\r\n setIsDrawing(false)\r\n onDrawingEnd?.()\r\n }\r\n })\r\n\r\n element.trigger('select', element)\r\n }\r\n PaneModel.bind('mousedown', onMouseDown)\r\n return () => {\r\n PaneModel.unbind('mousedown', onMouseDown)\r\n }\r\n }, [\r\n activeTool,\r\n onActiveToolChange,\r\n openElementStyleDialog,\r\n onDrawingEnd,\r\n drawingCreatorsModule,\r\n drawingSettings,\r\n isDrawing,\r\n ])\r\n\r\n return (\r\n \r\n {toolbarDrawingTools.map((item, index) => {\r\n const isActive = activeTool === item.defaultItem.id || item.toolGroup?.some((tool) => tool.id === activeTool)\r\n const isToolLoading = isDrawingCreatorsModuleLoading && isActive\r\n\r\n return (\r\n \r\n )\r\n })}\r\n \r\n {availableDrawingSettings.map((item, index) => (\r\n \r\n ))}\r\n {availableDrawingActions.map((item, index) => (\r\n \r\n ))}\r\n \r\n )\r\n}\r\n","import Toolbar from './toolbar'\r\n\r\nexport default Toolbar\r\n","import { Textarea } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { ObjectHash } from '../../../../types/shared'\r\nimport { useModelState } from '../../../model-hooks/use-model-state'\r\nimport Chart from '../../../models/chart'\r\nimport ChartLayout from '../../../models/chart_layout'\r\nimport { useDrawingAutoSaveControls } from '../../autosave/use-drawing-auto-save-controls'\r\nimport { getElementNoteText, getTickersAndContainerTypesInLayoutModel } from '../../autosave/utils'\r\n\r\ninterface ChartAutoSaveNoteProps {\r\n ticker: string\r\n note: string\r\n onNoteChange: (note: string, ticker: string) => void\r\n}\r\n\r\nfunction ChartAutoSaveNote({ ticker, note, onNoteChange }: ChartAutoSaveNoteProps) {\r\n return (\r\n ) => {\r\n onNoteChange(e.target.value, ticker)\r\n }}\r\n />\r\n )\r\n}\r\n\r\ninterface Props {\r\n chartLayoutModel: ChartLayout\r\n}\r\n\r\nexport function ChartAutoSaveNotes({ chartLayoutModel }: Props) {\r\n const { handleAutoSaveNoteChange } = useDrawingAutoSaveControls(chartLayoutModel)\r\n const [tickers, setTickers] = React.useState([])\r\n const unwatchedInternalStore = React.useMemo(() => chartLayoutModel.drawingsInternalStore(), [chartLayoutModel])\r\n const drawingsInternalStore = useModelState(unwatchedInternalStore, { watchProperties: ['elements'] })\r\n\r\n React.useEffect(() => {\r\n // There was no better way how to listen on ticker changes which is necessary for displaying correct text areas\r\n const handleChartChange = () => {\r\n const { tickers } = getTickersAndContainerTypesInLayoutModel(chartLayoutModel)\r\n setTickers(tickers)\r\n }\r\n\r\n Chart.bind('change', handleChartChange)\r\n handleChartChange()\r\n return () => {\r\n Chart.unbind('change', handleChartChange)\r\n }\r\n }, [chartLayoutModel])\r\n\r\n const tickerNoteMap = React.useMemo(() => {\r\n const map: ObjectHash = {}\r\n drawingsInternalStore.elements.forEach((element) => {\r\n if (element.containerType === 'note' && tickers.includes(element.ticker)) {\r\n map[element.ticker] = getElementNoteText(element)\r\n }\r\n })\r\n\r\n return map\r\n }, [drawingsInternalStore.elements, tickers])\r\n\r\n return (\r\n

\r\n {tickers.map((ticker) => (\r\n \r\n ))}\r\n
\r\n )\r\n}\r\n","import { Dialog, DialogBody, DialogHeader, DialogStateReturn, ZIndexContext } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport ChartLayout from '../../../models/chart_layout'\r\nimport { ChartAutoSaveNotes } from './auto-save-notes'\r\n\r\ninterface INoteDialog {\r\n state: DialogStateReturn\r\n chartLayoutModel: ChartLayout\r\n}\r\n\r\nexport function AutoSaveNotesDialog({ state, chartLayoutModel }: INoteDialog) {\r\n const isOpen = state.useState('open')\r\n const isAnimating = state.useState('animating')\r\n const isFullyClosed = !isOpen && !isAnimating\r\n\r\n return (\r\n \r\n \r\n Notes\r\n {!isFullyClosed && }\r\n \r\n \r\n )\r\n}\r\n","import {\r\n Button,\r\n ConfirmationDialog as ConfirmationDialogComponent,\r\n DialogDismiss,\r\n DialogStateReturn,\r\n} from '@finviz/website'\r\nimport React from 'react'\r\n\r\nconst getDialogContent = ({\r\n isAutosaveDialogContent,\r\n tickers,\r\n}: {\r\n isAutosaveDialogContent: boolean\r\n tickers: string[]\r\n}) => {\r\n if (isAutosaveDialogContent) {\r\n return {\r\n title: 'Remove all autosaved drawings?',\r\n message: (\r\n <>\r\n Do you really want to remove all autosaved drawings? This action is irreversible and will remove all\r\n non-idea drawings for {tickers.join(', ')}.\r\n \r\n ),\r\n }\r\n }\r\n return {\r\n title: 'Remove all drawings?',\r\n message: `Do you really want to remove all drawings? This action only affects the current page and visible tickers. This action doesn't remove autosaved drawings or ideas.`,\r\n }\r\n}\r\n\r\nexport interface IConfirmationDialog {\r\n state: DialogStateReturn\r\n onAction: () => void\r\n onCancel?: () => void\r\n isAutosaveDialogContent: boolean\r\n tickers: string[]\r\n}\r\n\r\nexport function ConfirmationDialog({\r\n state,\r\n onAction,\r\n onCancel,\r\n isAutosaveDialogContent = false,\r\n tickers,\r\n}: IConfirmationDialog) {\r\n const dialogContent = getDialogContent({ isAutosaveDialogContent, tickers })\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n }\r\n >\r\n {dialogContent.message}\r\n \r\n )\r\n}\r\n","import { Button, ButtonProps, Dropdown, Icon, useDropdownState } from '@finviz/website'\r\nimport React from 'react'\r\nimport ReactDOM from 'react-dom'\r\nimport { useSearchParams } from 'react-router-dom'\r\n\r\nimport { SIDEBAR_QUERY_PARAM } from '../../sidebar/sidebar'\r\nimport { MOBILE_TOOLBAR_DIV_ID } from '../../sidebar/sidebar-tabs'\r\nimport { drawingTools } from '../drawingTools'\r\nimport { DrawingActions, DrawingTool, IToolBarProps } from '../interfaces'\r\nimport Toolbar from '../toolbar'\r\n\r\ntype ToolbarMobileProps = Omit\r\n\r\nexport default function ToolbarMobile({\r\n activeTool,\r\n onActiveToolChange,\r\n onDrawingActionClick,\r\n ...rest\r\n}: ToolbarMobileProps) {\r\n const toolbarState = useDropdownState()\r\n const hideToolbar = toolbarState.hideAll\r\n const [urlSearchParams, setUrlSearchParams] = useSearchParams()\r\n\r\n // get toolbar mobile element on first render\r\n const [toolbarMobileElement, setToolbarMobileElement] = React.useState(null)\r\n React.useEffect(() => {\r\n setToolbarMobileElement(document.getElementById(MOBILE_TOOLBAR_DIV_ID))\r\n }, [])\r\n\r\n const drawButtonProps = React.useMemo(() => {\r\n if (urlSearchParams.has(SIDEBAR_QUERY_PARAM) || activeTool === DrawingTool.Mouse) {\r\n return {\r\n children: 'Draw',\r\n leftContent: 'draw',\r\n size: 'medium',\r\n onClick: () => {\r\n setUrlSearchParams((params) => {\r\n params.delete(SIDEBAR_QUERY_PARAM)\r\n return params\r\n })\r\n },\r\n }\r\n }\r\n\r\n return {\r\n appearance: 'square',\r\n active: true,\r\n size: 'medium',\r\n theme: 'chipTransparent',\r\n leftContent: ,\r\n }\r\n }, [activeTool, setUrlSearchParams, urlSearchParams])\r\n\r\n const handleActiveToolChange = React.useCallback(\r\n (drawingTool: DrawingTool, trigger?: 'button' | 'select' | 'group') => {\r\n onActiveToolChange(drawingTool, trigger)\r\n\r\n if (trigger !== 'group') return hideToolbar()\r\n },\r\n [hideToolbar, onActiveToolChange]\r\n )\r\n\r\n const handleDrawingActionClick = React.useCallback(\r\n (actionId: DrawingActions) => {\r\n onDrawingActionClick?.(actionId)\r\n hideToolbar()\r\n },\r\n [hideToolbar, onDrawingActionClick]\r\n )\r\n\r\n if (!toolbarMobileElement) return null\r\n\r\n return ReactDOM.createPortal(\r\n }\r\n // Move the dropdown to cover the button\r\n gutter={-32}\r\n modal={activeTool === DrawingTool.Mouse}\r\n backdrop={false}\r\n unmountOnHide={false}\r\n placement=\"top-end\"\r\n className=\"-translate-x-1\"\r\n >\r\n \r\n ,\r\n toolbarMobileElement\r\n )\r\n}\r\n","import React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { AutoSaveState } from '../../models/constants'\r\n\r\ninterface LoadLatestDataButtonProps {\r\n chartLayoutModel: ChartLayout\r\n}\r\n\r\nexport function AutoSaveStateIndicator({ chartLayoutModel }: LoadLatestDataButtonProps) {\r\n const drawingsInternalStoreUnwatched = React.useMemo(\r\n () => chartLayoutModel.drawingsInternalStore(),\r\n [chartLayoutModel]\r\n )\r\n const { autoSaveState } = useModelState(drawingsInternalStoreUnwatched, { watchProperties: ['autoSaveState'] })!\r\n const [isVisible, setIsVisible] = React.useState(false)\r\n\r\n React.useEffect(() => {\r\n if (autoSaveState === AutoSaveState.Off) {\r\n return\r\n }\r\n\r\n let setVisibilityTimeout: number | null = null\r\n const newIsVisible = autoSaveState !== AutoSaveState.Saved\r\n\r\n setVisibilityTimeout = window.setTimeout(\r\n () => {\r\n setIsVisible(newIsVisible)\r\n },\r\n newIsVisible ? 0 : 3000\r\n )\r\n\r\n const checkIfNeededPreventLeaving = (event: BeforeUnloadEvent) => {\r\n if (autoSaveState === AutoSaveState.Saved) {\r\n return undefined\r\n }\r\n\r\n const message = `Your latest changes haven't been saved yet. If you leave now, your changes might be lost.`\r\n event.returnValue = message\r\n return message\r\n }\r\n\r\n window.addEventListener('beforeunload', checkIfNeededPreventLeaving)\r\n\r\n return () => {\r\n window.removeEventListener('beforeunload', checkIfNeededPreventLeaving)\r\n if (setVisibilityTimeout) {\r\n clearTimeout(setVisibilityTimeout)\r\n }\r\n }\r\n }, [autoSaveState])\r\n\r\n if (!isVisible) {\r\n return null\r\n }\r\n\r\n // @todo - add proper indicator component here\r\n return null\r\n}\r\n","import { Textarea } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { isRedesignEnabled } from '../../utils'\r\nimport { useDrawingAutoSaveControls } from '../autosave/use-drawing-auto-save-controls'\r\n\r\ninterface Props {\r\n chartLayoutModel: ChartLayout\r\n ideaNoteRef?: React.RefObject\r\n}\r\n\r\nconst hasRedesign = isRedesignEnabled()\r\n\r\nexport function ChartLayoutAutoSaveNote({ chartLayoutModel: chartLayoutModelUnwatched, ideaNoteRef }: Props) {\r\n const chartLayoutModel = useModelState(chartLayoutModelUnwatched, {\r\n watchProperties: ['idea'],\r\n })!\r\n const { handleIdeaNoteChange } = useDrawingAutoSaveControls(chartLayoutModel)\r\n\r\n if (!chartLayoutModel.editable) {\r\n return null\r\n }\r\n\r\n return (\r\n
\r\n {!hasRedesign &&
Note:
}\r\n
\r\n ) => {\r\n handleIdeaNoteChange(e.target.value)\r\n }}\r\n />\r\n
\r\n
\r\n )\r\n}\r\n","import { useDialogState } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { publishModalAsyncModule } from '../../modals/publish/async-modules'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\n\r\ninterface PublishOldButtonClickListenerProps {\r\n isListening: boolean\r\n layoutModel: ChartLayout\r\n}\r\n\r\nexport function getPublishChartHtmlElements() {\r\n const publishChartElements = document.getElementsByClassName('js-publish-chart')\r\n const publishChartHtmlElements = Array.from(publishChartElements) as HTMLElement[]\r\n\r\n return publishChartHtmlElements\r\n}\r\n\r\nfunction getChartImgUrl(index: number) {\r\n const imgElement = document.getElementById(`chart${index}`) as HTMLImageElement | null\r\n return imgElement?.src ?? null\r\n}\r\n\r\nexport function PublishOldButtonClickListener({ isListening, layoutModel }: PublishOldButtonClickListenerProps) {\r\n const dialog = useDialogState()\r\n const isOpen = dialog.useState('open')\r\n const [dialogConfig, setDialogConfig] = React.useState({\r\n isCanvas: true,\r\n chartImgUrl: null as null | string,\r\n timeframe: '',\r\n ticker: '',\r\n })\r\n const [publishModalModule] = useAsyncModule({\r\n ...publishModalAsyncModule,\r\n shouldLoadModule: isOpen,\r\n })\r\n const PublishDialog = publishModalModule?.default\r\n\r\n React.useEffect(() => {\r\n const publishChartHtmlElements = getPublishChartHtmlElements()\r\n const clickHandler = (event: MouseEvent) => {\r\n const { index, ticker, timeframe } = (event.currentTarget as HTMLElement).dataset\r\n if (index && ticker && timeframe) {\r\n const indexInt = Number.parseInt(index)\r\n setDialogConfig({\r\n ticker,\r\n timeframe,\r\n isCanvas: indexInt === 0,\r\n chartImgUrl: indexInt > 0 ? getChartImgUrl(indexInt) : null,\r\n })\r\n dialog.show()\r\n }\r\n }\r\n\r\n if (isListening) {\r\n publishChartHtmlElements.forEach((el) => {\r\n el.addEventListener('click', clickHandler)\r\n })\r\n }\r\n\r\n return () => {\r\n publishChartHtmlElements.forEach((el) => {\r\n el.removeEventListener('click', clickHandler)\r\n })\r\n }\r\n }, [dialog, isListening])\r\n\r\n return PublishDialog ? : null\r\n}\r\n","import {\r\n Button,\r\n Dialog,\r\n DialogBody,\r\n DialogDismiss,\r\n DialogFooter,\r\n DialogHeader,\r\n DialogStateReturn,\r\n Paragraph,\r\n} from '@finviz/website'\r\nimport React from 'react'\r\n\r\nexport enum IdeaDrawingsConfirmationOptions {\r\n Merge,\r\n Override,\r\n Nothing,\r\n Cancel,\r\n}\r\n\r\ninterface IIdeaLeaveDialog {\r\n state: DialogStateReturn\r\n actionCallback: (action: IdeaDrawingsConfirmationOptions) => void\r\n}\r\n\r\nexport function IdeaLeaveDialog({ state, actionCallback }: IIdeaLeaveDialog) {\r\n return (\r\n actionCallback(IdeaDrawingsConfirmationOptions.Cancel)} />}\r\n >\r\n actionCallback(IdeaDrawingsConfirmationOptions.Cancel)}>\r\n You’re About to Leave your Idea\r\n \r\n \r\n
\r\n What would you like to do with the drawings from your current Idea?\r\n \r\n Replace Drawings\r\n
\r\n Your Autosaved Drawings for this ticker will be deleted, and the Idea Drawings will be copied to the live\r\n chart.\r\n
\r\n \r\n Combine Drawings\r\n
\r\n The Idea Drawings will be copied to the live chart without changing the positions or settings of any\r\n Autosaved Drawings. This may cause duplicates if some drawings were also autosaved.\r\n
\r\n \r\n Do Nothing\r\n
\r\n Close the idea without changing any Autosaved Drawings.\r\n
\r\n
\r\n
\r\n \r\n actionCallback(IdeaDrawingsConfirmationOptions.Override)}\r\n >\r\n Replace\r\n \r\n actionCallback(IdeaDrawingsConfirmationOptions.Merge)}\r\n >\r\n Combine\r\n \r\n actionCallback(IdeaDrawingsConfirmationOptions.Nothing)}\r\n >\r\n Do Nothing\r\n \r\n \r\n \r\n )\r\n}\r\n","import { useDialogState, useTrackPageView } from '@finviz/website'\r\nimport * as dateFns from 'date-fns'\r\nimport React from 'react'\r\nimport { useLocation, useNavigate } from 'react-router-dom'\r\n\r\nimport {\r\n ChartElementType,\r\n ChartsOrQuotePageQueryParams,\r\n ChartsPageQueryParams,\r\n QuotePageQueryChartTypes,\r\n QuotePageQueryParams,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n} from '../../constants/common'\r\nimport Chart from '../../models/chart'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\nimport { getRawTickerForInstrument } from '../../models/utils'\r\nimport utils from '../../utils'\r\nimport { getInstrument, handleTypeChange } from '../../utils/chart'\r\nimport { getUuid } from '../../utils/helpers'\r\nimport { initHlc } from '../../utils/hlc'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\nimport { IdeaLeaveDialog } from '../autosave/idea-leave-dialog'\r\nimport { IdeaDrawingsConfirmationOptions } from '../autosave/idea-leave-dialog'\r\nimport { useDrawingAutoSaveApi } from '../autosave/use-drawing-autosave-api'\r\nimport { getTickersAndContainerTypesInLayoutModel, handleCallMethodOnAllDrawings } from '../autosave/utils'\r\nimport { getChartElementTypeFromResponseType } from '../utils'\r\n\r\nconst getChartElementTypeFromQueryType = (queryType: QuotePageQueryChartTypes | null) => {\r\n switch (queryType) {\r\n case QuotePageQueryChartTypes.l:\r\n return ChartElementType.LineChart\r\n case QuotePageQueryChartTypes.hc:\r\n return ChartElementType.HollowCandleStick\r\n case QuotePageQueryChartTypes.ha:\r\n return ChartElementType.HeikinAshi\r\n case QuotePageQueryChartTypes.o:\r\n return ChartElementType.OhlcChart\r\n case QuotePageQueryChartTypes.p:\r\n return ChartElementType.PerfChart\r\n case QuotePageQueryChartTypes.c:\r\n case QuotePageQueryChartTypes.cs:\r\n return ChartElementType.CandleStick\r\n default:\r\n return (\r\n getChartElementTypeFromResponseType(window.FinvizSettings?.TA?.style ?? null) ?? ChartElementType.CandleStick\r\n )\r\n }\r\n}\r\n\r\nconst useChartRouteChange = (chartLayoutModel: ChartLayoutModel | null) => {\r\n useTrackPageView({ trackInitial: false })\r\n const location = useLocation()\r\n const navigate = useNavigate()\r\n const { deleteAllDrawings } = useDrawingAutoSaveApi()\r\n const dialog = useDialogState()\r\n const isIdeasDialogOpen = dialog.useState('open')\r\n\r\n const isQuoteOrQuoteFinancials = [\r\n SpecificChartFunctionality.quotePage,\r\n SpecificChartFunctionality.quoteFinancials,\r\n ].includes(chartLayoutModel?.specificChartFunctionality as SpecificChartFunctionality)\r\n const isChartPage = chartLayoutModel?.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isFuturesForexCryptoPage = [\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n ].includes(chartLayoutModel?.specificChartFunctionality as SpecificChartFunctionality)\r\n\r\n React.useEffect(() => {\r\n if (isChartPage) {\r\n utils.setCookie(\r\n 'chartsUrl',\r\n `?${encodeQueryString({ ...decodeQueryString(location.search), i: undefined, settings: undefined })}`,\r\n dateFns.add(new Date(), { months: 1 })\r\n )\r\n }\r\n }, [isChartPage, location.search])\r\n\r\n React.useEffect(() => {\r\n const decodedQueryString = decodeQueryString(location.search)\r\n // We can navigate to idea chart without a refresh e.g. using browser back button\r\n // It breaks charts because we don't have idea data & idea quote anymore\r\n // So if we end up on a page with idea in the url and we don't have any idea data in chartLayout model we'll refresh the page\r\n if (chartLayoutModel && decodedQueryString.i && !chartLayoutModel.idea?.id) {\r\n window.location.reload()\r\n }\r\n // No need to have chartLayoutModel as dependecny here , I'm only interested in idea on the model\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [location.search, chartLayoutModel?.idea?.id])\r\n\r\n const updateChartConfig = React.useCallback(() => {\r\n if (!chartLayoutModel) return\r\n\r\n const decodedSearch = decodeQueryString(location.search)\r\n\r\n const urlType = (decodedSearch as QuotePageQueryParams).ty ?? null\r\n handleTypeChange({\r\n type: getChartElementTypeFromQueryType(urlType),\r\n chartLayoutModel,\r\n })\r\n\r\n if (isChartPage && chartLayoutModel.layout !== (decodedSearch as ChartsPageQueryParams).l) {\r\n chartLayoutModel.updateAttributes({ layout: (decodedSearch as ChartsPageQueryParams).l })\r\n }\r\n\r\n chartLayoutModel.getAllCharts().forEach((chartModel, chartIndex) => {\r\n const urlTicker = decodedSearch.t.split(',')[chartIndex] ?? null\r\n const urlTimeframe = decodedSearch.p?.split(',')[chartIndex] ?? null\r\n const urlDateRange = decodedSearch.r?.split(',')[chartIndex] ?? null\r\n const upperCaseTicker = urlTicker?.toUpperCase()\r\n\r\n /**\r\n * Only Charts page charts can change instruments. Other pages need forced\r\n * instrument because we might not be able to guess it from urlTicker\r\n */\r\n let instrument = getInstrument(upperCaseTicker)\r\n if (chartLayoutModel.specificChartFunctionality !== SpecificChartFunctionality.chartPage) {\r\n instrument = chartModel.instrument\r\n }\r\n\r\n const newChartConfig = {\r\n instrument,\r\n ticker: getRawTickerForInstrument(instrument, upperCaseTicker),\r\n timeframe: urlTimeframe,\r\n dateRange: urlDateRange,\r\n }\r\n\r\n if (Object.entries(newChartConfig).some(([key, value]) => chartModel[key as keyof Chart] !== value)) {\r\n chartModel.updateAttributesAndSync(newChartConfig)\r\n }\r\n })\r\n }, [chartLayoutModel, location.search, isChartPage])\r\n\r\n React.useEffect(() => {\r\n const decodedSearch = decodeQueryString(location.search)\r\n\r\n if (\r\n !chartLayoutModel ||\r\n !decodedSearch.p ||\r\n !decodedSearch.t ||\r\n !(isQuoteOrQuoteFinancials || isChartPage || isFuturesForexCryptoPage)\r\n ) {\r\n if (!decodedSearch.p && isQuoteOrQuoteFinancials) {\r\n navigate(\r\n {\r\n search: `?${encodeQueryString({\r\n ...decodedSearch,\r\n p: window.FinvizSettings.defaultPeriod ?? TIMEFRAME.d,\r\n r: window.FinvizSettings.defaultDateRange,\r\n })}`,\r\n },\r\n {\r\n replace: true,\r\n }\r\n )\r\n }\r\n return\r\n }\r\n if (chartLayoutModel.idea?.id && isIdeasDialogOpen) {\r\n dialog.hide()\r\n }\r\n\r\n if (!decodedSearch.i && chartLayoutModel.idea?.id) {\r\n const urlTicker = decodedSearch.t.split(',')\r\n const isSameTicker = chartLayoutModel\r\n .getAllCharts()\r\n .every((chart, i) => chart.getQuoteRawTicker() === urlTicker[i])\r\n\r\n if (isSameTicker && window.FinvizSettings.hasUserPremium && chartLayoutModel.isPreserveDrawingsActive) {\r\n dialog.show()\r\n return\r\n }\r\n if (!chartLayoutModel.isPreserveDrawingsActive || !isSameTicker) {\r\n handleCallMethodOnAllDrawings({ chartLayoutModel, elementMethod: 'destroyCascade' })\r\n }\r\n chartLayoutModel.exitIdea()\r\n }\r\n updateChartConfig()\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [\r\n location.search,\r\n navigate,\r\n chartLayoutModel,\r\n isQuoteOrQuoteFinancials,\r\n isChartPage,\r\n isFuturesForexCryptoPage,\r\n updateChartConfig,\r\n ])\r\n\r\n const handleIdeaLeave = React.useCallback(\r\n async (action: IdeaDrawingsConfirmationOptions) => {\r\n if (!chartLayoutModel) return\r\n if (action === IdeaDrawingsConfirmationOptions.Cancel) {\r\n navigate(-1)\r\n return\r\n }\r\n switch (action) {\r\n case IdeaDrawingsConfirmationOptions.Merge: {\r\n handleCallMethodOnAllDrawings({\r\n chartLayoutModel,\r\n elementMethod: 'refreshElementId',\r\n })\r\n break\r\n }\r\n case IdeaDrawingsConfirmationOptions.Override: {\r\n const { tickers } = getTickersAndContainerTypesInLayoutModel(chartLayoutModel)\r\n await deleteAllDrawings({ tickers, lastLocalChange: initHlc(getUuid(), Date.now()) })\r\n break\r\n }\r\n case IdeaDrawingsConfirmationOptions.Nothing: {\r\n handleCallMethodOnAllDrawings({\r\n chartLayoutModel,\r\n elementMethod: 'destroyCascade',\r\n })\r\n break\r\n }\r\n default:\r\n break\r\n }\r\n chartLayoutModel.exitIdea()\r\n updateChartConfig()\r\n },\r\n [chartLayoutModel, updateChartConfig, deleteAllDrawings, navigate]\r\n )\r\n\r\n return {\r\n dialog,\r\n handleIdeaLeave,\r\n }\r\n}\r\n\r\nfunction getChartLayoutWithChartRouteChange

(\r\n Component: React.ComponentType

\r\n) {\r\n return function WrappedComponent(props: P) {\r\n const { dialog, handleIdeaLeave } = useChartRouteChange(props.chartLayoutModel)\r\n return (\r\n <>\r\n \r\n \r\n \r\n )\r\n }\r\n}\r\n\r\nexport function withChartRouteChange

(\r\n Component: React.ComponentType

\r\n) {\r\n // Chart layout is used in ReactRouter context and also outside of RR context\r\n // if we use RR hooks outside the context it will crash so this function will return different component for quote & chart pages than for other usecases\r\n const ChartLayoutComponent = getChartLayoutWithChartRouteChange(Component)\r\n return function WrappedComponent(props: P) {\r\n const { ty } = decodeQueryString()\r\n const isChartPage = props.chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isQuotePage = props.chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n const isQuoteFinancials =\r\n props.chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.quoteFinancials\r\n const isFuturesForexCryptoPage = [\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n ].includes(props.chartLayoutModel.specificChartFunctionality)\r\n if (\r\n isChartPage ||\r\n (isQuotePage && ty !== QuotePageQueryChartTypes.p) ||\r\n isQuoteFinancials ||\r\n isFuturesForexCryptoPage\r\n ) {\r\n return \r\n }\r\n\r\n return \r\n }\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport { ChartGrid, ChartGridCell, DialogStateReturn } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport flowRight from 'lodash.flowright'\r\nimport merge from 'lodash.merge'\r\nimport throttle from 'lodash.throttle'\r\nimport React from 'react'\r\nimport * as ReactDOM from 'react-dom'\r\n\r\nimport {\r\n ChartConfigObject,\r\n DrawingSpineOptionsEvent,\r\n IIdea,\r\n RootChartConfigObject,\r\n RootChartConfigObjectChart,\r\n} from '../../../types/shared'\r\nimport { ChartEditorEnum, LAYOUTS, LayoutType, SpecificChartFunctionality, TIMEFRAME } from '../../constants/common'\r\nimport ChartModel from '../../models/chart'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { AutoSaveState } from '../../models/constants'\r\nimport ElementModel from '../../models/element'\r\nimport utils, {\r\n getChartsDimensions,\r\n getFullscreenStatus,\r\n getIsMobilePortrait,\r\n isRedesignEnabled,\r\n isRedesignedPage,\r\n} from '../../utils'\r\nimport {\r\n getIsPreserveDrawingsAndAutosaveAvailable,\r\n getIsSidebarEnabled,\r\n isQuoteForexFuturesCryptoPage,\r\n} from '../../utils/chart'\r\nimport fetchApi from '../../utils/fetch_api'\r\nimport { getTickersAndContainerTypesInLayoutModel } from '../autosave/utils'\r\nimport { withDrawingsAutoSave } from '../autosave/with-auto-save'\r\nimport Chart from '../chart'\r\nimport { SidebarDirection } from '../sidebar/constants'\r\nimport { Sidebar } from '../sidebar/sidebar'\r\nimport Toolbar from '../toolbar'\r\nimport { AutoSaveNotesDialog } from '../toolbar/auto-save-notes'\r\nimport { ConfirmationDialog } from '../toolbar/confirmation_dialog'\r\nimport { DrawingActions, DrawingSetting, DrawingTool } from '../toolbar/interfaces'\r\nimport ToolbarMobile from '../toolbar/mobile/toolbar-mobile'\r\nimport { withDialogState } from '../with_dialog_state_hook'\r\nimport { AutoSaveStateIndicator } from './auto-save-state-indicator'\r\nimport { ChartLayoutAutoSaveNote } from './chart-layout-auto-save-note'\r\nimport { PublishOldButtonClickListener, getPublishChartHtmlElements } from './publish_old_button_click_listener'\r\nimport { withChartPageTitle } from './with-chart-page-title'\r\nimport { withChartRouteChange } from './with-chart-route-change'\r\nimport { withCompleteLayoutModelInit } from './with-complete-layout-model-init'\r\nimport { withIdeaModelState } from './with-idea-model-state'\r\nimport { withQuoteCacheManagement } from './with-quote-cache-management'\r\nimport { withQuotePolling } from './with-quote-polling'\r\n\r\ninterface ChartLayoutComponentProps {\r\n config: RootChartConfigObject\r\n confirmationDialogState: DialogStateReturn\r\n noteDialogState: DialogStateReturn\r\n shouldResize?: boolean\r\n chartLayoutModel: ChartLayoutModel\r\n idea?: IIdea\r\n deleteAllAutoSavedElements: () => void\r\n isAutoSaveActive: boolean\r\n}\r\n\r\ninterface ChartLayoutComponentState {\r\n editable: boolean\r\n editors: ChartEditorEnum[]\r\n layout: LayoutType\r\n activeChartInteraction: string | null\r\n touchEventsDisabled: boolean\r\n isToolbarHorizontal: boolean\r\n activeTool: DrawingTool\r\n drawingSettings: Record\r\n}\r\n\r\nclass ChartLayoutComponentBase extends React.Component {\r\n // expects config, bindPublic\r\n model: ChartLayoutModel\r\n isMobile = Boolean(utils.isMobile(true))\r\n charts: Array<{ model: ChartModel; config: RootChartConfigObjectChart }>\r\n orientationChangeTimeout: number | undefined\r\n preserveDrawingAbortController = new AbortController()\r\n\r\n // These two are used on quote to check whether or not we should recompute toolbar position\r\n prevModelWidth?: number\r\n prevTimeframeActiveChart?: TIMEFRAME\r\n\r\n constructor(props: ChartLayoutComponentProps) {\r\n super(props)\r\n\r\n this.model = props.chartLayoutModel\r\n this.prevModelWidth = this.model.width\r\n this.prevTimeframeActiveChart = this.model.activeChart?.timeframe\r\n const config = props.config\r\n\r\n this.charts = []\r\n for (const chartConfig of config.charts) {\r\n const modelProperties: Partial = merge({}, chartConfig)\r\n\r\n modelProperties.chart_layout = this.model\r\n delete modelProperties.panes\r\n if (modelProperties.zoomFactor == null) {\r\n modelProperties.zoomFactor = this.model.defaultZoomFactor\r\n }\r\n if (modelProperties.refreshData == null) {\r\n modelProperties.refreshData = true\r\n }\r\n if (!modelProperties.dateRange) {\r\n modelProperties.dateRange = null\r\n }\r\n modelProperties.isHideDrawingsActive = this.model.isHideDrawingsActive\r\n modelProperties.isScrolled = false\r\n const model = this.model.charts().create(modelProperties)\r\n this.charts.push({ model, config: chartConfig })\r\n }\r\n this.model.updateAttribute('activeChart', this.model.charts().first())\r\n\r\n this.state = {\r\n editable: this.model.editable,\r\n editors: this.model.editors,\r\n layout: this.model.layout,\r\n activeChartInteraction: null,\r\n activeTool: DrawingTool.Mouse,\r\n touchEventsDisabled: false,\r\n isToolbarHorizontal: true,\r\n drawingSettings: {\r\n [DrawingSetting.DrawingModeContinuous]: false,\r\n [DrawingSetting.PreserveDrawings]: this.handleInitialPreserveDrawingsState(),\r\n [DrawingSetting.HideDrawings]: false,\r\n [DrawingSetting.LockDrawings]: false,\r\n },\r\n }\r\n }\r\n\r\n componentDidMount() {\r\n if (this.state.editable) {\r\n const DELETE = 46\r\n window.addEventListener('keyup', (e) => {\r\n const selected = this.model.getPaneWithSelection()\r\n if (e.keyCode === DELETE && selected) {\r\n const element = ElementModel.findByAttribute('instance', selected.selection)\r\n if (element && !element.instance.isEditInProgress) {\r\n const elementPane = element.pane()\r\n element.destroyCascade({ eventType: DrawingSpineOptionsEvent.Remove })\r\n elementPane.normalizeZIndexes()\r\n }\r\n }\r\n })\r\n }\r\n\r\n if (this.isMobile) {\r\n this.model.settings.ThumbSettings.size = this.model.settings.ThumbSettings.touchSize\r\n }\r\n\r\n this.onModelChange()\r\n\r\n this.model.bind('change', this.onModelChange)\r\n this.model.charts().bind('destroy', this.onChartDestroy)\r\n\r\n this.setToolbarPosition()\r\n window.addEventListener('resize', this.onWindowResize)\r\n window.addEventListener('orientationchange', this.handleOrientationChange)\r\n\r\n if (this.isMobile) {\r\n this.checkTouchEventsDisabled()\r\n window.addEventListener('touchend', this.checkTouchEventsDisabled)\r\n }\r\n }\r\n\r\n componentDidUpdate(prevProps: Readonly): void {\r\n if (prevProps.idea && !this.props.idea) {\r\n if (this.model.specificChartFunctionality === SpecificChartFunctionality.chartPage) {\r\n this.onWindowResize()\r\n }\r\n document.querySelector('#idea-title-container')?.remove()\r\n }\r\n\r\n /**\r\n * `setToolbarPosition` calls `flushSync` so we want to use it as sparingly as we can\r\n * It is only needed when chart resizes (or quote timeframe changes)\r\n */\r\n const quoteTimeframe = this.model.activeChart.quote()?.timeframe\r\n if (\r\n (quoteTimeframe && this.prevTimeframeActiveChart !== quoteTimeframe) ||\r\n this.prevModelWidth !== this.model.width\r\n ) {\r\n this.setToolbarPosition()\r\n }\r\n this.prevTimeframeActiveChart = quoteTimeframe\r\n this.prevModelWidth = this.model.width\r\n }\r\n\r\n componentWillUnmount() {\r\n this.preserveDrawingAbortController.abort()\r\n this.model.unbind('change', this.onModelChange)\r\n\r\n window.removeEventListener('resize', this.onWindowResize)\r\n window.removeEventListener('orientationchange', this.handleOrientationChange)\r\n\r\n if (this.isMobile) {\r\n window.removeEventListener('touchend', this.checkTouchEventsDisabled)\r\n }\r\n\r\n clearTimeout(this.orientationChangeTimeout)\r\n this.throttledResize.cancel()\r\n this.model.destroyCascade()\r\n }\r\n\r\n handleInitialPreserveDrawingsState = () => {\r\n let preserveDrawings = false\r\n if (getIsPreserveDrawingsAndAutosaveAvailable(this.model)) {\r\n if (window.FinvizSettings.toolsState?.[DrawingSetting.PreserveDrawings] !== undefined) {\r\n preserveDrawings = window.FinvizSettings.toolsState[DrawingSetting.PreserveDrawings]\r\n } else {\r\n this.handlePreserveDrawingsSettings()\r\n }\r\n }\r\n this.model.updateAttribute('isPreserveDrawingsActive', preserveDrawings)\r\n return preserveDrawings\r\n }\r\n\r\n handlePreserveDrawingsSettings = async (value?: boolean) => {\r\n const setPreserveDrawings = (val: boolean) => {\r\n this.model.updateAttribute('isPreserveDrawingsActive', val)\r\n this.setState((prevState) => ({\r\n drawingSettings: {\r\n ...prevState.drawingSettings,\r\n [DrawingSetting.PreserveDrawings]: val,\r\n },\r\n }))\r\n }\r\n\r\n try {\r\n this.preserveDrawingAbortController.abort()\r\n this.preserveDrawingAbortController = new AbortController()\r\n const response = await fetchApi({\r\n location: '/api/tools_state.ashx',\r\n method: value !== undefined ? 'POST' : 'GET',\r\n body:\r\n value !== undefined\r\n ? new URLSearchParams({ tools_state: JSON.stringify({ [DrawingSetting.PreserveDrawings]: value }) })\r\n : undefined,\r\n throwOnStatusCodes: [404],\r\n abortController: this.preserveDrawingAbortController,\r\n })\r\n\r\n if (value === undefined && response?.[DrawingSetting.PreserveDrawings] !== undefined) {\r\n setPreserveDrawings(response[DrawingSetting.PreserveDrawings])\r\n }\r\n } catch {\r\n if (value !== undefined) {\r\n setPreserveDrawings(!value)\r\n }\r\n }\r\n }\r\n\r\n handleOrientationChange = () => {\r\n this.orientationChangeTimeout = window.setTimeout(() => {\r\n this.setToolbarPosition()\r\n if (this.props.shouldResize) {\r\n this.handleResize()\r\n }\r\n })\r\n }\r\n\r\n onWindowResize = () => {\r\n this.setToolbarPosition()\r\n\r\n if (this.props.shouldResize) {\r\n this.throttledResize()\r\n }\r\n }\r\n\r\n handleResize = () => {\r\n const modelAttrs: Partial = getChartsDimensions(this.model.getHTMLElementId())\r\n this.model.updateAttributes(modelAttrs)\r\n }\r\n\r\n throttledResize = throttle(this.handleResize, 200)\r\n\r\n setToolbarPosition() {\r\n // Toolbar doesn’t change position on other pages\r\n if (!isQuoteForexFuturesCryptoPage(this.model.specificChartFunctionality)) return\r\n\r\n requestAnimationFrame(() =>\r\n /**\r\n * Fixes a problem where React (probably) pushes updates for to\r\n * the next render, which results in multiple re-renders of which\r\n * causes a flicker when changes between vertical and horizontal placement\r\n */\r\n ReactDOM.flushSync(() => {\r\n // quote page toolbar\r\n // 210px represents: (20px (toolbar left margin) + 80px (toolbar width) + 5px (toolbar rigth margin)) * 2 (both sides of chart)\r\n const newIsToolbarHorizontal = this.model.width + 210 > window.innerWidth || window.innerWidth < 1000\r\n if (newIsToolbarHorizontal !== this.state.isToolbarHorizontal) {\r\n this.setState({\r\n isToolbarHorizontal: newIsToolbarHorizontal,\r\n })\r\n }\r\n })\r\n )\r\n }\r\n\r\n checkTouchEventsDisabled = () => {\r\n if (!/\\bcharts\\b/.test(window.location.pathname) || getFullscreenStatus() || this.getVisualViewportScale() === 1) {\r\n this.state?.touchEventsDisabled && this.setState({ touchEventsDisabled: false })\r\n } else {\r\n !this.state?.touchEventsDisabled && this.setState({ touchEventsDisabled: true })\r\n }\r\n }\r\n\r\n getVisualViewportScale = () => {\r\n if (process.env.IS_E2E_TESTING) {\r\n return 1\r\n }\r\n if (window.visualViewport && this.isMobile) {\r\n return window.visualViewport.scale\r\n } else {\r\n return 1\r\n }\r\n }\r\n\r\n handleActiveToolChange = (activeTool: DrawingTool) => {\r\n if (!this.model.isLockDrawingsActive) {\r\n this.setState({ activeTool })\r\n }\r\n }\r\n\r\n handleDrawingAction = (actionId: DrawingActions) => {\r\n switch (actionId) {\r\n case DrawingActions.AddNote:\r\n this.props.noteDialogState.toggle()\r\n break\r\n case DrawingActions.DeleteDrawings:\r\n case DrawingActions.DeleteAutoSavedDrawings:\r\n this.props.confirmationDialogState.show()\r\n break\r\n default:\r\n return\r\n }\r\n }\r\n\r\n handleConfirmationDialogDeleteBtn = () => {\r\n if (this.model.drawingsInternalStore().autoSaveState !== AutoSaveState.Off) {\r\n this.props.deleteAllAutoSavedElements()\r\n }\r\n this.model.getAllElements().forEach((element) => {\r\n if (element.isDrawing()) {\r\n element.destroyCascade({ eventType: DrawingSpineOptionsEvent.Remove })\r\n const drawingToRemove = this.model\r\n .drawingsInternalStore()\r\n .elements.find(({ elementId }) => elementId === element.id)\r\n if (drawingToRemove) {\r\n drawingToRemove.changeType = 'destroy'\r\n }\r\n }\r\n })\r\n this.props.confirmationDialogState.hide()\r\n }\r\n\r\n handleDrawingsSetting = (settingId: DrawingSetting) => {\r\n const newObj = { ...this.state.drawingSettings, [settingId]: !this.state.drawingSettings[settingId] }\r\n\r\n switch (settingId) {\r\n case DrawingSetting.HideDrawings:\r\n this.handleActiveToolChange(DrawingTool.Mouse)\r\n this.toggleHideDrawings(newObj[DrawingSetting.HideDrawings])\r\n this.handleLockDrawings(newObj)\r\n break\r\n case DrawingSetting.PreserveDrawings:\r\n this.handlePreserveDrawingsSettings(newObj[DrawingSetting.PreserveDrawings])\r\n this.model.updateAttribute('isPreserveDrawingsActive', newObj[DrawingSetting.PreserveDrawings])\r\n break\r\n case DrawingSetting.LockDrawings:\r\n this.handleActiveToolChange(DrawingTool.Mouse)\r\n this.handleLockDrawings(newObj)\r\n break\r\n case DrawingSetting.DrawingModeContinuous:\r\n this.model.updateAttribute('isDrawingModeContinuousActive', newObj[DrawingSetting.DrawingModeContinuous])\r\n newObj[DrawingSetting.DrawingModeContinuous] === false && this.handleActiveToolChange(DrawingTool.Mouse)\r\n break\r\n default:\r\n break\r\n }\r\n\r\n this.setState({ drawingSettings: newObj })\r\n window.gtag?.('event', 'drawings_settings_toggle', {\r\n event_category: newObj[settingId] ? 'enable' : 'disable',\r\n event_label: settingId,\r\n })\r\n }\r\n\r\n handleLockDrawings = (drawingSettings: Record) => {\r\n this.model.updateAttribute(\r\n 'isLockDrawingsActive',\r\n !(!drawingSettings[DrawingSetting.HideDrawings] && !drawingSettings[DrawingSetting.LockDrawings])\r\n )\r\n }\r\n\r\n toggleHideDrawings(value: boolean) {\r\n this.model.updateAttribute('isHideDrawingsActive', value)\r\n this.model.getAllCharts().forEach((chart) => chart.updateAttribute('isHideDrawingsActive', value))\r\n }\r\n\r\n renderToolbar(args: any) {\r\n const { activeTool, drawingSettings } = this.state\r\n return args.isOverlayToolbar ? (\r\n \r\n ) : (\r\n \r\n )\r\n }\r\n\r\n render() {\r\n const { newCharts, useGrid } = this.props.config\r\n const { activeTool, editable, editors, isToolbarHorizontal } = this.state\r\n const publish = editors.includes(ChartEditorEnum.publish) && getPublishChartHtmlElements().length > 0\r\n const chartLayout = LAYOUTS[this.model.layout]\r\n const isMobilePortrait = getIsMobilePortrait(this.isMobile)\r\n const { tickers } = getTickersAndContainerTypesInLayoutModel(this.model)\r\n\r\n if (newCharts) {\r\n const isSidebarEnabled = getIsSidebarEnabled(SpecificChartFunctionality.chartPage)\r\n return (\r\n <>\r\n

\r\n {!isMobilePortrait &&\r\n // Due safari iOS flex-column bug not resizing height properly we need to render toolbar\r\n // outside of flex for portrait and inside for landscape\r\n // https://github.com/finvizhq/charts/pull/784\r\n this.renderToolbar({\r\n isSidebar: true,\r\n isHorizontal: false,\r\n })}\r\n \r\n \r\n \r\n {this.charts.map(({ model, config }, index) => (\r\n }\r\n gridArea={chartLayout.gridAreas?.[index]}\r\n setActiveChartInteraction={this.setActiveChartInteraction}\r\n activeTool={activeTool}\r\n activeChartInteraction={this.state.activeChartInteraction}\r\n touchEventsDisabled={this.state.touchEventsDisabled}\r\n shouldResize={this.props.shouldResize}\r\n />\r\n ))}\r\n \r\n \r\n
\r\n {isMobilePortrait && isSidebarEnabled && (\r\n \r\n )}\r\n {isMobilePortrait &&\r\n this.renderToolbar({\r\n isSidebar: false,\r\n isHorizontal: true,\r\n isOverlayToolbar: isSidebarEnabled,\r\n })}\r\n {this.props.idea?.note && (\r\n
\r\n
\r\n {this.props.idea.note}\r\n
\r\n
\r\n )}\r\n \r\n )\r\n }\r\n\r\n const hasRedesign = isRedesignEnabled()\r\n const hasChartTools = editable && editors.includes(ChartEditorEnum.tools)\r\n const renderTools = isRedesignedPage(this.model) ? hasChartTools && !isToolbarHorizontal : hasChartTools\r\n\r\n const ideaTitleContainer = document.querySelector('#idea-title-container')\r\n const ideaTitle = this.props.idea?.date &&\r\n this.model.specificChartFunctionality === SpecificChartFunctionality.quotePage && (\r\n

{`Your idea from ${this.props.idea.date}`}

\r\n )\r\n\r\n return (\r\n <>\r\n {ideaTitleContainer ? ReactDOM.createPortal(ideaTitle, ideaTitleContainer) : ideaTitle}\r\n \r\n {renderTools && (\r\n \r\n {this.renderToolbar({\r\n isHorizontal: isToolbarHorizontal,\r\n isAlternativeTheme: true,\r\n })}\r\n \r\n )}\r\n \r\n \r\n {this.charts.map(({ model, config }, index) => (\r\n \r\n this.renderToolbar({\r\n isHorizontal: true,\r\n isAlternativeTheme: true,\r\n })\r\n : undefined\r\n }\r\n />\r\n ))}\r\n \r\n
\r\n
\r\n
\r\n {this.model.specificChartFunctionality === SpecificChartFunctionality.quotePage && (\r\n \r\n )}\r\n \r\n \r\n )\r\n }\r\n\r\n setActiveChartInteraction = (value: string | null) => {\r\n this.setState({ activeChartInteraction: value })\r\n }\r\n\r\n updateLayout() {\r\n const layout = LAYOUTS[this.model.layout]\r\n const charts = this.model.charts().all()\r\n if (charts.length === 0) {\r\n return\r\n }\r\n\r\n if (charts.length > layout.count) {\r\n this.removeCharts(layout.count)\r\n } else if (charts.length < layout.count) {\r\n this.addCharts(layout.count - charts.length)\r\n }\r\n\r\n this.model\r\n .charts()\r\n .all()\r\n .forEach((chart, index) => {\r\n const [rowStart, columnStart, rowEnd, columnEnd] =\r\n layout.gridAreas?.[index]\r\n .replace(/ /g, '')\r\n .split('/')\r\n .map((num) => Number.parseInt(num)) || []\r\n const numOfRowsCovered = [rowEnd, rowStart].every((value) => value !== undefined) ? rowEnd - rowStart : 1\r\n const numOfColumnsCovered = [columnStart, columnEnd].every((value) => value !== undefined)\r\n ? columnEnd - columnStart\r\n : 1\r\n const percentageOfRowsCovered = numOfRowsCovered / layout.rows\r\n const percentageOfColumnsCovered = numOfColumnsCovered / layout.columns\r\n const newWidth = ~~(this.model.width * percentageOfColumnsCovered)\r\n const isChartPage = this.model.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const chartLayoutHeight = isChartPage\r\n ? this.model.height\r\n : this.model.charts().first().height || this.model.height\r\n let newHeight = ~~(chartLayoutHeight * percentageOfRowsCovered)\r\n\r\n if (this.model.editors.includes(ChartEditorEnum.settings) && isChartPage) {\r\n newHeight -= this.model.settings.ChartSettings.general.settingsHeight\r\n }\r\n if ((chart.width !== newWidth || chart.height !== newHeight) && newWidth > 0 && newHeight > 0) {\r\n chart.updateAttributes({ width: newWidth, height: newHeight })\r\n }\r\n })\r\n }\r\n\r\n addCharts(count: number) {\r\n const quote = this.model.charts().last().quote()\r\n if (!quote) return\r\n const config = {\r\n ...this.model.charts().last().toObject(),\r\n leftOffset: null,\r\n chart_layout: this.model,\r\n aftermarket: quote.aftermarket,\r\n premarket: quote.premarket,\r\n }\r\n for (let i = 0; i < count; i++) {\r\n const model = this.model.charts().create(config)\r\n this.charts.push({ model, config })\r\n }\r\n }\r\n\r\n removeCharts(wantedCount: number) {\r\n while (this.model.charts().count() > wantedCount) {\r\n const chart = this.model.charts().last()\r\n chart.destroyCascade()\r\n this.charts.pop()\r\n }\r\n }\r\n\r\n onChartDestroy = (chartModel: ChartModel) => {\r\n this.updateLayout()\r\n if (this.model.activeChart?.eql(chartModel)) {\r\n this.model.updateAttribute('activeChart', this.model.charts().last())\r\n }\r\n }\r\n\r\n onModelChange = (layoutModel?: ChartLayout, event?: Spine.Event) => {\r\n if (event === 'refresh') {\r\n return\r\n }\r\n this.updateLayout()\r\n\r\n if (layoutModel && event === 'update') {\r\n this.setState({\r\n editable: layoutModel.editable,\r\n editors: layoutModel.editors,\r\n layout: layoutModel.layout,\r\n })\r\n }\r\n }\r\n}\r\n\r\nexport const ChartLayoutComponent = flowRight(\r\n withQuoteCacheManagement,\r\n withDialogState,\r\n withCompleteLayoutModelInit,\r\n withChartPageTitle,\r\n withChartRouteChange,\r\n withIdeaModelState,\r\n withQuotePolling,\r\n withDrawingsAutoSave\r\n)(ChartLayoutComponentBase)\r\n","import debounce from 'lodash.debounce'\r\nimport React from 'react'\r\n\r\nimport Chart from '../../models/chart'\r\nimport Quote from '../../models/quote'\r\n\r\nconst MAX_QUOTE_CACHE_TIME_IN_MS = 300000 // 5 min\r\n\r\nexport const withQuoteCacheManagement = (Component: any) => (props: any) => {\r\n React.useEffect(() => {\r\n const cleanupQuoteCache = () => {\r\n const allQuotes = Quote.all()\r\n const allCharts = Chart.all()\r\n const allChartQuotes = allCharts.flatMap((chart) => chart.getAllQuotes())\r\n\r\n allQuotes.forEach((quote) => {\r\n if (\r\n !allChartQuotes.some((usedQuote) => usedQuote.eql(quote)) &&\r\n !quote.isFetching &&\r\n quote.fetchedAt > -1 &&\r\n quote.fetchedAt < Date.now() - MAX_QUOTE_CACHE_TIME_IN_MS\r\n ) {\r\n quote.destroy()\r\n }\r\n })\r\n }\r\n\r\n const checkQuoteCacheDebounce = debounce(cleanupQuoteCache, 500)\r\n\r\n Quote.bind('change', checkQuoteCacheDebounce)\r\n return () => {\r\n checkQuoteCacheDebounce.cancel()\r\n Quote.unbind('change', checkQuoteCacheDebounce)\r\n }\r\n }, [])\r\n\r\n return \r\n}\r\n","import { useDialogState } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nexport const withDialogState = (Component: any) => (props: any) => {\r\n const confirmationDialogState = useDialogState()\r\n const noteDialogState = useDialogState()\r\n\r\n return \r\n}\r\n","import * as React from 'react'\r\n\r\nimport { SpecificChartFunctionality, TIMEFRAME } from '../../constants/common'\r\nimport math from '../../helpers/math'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\nimport Quote from '../../models/quote'\r\n\r\nfunction useChartPageTitle() {\r\n const defaultDocumentTitleRef = React.useRef(document.title)\r\n\r\n const { current: updateChartsTitle } = React.useRef((chartLayoutModel: ChartLayoutModel) => {\r\n const charts = chartLayoutModel\r\n .getAllCharts()\r\n .reduce(\r\n (acc, current) => {\r\n if (acc.some(({ ticker }) => ticker === current.ticker)) {\r\n return acc\r\n }\r\n return [...acc, { ticker: current.ticker, timeframe: current.timeframe, instrument: current.instrument }]\r\n },\r\n [] as Array<{ ticker: string; timeframe: TIMEFRAME; instrument: string }>\r\n )\r\n .map((chart) => {\r\n const { ticker, timeframe, instrument } = chart\r\n const quotes = Quote.select(\r\n (quote: Quote) =>\r\n quote.ticker === ticker.replace('@', '') &&\r\n quote.timeframe === timeframe &&\r\n quote.instrument === instrument &&\r\n chartLayoutModel.isIdeaId(quote.ideaID)\r\n )\r\n if (quotes.length > 0) {\r\n const { lastClose, instrument, afterClose, prevClose, name } = quotes[0]\r\n let percentageChange: number\r\n if (!lastClose) {\r\n return null\r\n }\r\n if (prevClose !== null) {\r\n percentageChange = (lastClose / prevClose - 1) * 100\r\n }\r\n if (afterClose !== null && afterClose !== lastClose) {\r\n percentageChange = (afterClose / lastClose - 1) * 100\r\n }\r\n return `${name || ticker} ${math.round({\r\n value: lastClose,\r\n lastClose,\r\n instrument,\r\n overridePlaces: undefined,\r\n })} ${percentageChange! > 0 ? '+' : '-'}${math.round({\r\n value: Math.abs(percentageChange!),\r\n overridePlaces: 2,\r\n })}%`\r\n }\r\n return null\r\n })\r\n .filter((chart) => chart !== null)\r\n\r\n if (charts && charts.length > 0) {\r\n const title = charts.join(' | ')\r\n if (document.title !== title) {\r\n document.title = title\r\n }\r\n } else if (document.title !== defaultDocumentTitleRef.current) {\r\n document.title = defaultDocumentTitleRef.current\r\n }\r\n })\r\n\r\n return { updateChartsTitle }\r\n}\r\n\r\nexport function withChartPageTitle

(\r\n Component: React.ComponentType

\r\n) {\r\n return function WrappedComponent(props: P) {\r\n const { updateChartsTitle } = useChartPageTitle()\r\n\r\n const handleChartsUpdate = React.useCallback(() => {\r\n updateChartsTitle(props.chartLayoutModel)\r\n }, [props.chartLayoutModel, updateChartsTitle])\r\n\r\n React.useEffect(() => {\r\n if (props.chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage) {\r\n props.chartLayoutModel.charts().bind('change', handleChartsUpdate)\r\n\r\n handleChartsUpdate()\r\n\r\n return () => {\r\n props.chartLayoutModel.charts().unbind('change', handleChartsUpdate)\r\n }\r\n }\r\n }, [props.chartLayoutModel, handleChartsUpdate])\r\n\r\n return \r\n }\r\n}\r\n","import React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\n\r\nexport function withIdeaModelState

(\r\n Component: React.ComponentType

\r\n) {\r\n return function WrappedComponent(props: P) {\r\n const chartLayoutModel = useModelState(props.chartLayoutModel, { watchProperties: ['idea'] })\r\n return \r\n }\r\n}\r\n","import { NotificationWrapper, withSuspense } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { RootChartConfigObject } from '../../../types/shared'\r\nimport { ElementStyleDialogWrapper } from '../../modals/element_style'\r\nimport { useChartLayoutGlobalModelAsync } from '../../utils/useChartLayoutGlobalModelAsync'\r\nimport { ChartLayoutComponent } from './chart_layout_component'\r\n\r\ninterface ChartLayoutProps {\r\n config: RootChartConfigObject\r\n shouldResize?: boolean\r\n parentElement?: React.RefObject | HTMLElement\r\n isWithNotifications?: boolean\r\n}\r\n\r\nexport function ChartLayout({ config, shouldResize, isWithNotifications = true, parentElement }: ChartLayoutProps) {\r\n const Wrapper = isWithNotifications ? NotificationWrapper : React.Fragment\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n )\r\n}\r\n\r\nexport function ChartLayoutWithGlobalStateRaw({\r\n config,\r\n shouldResize,\r\n parentElement,\r\n}: Omit) {\r\n const { setChartLayoutModel, getChartLayoutModelConfig, lastGlobalRerender } = useChartLayoutGlobalModelAsync()\r\n\r\n return (\r\n \r\n {config && (\r\n \r\n )}\r\n \r\n )\r\n}\r\n\r\nexport const ChartLayoutWithGlobalState = withSuspense(ChartLayoutWithGlobalStateRaw)\r\n","export const CHART_LAYOUT_CHILD_CHANGE_EVENT = 'chartLayoutChildChange'\r\n","import merge from 'lodash.merge'\r\nimport React from 'react'\r\n\r\nimport { RootChartConfigObject, Theme } from '../../../types/shared'\r\nimport {\r\n ChartEditorEnum,\r\n MOBILE_BARS_TO_VIEW,\r\n MOBILE_VIEW_BREAKPOINT_WIDTH,\r\n SpecificChartFunctionality,\r\n} from '../../constants/common'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\nimport DrawingsInternalStore from '../../models/drawings-internal-store'\r\nimport { getSettings } from '../../models/settings'\r\nimport utils, { isRedesignedPage } from '../../utils'\r\nimport { getIsPreserveDrawingsAndAutosaveAvailable, getZoomFactorForBarsToDisplay } from '../../utils/chart'\r\nimport { getContainerTypeFromPaneConfig, getInitialStoreDrawings } from '../autosave/utils'\r\nimport { DrawingSetting } from '../toolbar/interfaces'\r\nimport { CHART_LAYOUT_CHILD_CHANGE_EVENT } from './constants'\r\n\r\ninterface Props {\r\n config: RootChartConfigObject\r\n onRegisterChartLayoutModel?: (chartLayoutModel: ChartLayoutModel) => void\r\n parentElement?: HTMLElement\r\n}\r\n\r\nfunction getDefaultZoomFactor(chartLayout: ChartLayoutModel) {\r\n const innerWidth = window.innerWidth\r\n if (\r\n innerWidth >= MOBILE_VIEW_BREAKPOINT_WIDTH ||\r\n chartLayout.specificChartFunctionality !== SpecificChartFunctionality.chartPage\r\n ) {\r\n return 1\r\n }\r\n\r\n return getZoomFactorForBarsToDisplay({\r\n chartLayout,\r\n numOfVisibleBars: MOBILE_BARS_TO_VIEW,\r\n chartVisibleWidth: innerWidth,\r\n })\r\n}\r\n\r\nfunction OnInitListener({\r\n chartLayoutModel,\r\n config,\r\n onRegisterChartLayoutModel,\r\n parentElement,\r\n}: Props & { chartLayoutModel: ChartLayoutModel; parentElement?: React.RefObject | HTMLElement }) {\r\n const [isInit, setIsInit] = React.useState(false)\r\n\r\n /*\r\n * This entire effect is used to check for updates in entire chart layout obj tree.\r\n * Once config object matches object generated from chart layout, the layout model is completely initialised.\r\n *\r\n * We couldn't just add a callback to `componentDidMount` (or equivalent) because its children are rendered asynchronously.\r\n *\r\n * */\r\n React.useEffect(() => {\r\n if ((onRegisterChartLayoutModel || parentElement) && chartLayoutModel && !isInit) {\r\n const checkIfInitIsComplete = () => {\r\n const { charts } = chartLayoutModel.toConfig()\r\n const isReady =\r\n charts.length === config.charts.length &&\r\n charts.every(\r\n (chart, chartIndex) =>\r\n chart.panes.length === config.charts[chartIndex].panes.length &&\r\n chart.panes.every(\r\n (pane, paneIndex) =>\r\n pane.elements.length === config.charts[chartIndex].panes[paneIndex].elements.length &&\r\n pane.elements.every(\r\n (element, elementIndex) =>\r\n element.overlays?.length ===\r\n config.charts[chartIndex].panes[paneIndex].elements[elementIndex].overlays?.length\r\n )\r\n )\r\n )\r\n\r\n if (isReady) {\r\n setIsInit(true)\r\n chartLayoutModel.updateAttributes({ isInit: true })\r\n onRegisterChartLayoutModel?.(chartLayoutModel)\r\n\r\n const containerElement = parentElement?.hasOwnProperty('current')\r\n ? (parentElement as React.RefObject).current\r\n : parentElement\r\n\r\n if (containerElement) {\r\n containerElement.style.opacity = 'unset'\r\n containerElement.style.minHeight = 'unset'\r\n containerElement.style.minWidth = 'unset'\r\n }\r\n }\r\n }\r\n\r\n chartLayoutModel.bind(CHART_LAYOUT_CHILD_CHANGE_EVENT, checkIfInitIsComplete)\r\n\r\n checkIfInitIsComplete()\r\n\r\n return () => {\r\n chartLayoutModel.unbind(CHART_LAYOUT_CHILD_CHANGE_EVENT, checkIfInitIsComplete)\r\n }\r\n }\r\n }, [chartLayoutModel, config, isInit, onRegisterChartLayoutModel, parentElement])\r\n\r\n return null\r\n}\r\n\r\nexport const withCompleteLayoutModelInit = (Component: any) => (props: Props) => {\r\n const config = React.useMemo(() => {\r\n const newConfig = merge({}, props.config, {\r\n editable: props.config.editable ?? true,\r\n canChangeTicker: props.config.canChangeTicker ?? true,\r\n scrollable: props.config.scrollable ?? true,\r\n cross: props.config.cross ?? true,\r\n theme:\r\n props.config.theme && [Theme.light, Theme.dark].includes(props.config.theme) ? props.config.theme : Theme.light,\r\n editors: props.config.editors ?? [ChartEditorEnum.publish, ChartEditorEnum.tools, ChartEditorEnum.ideas],\r\n ideas: props.config.ideas ?? true,\r\n specificChartFunctionality: props.config.specificChartFunctionality ?? SpecificChartFunctionality.default,\r\n initialStoreDrawings: [],\r\n })\r\n\r\n if (!newConfig.ideas) {\r\n newConfig.editors = newConfig.editors.filter((x) => x !== 'ideas')\r\n }\r\n\r\n if (newConfig.specificChartFunctionality === SpecificChartFunctionality.quoteFinancials) {\r\n newConfig.editors = [ChartEditorEnum.timeframe, ChartEditorEnum.publish]\r\n } else if (isRedesignedPage(newConfig, [SpecificChartFunctionality.quotePage])) {\r\n // We need to add these because ideas might not have them and chart controls wouldn’t render properly\r\n newConfig.editors = newConfig.editors.concat([ChartEditorEnum.settings, ChartEditorEnum.timeframe])\r\n }\r\n\r\n const initialStoreDrawings = getInitialStoreDrawings()?.filter(({ changeType }) => changeType !== 'destroy') ?? []\r\n const isQuotePage = newConfig.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n const isQuotePageWithDrawingsOff = isQuotePage && utils.getCookie('charts-draw') !== 'on'\r\n\r\n if (initialStoreDrawings.length === 0 || isQuotePageWithDrawingsOff) {\r\n return newConfig\r\n }\r\n\r\n const noteDrawing = initialStoreDrawings.find(\r\n ({ containerType, ticker }) =>\r\n containerType === 'note' && props.config.charts.some((chart) => chart.ticker === ticker)\r\n )\r\n\r\n const note = noteDrawing && JSON.parse(noteDrawing.elementAttrs)?.text\r\n const ideaObject = isQuotePage && note ? { note } : undefined\r\n\r\n return {\r\n ...newConfig,\r\n initialStoreDrawings,\r\n idea: newConfig.idea ?? ideaObject,\r\n charts: newConfig.charts.map((chart) => {\r\n const { ticker, panes } = chart\r\n return {\r\n ...chart,\r\n panes: panes.map((pane) => {\r\n const containerType = getContainerTypeFromPaneConfig(pane)\r\n const newElements = initialStoreDrawings\r\n .filter(\r\n (drawing) =>\r\n drawing.containerType === containerType &&\r\n drawing.ticker === ticker &&\r\n !pane.elements.some((paneElement) => paneElement.elementId === drawing.elementId)\r\n )\r\n .map(({ elementId, zIndex, elementAttrs }) => ({\r\n elementId,\r\n zIndex,\r\n ...JSON.parse(elementAttrs),\r\n }))\r\n return {\r\n ...pane,\r\n elements: [...pane.elements, ...newElements],\r\n }\r\n }),\r\n }\r\n }),\r\n }\r\n // We need to disable the eslint check because the hook is supposed to run only once on mount\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n const chartLayoutModel = React.useMemo(() => {\r\n const settings = getSettings({ ...config, theme: config.theme! })\r\n const chartLayout = ChartLayoutModel.create({\r\n layout: config.layout,\r\n width: config.width,\r\n height: config.height,\r\n editable: config.editable,\r\n canChangeTicker: config.canChangeTicker,\r\n scrollable: config.scrollable,\r\n initialScrollable: config.scrollable,\r\n cross: config.cross,\r\n editors: config.editors,\r\n theme: config.theme,\r\n idea: config.idea,\r\n settings,\r\n isWheelZoomEnabled: config.specificChartFunctionality === SpecificChartFunctionality.chartPage,\r\n specificChartFunctionality: config.specificChartFunctionality,\r\n isHideDrawingsActive: false,\r\n isPreserveDrawingsActive: !!(\r\n getIsPreserveDrawingsAndAutosaveAvailable(config) &&\r\n window.FinvizSettings.toolsState?.[DrawingSetting.PreserveDrawings]\r\n ),\r\n isLockDrawingsActive: false,\r\n uuid: config.uuid,\r\n drawingsInternalStore: DrawingsInternalStore.create({\r\n elements: config.initialStoreDrawings,\r\n }),\r\n })\r\n\r\n chartLayout.updateAttributes({ defaultZoomFactor: getDefaultZoomFactor(chartLayout) })\r\n\r\n return chartLayout\r\n\r\n // We need to disable the eslint check because the hook is supposed to run only once on mount\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n return chartLayoutModel ? (\r\n <>\r\n \r\n \r\n \r\n ) : null\r\n}\r\n","import { intervalCallbackOnWindowVisible } from '@finviz/website'\r\nimport debounce from 'lodash.debounce'\r\nimport React from 'react'\r\n\r\nimport { ObjectHash } from '../../../types/shared'\r\nimport { EXTRA_MARKET_BUFFER_MINUTES, QUOTE_FETCH_EVENT, QuotePollingIntervalInMs } from '../../constants/common'\r\nimport Chart from '../../models/chart'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\nimport Pane from '../../models/pane'\r\nimport { QuoteFetchType } from '../../models/quote/constants'\r\n\r\ninterface Props {\r\n chartLayoutModel: ChartLayoutModel\r\n}\r\n\r\ntype PollingIntervalToChartsType = ObjectHash\r\n\r\n/**\r\n * Get the max refresh interval when the tab is in the background. The interval\r\n * is slowly decayed from regular refresh interval\r\n */\r\nfunction getMaxDecayInterval() {\r\n if (window.FinvizSettings.hasUserPremium) {\r\n return QuotePollingIntervalInMs.EliteStocksReduced\r\n }\r\n\r\n return QuotePollingIntervalInMs.Free\r\n}\r\n\r\n/*\r\n * This HOC loops through all charts and checks if they are supposed to be refetch in some interval\r\n * It creates groups of charts to be refreshed grouped by the refresh interval\r\n * */\r\nexport const withQuotePolling = (Component: any) => (props: Props) => {\r\n const [pollingIntervalToCharts, setPollingIntervalToCharts] = React.useState({})\r\n const checkForChartsWithPolling = React.useCallback(() => {\r\n // check for charts which have some refresh interval and group chart ids by the interval value e.g. { interval_in_ms: [id1, id2] }\r\n const newPollingIntervalToCharts: PollingIntervalToChartsType = {} // example { 60000: ['c-0', 'c-1'], 9000: ['c-4'] }\r\n props.chartLayoutModel.getAllCharts().forEach((chart) => {\r\n const chartRefreshInterval = chart.getRefreshInterval()\r\n\r\n if (chartRefreshInterval) {\r\n newPollingIntervalToCharts[chartRefreshInterval] = newPollingIntervalToCharts[chartRefreshInterval] ?? []\r\n newPollingIntervalToCharts[chartRefreshInterval].push(chart.id)\r\n }\r\n })\r\n\r\n if (JSON.stringify(newPollingIntervalToCharts) !== JSON.stringify(pollingIntervalToCharts)) {\r\n setPollingIntervalToCharts(newPollingIntervalToCharts)\r\n }\r\n }, [props.chartLayoutModel, pollingIntervalToCharts])\r\n const intervalSubscriptions = React.useRef void>>([])\r\n\r\n React.useEffect(() => {\r\n const checkForChartsWithPollingDebounced = debounce(checkForChartsWithPolling)\r\n const chartsCheckerIntervalId = window.setInterval(\r\n checkForChartsWithPollingDebounced,\r\n EXTRA_MARKET_BUFFER_MINUTES * 1000\r\n )\r\n\r\n // listen on any changes in all charts & panes and call debounced check for charts/indicators with quotes that needs to be refetched periodically\r\n Chart.bind('change', checkForChartsWithPollingDebounced)\r\n Pane.bind('change', checkForChartsWithPollingDebounced)\r\n\r\n return () => {\r\n checkForChartsWithPollingDebounced.cancel()\r\n Chart.unbind('change', checkForChartsWithPollingDebounced)\r\n Pane.unbind('change', checkForChartsWithPollingDebounced)\r\n window.clearInterval(chartsCheckerIntervalId)\r\n }\r\n }, [checkForChartsWithPolling])\r\n\r\n React.useEffect(() => {\r\n const timeoutDurations = Object.keys(pollingIntervalToCharts).map(Number)\r\n const allCharts = props.chartLayoutModel.getAllCharts()\r\n const timeoutDurationsMin = Math.min(...timeoutDurations)\r\n\r\n timeoutDurations.forEach((duration) => {\r\n const timeoutSubscription = intervalCallbackOnWindowVisible(\r\n { interval: duration, decay: true, maxDecayInterval: getMaxDecayInterval },\r\n () => {\r\n const chartIds = pollingIntervalToCharts[duration]\r\n // get all UNIQUE quotes used in charts and refetch them\r\n allCharts\r\n .filter((chart) => chartIds.includes(chart.id))\r\n .flatMap((chart) => chart.getAllQuotes())\r\n .filter(\r\n (quote, index, quotesToUpdate) =>\r\n !quote.isFetching && index === quotesToUpdate.findIndex((quoteToUpdate) => quote.eql(quoteToUpdate))\r\n )\r\n .forEach((quote) => {\r\n quote.fetchData({ fetchType: QuoteFetchType.NewerData })\r\n })\r\n if (duration === timeoutDurationsMin) {\r\n document.dispatchEvent(new Event(QUOTE_FETCH_EVENT))\r\n }\r\n }\r\n )\r\n intervalSubscriptions.current.push(timeoutSubscription)\r\n })\r\n\r\n return () => {\r\n if (intervalSubscriptions.current.length > 0) {\r\n intervalSubscriptions.current.forEach((unsubscribe) => {\r\n unsubscribe()\r\n })\r\n intervalSubscriptions.current = []\r\n }\r\n }\r\n }, [props.chartLayoutModel, pollingIntervalToCharts])\r\n\r\n return \r\n}\r\n","import queryString from 'query-string'\r\n\r\nimport { Instrument, ObjectHash } from '../../../types/shared'\r\nimport { LayoutType } from '../../constants/common'\r\nimport { getTickerNoteText } from '../../controllers/autosave/utils'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport Quote from '../../models/quote'\r\nimport fetchApi, { getFormDataFromObject } from '../../utils/fetch_api'\r\nimport { captureException } from '../../utils/helpers'\r\n\r\nexport interface IIdea {\r\n ticker: string\r\n instrument: string\r\n period: string\r\n company?: string\r\n date: string\r\n time: string\r\n note: string\r\n id: string\r\n}\r\n\r\nexport interface IIdeaCategory {\r\n ticker: string\r\n ideas: IIdea[]\r\n}\r\n\r\nexport function getIdeaUrl({ ticker, instrument, period, id }: Pick) {\r\n const searchObject = { t: ticker, p: period, i: id }\r\n const isStock = instrument === Instrument.Stock\r\n const isQuotePage = /\\/quote\\b/.test(window.location.pathname)\r\n const isStockOnQute = isQuotePage && isStock\r\n const path = !isQuotePage || isStock ? window.location.pathname : '/charts.ashx'\r\n\r\n return `${path}?${queryString.stringify({ ...searchObject, ...(isStockOnQute ? { ta: '2' } : { l: '1h1v' }) })}`\r\n}\r\n\r\nexport async function saveIdea(layoutModel: ChartLayout) {\r\n const activeChart = layoutModel.activeChart\r\n const activeChartQuote = activeChart.quote().toJSON()\r\n const { ticker, instrument, cid } = activeChart\r\n const period = activeChartQuote.timeframe\r\n const { ChartSettings } = layoutModel.settings\r\n const layout: ObjectHash = layoutModel.toObject()\r\n layout.layout = LayoutType['1h1v']\r\n layout.barWidth = ChartSettings.center.barWidth\r\n layout.barMargin = ChartSettings.center.barMargin\r\n layout.charts = layout.charts\r\n .filter((c: ObjectHash) => c.chartId === cid)\r\n .map((c: ObjectHash) => ({ ...c, dateRange: null, refreshData: false }))\r\n\r\n delete layout.charts[0].chartId\r\n if (!activeChart.isScrolled) delete layout.charts[0].leftOffset\r\n\r\n // TODO: replace with better solution after indicators overhaul\r\n const getChartTickers = (layoutModelObjectPanes: { elements: { type: string; tickers: string }[] }[]) => {\r\n let tickers = []\r\n let tickersString = ''\r\n for (const pane of layoutModelObjectPanes) {\r\n for (const element of pane.elements) {\r\n if (element.type === 'indicators/perf') {\r\n tickersString = element.tickers\r\n }\r\n }\r\n }\r\n tickers = tickersString.split(',').filter((item) => item)\r\n if (!tickers.includes(ticker)) {\r\n tickers.push(ticker.replace('@', ''))\r\n }\r\n return tickers\r\n }\r\n const tickers = getChartTickers(layout.charts[0].panes)\r\n const quotes = Quote.select(\r\n (quote: Quote) =>\r\n tickers.includes(quote.ticker) && quote.timeframe === activeChart.timeframe && layoutModel.isIdeaId(quote.ideaID)\r\n ).filter((element, index, array) => array.findIndex((t) => t.ticker === element.ticker) === index)\r\n const quotesJsonString = JSON.stringify(quotes.map((q) => q.toConfig(['ideaID', 'chartUuid'])))\r\n\r\n const chart = JSON.stringify(layout)\r\n const note =\r\n layoutModel.idea?.note ||\r\n getTickerNoteText({ ticker, elements: layoutModel.drawingsInternalStore().elements }) ||\r\n ''\r\n window.gtag?.('event', 'save', { event_category: 'ideas' })\r\n\r\n if (tickers.length !== quotes.length) {\r\n captureException(new Error('Idea saved with inconsistent quotes data'), {\r\n extra: {\r\n tickers,\r\n quoteTickersTimeframes: quotes.map((quote) => ({ ticker: quote.ticker, timeframe: quote.timeframe })),\r\n chartLayout: layoutModel.toConfig(['colors', 'panes']),\r\n },\r\n })\r\n }\r\n\r\n const data = await fetchApi<{ id: string }>({\r\n location: '/api/idea_save.ashx',\r\n method: 'POST',\r\n body: getFormDataFromObject({ ticker, period, chart, quotes: quotesJsonString, note }),\r\n })\r\n\r\n const ideaUrl = getIdeaUrl({\r\n ticker,\r\n period,\r\n instrument,\r\n id: data.id,\r\n })\r\n\r\n if (process.env.IS_E2E_TESTING) {\r\n window.location.href = ideaUrl\r\n } else {\r\n // need to be in setTimeout because Safari block any call to window.open made in async,\r\n // this is hack to force run window.open in main thread\r\n setTimeout(() => {\r\n window.open(ideaUrl, 'FinvizSavedIdea')\r\n })\r\n }\r\n}\r\n\r\nexport function categorizeIdeas(ideas: IIdea[], tickers: string[]) {\r\n if (ideas.length <= 0) return []\r\n\r\n const categorizedIdeas = ideas.reduce((processed, idea) => {\r\n const tickerIdeas = processed.find((i) => i.ticker === idea.ticker)\r\n\r\n if (tickerIdeas) {\r\n tickerIdeas.ideas.push(idea)\r\n } else if (tickers.includes(idea.ticker)) {\r\n processed.push({\r\n ticker: idea.ticker,\r\n ideas: [idea],\r\n })\r\n }\r\n\r\n return processed\r\n }, [] as IIdeaCategory[])\r\n categorizedIdeas.unshift({\r\n ticker: 'All Ideas',\r\n ideas: ideas,\r\n })\r\n\r\n return categorizedIdeas\r\n}\r\n","import { Button, Icon, decodeQueryString } from '@finviz/website'\r\nimport classNames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { ChartsOrQuotePageQueryParams, TIMEFRAME, TimeframeLabelShort } from '../../constants/common'\r\nimport { IIdea, getIdeaUrl } from './utils'\r\n\r\ntype IdeasListProps = {\r\n idea: IIdea\r\n onIdeaDeleted: (idea: IIdea) => void\r\n}\r\n\r\nexport default function IdeaItem({ idea, onIdeaDeleted }: IdeasListProps) {\r\n const [isDeleting, setIsDeleting] = React.useState(false)\r\n const [isConfirmDelete, setIsConfirmDelete] = React.useState(false)\r\n const { i: currentIdea } = decodeQueryString()\r\n\r\n const onDeleteIdeaClick = React.useRef(async (idea: IIdea) => {\r\n setIsDeleting(true)\r\n\r\n let wasDeleted\r\n try {\r\n const response = await fetch(`/api/idea_delete.ashx?id=${idea.id}`, {\r\n method: 'DELETE',\r\n })\r\n\r\n wasDeleted = response.status === 200\r\n } catch {}\r\n\r\n if (!wasDeleted) {\r\n return\r\n }\r\n\r\n if (currentIdea === idea.id.toString()) {\r\n const newUrl = new URL(window.location.href)\r\n newUrl.searchParams.delete('i')\r\n window.location.href = newUrl.href\r\n return\r\n }\r\n\r\n onIdeaDeleted(idea)\r\n })\r\n\r\n return (\r\n (document.location = getIdeaUrl(idea))}\r\n data-testid=\"charts-notice-idea-item\"\r\n >\r\n <>\r\n

\r\n

\r\n {idea.ticker}\r\n {idea.company && {idea.company}}\r\n

\r\n \r\n {idea.date}\r\n {idea.time}\r\n \r\n \r\n {TimeframeLabelShort[idea.period as TIMEFRAME]}\r\n \r\n \r\n {idea.note !== '' ? (\r\n

{idea.note}

\r\n ) : null}\r\n
\r\n\r\n ) => {\r\n ev.stopPropagation()\r\n setIsConfirmDelete(true)\r\n }}\r\n />\r\n \r\n\r\n {isConfirmDelete && (\r\n
\r\n
\r\n

\r\n Delete {idea.ticker} Idea from {idea.date}?\r\n

\r\n
\r\n\r\n
\r\n {\r\n setIsConfirmDelete(false)\r\n }}\r\n >\r\n Cancel\r\n \r\n {\r\n onDeleteIdeaClick.current(idea)\r\n }}\r\n >\r\n Delete\r\n \r\n
\r\n
\r\n )}\r\n \r\n )\r\n}\r\n","import { Badge, Tab, TabList, TabPanel, Tabs } from '@finviz/website'\r\nimport React from 'react'\r\nimport { useSearchParams } from 'react-router-dom'\r\n\r\nimport { getInstrument } from '../../utils/chart'\r\nimport fetchApi from '../../utils/fetch_api'\r\nimport IdeaItem from './IdeaItem'\r\nimport { IIdea, IIdeaCategory, categorizeIdeas } from './utils'\r\n\r\nexport default function IdeasTabs() {\r\n const [hasError, setHasError] = React.useState(false)\r\n const [hasFetched, setHasFetched] = React.useState(false)\r\n const [categorizedIdeas, setCategorizedIdeas] = React.useState([])\r\n const [params] = useSearchParams()\r\n const queryTickers = params.get('t')!.split(',') // there always be some t param defined\r\n\r\n React.useEffect(() => {\r\n async function fetchIdeas() {\r\n window.gtag?.('event', 'load', { event_category: 'ideas' })\r\n try {\r\n const data = await fetchApi({ location: '/api/ideas_load.ashx', throwOnStatusCodes: [404] })\r\n const ideas = data.ideas.map((idea: IIdea) => {\r\n const dateParts = idea.date.split(' ')\r\n return {\r\n ...idea,\r\n instrument: getInstrument(idea.ticker),\r\n date: dateParts[0].replace('-', ' ').replace('-', ', '),\r\n time: dateParts[1],\r\n }\r\n })\r\n\r\n setCategorizedIdeas(categorizeIdeas(ideas, queryTickers))\r\n setHasFetched(true)\r\n } catch {\r\n setHasError(true)\r\n }\r\n }\r\n\r\n fetchIdeas()\r\n\r\n // run only on mount\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n const handleIdeaDeleted = (idea: IIdea) => {\r\n setCategorizedIdeas((prev) => {\r\n const modifiedCategories = [...prev]\r\n\r\n // remove from specific ticker category\r\n const categoryIndex = modifiedCategories.findIndex((c) => c.ticker === idea.ticker)\r\n if (categoryIndex >= 0) {\r\n const updatedCategory = {\r\n ...modifiedCategories[categoryIndex],\r\n ideas: modifiedCategories[categoryIndex].ideas.filter((i) => i.id !== idea.id),\r\n }\r\n modifiedCategories[categoryIndex] = updatedCategory\r\n }\r\n\r\n // remove from all\r\n const updatedAll = {\r\n ...modifiedCategories[0],\r\n ideas: modifiedCategories[0].ideas.filter((i) => i.id !== idea.id),\r\n }\r\n modifiedCategories[0] = updatedAll\r\n\r\n // remove empty categories\r\n return modifiedCategories.filter((c) => c.ideas.length !== 0)\r\n })\r\n }\r\n\r\n if (!hasFetched || hasError) {\r\n return (\r\n
\r\n {hasError ? 'Unexpected error occurred, please refresh the page.' : 'Loading…'}\r\n
\r\n )\r\n }\r\n\r\n if (categorizedIdeas.length === 0) {\r\n return (\r\n \r\n No saved ideas.\r\n \r\n )\r\n }\r\n\r\n return (\r\n \r\n \r\n {categorizedIdeas.map((category) => (\r\n {category.ideas.length}}>\r\n {category.ticker}\r\n \r\n ))}\r\n \r\n {categorizedIdeas.map((category) => (\r\n \r\n
\r\n {category.ideas.map((idea) => (\r\n \r\n ))}\r\n
\r\n \r\n ))}\r\n
\r\n )\r\n}\r\n","import { Dialog, DialogBody, DialogHeader, DialogStateReturn } from '@finviz/website'\r\n\r\nimport IdeasTabs from './IdeasTabs'\r\n\r\ntype IdeasDialogProps = {\r\n state: DialogStateReturn\r\n}\r\n\r\nexport default function IdeasDialog({ state }: IdeasDialogProps) {\r\n return (\r\n \r\n Your Ideas\r\n \r\n \r\n \r\n \r\n )\r\n}\r\n","import {\r\n Button,\r\n ButtonComponentProps,\r\n ButtonProps,\r\n Dropdown,\r\n DropdownItem,\r\n Spinner,\r\n Tooltip,\r\n TooltipTrigger,\r\n useDialogState,\r\n useTooltipState,\r\n} from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport IdeasDialog from '../../modals/ideas/Ideas'\r\nimport { saveIdea } from '../../modals/ideas/utils'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport Quote from '../../models/quote'\r\nimport { getIsMobileScreenSize } from '../../utils'\r\nimport { encodeQueryString } from '../../utils/query_string'\r\n\r\ninterface IdeaDropdownProps {\r\n model: ChartLayout\r\n rounding?: 'none' | 'regular'\r\n theme?: ButtonProps['theme']\r\n size?: ButtonProps['size']\r\n dropdownButtonClassName?: string\r\n}\r\n\r\nexport function IdeasDropdown({\r\n model,\r\n rounding,\r\n dropdownButtonClassName,\r\n ...props\r\n}: React.PropsWithChildren) {\r\n const tooltipState = useTooltipState({ placement: 'right-start' })\r\n const [isAnyQuoteLoading, setIsAnyQuoteLoading] = React.useState(false)\r\n const ref = React.useRef(null)\r\n const dialog = useDialogState()\r\n const hideTooltip = tooltipState.hide\r\n\r\n const dropdownItemProps = isAnyQuoteLoading\r\n ? ({\r\n as: TooltipTrigger,\r\n state: tooltipState,\r\n } as ButtonComponentProps)\r\n : ({} as ButtonComponentProps)\r\n\r\n React.useEffect(() => {\r\n const checkIfAnyQuoteIsLoading = () => {\r\n const fetchingQuotes = Quote.select((quote) => quote.isFetching && quote.fetchedAt === -1)\r\n setIsAnyQuoteLoading(fetchingQuotes.length > 0)\r\n }\r\n\r\n Quote.bind('change', checkIfAnyQuoteIsLoading)\r\n return () => {\r\n Quote.unbind('change', checkIfAnyQuoteIsLoading)\r\n }\r\n }, [])\r\n\r\n React.useEffect(() => {\r\n if (!isAnyQuoteLoading) hideTooltip()\r\n }, [isAnyQuoteLoading, hideTooltip])\r\n\r\n if (!window.FinvizSettings.hasUserPremium) {\r\n return (\r\n \r\n )\r\n }\r\n\r\n return (\r\n <>\r\n \r\n }\r\n >\r\n {\r\n if (isAnyQuoteLoading) {\r\n tooltipState.show()\r\n return\r\n }\r\n saveIdea(model)\r\n }}\r\n >\r\n Save idea\r\n \r\n dialog.show()}\r\n >\r\n Load idea\r\n \r\n \r\n \r\n {isAnyQuoteLoading && (\r\n \r\n
\r\n \r\n
\r\n \r\n Some data is still loading. Please wait.\r\n \r\n
\r\n )}\r\n \r\n )\r\n}\r\n","import { Button, ButtonComponentProps, Delayed, Icon, Spinner, useDialogState } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { publishModalAsyncModule } from '../../modals/publish/async-modules'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\n\r\ninterface PublishProps extends Pick {\r\n model: ChartLayout\r\n}\r\n\r\nexport function Publish({ model, ...props }: React.PropsWithChildren) {\r\n const dialog = useDialogState()\r\n const isDialogOpen = dialog.useState('open')\r\n const [publishModalModule, { isLoading }] = useAsyncModule({\r\n ...publishModalAsyncModule,\r\n shouldLoadModule: isDialogOpen,\r\n errorSeverity: 'medium',\r\n onError: () => dialog.hide(),\r\n })\r\n const PublishDialog = publishModalModule?.default\r\n\r\n return (\r\n <>\r\n dialog.show()}\r\n leftContent={\r\n isLoading ? (\r\n \r\n }\r\n >\r\n \r\n \r\n ) : (\r\n 'share'\r\n )\r\n }\r\n />\r\n {PublishDialog && }\r\n \r\n )\r\n}\r\n","import {\r\n Button,\r\n ButtonSizeType,\r\n ButtonThemeType,\r\n Delayed,\r\n Icon,\r\n Spinner,\r\n TourDefinition,\r\n useTour,\r\n} from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport { getRequestFullscreen, isRedesignEnabled } from '../../utils'\r\nimport { encodeQueryString } from '../../utils/query_string'\r\n\r\nconst isPremium = window.FinvizSettings.hasUserPremium\r\n\r\n// If we need to update / discontinue some tour we can use skip flag on legacy version to ensure that it won't reset users tour but won't include it in new tours\r\nfunction getTour(page: SpecificChartFunctionality): TourDefinition[] {\r\n return [\r\n {\r\n id: 'chart-tour',\r\n steps: [\r\n {\r\n title: 'Chart Tour',\r\n body: 'Discover powerful Chart features in the 2-min tour to master your analysis of trading opportunities.',\r\n },\r\n ...(isPremium\r\n ? [\r\n {\r\n title: 'Scale the Timeline',\r\n body: 'Grab the timeline to zoom it in and out. Double-click the timeline to reset the scaling.',\r\n target: '[data-testid=\"chart-0-pane-0-zoomer\"]',\r\n },\r\n {\r\n title: 'Scale the Price Axis',\r\n body: 'Grab the Price Axis to zoom it in and out. Move the chart around freely in any direction when Price Axis has custom scale. Double-click the Price Axis to reset the scaling.',\r\n target: '[data-testid=\"chart-0-pane-0-scaler\"]',\r\n },\r\n {\r\n title: 'Drawing tools & settings',\r\n body: 'Pick any Drawing Tool to analyze the market. Tailor your drawing experience with additional settings.',\r\n target: '#toolbar',\r\n },\r\n {\r\n title: 'Fine-tune Drawings',\r\n body: 'Double-click on a chart drawing to tweak its color and style. Right-click on a drawing to access other options, such as changing its visibility, order, and more.',\r\n target: '[data-testid=\"chart-0-pane-0\"]',\r\n },\r\n ]\r\n : [\r\n {\r\n title: 'Enable Drawing mode',\r\n body: (\r\n <>\r\n \r\n Finviz*Elite\r\n {' '}\r\n subscribers get access a whole suite of drawing tools which allow them to draw on and annotate the\r\n chart.
\r\n While in drawing mode, you can also pan the chart, scale the timeline and price axis and much more.\r\n \r\n ),\r\n target: '[data-testid=\"quote-toggle-draw-btn\"]',\r\n placement: 'bottom-start',\r\n },\r\n ]),\r\n {\r\n title: 'Save your best Ideas',\r\n body: isPremium\r\n ? 'Besides your drawings being autosaved, you can manually save ideas that you wish to revisit later.'\r\n : 'Your drawings will be saved automatically, but you can also manually save ideas that you wish to revisit later.',\r\n target: '[data-testid=\"chart-toolbar-ideas\"]',\r\n placement: 'bottom-start',\r\n },\r\n ...(page === SpecificChartFunctionality.quotePage\r\n ? []\r\n : [\r\n {\r\n title: 'Chart Layouts & Charts Sync',\r\n body: 'Switch between Chart Layouts to view multiple charts on your screen. Synchronize Ticker, Timeframe or Crosshair position across your charts.',\r\n target: '[data-testid=\"chart-layout-layout\"]',\r\n },\r\n ]),\r\n ...(!getRequestFullscreen(document.documentElement) && page === SpecificChartFunctionality.chartPage\r\n ? []\r\n : [\r\n {\r\n title: 'Fullscreen mode',\r\n body:\r\n page === SpecificChartFunctionality.quotePage\r\n ? 'Open the chart in an expanded view for full-page display and split-screen charts.'\r\n : 'Toggle the window to fill your entire screen.',\r\n target: '[data-testid=\"chart-layout-fullscreen\"]',\r\n placement: page === SpecificChartFunctionality.chartPage ? 'bottom' : 'bottom-end',\r\n },\r\n ]),\r\n {\r\n title: 'Share chart',\r\n body: 'Share a chart together with your analysis and ideas.',\r\n target: '[data-testid=\"chart-toolbar-publish\"]',\r\n overlayPadding: page === SpecificChartFunctionality.quotePage ? 3 : undefined,\r\n placement: 'bottom',\r\n },\r\n ...(isRedesignEnabled() || page === SpecificChartFunctionality.chartPage\r\n ? [\r\n {\r\n title: 'Theme',\r\n body: 'Switch between the Light and Dark theme.',\r\n target: '[data-testid=\"chart-layout-theme\"]',\r\n },\r\n ]\r\n : []),\r\n {\r\n title: 'Study Settings',\r\n body: 'Customize the Chart Type and appearance. Add Overlays, Indicators and toggle Extended Hours.',\r\n target: '[data-testid=\"chart-settings-open-btn\"]',\r\n placement: page === SpecificChartFunctionality.chartPage ? 'bottom' : 'bottom-end',\r\n },\r\n ],\r\n },\r\n page === SpecificChartFunctionality.chartPage && {\r\n id: 'sidebar-watchlist',\r\n steps: [\r\n {\r\n title: 'Explore Your Portfolios',\r\n body: 'Effortlessly navigate through your portfolio holdings. With just a click, visualize individual stock charts, gain insights, and stay updated on your investments.',\r\n target: '[data-testid=\"sidebar-portfolio-btn\"]',\r\n placement: 'left-start',\r\n },\r\n ],\r\n },\r\n ].filter(Boolean) as TourDefinition[]\r\n}\r\n\r\ninterface TourButtonProps {\r\n page: SpecificChartFunctionality\r\n rounding?: 'none' | 'regular'\r\n size?: ButtonSizeType\r\n theme?: ButtonThemeType\r\n className?: string\r\n}\r\n\r\nexport function TourButton({ page, className, theme, ...props }: React.PropsWithChildren) {\r\n const tour = useTour()\r\n const pageTours = getTour(page)\r\n const [userTour, setCurrentTour] = React.useState(tour.getStepsForUser(pageTours))\r\n const buttonTheme: ButtonThemeType = userTour.hasNewTours ? 'blue' : (theme ?? 'headerItem')\r\n\r\n return (\r\n \r\n }\r\n >\r\n \r\n \r\n ) : (\r\n \r\n )\r\n }\r\n className={className}\r\n contentClass={page !== SpecificChartFunctionality.quotePage ? 'hidden lg:flex' : ''}\r\n title=\"Explore new features\"\r\n onClick={async () => {\r\n if (userTour) {\r\n const activeTour = await tour.startTour(userTour.tour)\r\n activeTour?.once('inactive', () => {\r\n setCurrentTour(tour.getStepsForUser(pageTours))\r\n })\r\n }\r\n }}\r\n />\r\n )\r\n}\r\n","import * as dateFns from 'date-fns'\r\n\r\nimport { getChartStartEndDates } from '../controllers/renderUtils'\r\nimport Quote from '../models/quote'\r\n\r\n// **************START**************\r\n// Functions from here until END have to be in sync with\r\n// Finviz-Website: components/timeframe-bar/custom-date-range-utils.ts\r\n// *********************************\r\n\r\nexport enum CustomDateRangePrefixEnum {\r\n Range = 'range',\r\n Prev = 'prev',\r\n}\r\n\r\nexport const CUSTOM_DATE_RANGE = 'custom'\r\nexport const DATE_RANGE_PREFIX_DELMITER = '_'\r\nconst CUSTOM_DATE_RANGE_DELIMITER = 'x'\r\nconst CUSTOM_PREV_RANGE_DELIMITER = '-'\r\n\r\nexport function getParsedDateRange(dateRange: string) {\r\n return dateRange.split(DATE_RANGE_PREFIX_DELMITER)\r\n}\r\n\r\nexport function parseCustomDateRangeUrlParam({ dateRange, anchorDate }: { dateRange: string; anchorDate: Date }) {\r\n const [dateRangePrefix, dateRangeValue] = getParsedDateRange(dateRange)\r\n\r\n if (dateRangePrefix === CustomDateRangePrefixEnum.Range) {\r\n const [dateFromString, dateToString] = dateRangeValue.replace(/-/g, '/').split(CUSTOM_DATE_RANGE_DELIMITER)\r\n const dateFrom = dateFromString ? new Date(dateFromString) : null\r\n const dateTo = dateToString ? new Date(dateToString) : null\r\n return {\r\n start: dateFrom && !Number.isNaN(dateFrom.getTime()) ? dateFrom : null,\r\n end: dateTo && !Number.isNaN(dateTo.getTime()) ? dateFns.endOfDay(dateTo) : null,\r\n }\r\n }\r\n\r\n if (dateRangePrefix === CustomDateRangePrefixEnum.Prev) {\r\n const [years, months, days] = dateRangeValue.split(CUSTOM_PREV_RANGE_DELIMITER).map(Number)\r\n\r\n if ([years, months, days].some(Number.isNaN)) {\r\n return { start: null, end: null }\r\n }\r\n\r\n return {\r\n start: dateFns.startOfDay(dateFns.sub(anchorDate, { years, months, days: days - 1 })),\r\n end: anchorDate,\r\n }\r\n }\r\n\r\n return { start: null, end: anchorDate }\r\n}\r\n\r\n// **************END**************\r\n// Functions below don't need to be\r\n// in sync with Website repository\r\n// *******************************\r\n\r\nexport function getParsedDateRangeMetaData({ dateRange, quote }: { dateRange: string; quote: Quote }) {\r\n const parsedRange = getChartStartEndDates({ dateRange, quote })\r\n const [dateRangePrefix] = getParsedDateRange(dateRange)\r\n\r\n let startQuoteDate: Date | null = null\r\n let endQuoteDate: Date | null = null\r\n let numOfDaysToRender: number | null = null\r\n\r\n if (parsedRange.start && dateRangePrefix === CustomDateRangePrefixEnum.Prev) {\r\n const daysInQuote = quote.getDaysInQuote()\r\n const reversedDaysInQuote = [...daysInQuote].reverse()\r\n const startQuoteDayIndex = reversedDaysInQuote.findIndex((date) => date.getTime() <= parsedRange.start!.getTime())\r\n const endQuoteDayIndex = reversedDaysInQuote.findIndex((date) => date.getTime() <= parsedRange.end!.getTime())\r\n startQuoteDate = reversedDaysInQuote[startQuoteDayIndex] ?? null\r\n endQuoteDate = reversedDaysInQuote[endQuoteDayIndex] ?? null\r\n numOfDaysToRender = quote.interval <= 5 ? startQuoteDayIndex - endQuoteDayIndex + 1 : null\r\n }\r\n\r\n return {\r\n start: parsedRange.start,\r\n end: parsedRange.end,\r\n startQuoteDate,\r\n endQuoteDate,\r\n numOfDaysToRender,\r\n numOfBarsToRender: (numOfDaysToRender ?? 0) * (quote.getBarsInDay() ?? 0) || undefined,\r\n renderDateStart: parsedRange.start && dateFns.startOfDay(parsedRange.start),\r\n renderDateEnd: parsedRange.end && dateFns.endOfDay(parsedRange.end),\r\n }\r\n}\r\n","import * as d3 from 'd3'\r\nimport * as dateFns from 'date-fns'\r\n\r\nimport { Instrument, ObjectHash } from '../../types/shared'\r\nimport type PerfChart from '../charts/perf_chart'\r\nimport {\r\n CHART_MARGIN,\r\n DateRangeType,\r\n PREMARKET_AFTERMARKET_HOURS,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n} from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport ChartEventElement from '../models/chart-event-element'\r\nimport ChartLayout from '../models/chart_layout'\r\nimport { IChartSettings, IIndicatorSettings, ISettings } from '../models/chart_settings/interfaces'\r\nimport { CHART_EVENT_BADGE_SIZE } from '../models/constants'\r\nimport Element from '../models/element'\r\nimport Pane, { ScaleAxis } from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport Utils from '../utils'\r\nimport utils, { convertLocalToNyTime, dateFromUnixTimestamp, isRedesignedPage } from '../utils'\r\nimport { getBarWidthWithMargin, getZoomFactorForBarsToDisplay } from '../utils/chart'\r\nimport {\r\n DATE_RANGE_PREFIX_DELMITER,\r\n getParsedDateRangeMetaData,\r\n parseCustomDateRangeUrlParam,\r\n} from '../utils/chart-date-range-utils'\r\n\r\ninterface VisibleBarNumberProps {\r\n start: Date | null\r\n end: Date\r\n quote: Quote\r\n dateRange: string\r\n}\r\n\r\ninterface ChartZoomAndLeftOffsetProps extends Omit {\r\n chartVisibleWidth: number\r\n numOfBarsToRender?: number\r\n chartModel: Chart\r\n}\r\n\r\ninterface ChartStartEndDatesProps {\r\n dateRange: string\r\n quote: Quote\r\n}\r\n\r\nexport const getVisibleBarsNumber = ({ start, end, quote, dateRange }: VisibleBarNumberProps) => {\r\n const startInSec = start ? start.getTime() / 1000 : 0\r\n const endInSec = end.getTime() / 1000\r\n const isQuoteDateInRange = (quoteDate: number) => quoteDate >= startInSec && quoteDate <= endInSec\r\n const lastQuoteDateIndex = quote.barIndex[quote.barIndex.length - 1]\r\n let lastVisibleBarIndex = lastQuoteDateIndex\r\n let numOfVisibleBars = 0\r\n if (\r\n [DateRangeType.d1, DateRangeType.d5].includes(dateRange as DateRangeType) &&\r\n quote.instrument === Instrument.Stock\r\n ) {\r\n numOfVisibleBars = quote.drawMinutesPerDay\r\n } else {\r\n let firstVisibleBarIndex = -1\r\n lastVisibleBarIndex = -1\r\n quote.date.forEach((quoteDate, index) => {\r\n if (isQuoteDateInRange(quoteDate)) {\r\n if (firstVisibleBarIndex === -1) {\r\n firstVisibleBarIndex = quote.barIndex[index]\r\n }\r\n lastVisibleBarIndex = quote.barIndex[index]\r\n }\r\n })\r\n numOfVisibleBars = lastVisibleBarIndex - firstVisibleBarIndex + 1\r\n\r\n if (firstVisibleBarIndex === -1 && lastVisibleBarIndex === -1) {\r\n return { numOfVisibleBars: 0, numOfBarsOffset: 0 }\r\n }\r\n }\r\n\r\n return { numOfVisibleBars, numOfBarsOffset: lastQuoteDateIndex - lastVisibleBarIndex }\r\n}\r\n\r\nexport const getChartZoomAndLeftOffset = ({\r\n chartVisibleWidth,\r\n start,\r\n end,\r\n quote,\r\n chartModel,\r\n numOfBarsToRender,\r\n}: ChartZoomAndLeftOffsetProps) => {\r\n const { numOfVisibleBars, numOfBarsOffset } = getVisibleBarsNumber({\r\n start,\r\n end,\r\n quote,\r\n dateRange: chartModel.dateRange,\r\n })\r\n if (numOfVisibleBars === 0) {\r\n return { zoomFactor: chartModel.zoomFactor, leftOffset: chartModel.leftOffset }\r\n }\r\n\r\n const chartLayout = chartModel.chart_layout()\r\n const zoomFactor = getZoomFactorForBarsToDisplay({\r\n chartLayout,\r\n chartVisibleWidth,\r\n numOfVisibleBars: numOfBarsToRender ?? numOfVisibleBars,\r\n })\r\n const barWidth = getBarWidthWithMargin({ chartLayout, zoomFactor })\r\n const leftOffset =\r\n getLeftOffset({\r\n quote,\r\n chartModel,\r\n config: {},\r\n barWidth,\r\n numberOfBarsToDraw: numOfBarsToRender,\r\n }) +\r\n numOfBarsOffset * barWidth\r\n return { zoomFactor, leftOffset }\r\n}\r\n\r\nexport const getChartStartEndDates = ({ dateRange, quote }: ChartStartEndDatesProps) => {\r\n const daysInQuote = quote.getDaysInQuote()\r\n const lastDate = dateFromUnixTimestamp(quote.date[quote.date.length - 1])\r\n\r\n if (dateRange.includes(DATE_RANGE_PREFIX_DELMITER)) {\r\n const range = parseCustomDateRangeUrlParam({ dateRange, anchorDate: lastDate })\r\n const end = convertLocalToNyTime(\r\n range.end && range.end.getTime() <= lastDate.getTime() ? range.end : lastDate,\r\n false\r\n )\r\n return {\r\n start: range.start && convertLocalToNyTime(range.start, false),\r\n end,\r\n }\r\n }\r\n\r\n let start\r\n // No condition is needed here, but this would be dateRangePrefix === DateRangePrefixEnum.Enum\r\n switch (dateRange) {\r\n case DateRangeType.d1:\r\n lastDate.setHours(23, 59, 59, 999)\r\n start = daysInQuote.length === 0 ? lastDate : daysInQuote[daysInQuote.length - 1]\r\n break\r\n case DateRangeType.d5:\r\n lastDate.setHours(23, 59, 59, 999)\r\n const startDateIndex = daysInQuote.length === 0 ? -1 : Math.max(daysInQuote.length - 5, 0)\r\n start = startDateIndex === -1 ? lastDate : daysInQuote[startDateIndex]\r\n break\r\n case DateRangeType.m1:\r\n start = dateFns.subMonths(lastDate, 1)\r\n break\r\n case DateRangeType.m3:\r\n start = dateFns.subMonths(lastDate, 3)\r\n break\r\n case DateRangeType.m6:\r\n start = dateFns.subMonths(lastDate, 6)\r\n break\r\n case DateRangeType.ytd:\r\n start = dateFns.startOfYear(lastDate)\r\n break\r\n case DateRangeType.y1:\r\n start = dateFns.subYears(lastDate, 1)\r\n break\r\n case DateRangeType.y2:\r\n start = dateFns.subYears(lastDate, 2)\r\n break\r\n case DateRangeType.y5:\r\n start = dateFns.subYears(lastDate, 5)\r\n break\r\n case DateRangeType.max:\r\n default:\r\n start = null\r\n break\r\n }\r\n\r\n return { start: start && convertLocalToNyTime(start, false), end: convertLocalToNyTime(lastDate, false) }\r\n}\r\n\r\ninterface GetLeftOffsetProps {\r\n quote: Quote\r\n chartModel: Chart\r\n config?: { stretch?: boolean }\r\n barWidth?: number\r\n barIndex?: number\r\n numberOfBarsToDraw?: number\r\n shouldAlignDaysToLeftApplied?: boolean\r\n}\r\n\r\nexport const getMinMaxLeftOffset = ({\r\n newLeftOffset,\r\n chartModel,\r\n barWidth = getBarWidthWithMargin({ zoomFactor: chartModel.zoomFactor, chartLayout: chartModel.chart_layout() }),\r\n barIndex,\r\n}: {\r\n newLeftOffset: number\r\n chartModel: Chart\r\n barWidth?: number\r\n barIndex: number\r\n}) => {\r\n const { ChartSettings } = chartModel.getChartLayoutSettings()\r\n const width = chartModel.width - ChartSettings.left.width - ChartSettings.right.width\r\n const numOfBarsInView = Math.floor(width / barWidth)\r\n const fx = (index: number) => index * barWidth\r\n return ~~Utils.min(barWidth / 2, Utils.max(newLeftOffset, width - fx(barIndex + numOfBarsInView)))\r\n}\r\n\r\nexport function getFullChartWidth({\r\n hasAftermarket,\r\n hasPremarket,\r\n timeframeMinutes,\r\n barWidthWithMargin,\r\n}: {\r\n hasPremarket: boolean\r\n hasAftermarket: boolean\r\n timeframeMinutes: number\r\n barWidthWithMargin: number\r\n}) {\r\n const premarketHoursLength = hasPremarket ? PREMARKET_AFTERMARKET_HOURS : 0\r\n const aftermarketHoursLength = hasAftermarket ? PREMARKET_AFTERMARKET_HOURS : 0\r\n const marketMinutesLength = (6.5 + premarketHoursLength + aftermarketHoursLength) * 60\r\n // CHART_MARGIN.L as left offset + CHART_MARGIN.XXL as right offset\r\n return CHART_MARGIN.L + CHART_MARGIN.XXL + (marketMinutesLength / timeframeMinutes) * barWidthWithMargin\r\n}\r\n\r\nexport function getIntradayChartConfig({\r\n timeframeMinutes,\r\n barWidthWithMargin,\r\n hasPremarket,\r\n hasAftermarket,\r\n maxWidth,\r\n canCropChart,\r\n}: {\r\n hasPremarket: boolean\r\n hasAftermarket: boolean\r\n timeframeMinutes: number\r\n barWidthWithMargin: number\r\n maxWidth: number\r\n canCropChart: boolean\r\n}) {\r\n const fullChartWidth = getFullChartWidth({ hasPremarket, hasAftermarket, barWidthWithMargin, timeframeMinutes })\r\n const offsetChartAfter = 16 // Int from 0-23 , if last quote date is >= this constant `offsetInPx` is applied (chart is moved to the left)\r\n const cropChartMinutesLength = PREMARKET_AFTERMARKET_HOURS * 60\r\n const offsetInPx = (cropChartMinutesLength / timeframeMinutes) * barWidthWithMargin\r\n const chartWidthWithOffset = fullChartWidth - offsetInPx\r\n const shouldCropChart =\r\n canCropChart && hasAftermarket && hasPremarket && maxWidth >= chartWidthWithOffset && maxWidth < fullChartWidth\r\n\r\n return {\r\n fullChartWidth,\r\n offsetInPx: shouldCropChart ? offsetInPx : 0,\r\n chartWidthWithOffset: shouldCropChart ? fullChartWidth - offsetInPx : fullChartWidth,\r\n offsetChartAfter,\r\n }\r\n}\r\n\r\nexport const getLeftOffset = ({\r\n quote,\r\n chartModel,\r\n config,\r\n barWidth = getBarWidthWithMargin({ zoomFactor: chartModel.zoomFactor, chartLayout: chartModel.chart_layout() }),\r\n barIndex = getBarIndex(quote),\r\n numberOfBarsToDraw,\r\n shouldAlignDaysToLeftApplied = true,\r\n}: GetLeftOffsetProps) => {\r\n const { ChartSettings } = chartModel.getChartLayoutSettings()\r\n const width = chartModel.width - ChartSettings.left.width - ChartSettings.right.width\r\n const specificChartFunctionality = chartModel.chart_layout().specificChartFunctionality\r\n if (config?.stretch) {\r\n return 0\r\n }\r\n if (getIsSmallIndexChart(specificChartFunctionality)) {\r\n return barWidth\r\n }\r\n const fx = (index: number) => index * barWidth\r\n let leftOffset = width - fx(barIndex) - Math.round(barWidth / 2)\r\n leftOffset = Math.round(Utils.min(barWidth / 2, Utils.max(leftOffset, width - fx(barIndex + 45))))\r\n if (\r\n shouldAlignDaysToLeftApplied &&\r\n shouldAlignDaysToLeft({\r\n quote,\r\n numberOfBarsToDraw,\r\n specificChartFunctionality,\r\n dateRange: chartModel.dateRange,\r\n })\r\n ) {\r\n let drawDaysInOneChart = 1\r\n if (numberOfBarsToDraw) {\r\n drawDaysInOneChart = Math.ceil(numberOfBarsToDraw / quote.getBarsInDay()!)\r\n } else if (quote.interval === 10 || chartModel.dateRange === DateRangeType.d5) {\r\n drawDaysInOneChart = 5\r\n } else if (quote.interval === 15) {\r\n drawDaysInOneChart = 6\r\n } else if (quote.interval === 30) {\r\n drawDaysInOneChart = 12\r\n } else if (quote.interval === 60) {\r\n drawDaysInOneChart = 22\r\n } else if (quote.interval === 120) {\r\n drawDaysInOneChart = 39\r\n } else if (quote.interval === 240) {\r\n drawDaysInOneChart = 78\r\n } else if (quote.interval > 240) {\r\n drawDaysInOneChart = (quote.interval / 30) * 10\r\n }\r\n const { offsetInPx, offsetChartAfter } = getIntradayChartConfig({\r\n hasPremarket: quote.premarket,\r\n hasAftermarket: quote.aftermarket,\r\n barWidthWithMargin: barWidth,\r\n timeframeMinutes: quote.interval,\r\n maxWidth: chartModel.width,\r\n canCropChart: !chartModel.dateRange,\r\n })\r\n const drawDaysWidth = drawDaysInOneChart * quote.getBarsInDay()! * barWidth - offsetInPx\r\n\r\n // +1 is a buffer as it often happens drawDaysWidth is wider than width by tiny amount (< 1/10000 of px)\r\n if (drawDaysWidth <= width + 1) {\r\n const lastQuoteDate = quote.date.last() ? utils.dateFromUnixTimestamp(quote.date.last()!) : null\r\n // Align start of day to left if we have enough space to show all bars in day\r\n const barsToOffset = (Object.keys(quote.getDayToOffset()).length - drawDaysInOneChart) * quote.getBarsInDay()!\r\n const offsetChartInPx = (lastQuoteDate?.getHours() ?? 0) >= offsetChartAfter ? offsetInPx : 0\r\n // Math.max(1, ~~num) is to mimic imlementation from getHalfBarWidth(),\r\n // we never render bar with width < 1 but at the same time when we have and odd\r\n // width like 5, wa want to floor because of pixel perfect rendering\r\n leftOffset = Math.round(-fx(barsToOffset) + Math.max(1, ~~(barWidth / 2))) - offsetChartInPx\r\n }\r\n }\r\n // getMinMaxLeftOffset move left offset to keep at least one bar in view what isn't desired for offscreen charts\r\n if (specificChartFunctionality === SpecificChartFunctionality.offScreen) {\r\n return leftOffset\r\n }\r\n return getMinMaxLeftOffset({\r\n newLeftOffset: leftOffset,\r\n chartModel,\r\n barWidth,\r\n barIndex,\r\n })\r\n}\r\n\r\nexport const getBarIndex = (quote: Quote) => quote?.getBarIndex(quote.open?.length ? quote.open.length - 1 : 0) || 0\r\n\r\nexport const getIsSmallIndexChart = (specificChartFunctionality: SpecificChartFunctionality) =>\r\n specificChartFunctionality === SpecificChartFunctionality.smallIndex\r\n\r\ninterface ShouldAlignDaysToLeftProps {\r\n quote: Quote\r\n numberOfBarsToDraw?: number\r\n specificChartFunctionality: SpecificChartFunctionality\r\n dateRange: DateRangeType | null\r\n}\r\n\r\n/**\r\n * Evaluate if days should be aligned to the left\r\n * @param {object} object.quote - Quote model\r\n * @param {string} object.specificChartFunctionality - SpecificChartFunctionality enum\r\n * @returns {boolean} boolean\r\n * */\r\nexport const shouldAlignDaysToLeft = ({\r\n quote,\r\n dateRange,\r\n numberOfBarsToDraw,\r\n specificChartFunctionality,\r\n}: ShouldAlignDaysToLeftProps) => {\r\n const isStockIntraday = quote.isIntraday && quote.instrument === Instrument.Stock\r\n const isIntradayDateRange = !!dateRange && [DateRangeType.d1, DateRangeType.d5].includes(dateRange)\r\n const isOffScreen = specificChartFunctionality === SpecificChartFunctionality.offScreen\r\n const isOffScreenWithNoDateRange = isOffScreen && !dateRange\r\n const isOffScreenIntradayDateRange = isOffScreen && isIntradayDateRange\r\n const isOffScreenWithFixedBars = isOffScreen && numberOfBarsToDraw\r\n\r\n const isQuoteOrQuoteFinancials = [\r\n SpecificChartFunctionality.quotePage,\r\n SpecificChartFunctionality.quoteFinancials,\r\n ].includes(specificChartFunctionality)\r\n const isQuotePageWithNoDateRange = isQuoteOrQuoteFinancials && !dateRange\r\n const isQuotePageIntradayDateRange = isQuoteOrQuoteFinancials && isIntradayDateRange\r\n const isQuotePageWithFixedBars = isQuoteOrQuoteFinancials && numberOfBarsToDraw\r\n\r\n const isChartPage = specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isChartsInradayDateRange = isChartPage && isIntradayDateRange\r\n const isChartPageWithFixedBars = isChartPage && numberOfBarsToDraw\r\n return (\r\n isStockIntraday &&\r\n (isOffScreenWithNoDateRange ||\r\n isOffScreenIntradayDateRange ||\r\n isOffScreenWithFixedBars ||\r\n isQuotePageWithNoDateRange ||\r\n isQuotePageIntradayDateRange ||\r\n isQuotePageWithFixedBars ||\r\n isChartsInradayDateRange ||\r\n isChartPageWithFixedBars)\r\n )\r\n}\r\n\r\ninterface ClipProps {\r\n canvasCtx: RenderingContext2DType\r\n width: number\r\n height: number\r\n Settings: ISettings['ChartSettings'] | ISettings['IndicatorSettings']\r\n}\r\n// pane canvasCtx clip\r\nexport const clip = ({ canvasCtx, width, height, Settings }: ClipProps) => {\r\n const contentWidth = width - Settings.left.width - Settings.right.width\r\n const contentHeight = height - Settings.top.height - Settings.bottom.height\r\n canvasCtx.beginPath()\r\n canvasCtx.rect(Settings.left.width, Settings.top.height, contentWidth, contentHeight)\r\n canvasCtx.clip()\r\n}\r\n\r\nexport const getSettings = (paneModel: Pane): IIndicatorSettings | IChartSettings => {\r\n const { ChartSettings, IndicatorSettings } = paneModel.chart().getChartLayoutSettings()\r\n for (const element of paneModel.elements().all()) {\r\n if (element.isIndicator()) {\r\n return IndicatorSettings\r\n }\r\n }\r\n return ChartSettings\r\n}\r\n\r\ninterface RecountScaleProps {\r\n chartModel: Chart\r\n paneModel: Pane\r\n}\r\n\r\ntype ScaledFn = Partial & (d3.ScaleLinear | d3.ScaleSymLog)\r\n\r\nconst getShouldOffsetChartDomain = (elementModel: Element | ChartEventElement) => {\r\n const quote = elementModel.pane().chart().quote()\r\n\r\n return quote.chartEvents.length > 0 && ![TIMEFRAME.w, TIMEFRAME.m].includes(quote.timeframe)\r\n}\r\n\r\nexport const recountScale = ({ chartModel, paneModel }: RecountScaleProps) => {\r\n const { ChartSettings, IndicatorSettings, MarketSentimentSettings } = chartModel.getChartLayoutSettings()\r\n const chartLayout = chartModel.chart_layout()\r\n const barWidthWithMargin = getBarWidthWithMargin({ chartLayout, zoomFactor: chartModel.zoomFactor })\r\n for (const elementModel of [...paneModel.getAllElements(), ...paneModel.getAllChartEvents(false)]) {\r\n const el = elementModel.instance\r\n const isChart = elementModel.isChart()\r\n if (isChart || elementModel.isIndicator()) {\r\n let fx: ScaledFn, Settings: ISettings['MarketSentimentSettings' | 'ChartSettings' | 'IndicatorSettings'], width\r\n const scaleType = isChart ? chartModel.scale : ScaleType.Linear\r\n if (isChart) {\r\n Settings = chartModel.instrument === Instrument.MarketSentiment ? MarketSentimentSettings : ChartSettings\r\n } else {\r\n Settings = IndicatorSettings as ISettings['IndicatorSettings']\r\n }\r\n const contentHeight = paneModel.height - Settings.top.height - Settings.bottom.height\r\n\r\n if (chartModel.stretch) {\r\n width = chartModel.width - Settings.left.width - Settings.right.width\r\n const chartElement = chartModel.getChartElement()\r\n // PerfChart can be only imported as type because of circular dependency, that's why it's not possible to do instanceof check\r\n const isPerfChart = !!chartElement?.instance && 'getCompleteChartNumOfBars' in chartElement?.instance\r\n const perfChartInstance = isPerfChart ? (chartElement.instance as PerfChart) : null\r\n const numOfBars = perfChartInstance?.getCompleteChartNumOfBars() ?? chartModel.quote().close.length\r\n fx = d3\r\n .scaleLinear()\r\n .range([0, width])\r\n .domain([0, Math.max(0, numOfBars - 1)]) as ScaledFn\r\n } else {\r\n fx = ((index: number) => index * barWidthWithMargin) as ScaledFn\r\n fx.invert = (x: number) => x / barWidthWithMargin\r\n fx.width = function (w) {\r\n return this.invert(w) - this.invert(0)\r\n }\r\n }\r\n paneModel.updateAttribute('scale', { x: fx }) // some elements need fx to count getMinMax\r\n\r\n const { min, max } = paneModel.scaleRange || el.getMinMax!()\r\n let fy\r\n\r\n const handleDomainOffset = (currentScale: ScaledFn, scaleCreator: any) => {\r\n if (isChart && getShouldOffsetChartDomain(elementModel)) {\r\n const protectedHeightPx = contentHeight - CHART_EVENT_BADGE_SIZE\r\n const minPx = currentScale(min)\r\n const domain = currentScale.domain()\r\n if (minPx > protectedHeightPx) {\r\n const tempScale = scaleCreator().range([0, protectedHeightPx]).domain([max, min])\r\n const extendedMin = tempScale.invert(contentHeight)\r\n currentScale.domain([domain[0], extendedMin])\r\n }\r\n }\r\n }\r\n\r\n switch (scaleType) {\r\n case ScaleType.Logarithmic:\r\n fy = d3.scaleSymlog().range([0, contentHeight]).domain([max, min]) as ScaledFn\r\n handleDomainOffset(fy, d3.scaleSymlog)\r\n break\r\n default:\r\n fy = d3.scaleLinear().range([0, contentHeight]).domain([max, min]) as ScaledFn\r\n if (!paneModel.scaleRange) {\r\n fy = fy.nice(10)\r\n handleDomainOffset(fy, d3.scaleLinear)\r\n }\r\n break\r\n }\r\n fy.height = function (h: number) {\r\n return this.invert(h) - this.invert(0)\r\n }\r\n paneModel.updateAttribute('scale', {\r\n x: fx,\r\n y: fy,\r\n })\r\n\r\n if (isChart) {\r\n el.setupAxis!(fx as ScaleAxis)\r\n }\r\n break\r\n }\r\n }\r\n}\r\n\r\n// general, only when blurry ends won't be visible or didn't matter\r\nexport const getOffsetFromLineWidth = (lineWidth: number) => (lineWidth % 2 === 0 ? 0 : 0.5)\r\n\r\ninterface IXYOffsetFromLine {\r\n lineWidth: number\r\n x1: number\r\n y1: number\r\n x2: number\r\n y2: number\r\n}\r\n\r\n// return x,y offsets for pixel perfect line rendering\r\nexport const getXYOffsetFromLine = ({ lineWidth, x1, y1, x2, y2 }: IXYOffsetFromLine) => {\r\n // don't add offset is lineWidth is even\r\n if (lineWidth % 2 === 0) {\r\n return { x: 0, y: 0 }\r\n }\r\n if (y1 === y2) {\r\n return { x: 0, y: 0.5 } // horizontal line\r\n } else if (x1 === x2) {\r\n return { x: 0.5, y: 0 } // vertical line\r\n } else {\r\n return { x: 0.5, y: 0.5 } // diagonal line\r\n }\r\n}\r\n\r\nexport const getRoundedObject = (obj: T): T => {\r\n const rounded = Object.entries(obj)\r\n for (let i = 0; i < rounded.length; i++) {\r\n rounded[i][1] = Math.round(rounded[i][1])\r\n }\r\n return Object.fromEntries(rounded) as T\r\n}\r\n\r\ninterface ITranslate {\r\n context: CanvasRenderingContext2D\r\n xOffset: number\r\n yOffset: number\r\n}\r\n\r\ninterface ITranslateObj {\r\n do: () => void\r\n undo: () => void\r\n}\r\n\r\nexport const getTranslate = ({ context, xOffset, yOffset }: ITranslate): ITranslateObj => ({\r\n do: () => context.translate(xOffset, yOffset),\r\n undo: () => context.translate(xOffset * -1, yOffset * -1),\r\n})\r\n\r\ninterface IPercentageScaleValue {\r\n number: number\r\n base: number\r\n}\r\n\r\nexport const getPercentageFromValue = ({ number, base }: IPercentageScaleValue) => ((number - base) / base) * 100\r\n\r\nexport const getValueFromPercentage = ({ number, base }: IPercentageScaleValue) => (number / 100) * base + base\r\n\r\ninterface UpdateZoomAndLeftOffsetByDateRangeProps {\r\n chartModel: Chart\r\n quote: Quote\r\n}\r\n\r\nexport function updateZoomAndLeftOffsetByDateRange({ chartModel, quote }: UpdateZoomAndLeftOffsetByDateRangeProps) {\r\n const { ChartSettings } = chartModel.getChartLayoutSettings()\r\n const chartVisibleWidth = chartModel.width - (ChartSettings.left.width + ChartSettings.right.width)\r\n\r\n const { start, end, numOfBarsToRender } = getParsedDateRangeMetaData({\r\n dateRange: chartModel.dateRange,\r\n quote,\r\n })\r\n\r\n const { zoomFactor, leftOffset } = getChartZoomAndLeftOffset({\r\n chartVisibleWidth,\r\n start,\r\n end,\r\n quote,\r\n numOfBarsToRender,\r\n chartModel: chartModel,\r\n })\r\n\r\n if (chartModel.zoomFactor !== zoomFactor || chartModel.leftOffset !== leftOffset) {\r\n chartModel.updateAttributes({ zoomFactor, leftOffset })\r\n }\r\n}\r\n\r\nexport function renderPane({\r\n chartLayoutModel,\r\n chartModel,\r\n paneModel,\r\n canvasCtx,\r\n shouldRenderCross = false,\r\n}: {\r\n chartLayoutModel: ChartLayout\r\n chartModel: Chart\r\n paneModel: Pane\r\n canvasCtx: CanvasRenderingContext2D\r\n shouldRenderCross?: boolean\r\n}) {\r\n if (paneModel.chart().instrument === Instrument.MarketSentiment) {\r\n canvasCtx.clearRect(0, 0, chartModel.width, paneModel.height)\r\n } else {\r\n canvasCtx.set('fillStyle', chartModel.getChartLayoutSettings().ChartSettings.general.Colors.canvasFill)\r\n canvasCtx.fillRect(0, 0, chartModel.width, paneModel.height)\r\n }\r\n const elements = paneModel.getAllElements()\r\n for (const { instance: elementInstance } of elements) {\r\n if (typeof elementInstance.renderGrid === 'function') {\r\n canvasCtx.save()\r\n elementInstance.renderGrid(canvasCtx)\r\n canvasCtx.restore()\r\n }\r\n }\r\n\r\n const chartEvents = paneModel.getAllChartEvents()\r\n const Settings = getSettings(paneModel)\r\n for (const { instance: elementInstance } of [...elements, ...chartEvents]) {\r\n const isDrawing = elementInstance.getIsDrawing()\r\n const isChartEvent = elementInstance.getIsChartEvent()\r\n\r\n if (isDrawing && (chartLayoutModel.isHideDrawingsActive || !elementInstance.getIsVisible())) {\r\n continue\r\n } else if ((isDrawing || isChartEvent) && !elementInstance.getIsInChartView(chartModel)) {\r\n continue\r\n }\r\n\r\n canvasCtx.save()\r\n if (elementInstance.renderContent != null) {\r\n canvasCtx.save()\r\n clip({\r\n canvasCtx,\r\n width: chartModel.width,\r\n height: paneModel.height,\r\n Settings,\r\n })\r\n canvasCtx.translate(paneModel.chart().leftOffset + Settings.left.width, Settings.top.height)\r\n elementInstance.renderContent(canvasCtx)\r\n canvasCtx.restore()\r\n if (typeof elementInstance.renderLabels === 'function') {\r\n elementInstance.renderLabels(canvasCtx)\r\n }\r\n } else {\r\n elementInstance.render(canvasCtx)\r\n }\r\n if (\r\n shouldRenderCross &&\r\n (chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage ||\r\n isRedesignedPage(chartLayoutModel)) &&\r\n elementInstance.renderCross != null\r\n ) {\r\n elementInstance.renderCross(canvasCtx)\r\n }\r\n canvasCtx.restore()\r\n }\r\n}\r\n","export const DEFAULT_WIDTHS = {\r\n min: 200,\r\n max: 400,\r\n}\r\n\r\nexport enum SidebarDirection {\r\n vertical,\r\n horizontal,\r\n}\r\n","import React from 'react'\r\n\r\nimport { DEFAULT_WIDTHS, SidebarDirection } from '../constants'\r\nimport { SidebarModule, SidebarModuleType } from '../modules/modules'\r\n\r\nexport type SidebarContextType = {\r\n isOpen: boolean\r\n isCloseVisible: boolean\r\n direction: SidebarDirection\r\n width?: {\r\n min?: number | string\r\n max?: number | string\r\n default?: { desktop?: number; mobile?: number }\r\n }\r\n activeModule: SidebarModuleType | null\r\n close: () => void\r\n onResize: () => void\r\n selectModule: (module?: SidebarModule) => void\r\n}\r\n\r\nconst DEFAULT_CONTEXT: SidebarContextType = {\r\n activeModule: null,\r\n isOpen: false,\r\n isCloseVisible: false,\r\n direction: SidebarDirection.horizontal,\r\n width: DEFAULT_WIDTHS,\r\n close: () => {},\r\n onResize: () => {},\r\n selectModule: () => {},\r\n}\r\n\r\nexport const SidebarContext = React.createContext(DEFAULT_CONTEXT)\r\nexport const useSidebarContext = () => React.useContext(SidebarContext)\r\n","import { DefaultErrorBoundary } from '@finviz/website'\r\nimport * as React from 'react'\r\nimport { FallbackProps } from 'react-error-boundary'\r\n\r\nexport function ModuleLoadFailed(props: Partial) {\r\n return (\r\n \r\n )\r\n}\r\n","export const portfolioWatchlistAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"portfolio-watchlist\" */ './portfolio-watchlist'),\r\n cacheKey: 'portfolio-watchlist',\r\n}\r\n","import { IconNameType } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { portfolioWatchlistAsyncModule } from './portfolio-watchlist/async-modules'\r\nimport { withModuleAsyncLoad } from './with-module-async-load'\r\n\r\nexport enum SidebarModule {\r\n portfolio = 'portfolio',\r\n}\r\n\r\nexport type SidebarModuleType = {\r\n key: SidebarModule\r\n icon: IconNameType\r\n description: string\r\n content: React.ComponentType\r\n width?: {\r\n min?: number | string\r\n max?: number | string\r\n default?: { desktop?: number; mobile?: number }\r\n }\r\n}\r\n\r\nexport const sidebarModules: Record = Object.freeze({\r\n [SidebarModule.portfolio]: {\r\n key: SidebarModule.portfolio,\r\n icon: 'briefcase',\r\n description: 'Portfolio watchlist',\r\n content: withModuleAsyncLoad(portfolioWatchlistAsyncModule, true),\r\n width: { min: 200, default: { mobile: 275 } },\r\n },\r\n})\r\n","import { Delayed, Spinner } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { useAsyncModule } from '../../../utils/async-modules-utils'\r\nimport { ModuleLoadFailed } from './module-load-failed'\r\n\r\nexport function withModuleAsyncLoad<\r\n T extends { default: React.ComponentType<{ setIsComponentReady: React.Dispatch> }> },\r\n>(asyncModule: { importFn: () => Promise; cacheKey: string }, withInitialLoading = false) {\r\n return function InnerFunction() {\r\n const [isComponentReady, setIsComponentReady] = React.useState(false)\r\n const [sidebarModule, { isError }] = useAsyncModule({\r\n ...asyncModule,\r\n isSuspenseMode: true,\r\n })\r\n\r\n const SidebarModule = sidebarModule?.default\r\n\r\n if (isError) {\r\n return \r\n }\r\n\r\n return (\r\n <>\r\n {!isComponentReady && withInitialLoading && (\r\n \r\n
\r\n \r\n
\r\n
\r\n )}\r\n {!!SidebarModule && }\r\n \r\n )\r\n }\r\n}\r\n","import { Button, Icon, Paragraph, Tooltip, TooltipTrigger, useTooltipState } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { SidebarDirection } from './constants'\r\nimport { useSidebarContext } from './hooks/sidebar-context'\r\nimport { sidebarModules } from './modules/modules'\r\n\r\nexport const MOBILE_TOOLBAR_DIV_ID = 'toolbar-mobile'\r\n\r\ntype SidebarTabsProps = {\r\n className?: string\r\n}\r\n\r\nexport default function SidebarTabs({ className }: SidebarTabsProps) {\r\n const { isOpen, direction, activeModule, selectModule } = useSidebarContext()\r\n const tooltipState = useTooltipState({ placement: 'left', showTimeout: 300 })\r\n\r\n return (\r\n \r\n {/* reserved space for drawing button on mobile devices */}\r\n {direction === SidebarDirection.horizontal && (\r\n \r\n )}\r\n\r\n {Object.entries(sidebarModules).map(([key, value]) => {\r\n const isActive = activeModule?.key === key\r\n return (\r\n \r\n {\r\n selectModule(isActive ? undefined : value.key)\r\n }}\r\n className={classnames({ 'ml-2': direction === SidebarDirection.horizontal })}\r\n data-testid={`sidebar-${key}-btn`}\r\n >\r\n \r\n \r\n }\r\n state={tooltipState}\r\n aria-label={value.description}\r\n isHideOnClick\r\n />\r\n\r\n \r\n {value.description}\r\n \r\n \r\n )\r\n })}\r\n \r\n )\r\n}\r\n","import { Resizable } from 're-resizable'\r\nimport React from 'react'\r\n\r\nimport Utils from '../../utils'\r\nimport { DEFAULT_WIDTHS, SidebarDirection } from './constants'\r\nimport { useSidebarContext } from './hooks/sidebar-context'\r\n\r\ntype SidebarContentProps = {\r\n children: React.ReactNode\r\n}\r\n\r\nexport default function SidebarContent({ children }: SidebarContentProps) {\r\n const { direction, onResize, close, width } = useSidebarContext()\r\n const minWidth = width?.min ?? DEFAULT_WIDTHS.min\r\n const maxWidth = width?.max ?? DEFAULT_WIDTHS.max\r\n const defaultMobile = width?.default?.mobile ?? minWidth\r\n const defaultDesktop = width?.default?.desktop ?? maxWidth\r\n\r\n return (\r\n <>\r\n {direction === SidebarDirection.vertical && (\r\n \r\n {children}\r\n \r\n )}\r\n {direction === SidebarDirection.horizontal && (\r\n <>\r\n
\r\n
\r\n {children}\r\n
\r\n \r\n )}\r\n \r\n )\r\n}\r\n","import { Delayed, Spinner, localStorage } from '@finviz/website'\r\nimport * as React from 'react'\r\nimport { ErrorBoundary } from 'react-error-boundary'\r\nimport { useNavigate, useSearchParams } from 'react-router-dom'\r\n\r\nimport { getIsMobilePortrait } from '../../utils'\r\nimport { SidebarDirection } from './constants'\r\nimport { SidebarContext, SidebarContextType } from './hooks/sidebar-context'\r\nimport { ModuleLoadFailed } from './modules/module-load-failed'\r\nimport { SidebarModule, SidebarModuleType, sidebarModules } from './modules/modules'\r\nimport SidebarContent from './sidebar-content'\r\nimport SidebarTabs from './sidebar-tabs'\r\n\r\nexport const SIDEBAR_QUERY_PARAM = 'sidebar'\r\n\r\n// This is a temp function, to remove unused property from localstorage\r\nfunction removeSidebarFromLocalstorage() {\r\n const SIDEBAR_LOCAL_STORAGE_KEY = 'sidebarModule'\r\n localStorage.removeValue(SIDEBAR_LOCAL_STORAGE_KEY)\r\n}\r\nremoveSidebarFromLocalstorage()\r\n\r\ntype SidebarProps = {\r\n onShouldResize: () => void\r\n direction: SidebarDirection\r\n tabsClassName?: string\r\n}\r\n\r\n// Todo - this is not correct approach but this component can unmount/mount on mobile orientation change so we can't keep it inside the component\r\nlet isInit = false\r\n\r\nexport function Sidebar({ onShouldResize, direction, tabsClassName }: SidebarProps) {\r\n const navigate = useNavigate()\r\n const [urlSearchParams] = useSearchParams()\r\n const sidebarModuleKey = (urlSearchParams.get(SIDEBAR_QUERY_PARAM) as keyof typeof sidebarModules | null) || null\r\n const [activeModule, setActiveModule] = React.useState(null)\r\n\r\n const isOpen = !!activeModule\r\n const handleSelectModule = React.useCallback(\r\n (key?: SidebarModule) => {\r\n const newUrlSearchParams = new URLSearchParams(urlSearchParams)\r\n if (key) {\r\n newUrlSearchParams.set(SIDEBAR_QUERY_PARAM, key)\r\n } else {\r\n newUrlSearchParams.delete(SIDEBAR_QUERY_PARAM)\r\n }\r\n navigate({ search: newUrlSearchParams.toString() }, { replace: true })\r\n },\r\n [urlSearchParams, navigate]\r\n )\r\n\r\n const handleCloseSidebar = React.useCallback(() => {\r\n handleSelectModule(undefined)\r\n }, [handleSelectModule])\r\n\r\n // Resize charts every time the sidebar is opened/closed or active module is changed\r\n React.useEffect(() => {\r\n onShouldResize()\r\n }, [activeModule, onShouldResize])\r\n\r\n // Set active module based on sidebarModuleKey\r\n React.useEffect(() => {\r\n let sidebarModule = sidebarModuleKey && sidebarModules[sidebarModuleKey]\r\n\r\n if (!isInit && getIsMobilePortrait()) {\r\n sidebarModule = null\r\n handleCloseSidebar()\r\n }\r\n\r\n setActiveModule(sidebarModule)\r\n isInit = true\r\n }, [sidebarModuleKey, handleCloseSidebar])\r\n\r\n const contextValue: SidebarContextType = React.useMemo(\r\n () => ({\r\n direction,\r\n isOpen,\r\n isCloseVisible: direction === SidebarDirection.horizontal,\r\n width: activeModule?.width,\r\n activeModule,\r\n onResize: onShouldResize,\r\n close: handleCloseSidebar,\r\n selectModule: handleSelectModule,\r\n }),\r\n [direction, isOpen, onShouldResize, activeModule, handleCloseSidebar, handleSelectModule]\r\n )\r\n\r\n return (\r\n \r\n {activeModule && (\r\n \r\n \r\n \r\n
\r\n \r\n
\r\n \r\n }\r\n >\r\n \r\n \r\n
\r\n
\r\n )}\r\n \r\n
\r\n )\r\n}\r\n","import { IconNameType } from '@finviz/website'\r\n\r\nimport ChartLayout from '../../models/chart_layout'\r\n\r\nexport enum DrawingTool {\r\n Arrow = 'arrow',\r\n Brush = 'brush',\r\n Callout = 'callout',\r\n Curve = 'curve',\r\n ElliottWaves = 'elliott-wave',\r\n Ellipse = 'ellipse',\r\n FibonacciRetracements = 'fibonacci-retracements',\r\n HorizontalLine = 'horizontal-line',\r\n Measure = 'measure',\r\n Mouse = 'mouse',\r\n Pitchfork = 'pitchfork',\r\n Polygon = 'polygon',\r\n Position = 'position',\r\n Rectangle = 'rectangle',\r\n RotatedRectangle = 'rotated-rectangle',\r\n ScaledLine = 'scaled-line',\r\n ScaledText = 'scaled-text',\r\n Triangle = 'triangle',\r\n VerticalLine = 'vertical-line',\r\n Xabcd = 'xabcd',\r\n}\r\n\r\nexport enum DrawingActions {\r\n AddNote = 'add-note',\r\n DeleteDrawings = 'delete-drawings',\r\n DeleteAutoSavedDrawings = 'delete-autosaved-drawings',\r\n}\r\n\r\nexport enum DrawingSetting {\r\n PreserveDrawings = 'preserve-drawings',\r\n DrawingModeContinuous = 'drawing-mode-continuous',\r\n HideDrawings = 'hide-drawings',\r\n LockDrawings = 'lock-drawings',\r\n}\r\n\r\nexport interface IToolBarProps {\r\n chartLayoutModel: ChartLayout\r\n isSidebar?: boolean\r\n isHorizontal?: boolean\r\n isMobileOverlay?: boolean\r\n /**\r\n * Current selected tool id\r\n */\r\n activeTool: DrawingTool\r\n /**\r\n * On tool item select callback\r\n */\r\n onActiveToolChange: (activeTool: DrawingTool, trigger?: 'button' | 'select' | 'group') => void\r\n /**\r\n * On drawing actions item select callback\r\n */\r\n onDrawingActionClick?: (actionId: DrawingActions) => void\r\n /**\r\n * On drawing settings item select callback\r\n */\r\n onDrawingSettingClick?: (settingId: DrawingSetting) => void\r\n /**\r\n * On drawing end callback\r\n */\r\n onDrawingEnd?: () => void\r\n /**\r\n * Current state of drawing settings\r\n */\r\n drawingSettings: Record\r\n isAlternativeTheme?: boolean\r\n /**\r\n * Are tools disabled\r\n */\r\n areToolsDisabled?: boolean\r\n}\r\n\r\nexport interface IToolbarItemProperties {\r\n icon: IconNameType\r\n iconActive?: IconNameType\r\n iconAction?: IconNameType\r\n title: string\r\n titleActive?: string\r\n titleAction?: string\r\n}\r\n\r\nexport interface IToolbarDrawingTool extends IToolbarItemProperties {\r\n id: DrawingTool\r\n}\r\n\r\nexport interface IToolbarDrawingAction extends IToolbarItemProperties {\r\n id: DrawingActions\r\n}\r\n\r\nexport interface IToolbarDrawingSetting extends IToolbarItemProperties {\r\n id: DrawingSetting\r\n}\r\n\r\nexport interface IToolbarDrawingToolItem {\r\n defaultItem: IToolbarDrawingTool\r\n toolGroup?: Array\r\n toolGroupTitle?: string\r\n}\r\n\r\nexport interface IToolbarDrawingActionItem {\r\n defaultItem: IToolbarDrawingAction\r\n isDisabled?: boolean\r\n disabledTooltip?: string\r\n}\r\n\r\nexport interface IToolbarDrawingsSettingItem {\r\n defaultItem: IToolbarDrawingSetting\r\n isDisabled?: boolean\r\n isInAction?: boolean\r\n disabledTooltip?: string\r\n}\r\n","import { Instrument } from '../../types/shared'\r\nimport { ChartElementType } from '../constants/common'\r\nimport QuoteModel from '../models/quote'\r\n\r\nexport function getInstrumentLabel(instrument: Instrument) {\r\n switch (instrument) {\r\n case Instrument.Stock:\r\n return 'Stock'\r\n case Instrument.Futures:\r\n return 'Futures'\r\n case Instrument.Forex:\r\n return 'Forex'\r\n case Instrument.Crypto:\r\n return 'Crypto'\r\n case Instrument.MarketSentiment:\r\n return 'Market Sentiment'\r\n }\r\n}\r\n\r\nexport function getChartAlt(quoteModel: QuoteModel) {\r\n return `${quoteModel.name || quoteModel.ticker} - ${getInstrumentLabel(quoteModel.instrument)} Price Chart`\r\n}\r\n\r\nexport const getResponseChartType = (chartType: ChartElementType) => {\r\n switch (chartType) {\r\n case ChartElementType.HeikinAshi:\r\n return 'heikinashi'\r\n case ChartElementType.HollowCandleStick:\r\n return 'hollowcandlestick'\r\n case ChartElementType.LineChart:\r\n return 'line'\r\n case ChartElementType.OhlcChart:\r\n return 'ohlc'\r\n case ChartElementType.CandleStick:\r\n default:\r\n return 'candlestick'\r\n }\r\n}\r\n\r\nexport const getChartElementTypeFromResponseType = (chartResponseType: string | null) =>\r\n chartResponseType === null\r\n ? null\r\n : Object.values(ChartElementType).find(\r\n (chartType: ChartElementType) => chartResponseType === getResponseChartType(chartType)\r\n )\r\n","import utils from '../utils'\r\n\r\nclass AverageTrueRange {\r\n period: number\r\n sum: number\r\n count: number\r\n value: number\r\n\r\n constructor(period: number) {\r\n this.period = period\r\n this.sum = 0\r\n this.count = 0\r\n this.value = 0\r\n }\r\n\r\n add(high: number, low: number, prevClose: number) {\r\n const tr = utils.max([high - low, Math.abs(high - prevClose), Math.abs(low - prevClose)])\r\n\r\n if (this.count < this.period) {\r\n this.sum += tr\r\n this.value = this.sum / (this.count + 1)\r\n if (this.count === this.period - 1) {\r\n this.sum /= this.period\r\n }\r\n } else {\r\n this.value = (this.value * (this.period - 1) + tr) / this.period\r\n }\r\n this.count++\r\n }\r\n}\r\n\r\nexport default AverageTrueRange\r\n","import { PaneArea } from '../../types/shared'\r\nimport Element, { DefaultAttrs } from '../canvas/element'\r\nimport BaseChart from '../charts/base_chart'\r\nimport { ChartEventBadgeType, ChartEventType, TIMEFRAME } from '../constants/common'\r\nimport { getRoundedObject } from '../controllers/renderUtils'\r\nimport Chart from '../models/chart'\r\nimport ChartEventElement from '../models/chart-event-element'\r\nimport { CHART_EVENT_BADGE_SIZE } from '../models/constants'\r\nimport type PaneModel from '../models/pane'\r\nimport Utils from '../utils'\r\nimport { ChartEventBadgeState } from '../utils/chart-events-utils'\r\n\r\nconst isMobile = Utils.isMobile()\r\n\r\ninterface ChartEventAttrs extends DefaultAttrs {\r\n x: number\r\n}\r\n\r\nfunction getChartEventState(chartEvent: ChartEvent): ChartEventBadgeState {\r\n if (chartEvent.isOpen) {\r\n return ChartEventBadgeState.selected\r\n }\r\n if (chartEvent.isHovered) {\r\n return ChartEventBadgeState.hover\r\n }\r\n return ChartEventBadgeState.default\r\n}\r\n\r\nclass ChartEvent extends Element {\r\n static type = ChartEventType.ChartEvent\r\n static label = 'ChartEvent'\r\n\r\n declare scaled: Pick\r\n\r\n declare chart: BaseChart\r\n\r\n declare model: PaneModel\r\n\r\n declare chartEventModel: ChartEventElement | undefined\r\n\r\n isOpen = false\r\n\r\n left = 0\r\n top = 0\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x'], y: [] })\r\n\r\n get type() {\r\n return (this.constructor as typeof ChartEvent).type\r\n }\r\n\r\n get label() {\r\n return (this.constructor as typeof ChartEvent).label\r\n }\r\n\r\n getChartEvenBadgeType(): ChartEventBadgeType {\r\n switch (this.type) {\r\n case ChartEventType.Dividends:\r\n return ChartEventBadgeType.Dividends\r\n case ChartEventType.Split:\r\n return ChartEventBadgeType.Split\r\n }\r\n\r\n return ChartEventBadgeType.EarningsNeutral\r\n }\r\n\r\n getChartEventModel(): ChartEventElement | undefined {\r\n if (!this.chartEventModel) {\r\n this.chartEventModel = this.model.chartEvents()?.findByAttribute('instance', this)\r\n }\r\n\r\n return this.chartEventModel\r\n }\r\n\r\n getXYPosition() {\r\n const { top, bottom } = this.getChartLayoutSettings().ChartSettings\r\n const chartEventModel = this.getChartEventModel()\r\n const { x } = this.scaled\r\n const roundedXY = getRoundedObject({ x })\r\n const y =\r\n (this.model as PaneModel).height -\r\n top.height -\r\n bottom.height -\r\n CHART_EVENT_BADGE_SIZE -\r\n (chartEventModel?.yIndex ?? 0) * CHART_EVENT_BADGE_SIZE\r\n\r\n return { x: roundedXY.x - CHART_EVENT_BADGE_SIZE / 2, y }\r\n }\r\n\r\n getIsVisible() {\r\n return ![TIMEFRAME.w, TIMEFRAME.m].includes(this.model.chart().quote()?.timeframe)\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n if (!this.getIsVisible() || !this.chartEventModel) return\r\n\r\n this.attrs.x = Math.round(this.attrs.x)\r\n const chart = this.model.chart()\r\n const chartLayout = chart.chart_layout()\r\n const { x, y } = this.getXYPosition()\r\n const buffer = 10 + CHART_EVENT_BADGE_SIZE\r\n if (x + chart.leftOffset < -buffer || x + chart.leftOffset > chart.width + buffer) {\r\n return\r\n }\r\n const item = this.chartEventModel.getChartEventBadgeImage({\r\n theme: chartLayout.theme,\r\n state: getChartEventState(this),\r\n badgeType: this.getChartEvenBadgeType(),\r\n })\r\n\r\n if (!item) return\r\n\r\n const { left, top } = this.getChartLayoutSettings().ChartSettings\r\n this.left = x + chart.leftOffset + left.width + CHART_EVENT_BADGE_SIZE / 2\r\n this.top = y + top.height\r\n context.drawImage(item, x, y, CHART_EVENT_BADGE_SIZE, CHART_EVENT_BADGE_SIZE)\r\n }\r\n\r\n setIsHovered(isHovered: boolean) {\r\n if (!this.getIsVisible()) return\r\n\r\n this.isHovered = isHovered\r\n this.model.updateChartEventsZIndexes()\r\n this.trigger('change')\r\n }\r\n\r\n // If isOpenOverride is undefined, the function works as toggle\r\n toggleIsOpen(isOpenOverride?: boolean) {\r\n const chartLayout = this.model.chart().chart_layout()\r\n const chartEventModel = this.getChartEventModel()\r\n\r\n const isCurrentEventActive = chartLayout.activeChartEvent?.elementId === chartEventModel?.elementId\r\n const isOpen = isOpenOverride ?? (isCurrentEventActive ? !chartEventModel?.instance.isOpen : true)\r\n this.isOpen = isOpen\r\n // Due to the fact that chart events logic depends heavily on hover state which isn't really present on touch devices\r\n // we need to mimic that state for touch devices, this enables chart event to be open, and counterpart in\r\n // chart-event-popover-with-state.tsx allow chart event to be closed on click outside\r\n if (isMobile) {\r\n this.isHovered = isOpen\r\n }\r\n if (chartLayout.activeChartEvent?.instance.isOpen && !isCurrentEventActive) {\r\n chartLayout.activeChartEvent?.instance.toggleIsOpen(false)\r\n }\r\n if (isOpen || isCurrentEventActive) {\r\n chartLayout.updateAttribute('activeChartEvent', !isOpen && isCurrentEventActive ? undefined : chartEventModel)\r\n }\r\n\r\n this.model.updateChartEventsZIndexes()\r\n this.trigger('change')\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (!this.getIsVisible()) return false\r\n\r\n const scaledArea = area.scaled\r\n const { x, y } = this.getXYPosition()\r\n const isInArea =\r\n x <= scaledArea.x &&\r\n x + CHART_EVENT_BADGE_SIZE >= scaledArea.x &&\r\n y <= scaledArea.y &&\r\n y + CHART_EVENT_BADGE_SIZE >= scaledArea.y\r\n return isInArea\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n if (!this.getIsVisible()) return false\r\n\r\n const { x } = this.getXYPosition()\r\n const isInView = x + CHART_EVENT_BADGE_SIZE >= -chart.leftOffset && x <= -chart.leftOffset + chart.width\r\n return isInView\r\n }\r\n}\r\n\r\nexport default ChartEvent\r\n","import { ChartEventLabels, ChartEventType } from '../constants/common'\r\nimport ChartEvent from './chart-event'\r\n\r\nclass Dividends extends ChartEvent {\r\n static type = ChartEventType.Dividends\r\n static label = ChartEventLabels[ChartEventType.Dividends]\r\n}\r\n\r\nexport default Dividends\r\n","import { ChartEventBadgeType, ChartEventLabels, ChartEventType } from '../constants/common'\r\nimport { IEarnings } from '../utils/chart-events-utils'\r\nimport ChartEvent from './chart-event'\r\n\r\nclass Earnings extends ChartEvent {\r\n static type = ChartEventType.Earnings\r\n static label = ChartEventLabels[ChartEventType.Earnings]\r\n\r\n getChartEvenBadgeType(): ChartEventBadgeType {\r\n const eventItem = this.getChartEventModel()?.getChartEventData() as IEarnings | undefined\r\n\r\n if (!eventItem) {\r\n return ChartEventBadgeType.EarningsNeutral\r\n }\r\n\r\n if (eventItem.epsActual === undefined || eventItem.epsEstimate === undefined) {\r\n const now = Date.now() / 1000\r\n return eventItem.dateTimestamp > now ? ChartEventBadgeType.EarningsFuture : ChartEventBadgeType.EarningsNeutral\r\n }\r\n return eventItem.epsActual - eventItem.epsEstimate < 0\r\n ? ChartEventBadgeType.EarningsNegative\r\n : ChartEventBadgeType.EarningsPositive\r\n }\r\n}\r\n\r\nexport default Earnings\r\n","import { ChartEventLabels, ChartEventType } from '../constants/common'\r\nimport ChartEvent from './chart-event'\r\n\r\nclass Split extends ChartEvent {\r\n static type = ChartEventType.Split\r\n static label = ChartEventLabels[ChartEventType.Split]\r\n}\r\n\r\nexport default Split\r\n","import { ChartEventType } from '../constants/common'\r\nimport chartEvent from './chart-event'\r\nimport dividends from './dividends'\r\nimport earnings from './earnings'\r\nimport split from './split'\r\n\r\nexport const chartEventsByType = Object.freeze({\r\n [ChartEventType.ChartEvent]: chartEvent,\r\n [ChartEventType.Dividends]: dividends,\r\n [ChartEventType.Split]: split,\r\n [ChartEventType.Earnings]: earnings,\r\n})\r\n","import { ChartConfigChartPaneElement } from '../../types/shared'\r\nimport { drawingToolsByType } from '../canvas/drawingTools'\r\nimport { chartEventsByType } from '../chart-events'\r\nimport { chartsByType } from '../charts/charts'\r\nimport { indicatorsByType } from '../indicators/indicators'\r\nimport { overlaysByType } from '../overlays/overlays'\r\n\r\nconst canvasElements = {\r\n ...overlaysByType,\r\n ...indicatorsByType,\r\n ...drawingToolsByType,\r\n ...chartsByType,\r\n ...chartEventsByType,\r\n}\r\n\r\nexport function getCanvasElementByType(elementType: ChartConfigChartPaneElement['type']) {\r\n return canvasElements[elementType]\r\n}\r\n","import { Instrument, Point } from '../../types/shared'\r\n\r\ninterface LinePoints {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n}\r\n\r\nexport enum BigNumber {\r\n Thousand,\r\n Million,\r\n Billion,\r\n Trillion,\r\n}\r\n\r\nexport const BIG_NUMBER_VALUES = {\r\n [BigNumber.Thousand]: 1e3,\r\n [BigNumber.Million]: 1e6,\r\n [BigNumber.Billion]: 1e9,\r\n [BigNumber.Trillion]: 1e12,\r\n}\r\n\r\nconst BIG_NUMBER_ZEROES = {\r\n [BigNumber.Thousand]: 3,\r\n [BigNumber.Million]: 6,\r\n [BigNumber.Billion]: 9,\r\n [BigNumber.Trillion]: 12,\r\n}\r\n\r\nconst BIG_NUMBER_SUFFIX = {\r\n [BigNumber.Thousand]: 'K',\r\n [BigNumber.Million]: 'M',\r\n [BigNumber.Billion]: 'B',\r\n [BigNumber.Trillion]: 'T',\r\n}\r\n\r\nconst math = {\r\n dotProduct(p1: Point, p2: Point) {\r\n return p1.x * p2.x + p1.y * p2.y\r\n },\r\n\r\n crossProduct(p1: Point, p2: Point) {\r\n return p1.x * p2.y - p1.y * p2.x\r\n },\r\n\r\n distance(p1: Point, p2: Point) {\r\n return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2))\r\n },\r\n\r\n lineEquation(line: LinePoints) {\r\n // ax + by + c = 0\r\n if (line.x1 === line.x2) {\r\n return {\r\n a: 1,\r\n b: 0,\r\n c: -line.x1,\r\n }\r\n }\r\n const k = (line.y2 - line.y1) / (line.x2 - line.x1)\r\n return {\r\n a: -k,\r\n b: 1,\r\n c: k * line.x1 - line.y1,\r\n k,\r\n }\r\n },\r\n\r\n pointInPolygon(point: Point, polygon: Point[]) {\r\n // http://alienryderflex.com/polygon/\r\n let j = polygon.length - 1\r\n let oddNodes = false\r\n for (let i = 0; i < polygon.length; i++) {\r\n const p = polygon[i]\r\n if (\r\n ((p.y < point.y && polygon[j].y >= point.y) || (polygon[j].y < point.y && p.y >= point.y)) &&\r\n (p.x <= point.x || polygon[j].x <= point.x)\r\n ) {\r\n if (p.x + ((point.y - p.y) / (polygon[j].y - p.y)) * (polygon[j].x - p.x) < point.x) {\r\n oddNodes = !oddNodes\r\n }\r\n }\r\n j = i\r\n }\r\n return oddNodes\r\n },\r\n\r\n distanceToLine(point: Point, line: LinePoints) {\r\n const { a, b, c } = this.lineEquation(line)\r\n const dist = Math.abs(a * point.x + b * point.y + c) / Math.sqrt(a * a + b * b)\r\n return dist\r\n },\r\n\r\n distanceToSegment(point: Point, line: LinePoints) {\r\n const l2 = Math.pow(line.x1 - line.x2, 2) + Math.pow(line.y1 - line.y2, 2)\r\n if (l2 === 0) {\r\n return Math.sqrt(Math.pow(point.x - line.x1, 2) + Math.pow(point.y - line.y1, 2))\r\n }\r\n const t = ((point.x - line.x1) * (line.x2 - line.x1) + (point.y - line.y1) * (line.y2 - line.y1)) / l2\r\n if (t < 0) {\r\n return Math.sqrt(Math.pow(point.x - line.x1, 2) + Math.pow(point.y - line.y1, 2))\r\n }\r\n if (t > 1) {\r\n return Math.sqrt(Math.pow(point.x - line.x2, 2) + Math.pow(point.y - line.y2, 2))\r\n }\r\n const x = line.x1 + t * (line.x2 - line.x1)\r\n const y = line.y1 + t * (line.y2 - line.y1)\r\n return Math.sqrt(Math.pow(point.x - x, 2) + Math.pow(point.y - y, 2))\r\n },\r\n\r\n getInstrumentDecimalPlaces({ value, instrument }: { value: number; instrument?: Instrument }) {\r\n if (instrument === Instrument.Crypto && value <= 0.001) {\r\n return 8\r\n }\r\n\r\n if ((instrument !== Instrument.Stock && value <= 6) || (instrument === Instrument.Stock && value < 1)) {\r\n return 4\r\n }\r\n\r\n return 2\r\n },\r\n\r\n formatBigNumber(number: number, toFixed?: number, minNumber?: BigNumber) {\r\n const absNum = Math.abs(number)\r\n const getString = ({ num, suffix, zeroes }: { num: number; suffix: string; zeroes: number }) => {\r\n const str = num.toString()\r\n if (str.includes('e')) {\r\n const splitString = str.split('e')\r\n const addZeroes = Number(splitString[1]) - zeroes\r\n return Math.round(Number(splitString[0])).toString().padEnd(Math.max(0, addZeroes), '0') + suffix\r\n }\r\n const sign = Math.sign(num)\r\n const numberByZeroesCount = Math.pow(10, zeroes)\r\n const result = (absNum / numberByZeroesCount) * sign\r\n return (Number.isInteger(result) ? result : result.toFixed(toFixed !== undefined ? toFixed : 1)) + suffix\r\n }\r\n\r\n if (absNum >= BIG_NUMBER_VALUES[BigNumber.Trillion] || minNumber === BigNumber.Trillion) {\r\n return getString({\r\n num: number,\r\n suffix: BIG_NUMBER_SUFFIX[BigNumber.Trillion],\r\n zeroes: BIG_NUMBER_ZEROES[BigNumber.Trillion],\r\n })\r\n } else if (absNum >= BIG_NUMBER_VALUES[BigNumber.Billion] || minNumber === BigNumber.Billion) {\r\n return getString({\r\n num: number,\r\n suffix: BIG_NUMBER_SUFFIX[BigNumber.Billion],\r\n zeroes: BIG_NUMBER_ZEROES[BigNumber.Billion],\r\n })\r\n } else if (absNum >= BIG_NUMBER_VALUES[BigNumber.Million] || minNumber === BigNumber.Million) {\r\n return getString({\r\n num: number,\r\n suffix: BIG_NUMBER_SUFFIX[BigNumber.Million],\r\n zeroes: BIG_NUMBER_ZEROES[BigNumber.Million],\r\n })\r\n } else if (absNum >= BIG_NUMBER_VALUES[BigNumber.Thousand] || minNumber === BigNumber.Thousand) {\r\n return getString({\r\n num: number,\r\n suffix: BIG_NUMBER_SUFFIX[BigNumber.Thousand],\r\n zeroes: BIG_NUMBER_ZEROES[BigNumber.Thousand],\r\n })\r\n } else {\r\n return toFixed !== undefined ? number.toFixed(toFixed) : number.toString()\r\n }\r\n },\r\n\r\n round({\r\n value,\r\n lastClose = 0,\r\n instrument,\r\n overridePlaces,\r\n }: {\r\n value: number\r\n lastClose?: number\r\n instrument?: Instrument\r\n overridePlaces?: number\r\n }) {\r\n if (Math.abs(value) >= BIG_NUMBER_VALUES[BigNumber.Million]) {\r\n return this.formatBigNumber(value, overridePlaces)\r\n }\r\n\r\n const places =\r\n typeof overridePlaces === 'number'\r\n ? overridePlaces\r\n : this.getInstrumentDecimalPlaces({ value: lastClose, instrument })\r\n\r\n if (value < 0.000001) {\r\n // There was an issue with getting NaN when rounding small numbers with latter method\r\n return value.toFixed(places)\r\n }\r\n return Number(`${Math.round(Number(`${value}e+${places}`))}e-${places}`).toFixed(places)\r\n },\r\n\r\n perpendicularPointToLine({ line, distance }: { line: LinePoints; distance: number }) {\r\n if (distance === 0) {\r\n return { x: line.x2, y: line.y2 }\r\n }\r\n\r\n let yAxisCoeficient\r\n let xAxisCoeficient\r\n\r\n if (line.x1 <= line.x2 && line.y1 >= line.y2) {\r\n xAxisCoeficient = -1\r\n yAxisCoeficient = -1\r\n } else if (line.x1 <= line.x2 && line.y1 <= line.y2) {\r\n xAxisCoeficient = 1\r\n yAxisCoeficient = -1\r\n } else if (line.x1 >= line.x2 && line.y1 >= line.y2) {\r\n xAxisCoeficient = -1\r\n yAxisCoeficient = 1\r\n } else {\r\n // conditions falling to else: (line.x1 >= line.x2 && line.y1 <= line.y2)\r\n xAxisCoeficient = 1\r\n yAxisCoeficient = 1\r\n }\r\n\r\n const radAngle = Math.atan2(Math.abs(line.x2 - line.x1), Math.abs(line.y2 - line.y1))\r\n const x = line.x2 + xAxisCoeficient * (distance * Math.cos(radAngle))\r\n const y = line.y2 + yAxisCoeficient * (distance * Math.sin(radAngle))\r\n return { x, y }\r\n },\r\n\r\n rotatedPointCoordinates({\r\n rotationAxisPoint,\r\n angle,\r\n pointToRotate,\r\n }: {\r\n rotationAxisPoint: Point\r\n angle: number\r\n pointToRotate: Point\r\n }) {\r\n // return newCoordinates for pointToRotate after rotation defined by\r\n // angle around rotationAxisPoint\r\n const sin = Math.sin(angle)\r\n const cos = Math.cos(angle)\r\n const rotatedX =\r\n cos * (pointToRotate.x - rotationAxisPoint.x) +\r\n sin * (pointToRotate.y - rotationAxisPoint.y) +\r\n rotationAxisPoint.x\r\n const rotatedY =\r\n cos * (pointToRotate.y - rotationAxisPoint.y) -\r\n sin * (pointToRotate.x - rotationAxisPoint.x) +\r\n rotationAxisPoint.y\r\n return { x: rotatedX, y: rotatedY }\r\n },\r\n sharedPointLinesAngle({\r\n sharedPoint,\r\n oldLinePoint,\r\n newLinePoint,\r\n }: {\r\n sharedPoint: Point\r\n oldLinePoint: Point\r\n newLinePoint: Point\r\n }) {\r\n // return angle between line from sharedPoint to oldLinePoint and\r\n // line from sharedPoint to newLinePoint\r\n const numerator =\r\n oldLinePoint.y * (sharedPoint.x - newLinePoint.x) +\r\n sharedPoint.y * (newLinePoint.x - oldLinePoint.x) +\r\n newLinePoint.y * (oldLinePoint.x - sharedPoint.x)\r\n const denominator =\r\n (oldLinePoint.x - sharedPoint.x) * (sharedPoint.x - newLinePoint.x) +\r\n (oldLinePoint.y - sharedPoint.y) * (sharedPoint.y - newLinePoint.y)\r\n const ratio = numerator / denominator\r\n\r\n return Math.atan(ratio)\r\n },\r\n\r\n twoSegmentLinesIntersection(p1: Point, p2: Point, p3: Point, p4: Point) {\r\n // line intercept math by Paul Bourke http://paulbourke.net/geometry/pointlineplane/\r\n // Determine the intersection point of two line segments\r\n // Return FALSE if the lines don't intersect\r\n\r\n // Check if none of the lines are of length 0\r\n if ((p1.x === p2.x && p1.y === p2.y) || (p3.x === p4.x && p3.y === p4.y)) {\r\n return false\r\n }\r\n\r\n const denominator = (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y)\r\n\r\n // Lines are parallel\r\n if (denominator === 0) {\r\n return false\r\n }\r\n\r\n const ua = ((p4.x - p3.x) * (p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x)) / denominator\r\n const ub = ((p2.x - p1.x) * (p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x)) / denominator\r\n\r\n // is the intersection along the segments\r\n if (ua < 0 || ua > 1 || ub < 0 || ub > 1) {\r\n return false\r\n }\r\n\r\n // Return a object with the x and y coordinates of the intersection\r\n const x = p1.x + ua * (p2.x - p1.x)\r\n const y = p1.y + ua * (p2.y - p1.y)\r\n\r\n return { x, y }\r\n },\r\n\r\n // https://stackoverflow.com/a/60368757\r\n checkLineIntersection(line1_p1: Point, line1_p2: Point, line2_p1: Point, line2_p2: Point) {\r\n // if the lines intersect, the result contains the x and y of the intersection (treating the lines as infinite) and booleans for whether line segment 1 or line segment 2 contain the point\r\n let a, b\r\n const result: { x: number; y: number; onLine1: boolean; onLine2: boolean } = {\r\n x: 0,\r\n y: 0,\r\n onLine1: false,\r\n onLine2: false,\r\n }\r\n const denominator =\r\n (line2_p2.y - line2_p1.y) * (line1_p2.x - line1_p1.x) - (line2_p2.x - line2_p1.x) * (line1_p2.y - line1_p1.y)\r\n if (denominator === 0) {\r\n return false\r\n }\r\n\r\n a = line1_p1.y - line2_p1.y\r\n b = line1_p1.x - line2_p1.x\r\n const numerator1 = (line2_p2.x - line2_p1.x) * a - (line2_p2.y - line2_p1.y) * b\r\n const numerator2 = (line1_p2.x - line1_p1.x) * a - (line1_p2.y - line1_p1.y) * b\r\n a = numerator1 / denominator\r\n b = numerator2 / denominator\r\n\r\n // if we cast these lines infinitely in both directions, they intersect here:\r\n result.x = line1_p1.x + a * (line1_p2.x - line1_p1.x)\r\n result.y = line1_p1.y + a * (line1_p2.y - line1_p1.y)\r\n\r\n // if line1 is a segment and line2 is infinite, they intersect if:\r\n if (a > 0 && a < 1) {\r\n result.onLine1 = true\r\n }\r\n // if line2 is a segment and line1 is infinite, they intersect if:\r\n if (b > 0 && b < 1) {\r\n result.onLine2 = true\r\n }\r\n // if line1 and line2 are segments, they intersect if both of the above are true\r\n return result\r\n },\r\n\r\n // ray is considered line1, segment is considered line2\r\n getRayToLineSegmentIntersection(rayOrigin: Point, rayEnd: Point, segmentStart: Point, segmentEnd: Point) {\r\n const lineIntersection = this.checkLineIntersection(rayOrigin, rayEnd, segmentStart, segmentEnd)\r\n\r\n if (\r\n !lineIntersection ||\r\n lineIntersection.onLine1 ||\r\n this.dotProduct(\r\n this.subtractPoints(rayOrigin, lineIntersection as Point),\r\n this.subtractPoints(rayOrigin, rayEnd)\r\n ) <= 0\r\n )\r\n return false\r\n return { ...lineIntersection, x: Math.round(lineIntersection.x), y: Math.round(lineIntersection.y) } // sometimes edge value can have crazy precision instead of `0` something like `5.684341886080802e-14` which is basically 0.00000000000005684341886080802 we should round it\r\n },\r\n\r\n getMiddlePointOnLineSegment(P1: Point, P2: Point) {\r\n const x = (P1.x - P2.x) / 2 + P2.x\r\n const y = (P1.y - P2.y) / 2 + P2.y\r\n return { x, y }\r\n },\r\n\r\n normalizeVector(v: Point) {\r\n const length = Math.sqrt(v.x * v.x + v.y * v.y)\r\n return { x: v.x / length, y: v.y / length }\r\n },\r\n\r\n multiplyVectorByScalar(v: Point, scalar: number) {\r\n return { x: v.x * scalar, y: v.y * scalar }\r\n },\r\n\r\n addPoints(P1: Point, P2: Point) {\r\n return { x: P1.x + P2.x, y: P1.y + P2.y }\r\n },\r\n\r\n subtractPoints(P1: Point, P2: Point): Point {\r\n return { x: P1.x - P2.x, y: P1.y - P2.y }\r\n },\r\n\r\n isSamePoint(P1: Point, P2: Point, margin = { x: 0, y: 0 }) {\r\n return P1.x - margin.x <= P2.x && P2.x <= P1.x + margin.x && P1.y - margin.y <= P2.y && P2.y <= P1.y + margin.y\r\n },\r\n}\r\n\r\nexport default math\r\n","import { EMAConfig, Options } from '../overlays/configs/ema'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\nexport class ExponentialMovingAverage {\r\n period: number\r\n multiplier: number\r\n sum: number\r\n count: number\r\n value: number\r\n\r\n constructor(period: number) {\r\n this.period = period\r\n this.multiplier = 2 / (this.period + 1)\r\n this.sum = 0\r\n this.count = 0\r\n this.value = 0\r\n }\r\n\r\n add(d: number) {\r\n if (this.count < this.period) {\r\n this.sum += d\r\n this.count++\r\n this.value = this.sum / this.count\r\n } else {\r\n this.value = d * this.multiplier + this.value * (1 - this.multiplier)\r\n }\r\n }\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n ema: number[]\r\n}\r\n\r\nexport class EMACalculation extends MainCalculation {\r\n static config = EMAConfig\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period } = this.options\r\n const { close } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n if (close.length < period) return\r\n\r\n const ema = new ExponentialMovingAverage(period)\r\n for (let index = 0; index < close.length; index++) {\r\n ema.add(close[index])\r\n\r\n if (index < period - 1) continue\r\n\r\n this.calculatedValues.ema[index] = ema.value\r\n\r\n if (onValueCalculated?.(this.calculatedValues, index) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { ObjectHash } from '../../types/shared'\r\nimport IndicatorBaseConfig from '../indicators/configs/indicatorBaseConfig'\r\nimport type Quote from '../models/quote'\r\nimport OverlayBaseConfig from '../overlays/configs/overlayBaseConfig'\r\n\r\ntype OptionValuesType = ObjectHash\r\ntype CalculatedValuesType = ObjectHash\r\ninterface MainProps {\r\n quote: Quote\r\n options: T\r\n}\r\n\r\nexport type OnValueCalculatedReturnValue = boolean | undefined\r\nexport type OnValueCalculated = ((value: T, dataIndex: number) => OnValueCalculatedReturnValue) | undefined\r\n\r\nexport class MainCalculation<\r\n TOptionValues extends OptionValuesType | undefined = undefined,\r\n TCalculatedValues extends CalculatedValuesType = CalculatedValuesType,\r\n> {\r\n declare static config: OverlayBaseConfig | IndicatorBaseConfig\r\n\r\n quote: NonNullable['quote']>\r\n options: MainProps['options']\r\n\r\n protected declare _calculatedValues: TCalculatedValues\r\n\r\n constructor({ quote, options }: MainProps) {\r\n this.quote = quote\r\n this.options = options\r\n }\r\n\r\n get calculatedValues() {\r\n return this._calculatedValues ?? this.getDefaultCalculatedValues()\r\n }\r\n\r\n get config() {\r\n return (this.constructor as typeof MainCalculation).config\r\n }\r\n\r\n getDefaultCalculatedValues(): TCalculatedValues {\r\n const defaultCalculatedValues = this.config.getDefaultCalculatedValues() as TCalculatedValues\r\n if (Object.keys(defaultCalculatedValues).length === 0) {\r\n throw Error('Add calculatedValues to indicator config')\r\n }\r\n return defaultCalculatedValues\r\n }\r\n\r\n calculate(_: OnValueCalculated) {\r\n throw Error('Implement calculate')\r\n }\r\n\r\n getAllCalculatedValues(lastNItems: number) {\r\n const calculatedValues = {} as TCalculatedValues\r\n Object.keys(this.calculatedValues).forEach((key) => {\r\n calculatedValues[key as keyof TCalculatedValues] = this.getCalculatedValues(key, lastNItems)\r\n })\r\n return calculatedValues\r\n }\r\n\r\n getCalculatedValues(key: keyof TCalculatedValues, lastNItems: number) {\r\n const result = (this.calculatedValues[key] as number[]).slice(-lastNItems)\r\n return (result.length > 0 ? result : [...Array(lastNItems)]) as TCalculatedValues[keyof TCalculatedValues]\r\n }\r\n\r\n /**\r\n * This function is used to construct sql script for db table creation\r\n * and also to build precalculated data object used on node server.\r\n *\r\n * Precalculated data object uses database column names as property keys to simplify data mapping on BE\r\n */\r\n getDbColumnName() {\r\n const colName = this.config.abbreviation\r\n const optionKeys = this.config.optionsOrder\r\n\r\n const optionsStrings = optionKeys.map((key) => this.options![key])\r\n return [colName, ...optionsStrings].join('_')\r\n }\r\n}\r\n","import type { ObjectHash } from '../../../types/shared'\r\nimport ElementBaseConfig from '../../canvas/ElementBaseConfig'\r\nimport { IndicatorType, QuoteFinancialAttachment } from '../../constants/common'\r\n\r\nexport default class IndicatorBaseConfig extends ElementBaseConfig {\r\n static type = IndicatorType.Indicator\r\n static abbreviation = 'ind'\r\n static label = 'Indicator'\r\n static shortLabel = 'Indicator'\r\n static description = ''\r\n static optionsOrder = [] as readonly string[]\r\n static optionsLabels = {}\r\n static inputsOrder = [] as readonly string[]\r\n static inputsLabels = {}\r\n static calculatedValuesOrder = [] as readonly string[]\r\n static calculatedValuesLabels = {}\r\n static defaultCalculatedValueOption = undefined as undefined | string\r\n static quoteFinancialAttachments: QuoteFinancialAttachment[] = []\r\n\r\n static getShortLabelWithAttrs(attrs: ObjectHash) {\r\n return [this.shortLabel, this.optionsOrder.map((item) => attrs[item]).join(',')].filter((item) => !!item).join(' ')\r\n }\r\n\r\n get getShortLabelWithAttrs() {\r\n return (this.constructor as typeof IndicatorBaseConfig).getShortLabelWithAttrs\r\n }\r\n\r\n static getDefaultCalculatedValues() {\r\n return this.calculatedValuesOrder.reduce((prev, curr) => ({ ...prev, [curr]: [] }), {})\r\n }\r\n\r\n get getDefaultCalculatedValues() {\r\n return (this.constructor as typeof IndicatorBaseConfig).getDefaultCalculatedValues\r\n }\r\n}\r\n","import { IndicatorType, QuoteFinancialAttachment } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport class ShrtflConfig extends IndicatorBaseConfig {\r\n static quoteFinancialAttachments: QuoteFinancialAttachment[] = [QuoteFinancialAttachment.shortInterest]\r\n static type = IndicatorType.Shrtfl\r\n static label = 'Short Float%'\r\n static shortLabel = 'Short Float%'\r\n static abbreviation = 'shrtfl'\r\n}\r\n","import { IndicatorType, QuoteFinancialAttachment } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport class ShrtraConfig extends IndicatorBaseConfig {\r\n static quoteFinancialAttachments: QuoteFinancialAttachment[] = [QuoteFinancialAttachment.shortInterest]\r\n static type = IndicatorType.Shrtra\r\n static label = 'Short Ratio'\r\n static shortLabel = 'Short Ratio'\r\n static abbreviation = 'shrtra'\r\n}\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class ADXConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Adx\r\n static abbreviation = 'adx'\r\n static label = 'ADX'\r\n static shortLabel = 'ADX'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport merge from 'lodash.merge'\r\n\r\nimport {\r\n ChartConfigChartPaneElement,\r\n CustomSpineEvents,\r\n IModalConfig,\r\n IModalConfigInput,\r\n ObjectHash,\r\n PaneArea,\r\n RequireByKey,\r\n Theme,\r\n} from '../../types/shared'\r\nimport Line from '../canvas/line'\r\nimport Text, { ITextAttrs } from '../canvas/text'\r\nimport tailwindColors from '../constants/colors'\r\nimport {\r\n FONT_SIZE,\r\n INDICATOR_LABEL_HEIGHT,\r\n IndicatorType,\r\n OFFSET,\r\n PADDING,\r\n SpecificChartFunctionality,\r\n TextAlign,\r\n TextBaseline,\r\n} from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport Chart from '../models/chart'\r\nimport { ISettings } from '../models/chart_settings/interfaces'\r\nimport mouseModel from '../models/mouse'\r\nimport Pane from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport { isRedesignEnabled } from '../utils'\r\nimport { roundedRect } from '../utils/canvas-render'\r\nimport { renderCross } from '../utils/chart'\r\nimport { renderFadeExtendedHours, renderXAxis } from '../utils/chart-grid-render-utils'\r\nimport { getHEXWithSpecificAplha } from '../utils/colors'\r\nimport {\r\n drawInVisibleArea,\r\n getAreNoBarsVisible,\r\n getCompensatedFirstBarToRenderIndex,\r\n getVisibleBarToRenderIndex,\r\n} from '../utils/draw_in_visible_area'\r\nimport { getIsSSr, getParsedIntegersFromPeriodString, isInRange, isPositiveInteger } from '../utils/helpers'\r\nimport IndicatorBaseConfig from './configs/indicatorBaseConfig'\r\n\r\nconst MAX_POSITIVE_DEFAULT_VALUE = Number.MAX_VALUE\r\nconst MAX_NEGATIVE_DEFAULT_VALUE = -Number.MAX_VALUE\r\n\r\nconst INDICATOR_DEFAULT_DOMAIN = (indicator: IndicatorType) => {\r\n switch (indicator) {\r\n case IndicatorType.Rvol:\r\n return { min: 0, max: 2 }\r\n case IndicatorType.Atr:\r\n return { min: 0, max: 10 }\r\n case IndicatorType.Adx:\r\n case IndicatorType.Aro:\r\n case IndicatorType.Mfi:\r\n case IndicatorType.Perf:\r\n case IndicatorType.Rmi:\r\n case IndicatorType.Rsi:\r\n case IndicatorType.Stofu:\r\n case IndicatorType.Ult:\r\n return { min: 0, max: 100 }\r\n case IndicatorType.Macd:\r\n case IndicatorType.Rwi:\r\n case IndicatorType.Trix:\r\n return { min: -1, max: 1 }\r\n case IndicatorType.Wr:\r\n return { min: -100, max: 0 }\r\n case IndicatorType.Aroosc:\r\n case IndicatorType.Roc:\r\n return { min: -100, max: 100 }\r\n case IndicatorType.Cci:\r\n case IndicatorType.Fi:\r\n return { min: -200, max: 200 }\r\n case IndicatorType.Shrtfl:\r\n case IndicatorType.Shrtra:\r\n return { min: 0, max: 1 }\r\n default:\r\n return { min: 0, max: 100 }\r\n }\r\n}\r\n\r\nexport interface IIndicatorIsValid {\r\n getIsValid(key: string): boolean | void\r\n}\r\n\r\nclass Indicator extends Spine.Module implements IIndicatorIsValid {\r\n static config = IndicatorBaseConfig\r\n\r\n static initClass() {\r\n Object.defineProperty(this.prototype, 'height', {\r\n get() {\r\n return this.model.height\r\n },\r\n })\r\n Object.defineProperty(this.prototype, 'contentHeight', {\r\n get() {\r\n const { IndicatorSettings } = this.getChartLayoutSettings() as ISettings\r\n return this.height - IndicatorSettings.top.height - IndicatorSettings.bottom.height\r\n },\r\n })\r\n }\r\n\r\n static fromObject(values: ObjectHash, model: Pane) {\r\n const indicator = new this(values, model)\r\n indicator.set(values)\r\n return indicator\r\n }\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt = 0] = getParsedIntegersFromPeriodString(period)\r\n return periodInt\r\n }\r\n\r\n declare data: Quote\r\n declare min: number\r\n declare max: number\r\n declare contentHeight: number\r\n declare height: number\r\n\r\n attrs: Attrs\r\n model: Pane\r\n labelWidth = 0\r\n fetchedAt = -1\r\n leftOffset = 0\r\n width = 0\r\n contentWidth = 0\r\n lastValue: number | null = null\r\n shouldUpdate = true\r\n tickers: string | null = null\r\n period?: string | number\r\n\r\n // Used to calculate yAxis min/max values if min === max, and we don't want to use domain defaults\r\n applyMinMaxPadding = false\r\n\r\n constructor(attrs: Attrs, model: Pane) {\r\n super(attrs, model)\r\n this.attrs = attrs\r\n this.model = model\r\n this.data = this.model.chart().quote()\r\n\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n this.renderCrossText = this.renderCrossText.bind(this)\r\n\r\n this.model.chart().bind('update', this.trigger.bind(this, 'change'))\r\n this.model.bind('update change', this.trigger.bind(this, 'change'))\r\n const mouseModelChangeHandler = this.trigger.bind(this, 'change', 'cross')\r\n this.model.bind('destroy', () => {\r\n mouseModel.unbind('change', mouseModelChangeHandler)\r\n })\r\n mouseModel.bind('change', mouseModelChangeHandler)\r\n\r\n this.model.chart().chart_layout().bind('theme', this.setupCache.bind(this))\r\n }\r\n\r\n get type() {\r\n return (this.constructor as typeof Indicator).config.type\r\n }\r\n\r\n get label() {\r\n return (this.constructor as typeof Indicator).config.label\r\n }\r\n\r\n get config() {\r\n return (this.constructor as typeof Indicator).config\r\n }\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n this.data = this.model.chart().quote()\r\n this.leftOffset = this.model.chart().leftOffset\r\n this.width = this.model.chart().width\r\n this.contentWidth = this.width - IndicatorSettings.left.width - IndicatorSettings.right.width\r\n\r\n this.compute()\r\n\r\n this.setupCache()\r\n\r\n this.renderYAxis(context)\r\n\r\n context.save()\r\n this.clip(context)\r\n this.renderXAxis(context)\r\n const translate = getTranslate({\r\n context,\r\n xOffset: this.leftOffset + IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n this.renderIndicator(context)\r\n translate.undo()\r\n\r\n renderFadeExtendedHours({ context, paneModel: this.model, quote: this.data })\r\n\r\n context.restore()\r\n\r\n if (!this.getIsChartPageSpecificFunctionality()) {\r\n this.renderLabel(context)\r\n }\r\n }\r\n\r\n isComputeNecessary() {\r\n // if quote was updated (this.fetchedAt !== this.data.fetchedAt)\r\n // or indicator setting was changed via modal (this.shouldUpdate)\r\n // allow compute and update variables to prevent another unless\r\n // those variables change again\r\n if (this.fetchedAt !== this.data.fetchedAt || this.shouldUpdate) {\r\n this.fetchedAt = this.data.fetchedAt\r\n this.shouldUpdate = false\r\n return true\r\n }\r\n return false\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D, options?: { lastValueSuffix?: string }) {\r\n const { IndicatorSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n let y\r\n const translate = getTranslate({\r\n context,\r\n xOffset: IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n const ticks = this.model.scale.y.ticks(10)\r\n const tickTextStep = Math.abs(ticks[2] - ticks[0])\r\n const yLine = new Line(\r\n {\r\n x1: 0,\r\n x2: this.contentWidth,\r\n strokeStyle: Colors.grid,\r\n dashLength: 3,\r\n },\r\n this.model\r\n )\r\n const text = new Text(\r\n {\r\n x: this.contentWidth + OFFSET.M + IndicatorSettings.right.axis.margin.left!,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.right.axis.font),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.model\r\n )\r\n for (let index = 0; index < ticks.length; index++) {\r\n const tick = ticks[index]\r\n y = Math.round(this.fy(tick))\r\n yLine.set({ y1: y, y2: y }).render(context)\r\n if (index % 2 === 0) {\r\n text.set({ text: this.formatAxis(tick, tickTextStep), y }).render(context)\r\n }\r\n }\r\n\r\n const minY = 0\r\n const maxY = this.contentHeight\r\n const valueY = this.lastValue === null ? 0 : Math.round(this.fy(this.lastValue))\r\n if (this.lastValue != null && valueY >= minY && valueY <= maxY) {\r\n new Text(\r\n {\r\n text: `${math.formatBigNumber(this.lastValue, 2)}${options?.lastValueSuffix ?? ''}`,\r\n x: this.contentWidth + OFFSET.M - PADDING.XXS + IndicatorSettings.right.axis.margin.left!,\r\n y: valueY,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.right.axis.font),\r\n lineHeight: IndicatorSettings.right.axis.font.lineHeight,\r\n padding: {\r\n top: IndicatorSettings.right.axis.font?.padding?.top ?? PADDING.XXS,\r\n right: IndicatorSettings.right.axis.font?.padding?.right ?? PADDING.XXS,\r\n bottom: IndicatorSettings.right.axis.font?.padding?.bottom ?? PADDING.XXS,\r\n left: IndicatorSettings.right.axis.font?.padding?.left ?? PADDING.XXS,\r\n },\r\n textBaseline: TextBaseline.middle,\r\n fillStyle: Colors.indicatorCurrentText,\r\n background: Colors.indicatorCurrentBackground,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n renderXAxis(context: CanvasRenderingContext2D) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n\r\n const translate = getTranslate({\r\n context,\r\n xOffset: IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n\r\n translate.do()\r\n\r\n renderXAxis({ context, quote: this.data, paneModel: this.model, type: this.type })\r\n\r\n translate.undo()\r\n }\r\n\r\n renderLabel(context: CanvasRenderingContext2D) {\r\n if (this.getIsChartPageSpecificFunctionality()) {\r\n this.renderLabelChartsPage(context)\r\n } else {\r\n this.renderLabelQuotePage(context)\r\n }\r\n }\r\n\r\n renderLabelQuotePage(context: CanvasRenderingContext2D) {\r\n const { IndicatorSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const label = new Text(\r\n {\r\n text: this.toString(),\r\n x: IndicatorSettings.left.indicatorLabel.margin.left,\r\n y: IndicatorSettings.left.indicatorLabel.margin.top,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.left.indicatorLabel.font),\r\n fillStyle: Colors.text,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.model\r\n )\r\n this.labelWidth = label.measure(context)\r\n return label.render(context)\r\n }\r\n\r\n renderLabelChartsPage(context: CanvasRenderingContext2D): { x: number; y: number; labelWidth: number } | void {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n const { theme, specificChartFunctionality } = this.model.chart().chart_layout()\r\n const isQuoteOrQuoteFinancials = [\r\n SpecificChartFunctionality.quotePage,\r\n SpecificChartFunctionality.quoteFinancials,\r\n ].includes(specificChartFunctionality)\r\n const isDarkMode = theme === Theme.dark\r\n const x = isQuoteOrQuoteFinancials ? OFFSET.S : IndicatorSettings.left.indicatorLabel.margin.left!\r\n const y = IndicatorSettings.left.indicatorLabel.margin.top!\r\n const label = new Text(\r\n {\r\n text: this.toString(),\r\n x: x * 2,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.left.indicatorLabel.font),\r\n fillStyle: tailwindColors.gray[isDarkMode ? 50 : 900],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.model\r\n )\r\n this.labelWidth = label.measure(context) + IndicatorSettings.left.indicatorLabel.margin.left! * 2\r\n label.set({ y: y + (INDICATOR_LABEL_HEIGHT - label.attrs.lineHeight / 2) })\r\n roundedRect({\r\n ctx: context,\r\n x,\r\n y,\r\n height: INDICATOR_LABEL_HEIGHT,\r\n width: this.labelWidth,\r\n radius: 6,\r\n color: `${tailwindColors.gray[isDarkMode ? 700 : 50]}cc`,\r\n })\r\n label.render(context)\r\n\r\n return { x, y, labelWidth: this.labelWidth }\r\n }\r\n\r\n renderCross(context: CanvasRenderingContext2D) {\r\n renderCross({\r\n context,\r\n mouseModel,\r\n paneModel: this.model,\r\n quote: this.data,\r\n contentWidth: this.contentWidth,\r\n contentHeight: this.contentHeight,\r\n isIndicator: true,\r\n isPerfIndicator: this.type === IndicatorType.Perf || this.type === IndicatorType.Shrtfl,\r\n onRenderCrossText: !this.getIsChartPageSpecificFunctionality() ? this.renderCrossText : undefined,\r\n })\r\n\r\n if (this.getIsChartPageSpecificFunctionality()) {\r\n this.renderCrossText(context, mouseModel.getCrossIndexForPane(this.model))\r\n }\r\n }\r\n\r\n renderCrossText(context: CanvasRenderingContext2D, crossIndex: number) {\r\n this.data = this.model.chart().quote()\r\n const index = Number.isNaN(crossIndex) ? -1 : crossIndex\r\n if (this.getIsChartPageSpecificFunctionality()) {\r\n this.renderLabelChartsPage(context)\r\n\r\n this.renderCrossTextChartsPage(context, index)\r\n } else {\r\n this.renderCrossTextQuotePage(context, index)\r\n }\r\n }\r\n\r\n getValueLabelsAtIndex(_: number): Array<{ color: string; text: string | null }> {\r\n return []\r\n }\r\n\r\n renderCrossTextValueLabels(\r\n context: CanvasRenderingContext2D,\r\n crossIndex: number,\r\n { textBaseline, y }: Pick\r\n ) {\r\n if (!context || isNaN(crossIndex) || crossIndex === -1) {\r\n return\r\n }\r\n\r\n const { ChartSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const crossValueText = new Text(\r\n {\r\n font: Text.getMergedPropsWithDefaults('font', {\r\n ...IndicatorSettings.left.indicatorLabel.font,\r\n style: 'normal',\r\n }),\r\n textAlign: TextAlign.left,\r\n textBaseline,\r\n background: getHEXWithSpecificAplha(Colors.canvasFill, 0.8),\r\n padding: { top: 0, bottom: 0, left: 5, right: 5 },\r\n },\r\n this.model\r\n )\r\n\r\n let x = this.labelWidth + IndicatorSettings.left.indicatorLabel.margin.left! * 2\r\n\r\n const renderLabel = ({ color, text }: { color: string; text: string | null }) => {\r\n crossValueText.set({\r\n x,\r\n y,\r\n fillStyle: color,\r\n text: text ?? ' - ',\r\n })\r\n\r\n x += crossValueText.measure(context) + crossValueText.attrs.padding.left + crossValueText.attrs.padding.right\r\n\r\n crossValueText.render(context)\r\n }\r\n\r\n let lastRenderedIndex = -1\r\n this.getValueLabelsAtIndex(crossIndex).forEach(({ color, text }, index) => {\r\n if (text !== null) {\r\n if (lastRenderedIndex > -1) {\r\n renderLabel({ color: Colors.zeroChange, text: '·' })\r\n }\r\n renderLabel({ color, text })\r\n\r\n lastRenderedIndex = index\r\n }\r\n })\r\n }\r\n\r\n renderCrossTextChartsPage(context: CanvasRenderingContext2D, crossIndex: number) {\r\n const { indicatorLabel } = this.getChartLayoutSettings().IndicatorSettings.left\r\n // @todo - Default text lineheight is 20 , and is not overwritten by indicatorLabel.font (which is probably a bug) , in this case it's easier to hardcode this value than access is on Text instance\r\n const lineHeight = 20\r\n this.renderCrossTextValueLabels(context, crossIndex, {\r\n textBaseline: TextBaseline.middle,\r\n y: indicatorLabel.margin.top! + (2 * INDICATOR_LABEL_HEIGHT - lineHeight) / 2,\r\n })\r\n }\r\n\r\n renderCrossTextQuotePage(context: CanvasRenderingContext2D, crossIndex: number) {\r\n this.renderCrossTextValueLabels(context, crossIndex, {\r\n textBaseline: TextBaseline.top,\r\n y: this.getChartLayoutSettings().IndicatorSettings.left.indicatorLabel.margin.top,\r\n })\r\n }\r\n\r\n getValueLabel(value: number | undefined | null, unit = '') {\r\n if (value === undefined || value === null || !Number.isFinite(value)) return null\r\n\r\n return `${math.formatBigNumber(value, 2)}${unit}`\r\n }\r\n\r\n getOversoldOverboughtValueLabelsAtIndex(index: number, array: number[]) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n const dataIndex = this.data.barToDataIndex[index]\r\n return [{ color: IndicatorSettings.general.Colors.line, text: this.getValueLabel(array[dataIndex]) }]\r\n }\r\n\r\n renderOversoldOverbought(\r\n context: CanvasRenderingContext2D,\r\n array: number[],\r\n from: number,\r\n oversold: number,\r\n zero: number,\r\n overbought: number,\r\n drawLines?: boolean\r\n ) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n if (this.data.close.length === 0) return\r\n const drawInVisibleAreaProps = {\r\n fromIndexOffset: from,\r\n leftOffset: this.leftOffset,\r\n paneModel: this.model,\r\n quote: this.data,\r\n width: this.width,\r\n }\r\n\r\n const firstBarToRenderIndex = getCompensatedFirstBarToRenderIndex(drawInVisibleAreaProps)\r\n\r\n if (drawLines == null) {\r\n drawLines = true\r\n }\r\n\r\n context.save()\r\n\r\n let clipHeight = Math.round(this.fy(oversold) - this.fy(this.model.scale.y.domain()[1]))\r\n if (clipHeight <= 0 || getIsSSr()) {\r\n context.beginPath()\r\n context.rect(\r\n -this.leftOffset,\r\n this.fy(this.model.scale.y.domain()[1]) + 1, // compensation to addition of 1 in clip function\r\n this.contentWidth,\r\n clipHeight < 0 ? clipHeight - 1 : -1 // clipHeight - 1 is a compensation to addition of 1 in clip function ; fix bug in skia-canvas when clip is incorrect if height is 0 or clip is outside of previous clip https://github.com/samizdatco/skia-canvas/issues/87\r\n )\r\n }\r\n context.clip()\r\n context.set('fillStyle', '#87ceef')\r\n\r\n context.beginPath()\r\n const firstIndex = array.findIndex((value) => value !== undefined)\r\n const firstFx = this.fx(Math.max(firstBarToRenderIndex, firstIndex))\r\n context.moveTo(firstFx, Math.round(this.fy(this.model.scale.y.domain()[0])))\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n if (array[i] !== undefined) context.lineTo(x, Math.round(this.fy(array[i])))\r\n },\r\n })\r\n context.lineTo(this.fx(this.data.close.length - 1), Math.round(this.fy(this.model.scale.y.domain()[0])))\r\n context.fill()\r\n context.restore()\r\n if (drawLines) {\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(oversold)),\r\n y2: Math.round(this.fy(oversold)),\r\n strokeStyle: '#69c1ea',\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n if (drawLines) {\r\n this.renderZeroLine(context, zero)\r\n }\r\n\r\n context.save()\r\n clipHeight = Math.round(this.fy(overbought))\r\n if (clipHeight >= 0 || getIsSSr()) {\r\n context.beginPath()\r\n context.rect(\r\n -this.leftOffset,\r\n this.fy(this.model.scale.y.domain()[0]),\r\n this.contentWidth,\r\n clipHeight > 0 ? clipHeight : 1 // // fix bug in skia-canvas when clip is incorrect if height is 0 or clip is outside of previous clip https://github.com/samizdatco/skia-canvas/issues/87\r\n )\r\n }\r\n\r\n context.clip()\r\n context.set('fillStyle', '#dc9fe5')\r\n context.beginPath()\r\n context.moveTo(firstFx, Math.round(this.fy(this.model.scale.y.domain()[1])))\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n if (array[i] !== undefined) context.lineTo(x, Math.round(this.fy(array[i])))\r\n },\r\n })\r\n context.lineTo(this.fx(this.data.close.length - 1), Math.round(this.fy(this.model.scale.y.domain()[1]) + 1))\r\n context.fill()\r\n context.restore()\r\n if (drawLines) {\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(overbought)),\r\n y2: Math.round(this.fy(overbought)),\r\n strokeStyle: '#d386df',\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n context.set('strokeStyle', IndicatorSettings.general.Colors.line)\r\n context.set('fillStyle', '#dc9fe5')\r\n\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n if (array[i] !== undefined) context.lineTo(Math.round(x), Math.round(this.fy(array[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n renderZeroLine(context: CanvasRenderingContext2D, zero: number) {\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(zero)),\r\n y2: Math.round(this.fy(zero)),\r\n strokeStyle: '#ff8787',\r\n dashLength: 3,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n setupCache() {}\r\n\r\n clip(context: CanvasRenderingContext2D) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n context.beginPath()\r\n context.rect(IndicatorSettings.left.width, IndicatorSettings.top.height, this.contentWidth, this.contentHeight + 1) // +1 shows one more pixel which is needed to be able to see a line at very bottom of an indicaor\r\n return context.clip()\r\n }\r\n\r\n formatAxis(value: number, tickStep?: number) {\r\n if (tickStep !== undefined && 10 > tickStep) {\r\n return value.toFixed(2)\r\n }\r\n return value.toString()\r\n }\r\n\r\n fx = (x: number) => this.model.scale.x(this.data.barIndex[x])\r\n\r\n fy = (y: number) => this.model.scale.y(y)\r\n\r\n set(values: Partial) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n this.shouldUpdate = true\r\n for (const key in values) {\r\n if (key !== 'type') {\r\n // @ts-expect-error - values keys don't have to always match variables on the instance\r\n this[key] = values[key]\r\n }\r\n }\r\n this.width = this.model.chart().width\r\n this.contentWidth = this.width - IndicatorSettings.left.width - IndicatorSettings.right.width\r\n\r\n const newAttrs = this.getModalConfig()\r\n .inputs.map(({ value }) => value.toString())\r\n .join(',')\r\n if (newAttrs) this.attrs = { ...this.attrs, period: newAttrs }\r\n\r\n this.model.trigger(CustomSpineEvents.ManualChange)\r\n }\r\n\r\n parsePeriodInt(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n this.period = Number.parseInt(values.period, 10)\r\n this.model.trigger(CustomSpineEvents.ManualChange)\r\n }\r\n }\r\n\r\n setModel(model: Pane) {\r\n return (this.model = model)\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n const x = IndicatorSettings.left.indicatorLabel.margin.left!\r\n const y = IndicatorSettings.left.indicatorLabel.margin.top!\r\n let width = OFFSET.M * 2 + this.labelWidth\r\n let height = OFFSET.S * 2 + FONT_SIZE.M\r\n\r\n if (this.getIsChartPageSpecificFunctionality()) {\r\n width = this.labelWidth\r\n height = INDICATOR_LABEL_HEIGHT\r\n }\r\n\r\n if (x < area.cursorX && area.cursorX < width + x && y < area.cursorY && area.cursorY < height + y) {\r\n return true\r\n }\r\n return false\r\n }\r\n\r\n getIsInChartView(_: Chart) {\r\n return true\r\n }\r\n\r\n moveBy() {}\r\n\r\n thumbsAreInArea() {\r\n return false\r\n }\r\n\r\n computeVisibleMinMax(...arrays: number[][]) {\r\n let min = MAX_POSITIVE_DEFAULT_VALUE\r\n let max = MAX_NEGATIVE_DEFAULT_VALUE\r\n\r\n const { leftOffset } = this.model.chart()\r\n\r\n const firstBarToRenderIndex = getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset,\r\n })\r\n const lastBarToRenderIndex = getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset,\r\n chartWidth: this.contentWidth,\r\n })\r\n const areNoBarsVisible = getAreNoBarsVisible(firstBarToRenderIndex, lastBarToRenderIndex)\r\n\r\n for (const arr of arrays) {\r\n for (let i = firstBarToRenderIndex.index; i <= lastBarToRenderIndex.index; i++) {\r\n if (!isNaN(arr[i])) {\r\n min = Math.min(min, arr[i])\r\n max = Math.max(max, arr[i])\r\n }\r\n }\r\n }\r\n\r\n if (!areNoBarsVisible && min !== MAX_POSITIVE_DEFAULT_VALUE && max !== MAX_NEGATIVE_DEFAULT_VALUE) {\r\n if (min === max && this.applyMinMaxPadding) {\r\n min = min - min * Math.sign(min)\r\n max = max + max * Math.sign(max)\r\n }\r\n if (min !== max) {\r\n return { min, max }\r\n }\r\n }\r\n return this.getDomainDefaults(this.type)\r\n }\r\n\r\n getModalConfig(): IModalConfig {\r\n return {\r\n title: this.label,\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n getDomainDefaults = (indicatorType: IndicatorType) => INDICATOR_DEFAULT_DOMAIN(indicatorType)\r\n\r\n getMinMax() {\r\n this.data = this.model.chart().quote()\r\n this.compute()\r\n return { min: this.min, max: this.max }\r\n }\r\n\r\n toObject() {\r\n return merge({}, this.attrs, { type: this.type, tickers: this.tickers })\r\n }\r\n\r\n toConfig(): T['attrs'] & { type: T['type'] } {\r\n return {\r\n type: this.type,\r\n period: this.getModalConfig()\r\n .inputs.map((input: IModalConfigInput) => input.value.toString())\r\n .join(','),\r\n }\r\n }\r\n\r\n toString() {\r\n return this.config.getShortLabelWithAttrs(this)\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.model.chart().chart_layout())\r\n }\r\n\r\n renderIndicator(_: CanvasRenderingContext2D) {\r\n throw Error('Implement renderIndicator method')\r\n }\r\n\r\n getIsValid(_: string): boolean | undefined {\r\n throw Error('Implement')\r\n }\r\n\r\n getIsNumberInputValid({ key, integerOnly = true }: { key: string; integerOnly?: boolean }): boolean {\r\n const input = this.getModalConfig().inputs.find(({ name }: { name: string }) => key === name)\r\n return !!input && isInRange(input) && (!integerOnly || isPositiveInteger(input.value))\r\n }\r\n\r\n getIsChartPageSpecificFunctionality() {\r\n const { specificChartFunctionality } = this.model.chart().chart_layout()\r\n const isCharts = specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isRedesignedFuturesForexCrypto =\r\n isRedesignEnabled() &&\r\n [\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n SpecificChartFunctionality.quotePage,\r\n ].includes(specificChartFunctionality)\r\n\r\n return isCharts || isRedesignedFuturesForexCrypto\r\n }\r\n\r\n getIsDrawing() {\r\n return false\r\n }\r\n\r\n getIsChartEvent() {\r\n return false\r\n }\r\n\r\n compute() {\r\n throw Error('Implement compute method')\r\n }\r\n}\r\n\r\nIndicator.initClass()\r\n\r\nexport default Indicator\r\n","export function roundedRect({\r\n ctx,\r\n x,\r\n y,\r\n width,\r\n height,\r\n radius,\r\n color,\r\n}: {\r\n ctx: CanvasRenderingContext2D\r\n x: number\r\n y: number\r\n width: number\r\n height: number\r\n radius: number\r\n color: string\r\n}) {\r\n ctx.translate(0.5, 0.5)\r\n ctx.set('strokeStyle', color)\r\n ctx.set('fillStyle', color)\r\n ctx.beginPath()\r\n ctx.moveTo(x, y + radius)\r\n ctx.lineTo(x, y + height - radius)\r\n ctx.arcTo(x, y + height, x + radius, y + height, radius)\r\n ctx.lineTo(x + width - radius, y + height)\r\n ctx.arcTo(x + width, y + height, x + width, y + height - radius, radius)\r\n ctx.lineTo(x + width, y + radius)\r\n ctx.arcTo(x + width, y, x + width - radius, y, radius)\r\n ctx.lineTo(x + radius, y)\r\n ctx.arcTo(x, y, x, y + radius, radius)\r\n ctx.stroke()\r\n ctx.fill()\r\n ctx.translate(-0.5, -0.5)\r\n}\r\n","import utils from '../utils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { ADXConfig, Attrs } from './configs/adx'\r\nimport Indicator from './indicator'\r\n\r\nclass ADX extends Indicator {\r\n static config = ADXConfig\r\n\r\n declare period: number\r\n pdi: number[] = []\r\n mdi: number[] = []\r\n adx: number[] = []\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n let adx, amdm, apdm, mdi, pdi\r\n this.pdi = []\r\n this.mdi = []\r\n this.adx = []\r\n let atr = (apdm = amdm = adx = 0)\r\n for (let i = this.period; i < this.data.close.length; i++) {\r\n const deltaHigh = this.data.high[i] - this.data.high[i - 1]\r\n const deltaLow = this.data.low[i - 1] - this.data.low[i]\r\n\r\n let pdm = 0\r\n if (deltaHigh > 0 && deltaHigh > deltaLow) {\r\n pdm = deltaHigh\r\n }\r\n\r\n let mdm = 0\r\n if (deltaLow > 0 && deltaLow > deltaHigh) {\r\n mdm = deltaLow\r\n }\r\n\r\n const tr = utils.max([\r\n this.data.high[i] - this.data.low[i],\r\n Math.abs(this.data.high[i] - this.data.close[i - 1]),\r\n Math.abs(this.data.low[i] - this.data.close[i - 1]),\r\n ])\r\n\r\n atr = (atr * (this.period - 1) + tr) / this.period\r\n apdm = (apdm * (this.period - 1) + pdm) / this.period\r\n amdm = (amdm * (this.period - 1) + mdm) / this.period\r\n\r\n pdi = atr > 0 ? (apdm * 100) / atr : 0\r\n mdi = atr > 0 ? (amdm * 100) / atr : 0\r\n const di = Math.abs(pdi - mdi)\r\n const dx = pdi + mdi > 0 ? (di * 100) / (pdi + mdi) : 0\r\n adx = (adx * (this.period - 1) + dx) / this.period\r\n\r\n this.pdi[i] = pdi\r\n this.mdi[i] = mdi\r\n this.adx[i] = adx\r\n }\r\n this.lastValue = this.adx.last() ?? null\r\n }\r\n const { min, max } =\r\n this.pdi.length > 0 || this.mdi.length > 0 || this.adx.length > 0\r\n ? this.computeVisibleMinMax(this.pdi, this.mdi, this.adx)\r\n : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getLineColors() {\r\n return {\r\n pdi: '#2eb12e',\r\n mdi: '#d43737',\r\n adx: this.getChartLayoutSettings().IndicatorSettings.general.Colors.line,\r\n }\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n const lineColors = this.getLineColors()\r\n const dataIndex = this.data.barToDataIndex[index]\r\n return [\r\n { color: lineColors.pdi, text: this.getValueLabel(this.pdi[dataIndex]) },\r\n { color: lineColors.mdi, text: this.getValueLabel(this.mdi[dataIndex]) },\r\n { color: lineColors.adx, text: this.getValueLabel(this.adx[dataIndex]) },\r\n ]\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (this.data.close.length === 0) return\r\n\r\n const lineColors = this.getLineColors()\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', lineColors.pdi)\r\n context.beginPath()\r\n\r\n const drawInVisibleAreaProps = {\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n fromIndexOffset: this.period,\r\n }\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.pdi[i])))\r\n },\r\n })\r\n\r\n context.stroke()\r\n\r\n context.set('strokeStyle', lineColors.mdi)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.mdi[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.set('strokeStyle', lineColors.adx)\r\n context.beginPath()\r\n\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.adx[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: ADXConfig.label,\r\n inputs: ADXConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default ADX\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class AroConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Aro\r\n static abbreviation = 'aro'\r\n static label = 'Aroon'\r\n static shortLabel = 'Aroon'\r\n static description =\r\n 'Aroon is a technical indicator that measures trend strength and direction. It consists of two lines: Aroon Up and Aroon Down. When Aroon Up crosses above Aroon Down, it signals a potential uptrend, while the opposite indicates a potential downtrend. Divergence between Aroon and price can also suggest trend reversals.'\r\n\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n static calculatedValuesOrder = ['aroonUp', 'aroonDown', 'oscillator'] as const\r\n static calculatedValuesLabels = {\r\n aroonUp: 'Aroon Up',\r\n aroonDown: 'Aroon Down',\r\n oscillator: 'Oscillator',\r\n }\r\n\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { AroConfig, Attrs } from '../indicators/configs/aro'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n aroonUp: number[]\r\n aroonDown: number[]\r\n oscillator: number[]\r\n}\r\n\r\nexport class AroonCalculation extends MainCalculation {\r\n static config = AroConfig\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period } = this.options\r\n const { low, high } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n for (let i = period; i < high.length; i++) {\r\n const highPeriod = high.slice(i - period, i + 1)\r\n const highestInPeriod = Math.max(...highPeriod)\r\n const periodSinceHigh = period - highPeriod.lastIndexOf(highestInPeriod)\r\n this._calculatedValues.aroonUp[i] = 100 * ((period - periodSinceHigh) / period)\r\n\r\n const lowPeriod = low.slice(i - period, i + 1)\r\n const lowestInPeriod = Math.min(...lowPeriod)\r\n const periodSinceLow = period - lowPeriod.lastIndexOf(lowestInPeriod)\r\n this._calculatedValues.aroonDown[i] = 100 * ((period - periodSinceLow) / period)\r\n\r\n this._calculatedValues.oscillator[i] = this._calculatedValues.aroonUp[i] - this._calculatedValues.aroonDown[i]\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import Text from '../canvas/text'\r\nimport { OFFSET, PADDING, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport { AroonCalculation } from '../indicator-calculation/aroon'\r\nimport Pane from '../models/pane'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { AroConfig, Attrs } from './configs/aro'\r\nimport Indicator from './indicator'\r\n\r\nconst COLORS = {\r\n aroonUp: '#00a000',\r\n aroonDown: '#c80000',\r\n}\r\n\r\nclass Aroon extends Indicator {\r\n static config = AroConfig\r\n\r\n aroonCalculation: AroonCalculation | null = null\r\n declare period: number\r\n\r\n constructor(attrs: Attrs, model: Pane) {\r\n super(attrs, model)\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n }\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary() && this.aroonCalculation !== null) return\r\n\r\n this.aroonCalculation = new AroonCalculation({\r\n quote: this.data,\r\n options: { period: this.period },\r\n })\r\n\r\n this.aroonCalculation.calculate()\r\n\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getLineColors() {\r\n return {\r\n aroonUp: COLORS.aroonUp,\r\n aroonDown: COLORS.aroonDown,\r\n }\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n if (this.data.close.length === 0 || !this.aroonCalculation) return []\r\n\r\n const lineColors = this.getLineColors()\r\n const { aroonUp, aroonDown } = this.aroonCalculation.calculatedValues\r\n const dataIndex = this.data.barToDataIndex[index]\r\n return [\r\n { color: lineColors.aroonDown, text: this.getValueLabel(aroonDown[dataIndex]) },\r\n { color: lineColors.aroonUp, text: this.getValueLabel(aroonUp[dataIndex]) },\r\n ]\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (this.data.close.length === 0 || !this.aroonCalculation) return\r\n\r\n const lineColors = this.getLineColors()\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', lineColors.aroonUp)\r\n context.beginPath()\r\n const drawInVisibleAreaProps = {\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n fromIndexOffset: this.period,\r\n }\r\n const { aroonUp, aroonDown } = this.aroonCalculation.calculatedValues\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(aroonUp[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n context.set('strokeStyle', lineColors.aroonDown)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(aroonDown[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n super.renderYAxis(context)\r\n if (!this.aroonCalculation) return\r\n const { IndicatorSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const { aroonUp, aroonDown } = this.aroonCalculation.calculatedValues\r\n\r\n const translate = getTranslate({\r\n context,\r\n xOffset: IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n const text = new Text(\r\n {\r\n x: this.contentWidth + OFFSET.M - PADDING.XXS + IndicatorSettings.right.axis.margin.left!,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.right.axis.font),\r\n lineHeight: IndicatorSettings.right.axis.font.lineHeight,\r\n padding: {\r\n top: IndicatorSettings.right.axis.font?.padding?.top ?? PADDING.XXS,\r\n right: IndicatorSettings.right.axis.font?.padding?.right ?? PADDING.XXS,\r\n bottom: IndicatorSettings.right.axis.font?.padding?.bottom ?? PADDING.XXS,\r\n left: IndicatorSettings.right.axis.font?.padding?.left ?? PADDING.XXS,\r\n },\r\n textBaseline: TextBaseline.middle,\r\n fillStyle: Colors.indicatorCurrentText,\r\n },\r\n this.model\r\n )\r\n const textLabels = []\r\n if (aroonDown.length > 0) {\r\n textLabels.push({\r\n text: aroonDown.last()!.toFixed(2),\r\n y: Math.round(this.fy(aroonDown.last()!)),\r\n background: COLORS.aroonDown,\r\n })\r\n }\r\n if (aroonUp.length > 0) {\r\n textLabels.push({\r\n text: aroonUp.last()!.toFixed(2),\r\n y: Math.round(this.fy(aroonUp.last()!)),\r\n background: COLORS.aroonUp,\r\n })\r\n }\r\n\r\n const minY = 0\r\n const maxY = this.height - IndicatorSettings.bottom.height - IndicatorSettings.top.height\r\n textLabels.forEach((labelSetting) => {\r\n if (labelSetting.y >= minY && labelSetting.y <= maxY) {\r\n text.set(labelSetting).render(context)\r\n }\r\n })\r\n\r\n translate.undo()\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 25,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: AroConfig.label,\r\n inputs: AroConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default Aroon\r\n","import { IndicatorType } from '../../constants/common'\r\nimport { AroConfig } from './aro'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class ArooscConfig extends AroConfig {\r\n static type = IndicatorType.Aroosc\r\n static abbreviation = 'aroosc'\r\n static label = 'Aroon Oscillator'\r\n static shortLabel = 'Aroon Oscillator'\r\n}\r\n","import { AroonCalculation } from '../indicator-calculation/aroon'\r\nimport { ArooscConfig, Attrs } from './configs/aroosc'\r\nimport Indicator from './indicator'\r\n\r\nclass AroonOscillator extends Indicator {\r\n static config = ArooscConfig\r\n aroonCalculation: AroonCalculation | null = null\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary() && this.aroonCalculation !== null) return\r\n\r\n this.aroonCalculation = new AroonCalculation({\r\n quote: this.data,\r\n options: { period: this.period },\r\n })\r\n\r\n this.aroonCalculation.calculate()\r\n\r\n this.lastValue = this.aroonCalculation.calculatedValues.oscillator.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n return this.getOversoldOverboughtValueLabelsAtIndex(index, this.aroonCalculation?.calculatedValues.oscillator ?? [])\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(\r\n context,\r\n this.aroonCalculation?.calculatedValues.oscillator ?? [],\r\n this.period,\r\n 0,\r\n 0,\r\n 0,\r\n false\r\n )\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 25,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: ArooscConfig.label,\r\n inputs: ArooscConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default AroonOscillator\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class ATRConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Atr\r\n static abbreviation = 'atr'\r\n static label = 'Average True Range'\r\n static shortLabel = 'ATR'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import AverageTrueRange from '../helpers/atr'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { ATRConfig, Attrs } from './configs/atr'\r\nimport Indicator from './indicator'\r\n\r\nclass ATR extends Indicator {\r\n static config = ATRConfig\r\n\r\n atr: number[] = []\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.atr = []\r\n const atr = new AverageTrueRange(this.period)\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n atr.add(this.data.high[i], this.data.low[i], this.data.close[i - 1])\r\n this.atr[i] = atr.value\r\n }\r\n\r\n this.lastValue = this.atr.last() ?? null\r\n }\r\n const { min, max } = this.atr.length > 0 ? this.computeVisibleMinMax(this.atr) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n const dataIndex = this.data.barToDataIndex[index]\r\n return [\r\n {\r\n color: this.getChartLayoutSettings().IndicatorSettings.general.Colors.line!,\r\n text: this.getValueLabel(this.atr[dataIndex]),\r\n },\r\n ]\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(this.atr[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: ATRConfig.label,\r\n inputs: ATRConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default ATR\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class CCIConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Cci\r\n static abbreviation = 'cci'\r\n static label = 'Commodity Channel Index'\r\n static shortLabel = 'CCI'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import { Attrs, CCIConfig } from './configs/cci'\r\nimport Indicator from './indicator'\r\n\r\nconst constant = 0.015\r\nclass CommodityChannelIndex extends Indicator {\r\n static config = CCIConfig\r\n\r\n cci: number[] = []\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n let smaCount\r\n const tp = []\r\n this.cci = []\r\n let smaSum = (smaCount = 0)\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n let devCount\r\n const typicalPrice = (this.data.close[i] + this.data.low[i] + this.data.high[i]) / 3\r\n tp[i] = typicalPrice\r\n\r\n smaSum += typicalPrice\r\n smaCount++\r\n if (smaCount > this.period) {\r\n smaSum -= tp[i - this.period]\r\n smaCount--\r\n }\r\n const sma = smaSum / smaCount\r\n\r\n if (i < this.period - 1) {\r\n continue\r\n }\r\n\r\n let devSum = (devCount = 0)\r\n for (let j = i - this.period + 1; j <= i; j++) {\r\n devSum += Math.abs(tp[j] - sma)\r\n devCount++\r\n }\r\n\r\n const dev = devSum / devCount\r\n this.cci[i] = 0\r\n if (dev > 0) {\r\n this.cci[i] = (typicalPrice - sma) / (constant * dev)\r\n }\r\n }\r\n\r\n this.lastValue = this.cci.last() ?? null\r\n }\r\n\r\n const { min, max } = this.cci.length > 0 ? this.computeVisibleMinMax(this.cci) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n return this.getOversoldOverboughtValueLabelsAtIndex(index, this.cci)\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.cci, this.period, -100, 0, 100)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 20,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: CCIConfig.label,\r\n inputs: CCIConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default CommodityChannelIndex\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Attrs = {\r\n period: string\r\n code: string\r\n}\r\n\r\nexport class COTConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Cot\r\n static abbreviation = 'cot'\r\n static label = 'COT'\r\n static shortLabel = 'CCI'\r\n}\r\n","import * as d3 from 'd3'\r\n\r\nimport { Theme } from '../../types/shared'\r\nimport Text from '../canvas/text'\r\nimport tailwindColors from '../constants/colors'\r\nimport { INDICATOR_LABEL_HEIGHT, TextAlign, TextBaseline } from '../constants/common'\r\nimport utils from '../utils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { Attrs, COTConfig } from './configs/cot'\r\nimport Indicator from './indicator'\r\n\r\nexport interface ICOT {\r\n code: string\r\n name: string\r\n units: string\r\n commercialHedgers: number[]\r\n largeTraders: number[]\r\n smallTraders: number[]\r\n}\r\n\r\ntype ColorsKeys = keyof Pick\r\n\r\nclass COT extends Indicator {\r\n static config = COTConfig\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary() || !this.data.COTs) return\r\n const cotQuoteCode = Object.keys(this.data.COTs)[0]\r\n if (!this.attrs.code && cotQuoteCode) {\r\n this.attrs.code = cotQuoteCode\r\n }\r\n const cot = this.data.COTs[this.attrs.code]\r\n const [min, max] = utils.minMax(cot.commercialHedgers, cot.largeTraders, cot.smallTraders)\r\n this.max = Math.max(Math.abs(max), Math.abs(min))\r\n this.min = -this.max\r\n }\r\n\r\n getLineColors() {\r\n const isDarkMode = this.model.chart().chart_layout().theme === Theme.dark\r\n return {\r\n commercialHedgers: tailwindColors.green[400],\r\n largeTraders: tailwindColors.red[400],\r\n smallTraders: tailwindColors.blue[isDarkMode ? 300 : 500],\r\n }\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n if (!this.data.COTs) return []\r\n const colors = this.getLineColors()\r\n\r\n return Object.keys(colors).map((key) => {\r\n const data = this.data.COTs[this.attrs.code][key as ColorsKeys]\r\n return {\r\n color: colors[key as ColorsKeys],\r\n text: this.getValueLabel(data[index]),\r\n }\r\n })\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (!this.data.COTs) return\r\n context.translate(0.5, 0.5)\r\n const colors = this.getLineColors()\r\n for (const key in colors) {\r\n context.set('strokeStyle', colors[key as ColorsKeys])\r\n context.beginPath()\r\n const data = this.data.COTs[this.attrs.code][key as ColorsKeys]\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(data[i])))\r\n },\r\n })\r\n context.stroke()\r\n }\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n renderLabel(context: CanvasRenderingContext2D) {\r\n if (!this.data.COTs) return\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const name = new Text(\r\n {\r\n text: this.toString(),\r\n x: 8,\r\n y: 16,\r\n font: { size: 10, style: 'bold' },\r\n fillStyle: Colors.text,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.bottom,\r\n },\r\n this.model\r\n )\r\n name.render(context)\r\n const secondarylabelX = 38 + name.measure()\r\n const secondarylabel = new Text(\r\n {\r\n text: this.data.COTs[this.attrs.code].units as string,\r\n x: secondarylabelX,\r\n y: 16,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.bottom,\r\n },\r\n this.model\r\n )\r\n\r\n this.labelWidth = secondarylabelX + 8 + secondarylabel.measure(context)\r\n secondarylabel.render(context)\r\n\r\n this.renderAdditionalLabels(context)\r\n }\r\n\r\n renderLabelChartsPage(context: CanvasRenderingContext2D) {\r\n const { x, y, labelWidth } = super.renderLabelChartsPage(context) as { x: number; y: number; labelWidth: number }\r\n\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n const isDarkMode = this.model.chart().chart_layout().theme === Theme.dark\r\n const secondarylabelX = labelWidth + x * 2\r\n const fontSettings = IndicatorSettings.left.indicatorLabel.font\r\n const scaleCoefficient = 0.7\r\n\r\n const secondarylabel = new Text(\r\n {\r\n text: this.data.COTs[this.attrs.code].units as string,\r\n x: secondarylabelX + x,\r\n font: Text.getMergedPropsWithDefaults('font', {\r\n ...fontSettings,\r\n size: fontSettings.size ? fontSettings.size * scaleCoefficient : undefined,\r\n style: 'normal',\r\n }),\r\n fillStyle: tailwindColors.gray[isDarkMode ? 50 : 900],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.model\r\n )\r\n secondarylabel.set({\r\n y: y + (INDICATOR_LABEL_HEIGHT * scaleCoefficient - (secondarylabel.attrs.lineHeight * scaleCoefficient) / 2),\r\n })\r\n this.labelWidth = secondarylabelX + x + secondarylabel.measure(context)\r\n secondarylabel.render(context)\r\n\r\n this.renderAdditionalLabels(context)\r\n }\r\n\r\n renderAdditionalLabels(context: CanvasRenderingContext2D) {\r\n const { ChartSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const colors = this.getLineColors()\r\n\r\n new Text(\r\n {\r\n text: 'COT',\r\n x: 23,\r\n y: IndicatorSettings.top.height + (IndicatorSettings.bottom.height + this.contentHeight) / 2,\r\n angle: -90,\r\n font: { size: 10, weight: '900', family: 'Lato, sans-serif' },\r\n fillStyle: Colors.textSecondary,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.alphabetic,\r\n },\r\n this.model\r\n ).render(context)\r\n\r\n const text = new Text(\r\n {\r\n text: 'Commercial Hedgers',\r\n x: IndicatorSettings.left.width,\r\n y: IndicatorSettings.top.height + this.contentHeight + IndicatorSettings.bottom.height - 1, // allign to very bottom of indicator with 1 pixel bottom padding\r\n font: { size: 8, style: 'bold' },\r\n fillStyle: colors.commercialHedgers,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.bottom,\r\n },\r\n this.model\r\n )\r\n text.render(context)\r\n\r\n let x = text.get('x')! + 8 + text.measure()\r\n text.set({ text: 'Large Traders', x, fillStyle: colors.largeTraders })\r\n text.render(context)\r\n\r\n x += 8 + text.measure()\r\n text.set({ text: 'Small Traders', x, fillStyle: colors.smallTraders })\r\n text.render(context)\r\n }\r\n\r\n formatAxis(value: number) {\r\n // https://github.com/d3/d3-format/blob/master/README.md#locale_formatPrefix\r\n const scaleY = this.model.scale.y as unknown as d3.ScaleLinear\r\n return scaleY.tickFormat(4, 's')(value).replace(/G/, 'B')\r\n }\r\n\r\n getModalConfig() {\r\n return {\r\n title: COTConfig.label,\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n toString() {\r\n return this.data?.COTs ? (this.data.COTs[this.attrs.code].name as string) : ''\r\n }\r\n\r\n toConfig(): T['attrs'] & { type: T['type'] } {\r\n return {\r\n type: this.type,\r\n code: this.attrs.code,\r\n }\r\n }\r\n}\r\n\r\nexport default COT\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class FIConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Fi\r\n static abbreviation = 'fi'\r\n static label = 'Force Index'\r\n static shortLabel = 'FORCE'\r\n static description =\r\n 'The Force Index combines price movement and volume to evaluate the strength of a trend. Positive Force Index values indicate buying pressure, while negative values suggest selling pressure, helping to gauge the intensity of market moves.'\r\n\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n static calculatedValuesOrder = ['fi'] as const\r\n static calculatedValuesLabels = { fi: 'Force Index' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { Attrs, FIConfig } from '../indicators/configs/fi'\r\nimport { ExponentialMovingAverage } from './ema'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n fi: number[]\r\n}\r\n\r\nexport class FICalculation extends MainCalculation {\r\n static config = FIConfig\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period } = this.options\r\n const { close, volume } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n if (close.length < period) return\r\n\r\n const ema = new ExponentialMovingAverage(period)\r\n\r\n for (let index = 1; index < close.length; index++) {\r\n const value = ((close[index] - close[index - 1]) * volume[index]) / 1000000\r\n ema.add(value)\r\n\r\n if (index < period) continue\r\n\r\n this.calculatedValues.fi[index] = ema.value\r\n\r\n if (onValueCalculated?.(this.calculatedValues, index) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { FICalculation } from '../indicator-calculation/fi'\r\nimport { Attrs, FIConfig } from './configs/fi'\r\nimport Indicator from './indicator'\r\n\r\nclass ForceIndex extends Indicator {\r\n static config = FIConfig\r\n\r\n fiCalculation: FICalculation | null = null\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.fiCalculation = new FICalculation({\r\n quote: this.data,\r\n options: {\r\n period: this.period,\r\n },\r\n })\r\n this.fiCalculation.calculate()\r\n this.lastValue = this.fiCalculation.calculatedValues.fi.last() ?? null\r\n }\r\n const fi = this.fiCalculation?.calculatedValues.fi ?? []\r\n const { min, max } = fi.length > 0 ? this.computeVisibleMinMax(fi) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n return this.getOversoldOverboughtValueLabelsAtIndex(index, this.fiCalculation?.calculatedValues.fi ?? [])\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.fiCalculation?.calculatedValues.fi ?? [], 1, 0, 0, 0, false)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 13,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: FIConfig.label,\r\n inputs: FIConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default ForceIndex\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n fastPeriod: number\r\n slowPeriod: number\r\n signalPeriod: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n period: string\r\n}\r\n\r\nexport class MACDConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Macd\r\n static abbreviation = 'macd'\r\n static label = 'MACD'\r\n static shortLabel = 'MACD'\r\n static description =\r\n 'The MACD (Moving Average Convergence Divergence) indicator identifies potential buy/sell signals by comparing two EMAs (eg. 12.period and 26.period). It consists of the MACD line, Signal line (9.period EMA of MACD), and Histogram. A MACD line crossing above the Signal line suggests a buy, while crossing below suggests a sell.'\r\n\r\n static optionsOrder = ['fastPeriod', 'slowPeriod', 'signalPeriod'] as const\r\n static optionsLabels = { fastPeriod: 'Period', slowPeriod: 'Slow', signalPeriod: 'Signal' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n static calculatedValuesOrder = ['macd', 'signal', 'histogram'] as const\r\n static calculatedValuesLabels = { macd: 'MACD Line', signal: 'Signal', histogram: 'Histogram' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { MACDConfig, Options } from '../indicators/configs/macd'\r\nimport { ExponentialMovingAverage } from './ema'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n macd: number[]\r\n signal: number[]\r\n histogram: number[]\r\n}\r\n\r\nexport class MACDCalculation extends MainCalculation {\r\n static config = MACDConfig\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { close } = this.quote\r\n const { fastPeriod, slowPeriod, signalPeriod } = this.options\r\n\r\n if (close.length <= slowPeriod) return\r\n\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n const emaFast = new ExponentialMovingAverage(fastPeriod)\r\n const emaSlow = new ExponentialMovingAverage(slowPeriod)\r\n const emaSignal = new ExponentialMovingAverage(signalPeriod)\r\n let macdCount = 0\r\n\r\n for (let i = 0; i < close.length; i++) {\r\n const d = close[i]\r\n\r\n emaFast.add(d)\r\n emaSlow.add(d)\r\n\r\n if (i < slowPeriod - 1) continue\r\n\r\n const macd = emaFast.value - emaSlow.value\r\n emaSignal.add(macd)\r\n this.calculatedValues.macd[i] = macd\r\n macdCount += 1\r\n\r\n if (macdCount < signalPeriod) continue\r\n\r\n this.calculatedValues.signal[i] = emaSignal.value\r\n this.calculatedValues.histogram[i] = macd - emaSignal.value\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { MACDCalculation } from '../indicator-calculation/macd'\r\nimport { getBarWidthWithMarginByParts } from '../utils/chart'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport { Attrs, MACDConfig } from './configs/macd'\r\nimport Indicator from './indicator'\r\n\r\nclass MACD extends Indicator {\r\n static config = MACDConfig\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [fastPeriod = 0, slowPeriod = 0, signalPeriod = 0] = getParsedIntegersFromPeriodString(period)\r\n return Math.max(fastPeriod, slowPeriod, signalPeriod)\r\n }\r\n\r\n macdCalculation: MACDCalculation | null = null\r\n\r\n declare fastPeriod: number\r\n declare slowPeriod: number\r\n declare signalPeriod: number\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [fastPeriod = 0, slowPeriod = 0, signalPeriod = 0] = getParsedIntegersFromPeriodString(this.attrs.period)\r\n super.set({ ...values, fastPeriod, slowPeriod, signalPeriod })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary() || this.macdCalculation === null) {\r\n this.macdCalculation = new MACDCalculation({\r\n quote: this.data,\r\n options: {\r\n signalPeriod: this.signalPeriod,\r\n fastPeriod: this.fastPeriod,\r\n slowPeriod: this.slowPeriod,\r\n },\r\n })\r\n this.macdCalculation.calculate()\r\n\r\n this.lastValue = this.macdCalculation.calculatedValues.macd.last() ?? null\r\n }\r\n\r\n const { macd, histogram, signal } = this.macdCalculation.calculatedValues\r\n\r\n const { min, max } =\r\n macd.length > 0 || signal.length > 0 || histogram.length > 0\r\n ? this.computeVisibleMinMax(macd, signal, histogram)\r\n : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getLineColors() {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n return {\r\n histogram: '#79c3e8',\r\n macd: IndicatorSettings.general.Colors.line,\r\n signal: IndicatorSettings.general.Colors.signalLine,\r\n }\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n if (this.macdCalculation === null || this.data.close.length === 0) return []\r\n\r\n const lineColors = this.getLineColors()\r\n const { macd, histogram, signal } = this.macdCalculation.calculatedValues\r\n const dataIndex = this.data.barToDataIndex[index]\r\n return [\r\n { color: lineColors.histogram, text: this.getValueLabel(histogram[dataIndex]) },\r\n { color: lineColors.macd, text: this.getValueLabel(macd[dataIndex]) },\r\n { color: lineColors.signal, text: this.getValueLabel(signal[dataIndex]) },\r\n ]\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (this.macdCalculation === null || this.data.close.length === 0) return\r\n const lineColors = this.getLineColors()\r\n const y = Math.round(this.fy(0))\r\n const chartModel = this.model.chart()\r\n const { zoomFactor } = chartModel\r\n const { barFillWidth, barBorderWidth } = getBarWidthWithMarginByParts({\r\n zoomFactor,\r\n chartLayout: chartModel.chart_layout(),\r\n })\r\n const barWidthWithoutMargin = barFillWidth + barBorderWidth * 2\r\n const halfBarWidth = ~~Math.max(1, barWidthWithoutMargin / 2)\r\n const { macd, histogram, signal } = this.macdCalculation.calculatedValues\r\n const drawInVisibleAreaProps = {\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n }\r\n\r\n context.set('fillStyle', lineColors.histogram)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.rect(x - halfBarWidth, y, barWidthWithoutMargin, Math.round(this.fy(histogram[i]) - y))\r\n },\r\n })\r\n context.fill()\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', lineColors.macd)\r\n context.beginPath()\r\n\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(macd[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n context.set('strokeStyle', lineColors.signal)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(signal[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n fastPeriod: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'fastPeriod',\r\n value: this.fastPeriod ?? 12,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n slowPeriod: {\r\n type: 'number',\r\n label: 'Slow',\r\n name: 'slowPeriod',\r\n value: this.slowPeriod ?? 26,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n signalPeriod: {\r\n type: 'number',\r\n label: 'Signal',\r\n name: 'signalPeriod',\r\n value: this.signalPeriod ?? 9,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: MACDConfig.label,\r\n inputs: MACDConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n fastPeriod: `${options.fastPeriod.label} must be a whole number between ${options.fastPeriod.min} and ${options.fastPeriod.max}`,\r\n slowPeriod: `${options.slowPeriod.label} must be a whole number between ${options.slowPeriod.min} and ${options.slowPeriod.max}`,\r\n signalPeriod: `${options.signalPeriod.label} must be a whole number between ${options.signalPeriod.min} and ${options.signalPeriod.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'fastPeriod':\r\n case 'slowPeriod':\r\n case 'signalPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default MACD\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class MFIConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Mfi\r\n static abbreviation = 'mfi'\r\n static label = 'Money Flow Index'\r\n static shortLabel = 'MFI'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import { Attrs, MFIConfig } from './configs/mfi'\r\nimport Indicator from './indicator'\r\n\r\nclass MFI extends Indicator {\r\n static config = MFIConfig\r\n\r\n mfi: number[] = []\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary()) return\r\n\r\n let negativeMoneyFlow\r\n const mf = []\r\n this.mfi = []\r\n let prevTypicalPrice = (this.data.close[0] + this.data.low[0] + this.data.high[0]) / 3\r\n let positiveMoneyFlow = (negativeMoneyFlow = 0)\r\n for (let i = 1; i < this.data.close.length; i++) {\r\n const typicalPrice = (this.data.close[i] + this.data.low[i] + this.data.high[i]) / 3\r\n const moneyFlow = typicalPrice * this.data.volume[i]\r\n\r\n if (typicalPrice > prevTypicalPrice) {\r\n positiveMoneyFlow += moneyFlow\r\n mf[i] = moneyFlow\r\n } else if (typicalPrice < prevTypicalPrice) {\r\n negativeMoneyFlow += moneyFlow\r\n mf[i] = -moneyFlow\r\n }\r\n\r\n if (i > this.period) {\r\n const oldMF = mf[i - this.period]\r\n if (oldMF > 0) {\r\n positiveMoneyFlow -= oldMF\r\n } else if (oldMF < 0) {\r\n negativeMoneyFlow += oldMF\r\n }\r\n\r\n if (positiveMoneyFlow + negativeMoneyFlow > 0) {\r\n this.mfi[i] = (positiveMoneyFlow * 100) / (positiveMoneyFlow + negativeMoneyFlow)\r\n } else {\r\n this.mfi[i] = 50\r\n }\r\n }\r\n\r\n prevTypicalPrice = typicalPrice\r\n }\r\n\r\n this.lastValue = this.mfi.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n return this.getOversoldOverboughtValueLabelsAtIndex(index, this.mfi)\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.mfi, this.period, 20, 50, 80)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: MFIConfig.label,\r\n inputs: MFIConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default MFI\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport class NoneConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.None\r\n static abbreviation = 'none'\r\n static label = 'None'\r\n static shortLabel = 'None'\r\n}\r\n","import { NoneConfig } from './configs/none'\r\nimport Indicator from './indicator'\r\n\r\nclass None extends Indicator {\r\n static config = NoneConfig\r\n\r\n compute() {}\r\n\r\n renderIndicator() {}\r\n\r\n toString() {\r\n return ''\r\n }\r\n}\r\n\r\nexport default None\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport class OBVConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Obv\r\n static abbreviation = 'obv'\r\n static label = 'On-Balance Volume'\r\n static shortLabel = 'OBV'\r\n}\r\n","import math from '../helpers/math'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { OBVConfig } from './configs/obv'\r\nimport Indicator from './indicator'\r\n\r\nclass OBV extends Indicator {\r\n static config = OBVConfig\r\n\r\n obv: number[] = []\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.obv = [0]\r\n\r\n for (let i = 1; i < this.data.volume.length; i++) {\r\n let currentObv = this.obv[i - 1]\r\n if (this.data.close[i] > this.data.close[i - 1]) {\r\n currentObv += this.data.volume[i]\r\n } else if (this.data.close[i] < this.data.close[i - 1]) {\r\n currentObv -= this.data.volume[i]\r\n }\r\n\r\n this.obv[i] = currentObv\r\n }\r\n\r\n this.lastValue = this.obv.last() ?? null\r\n }\r\n const { min, max } = this.obv.length > 0 ? this.computeVisibleMinMax(this.obv) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n const dataIndex = this.data.barToDataIndex[index]\r\n return [\r\n {\r\n color: this.getChartLayoutSettings().IndicatorSettings.general.Colors.line!,\r\n text: this.getValueLabel(this.obv[dataIndex]),\r\n },\r\n ]\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(this.obv[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n formatAxis(value: number) {\r\n return math.formatBigNumber(value, 2)\r\n }\r\n\r\n getModalConfig() {\r\n return {\r\n title: OBVConfig.label,\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n}\r\n\r\nexport default OBV\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: string\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n tickers?: string\r\n}\r\n\r\nexport class PerfConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Perf\r\n static abbreviation = 'perf'\r\n static label = 'Price Performance %'\r\n static shortLabel = 'PERF %'\r\n static optionsOrder = ['tickers'] as const\r\n static optionsLabels = { tickers: 'Tickers' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import * as d3 from 'd3'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\nimport Line from '../canvas/line'\r\nimport Text from '../canvas/text'\r\nimport {\r\n INDICATOR_LABEL_HEIGHT,\r\n MOBILE_VIEW_BREAKPOINT_WIDTH,\r\n OFFSET,\r\n PADDING,\r\n SpecificChartFunctionality,\r\n TextAlign,\r\n TextBaseline,\r\n} from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport { getSanitizedTicker } from '../utils'\r\nimport { getInstrument } from '../utils/chart'\r\nimport { getHEXWithSpecificAplha } from '../utils/colors'\r\nimport { getVisibleBarToRenderIndex } from '../utils/draw_in_visible_area'\r\nimport { Attrs, PerfConfig } from './configs/perf'\r\nimport Indicator from './indicator'\r\n\r\nconst DEFAULT_TICKERS = 'SPY,QQQ'\r\nconst NO_VALUE = ' - '\r\n\r\ntype PerfData = { lastValueIndex: number; values: Array }\r\nfunction getDefaultPerfData(): PerfData {\r\n return {\r\n lastValueIndex: 0,\r\n values: [],\r\n }\r\n}\r\n\r\nclass PricePerformance extends Indicator {\r\n static config = PerfConfig\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n timeframe: string\r\n tickers = ''\r\n ready = false\r\n perf: ObjectHash = {}\r\n quotes: ObjectHash = {} // this is used in getAllQuotes() in charts/app/models/chart.ts\r\n indicatorLabelWidth: ObjectHash = {}\r\n\r\n constructor(attrs: Attrs, model: Pane) {\r\n super(attrs, model)\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n\r\n this.timeframe = this.model.chart().timeframe\r\n this.fy = d3.scaleLinear().range([0, this.contentHeight])\r\n if (this.attrs.period && !this.tickers) {\r\n this.tickers = this.attrs.period\r\n }\r\n }\r\n\r\n async compute() {\r\n const data: ObjectHash = {}\r\n let hasCachedData = true\r\n this.getTickersAndTimeframe().forEach((quoteSettings) => {\r\n const quote = Quote.getFromCacheSync(quoteSettings)\r\n hasCachedData = hasCachedData && !!quote\r\n if (quote) {\r\n data[quoteSettings.ticker] = quote\r\n }\r\n })\r\n\r\n if (hasCachedData) {\r\n return this._compute(Object.keys(data), data)\r\n }\r\n\r\n const fetchedData = await Quote.getAll(this.getTickersAndTimeframe())\r\n if (fetchedData) {\r\n this._compute(Object.keys(fetchedData), fetchedData)\r\n this.trigger('change')\r\n }\r\n }\r\n\r\n _compute(tickers: string[], data: ObjectHash) {\r\n const { leftOffset } = this.model.chart()\r\n data[this.data.ticker] = this.data\r\n this.quotes = data\r\n this.perf = {}\r\n\r\n const firstVisibleBar = getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n leftOffset,\r\n paneModel: this.model,\r\n })\r\n const lastVisibleBar = getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n leftOffset,\r\n paneModel: this.model,\r\n chartWidth: this.contentWidth,\r\n })\r\n\r\n let min: number | null = null\r\n let max: number | null = null\r\n\r\n for (const ticker of [this.data.ticker, ...tickers]) {\r\n this.perf[ticker] = getDefaultPerfData()\r\n const d = data[ticker]\r\n const lastTickerTimestamp = d.date[d.date.length - 1]\r\n if (!d) {\r\n continue\r\n }\r\n const dateToIndex = d.getDateToIndex()\r\n let first = null\r\n let lastValue = null\r\n let dataIndex = -1\r\n for (let i = firstVisibleBar.barIndex; i <= lastVisibleBar.barIndex; i++) {\r\n const timestamp = this.data.getTimestampFomPositionX(i)\r\n dataIndex = dateToIndex[timestamp]\r\n\r\n if (typeof dataIndex === 'number') {\r\n first = first === null ? d.close[dataIndex] : first\r\n lastValue = (d.close[dataIndex] * 100) / (first ?? 0) - 100\r\n }\r\n\r\n this.perf[ticker].values[i] = null\r\n if (lastTickerTimestamp >= timestamp && lastValue !== null && !isNaN(lastValue)) {\r\n this.perf[ticker].values[i] = lastValue\r\n this.perf[ticker].lastValueIndex = i\r\n if (min === null || (lastValue !== null && min > lastValue)) min = lastValue\r\n if (max === null || (lastValue !== null && max < lastValue)) max = lastValue\r\n }\r\n }\r\n\r\n if (firstVisibleBar.barIndex > 0) {\r\n this.perf[ticker].values[firstVisibleBar.barIndex - 1] = this.perf[ticker].values[firstVisibleBar.barIndex]\r\n }\r\n if (lastVisibleBar.barIndex < this.data.barToDataIndex.length) {\r\n this.perf[ticker].values[lastVisibleBar.barIndex + 1] = this.perf[ticker].values[lastVisibleBar.barIndex]\r\n }\r\n }\r\n\r\n // > 2 because we need at least 2 bars to be able to calculate price perf and also we copy first visible bar value\r\n // to its index - 1 to ensure line is drawn from the very left edge of the chart\r\n // so first 2 values are the same and we need one more\r\n const canUseCustomMinMax = Object.values(this.perf).some(\r\n ({ values }) => values.filter((val) => typeof val === 'number').length > 2\r\n )\r\n const domainDefaults = this.getDomainDefaults(this.type)\r\n this.min = canUseCustomMinMax && min !== null ? min : domainDefaults.min\r\n this.max = canUseCustomMinMax && max !== null ? max : domainDefaults.max\r\n\r\n const fy = d3\r\n .scaleLinear()\r\n .range([0, this.contentHeight])\r\n .domain([this.model.scaleRange?.max ?? this.max, this.model.scaleRange?.min ?? this.min])\r\n if (!this.model.scaleRange) {\r\n fy.nice(10)\r\n }\r\n // @ts-expect-error - TODO scale.y types dont match\r\n this.model.scale.y = this.fy = fy\r\n this.ready = true\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (!this.ready) {\r\n return\r\n }\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(0)),\r\n y2: Math.round(this.fy(0)),\r\n strokeStyle: '#ff8787',\r\n dashLength: 3,\r\n },\r\n this.model\r\n ).render(context)\r\n\r\n context.translate(0.5, 0.5)\r\n\r\n const allTickers = [...this.getTickers(), this.data.ticker]\r\n\r\n allTickers.forEach((ticker) => {\r\n context.set('strokeStyle', this.getTickerColor(ticker))\r\n context.beginPath()\r\n this.perf[ticker].values.forEach((value, index) => {\r\n const y = value !== null ? Math.round(this.fy(value)) : null\r\n if (y !== null && !isNaN(y)) {\r\n context.lineTo(this.model.scale.x(index), y)\r\n }\r\n })\r\n context.stroke()\r\n })\r\n\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n renderCrossTextQuotePage(context: CanvasRenderingContext2D, crossIndex: number, hasBackground = true) {\r\n if (!context || isNaN(crossIndex) || !this.ready) {\r\n return\r\n }\r\n const { ChartSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const tickers = [this.data.ticker, ...this.getTickers()]\r\n tickers.forEach((key, index) => {\r\n const tickerValue = this.perf[key]?.values[crossIndex] ?? null\r\n const { margin, font, labelSpacing } = IndicatorSettings.left.indicatorLabel\r\n const textPosX = margin.left ?? 0\r\n const textPosY = (font.lineHeight! + labelSpacing) * (index + 1) + margin.top!\r\n\r\n const text = new Text(\r\n {\r\n text: `${key} ${tickerValue !== null ? `${tickerValue.toFixed(2)}%` : NO_VALUE}`,\r\n x: textPosX,\r\n y: textPosY,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.left.indicatorLabel.font),\r\n fillStyle: this.getTickerColor(key),\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.model\r\n )\r\n\r\n // Rendering background on server charts covers labels because of small spacing between them\r\n if (this.model.chart().chart_layout().specificChartFunctionality !== SpecificChartFunctionality.offScreen) {\r\n const measuredWidth = text.measure(context)\r\n const labelWidth = hasBackground ? Math.max(this.indicatorLabelWidth[key] ?? 0, measuredWidth) : measuredWidth\r\n this.indicatorLabelWidth[key] = labelWidth\r\n\r\n context.set('fillStyle', hasBackground ? Colors.canvasFill : getHEXWithSpecificAplha(Colors.canvasFill, 0.8))\r\n context.fillRect(\r\n textPosX! - PADDING.XXXS,\r\n textPosY - PADDING.XXXS,\r\n labelWidth + PADDING.XXXS * 2,\r\n font.size! + PADDING.XXXS * 2\r\n )\r\n }\r\n\r\n text.render(context)\r\n })\r\n }\r\n\r\n renderCrossTextChartsPage(context: CanvasRenderingContext2D, crossIndex: number) {\r\n if (!context || isNaN(crossIndex)) {\r\n return\r\n }\r\n\r\n const { ChartSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n let isVertical = true\r\n const labelBottom = IndicatorSettings.left.indicatorLabel.margin.top! + INDICATOR_LABEL_HEIGHT\r\n const tickers = [this.data.ticker, ...this.getTickers()]\r\n const tickerText = new Text(\r\n {\r\n font: Text.getMergedPropsWithDefaults('font', {\r\n ...IndicatorSettings.left.indicatorLabel.font,\r\n style: 'normal',\r\n }),\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.middle,\r\n background: getHEXWithSpecificAplha(Colors.canvasFill, 0.8),\r\n padding: { top: 0, bottom: 0, left: 5, right: 5 },\r\n },\r\n this.model\r\n )\r\n let x = IndicatorSettings.left.indicatorLabel.margin.left!\r\n let y =\r\n IndicatorSettings.left.indicatorLabel.margin.top! + (2 * INDICATOR_LABEL_HEIGHT - tickerText.attrs.lineHeight) / 2\r\n\r\n const maxHeight = tickerText.attrs.lineHeight * tickers.length\r\n\r\n const canFitItemsVertically = maxHeight + labelBottom <= this.height\r\n if (this.width <= MOBILE_VIEW_BREAKPOINT_WIDTH || !canFitItemsVertically) {\r\n isVertical = false\r\n x += x + this.labelWidth\r\n } else {\r\n y += IndicatorSettings.left.indicatorLabel.margin.top! + INDICATOR_LABEL_HEIGHT\r\n }\r\n\r\n tickers.forEach((key) => {\r\n const tickerValue = this.perf[key]?.values[crossIndex > -1 ? crossIndex : this.perf[key].lastValueIndex] ?? null\r\n tickerText.set({\r\n x,\r\n y,\r\n fillStyle: this.getTickerColor(key),\r\n text: `${key} ${tickerValue !== null ? `${tickerValue.toFixed(2)}%` : NO_VALUE}`,\r\n })\r\n const tickerTextWidth =\r\n tickerText.measure(context) + tickerText.attrs.padding.left + tickerText.attrs.padding.right\r\n if (\r\n !isVertical &&\r\n this.width - IndicatorSettings.left.indicatorLabel.margin.left! - IndicatorSettings.right.width! <=\r\n x + tickerTextWidth\r\n ) {\r\n x = 2 * IndicatorSettings.left.indicatorLabel.margin.left! + this.labelWidth\r\n y += tickerText.attrs.lineHeight\r\n tickerText.set({ x, y })\r\n }\r\n tickerText.render(context)\r\n\r\n if (isVertical) {\r\n y += tickerText.attrs.lineHeight\r\n } else {\r\n x += tickerTextWidth\r\n }\r\n })\r\n }\r\n\r\n getTickerColor(ticker: string) {\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n\r\n if (ticker === this.data.ticker) {\r\n return Colors.performanceIndicatorLabel\r\n }\r\n\r\n return ColorsSettings[this.getTickers().indexOf(ticker) % ColorsSettings.length]\r\n }\r\n\r\n renderXAxis(context: CanvasRenderingContext2D) {\r\n if (!this.ready) {\r\n return\r\n }\r\n return super.renderXAxis(context)\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n super.renderYAxis(context)\r\n const { IndicatorSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n if (!this.ready) {\r\n return\r\n }\r\n const translate = getTranslate({\r\n context,\r\n xOffset: IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n const { lineHeight, padding, size } = IndicatorSettings.right.axis.font\r\n const text = new Text(\r\n {\r\n x: this.contentWidth + OFFSET.M - padding!.left! + IndicatorSettings.right.axis.margin.left!,\r\n font: Text.getMergedPropsWithDefaults('font', { size }),\r\n lineHeight,\r\n padding: {\r\n left: padding!.left!,\r\n right: padding!.right!,\r\n top: padding!.top!,\r\n bottom: padding!.bottom!,\r\n },\r\n textBaseline: TextBaseline.middle,\r\n fillStyle: Colors.crossText,\r\n },\r\n this.model\r\n )\r\n const allTickers = [...this.getTickers(), this.data.ticker]\r\n\r\n const minY = 0\r\n const maxY = this.contentHeight\r\n allTickers.forEach((ticker) => {\r\n const lastValue = this.perf[ticker]?.values[this.perf[ticker]?.lastValueIndex] ?? null\r\n if (lastValue !== null) {\r\n const labelSetting = {\r\n text: `${lastValue.toFixed(2)}%`,\r\n y: Math.round(this.fy(lastValue)),\r\n background: this.getTickerColor(ticker),\r\n }\r\n if (labelSetting.y >= minY && labelSetting.y <= maxY) {\r\n text.set(labelSetting).render(context)\r\n }\r\n }\r\n })\r\n\r\n translate.undo()\r\n }\r\n\r\n renderLabelQuotePage(context: CanvasRenderingContext2D) {\r\n super.renderLabelQuotePage(context)\r\n this.renderCrossTextQuotePage(context, this.perf[this.data.ticker].lastValueIndex, false)\r\n }\r\n\r\n getTickers() {\r\n return this.tickers\r\n .split(',')\r\n .filter((ticker, i, arr) => ticker && ticker !== this.data.ticker && arr.indexOf(ticker) === i)\r\n }\r\n\r\n getTickersAndTimeframe() {\r\n const chartModel = this.model.chart()\r\n const chartLayoutModel = chartModel.chart_layout()\r\n const { timeframe, premarket, aftermarket, hasPatterns } = chartModel.quote()\r\n return this.getTickers().map((ticker) => ({\r\n ticker,\r\n instrument: getInstrument(ticker),\r\n timeframe,\r\n chartUuid: chartLayoutModel.uuid,\r\n canBeEmptyQuote: chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.offScreen,\r\n options: {\r\n premarket,\r\n aftermarket,\r\n patterns: hasPatterns,\r\n },\r\n }))\r\n }\r\n\r\n set(values: Partial) {\r\n super.set({ ...values, tickers: values.period || (values.tickers ? getSanitizedTicker(values.tickers, true) : '') })\r\n this.tickers = (this.tickers || '').toUpperCase()\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n tickers: {\r\n type: 'text',\r\n label: 'Tickers',\r\n name: 'tickers',\r\n value: !!this.tickers ? this.tickers : DEFAULT_TICKERS,\r\n required: true,\r\n },\r\n }\r\n\r\n return {\r\n title: PerfConfig.label,\r\n inputs: PerfConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n tickers: 'At least one ticker has to be provided',\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'tickers':\r\n return this[key].length > 0\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return this.getIsChartPageSpecificFunctionality() ? PerfConfig.shortLabel : super.toString()\r\n }\r\n}\r\n\r\nexport default PricePerformance\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number | string\r\n momentum: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class RMIConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Rmi\r\n static abbreviation = 'rmi'\r\n static label = 'Relative Momentum Index'\r\n static shortLabel = 'RMI'\r\n static optionsOrder = ['period', 'momentum'] as const\r\n static optionsLabels = { period: 'Period', momentum: 'Momentum' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport { Attrs, RMIConfig } from './configs/rmi'\r\nimport Indicator from './indicator'\r\n\r\nclass RMI extends Indicator {\r\n static config = RMIConfig\r\n\r\n rmi: number[] = []\r\n declare momentum: number\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period = 0, momentum = 0] = getParsedIntegersFromPeriodString(values.period)\r\n super.set({ ...values, period, momentum })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary()) return\r\n\r\n this.rmi = []\r\n let count = 0\r\n let sumu = 0\r\n let sumd = 0\r\n let u: number, d: number, ad: number, au: number\r\n for (let i = this.momentum; i < this.data.close.length; i++) {\r\n u = d = 0\r\n if (this.data.close[i] > this.data.close[i - this.momentum]) {\r\n u = this.data.close[i] - this.data.close[i - this.momentum]\r\n }\r\n if (this.data.close[i] < this.data.close[i - this.momentum]) {\r\n d = this.data.close[i - this.momentum] - this.data.close[i]\r\n }\r\n\r\n if (count < this.period) {\r\n sumu += u\r\n sumd += d\r\n count++\r\n au = sumu / count\r\n ad = sumd / count\r\n } else {\r\n au = (au! * (this.period - 1) + u) / this.period\r\n ad = (ad! * (this.period - 1) + d) / this.period\r\n }\r\n\r\n const rs = ad > 0 ? au / ad : 1\r\n this.rmi[i] = 100 - 100 * (1 / (1 + rs))\r\n }\r\n\r\n this.lastValue = this.rmi.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n return this.getOversoldOverboughtValueLabelsAtIndex(index, this.rmi)\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.rmi, this.momentum, 30, 50, 70)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 20,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n momentum: {\r\n type: 'number',\r\n label: 'Momentum',\r\n name: 'momentum',\r\n value: this.momentum ?? 5,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: RMIConfig.label,\r\n inputs: RMIConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n momentum: `${options.momentum.label} must be a whole number between ${options.momentum.min} and ${options.momentum.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n case 'momentum':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default RMI\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class ROCConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Roc\r\n static abbreviation = 'roc'\r\n static label = 'Rate of Change %'\r\n static shortLabel = 'ROC'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import Line from '../canvas/line'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { Attrs, ROCConfig } from './configs/roc'\r\nimport Indicator from './indicator'\r\n\r\nclass ROC extends Indicator {\r\n static config = ROCConfig\r\n\r\n roc: number[] = []\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.roc = []\r\n for (let i = this.period; i < this.data.close.length; i++) {\r\n this.roc[i] = ((this.data.close[i] - this.data.close[i - this.period]) / this.data.close[i - this.period]) * 100\r\n }\r\n\r\n this.lastValue = this.roc.last() ?? null\r\n }\r\n const { min, max } = this.roc.length > 0 ? this.computeVisibleMinMax(this.roc) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n const dataIndex = this.data.barToDataIndex[index]\r\n return [\r\n {\r\n color: this.getChartLayoutSettings().IndicatorSettings.general.Colors.line!,\r\n text: this.getValueLabel(this.roc[dataIndex]),\r\n },\r\n ]\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(0)),\r\n y2: Math.round(this.fy(0)),\r\n strokeStyle: '#ff8787',\r\n dashLength: 3,\r\n },\r\n this.model\r\n ).render(context)\r\n context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(this.roc[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 12,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: ROCConfig.label,\r\n inputs: ROCConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default ROC\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class RSIConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Rsi\r\n static abbreviation = 'rsi'\r\n static label = 'Relative Strength Index'\r\n static shortLabel = 'RSI'\r\n static description =\r\n 'The RSI indicator measures the speed and change of price movements on a scale of 0 to 100. Values above 70 indicate overbought conditions, while values below 30 suggest oversold conditions, potentially signaling a trend reversal.'\r\n\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n static calculatedValuesOrder = ['rsi'] as const\r\n static calculatedValuesLabels = { rsi: 'RSI' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { Attrs, RSIConfig } from '../indicators/configs/rsi'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n rsi: number[]\r\n}\r\n\r\nexport class RsiCalculation extends MainCalculation {\r\n static config = RSIConfig\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period } = this.options\r\n const { close } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n if (close.length <= period) return\r\n\r\n let sumu = 0\r\n let sumd = 0\r\n let u: number, d: number, ad: number, au: number\r\n for (let i = 1; i < close.length; i++) {\r\n u = d = 0\r\n if (close[i] > close[i - 1]) {\r\n u = close[i] - close[i - 1]\r\n }\r\n if (close[i] < close[i - 1]) {\r\n d = close[i - 1] - close[i]\r\n }\r\n\r\n if (i < period) {\r\n sumu += u\r\n sumd += d\r\n au = sumu / i\r\n ad = sumd / i\r\n continue\r\n }\r\n\r\n au = (au! * (period - 1) + u) / period\r\n ad = (ad! * (period - 1) + d) / period\r\n\r\n const rs = ad > 0 ? au / ad : 1\r\n this.calculatedValues.rsi[i] = 100 - 100 * (1 / (1 + rs))\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { RsiCalculation } from '../indicator-calculation/rsi'\r\nimport { Attrs, RSIConfig } from './configs/rsi'\r\nimport Indicator from './indicator'\r\n\r\nclass RSI extends Indicator {\r\n static config = RSIConfig\r\n\r\n rsiCalculation: RsiCalculation | null = null\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary() && this.rsiCalculation !== null) return\r\n\r\n this.rsiCalculation = new RsiCalculation({\r\n quote: this.data,\r\n options: { period: this.period },\r\n })\r\n\r\n this.rsiCalculation.calculate()\r\n\r\n this.lastValue = this.rsiCalculation.calculatedValues.rsi.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n return this.getOversoldOverboughtValueLabelsAtIndex(index, this.rsiCalculation?.calculatedValues.rsi ?? [])\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.rsiCalculation?.calculatedValues.rsi ?? [], this.period, 30, 50, 70)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: RSIConfig.label,\r\n inputs: RSIConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default RSI\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number | string\r\n baseLine: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class RVOLConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Rvol\r\n static abbreviation = 'rvol'\r\n static label = 'Relative Volume'\r\n static shortLabel = 'RVOL'\r\n static optionsOrder = ['period', 'baseLine'] as const\r\n static optionsLabels = { period: 'Period', baseLine: 'BaseLine' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import Line from '../canvas/line'\r\nimport { getBarWidthWithMarginByParts } from '../utils/chart'\r\nimport { getHEXWithSpecificAplha } from '../utils/colors'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { Attrs, RVOLConfig } from './configs/rvol'\r\nimport Indicator from './indicator'\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Period: 50,\r\n BaseLine: 1.0,\r\n}\r\n\r\nfunction parsePeriod(periodStr: string) {\r\n const values = periodStr.split(',')\r\n const period = parseInt(values[0]) || DEFAULT_PARAMETERS.Period\r\n const baseLine = parseFloat(values[1]) || DEFAULT_PARAMETERS.BaseLine\r\n\r\n return [period, baseLine]\r\n}\r\n\r\nclass RelativeVolume extends Indicator {\r\n static config = RVOLConfig\r\n\r\n rvol: number[] = []\r\n declare period: number\r\n declare baseLine: number\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period = 0, baseLine = 0] = parsePeriod(values.period)\r\n super.set({ ...values, period, baseLine })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.rvol = []\r\n\r\n let sum = 0\r\n for (let i = 0; i < this.period; i++) {\r\n sum += this.data.volume[i]\r\n }\r\n for (let i = this.period; i < this.data.volume.length; i++) {\r\n sum = sum - this.data.volume[i - this.period] + this.data.volume[i]\r\n this.rvol[i] = sum > 0 ? this.data.volume[i] / (sum / this.period) : 0\r\n }\r\n\r\n this.lastValue = this.rvol.last() ?? null\r\n }\r\n\r\n const { min, max } =\r\n this.rvol.length > 0\r\n ? this.computeVisibleMinMax([...this.rvol, this.baseLine])\r\n : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n const { Colors } = this.getChartLayoutSettings().ChartSettings.general\r\n const dataIndex = this.data.barToDataIndex[index]\r\n const value = this.rvol[dataIndex]\r\n return [\r\n { color: value < this.baseLine ? Colors.volumeTrendDown : Colors.volumeTrendUp, text: this.getValueLabel(value) },\r\n ]\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const chartModel = this.model.chart()\r\n const { zoomFactor } = chartModel\r\n const { barFillWidth, barBorderWidth } = getBarWidthWithMarginByParts({\r\n zoomFactor,\r\n chartLayout: chartModel.chart_layout(),\r\n })\r\n const barWidthWithoutMargin = barFillWidth + barBorderWidth * 2\r\n const halfBarWidth = ~~Math.max(1, barWidthWithoutMargin / 2)\r\n\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n fromIndexOffset: this.period + 1,\r\n drawBarCallback: (i, x) => {\r\n if (this.rvol[i] === undefined) return\r\n\r\n const baseLine = Math.round(this.fy(this.baseLine))\r\n const y = Math.round(this.fy(this.rvol[i]))\r\n\r\n context.fillStyle = this.rvol[i] < this.baseLine ? Colors.volumeTrendDown : Colors.volumeTrendUp\r\n context.fillRect(x - halfBarWidth, baseLine, barWidthWithoutMargin, y - baseLine)\r\n },\r\n })\r\n\r\n const baseLineY = this.fy(this.baseLine)\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(baseLineY),\r\n y2: Math.round(baseLineY),\r\n strokeStyle: getHEXWithSpecificAplha(Colors.zeroChange, 0.5),\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? DEFAULT_PARAMETERS.Period,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n baseLine: {\r\n type: 'number',\r\n label: 'Baseline',\r\n name: 'baseLine',\r\n value: this.baseLine ?? DEFAULT_PARAMETERS.BaseLine,\r\n required: true,\r\n step: 0.1,\r\n allowDecimal: true,\r\n min: 0,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: RVOLConfig.label,\r\n inputs: RVOLConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n baseLine: `${options.baseLine.label} must be a number between ${options.baseLine.min} and ${options.baseLine.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'baseLine':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `${super.toString()}, SMA`\r\n }\r\n}\r\n\r\nexport default RelativeVolume\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class RWIConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Rwi\r\n static abbreviation = 'rwi'\r\n static label = 'Random Walk Index'\r\n static shortLabel = 'RWI'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import Text from '../canvas/text'\r\nimport { OFFSET, PADDING, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport utils from '../utils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { Attrs, RWIConfig } from './configs/rwi'\r\nimport Indicator from './indicator'\r\n\r\nclass RWI extends Indicator {\r\n static config = RWIConfig\r\n\r\n tr: number[] = []\r\n atr: number[] = []\r\n rwiHi: number[] = []\r\n rwiLo: number[] = []\r\n declare period: number\r\n\r\n constructor(attrs: Attrs, model: Pane) {\r\n super(attrs, model)\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n }\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.tr = []\r\n this.atr = []\r\n this.rwiHi = []\r\n this.rwiLo = []\r\n let atr = 0\r\n\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n const tr = utils.max([\r\n this.data.high[i] - this.data.low[i],\r\n Math.abs(this.data.high[i] - this.data.close[i - 1]),\r\n Math.abs(this.data.low[i] - this.data.close[i - 1]),\r\n ])\r\n this.tr[i] = tr\r\n\r\n if (i < this.period) {\r\n atr += tr\r\n this.atr[i] = atr / (i + 1)\r\n if (i === this.period - 1) {\r\n atr /= this.period\r\n }\r\n } else {\r\n this.atr[i] = (this.atr[i - 1] * (this.period - 1) + tr) / this.period\r\n }\r\n }\r\n\r\n for (let i = this.period + 2; i < this.data.close.length; i++) {\r\n const h = this.data.high[i]\r\n const l = this.data.low[i]\r\n let trSum = this.tr[i - 1] + this.tr[i - 2]\r\n let count = 2\r\n let atrWeight = (trSum / count) * Math.sqrt(count)\r\n let maxHi = atrWeight > 0 ? (h - this.data.low[i - 1]) / atrWeight : -1\r\n let maxLo = atrWeight > 0 ? (this.data.high[i - 1] - l) / atrWeight : -1\r\n for (let j = i - 1; j > i - this.period + 1; j--) {\r\n trSum += this.tr[j - 2]\r\n count++\r\n atrWeight = (trSum / count) * Math.sqrt(count)\r\n if (atrWeight === 0) {\r\n continue\r\n }\r\n\r\n const hi = (h - this.data.low[j - 1]) / atrWeight\r\n if (hi > maxHi) {\r\n maxHi = hi\r\n }\r\n\r\n const lo = (this.data.high[j - 1] - l) / atrWeight\r\n if (lo > maxLo) {\r\n maxLo = lo\r\n }\r\n }\r\n this.rwiHi[i] = maxHi\r\n this.rwiLo[i] = maxLo\r\n }\r\n }\r\n const { min, max } =\r\n this.rwiHi.length > 0 || this.rwiLo.length > 0\r\n ? this.computeVisibleMinMax(this.rwiHi, this.rwiLo)\r\n : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getLineColors() {\r\n return {\r\n rwiLo: '#c80000',\r\n rwiHi: '#00a000',\r\n }\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n if (this.data.close.length === 0) return []\r\n\r\n const lineColors = this.getLineColors()\r\n const dataIndex = this.data?.barToDataIndex[index]\r\n return [\r\n { color: lineColors.rwiLo, text: this.getValueLabel(this.rwiLo[dataIndex]) },\r\n { color: lineColors.rwiHi, text: this.getValueLabel(this.rwiHi[dataIndex]) },\r\n ]\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (this.data.close.length === 0) return\r\n\r\n const drawInVisibleAreaProps = {\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n fromIndexOffset: this.period,\r\n }\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', '#c80000')\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(this.rwiLo[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n context.set('strokeStyle', '#00a000')\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(this.rwiHi[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n super.renderYAxis(context)\r\n const { IndicatorSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const translate = getTranslate({\r\n context,\r\n xOffset: IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n const text = new Text(\r\n {\r\n x: this.contentWidth + OFFSET.M - PADDING.XXS + IndicatorSettings.right.axis.margin.left!,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.right.axis.font),\r\n lineHeight: IndicatorSettings.right.axis.font.lineHeight,\r\n padding: {\r\n top: IndicatorSettings.right.axis.font?.padding?.top ?? PADDING.XXS,\r\n right: IndicatorSettings.right.axis.font?.padding?.right ?? PADDING.XXS,\r\n bottom: IndicatorSettings.right.axis.font?.padding?.bottom ?? PADDING.XXS,\r\n left: IndicatorSettings.right.axis.font?.padding?.left ?? PADDING.XXS,\r\n },\r\n textBaseline: TextBaseline.middle,\r\n fillStyle: Colors.indicatorCurrentText,\r\n },\r\n this.model\r\n )\r\n const textLabels = []\r\n if (this.rwiLo.length > 0) {\r\n textLabels.push({\r\n text: this.rwiLo.last()!.toFixed(2),\r\n y: Math.round(this.fy(this.rwiLo.last()!)),\r\n background: '#c80000',\r\n })\r\n }\r\n if (this.rwiHi.length > 0) {\r\n textLabels.push({\r\n text: this.rwiHi.last()!.toFixed(2),\r\n y: Math.round(this.fy(this.rwiHi.last()!)),\r\n background: '#00a000',\r\n })\r\n }\r\n\r\n const minY = 0\r\n const maxY = this.height - IndicatorSettings.bottom.height - IndicatorSettings.top.height\r\n textLabels.forEach((labelSetting) => {\r\n if (labelSetting.y >= minY && labelSetting.y <= maxY) {\r\n text.set(labelSetting).render(context)\r\n }\r\n })\r\n\r\n translate.undo()\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 9,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: RWIConfig.label,\r\n inputs: RWIConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default RWI\r\n","import { format } from 'date-fns'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\nimport { TIMEFRAME } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport { dateFromUnixTimestamp } from '../utils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\ntype ValuesType = Array<{\r\n isBeforeData: boolean\r\n timestamp: number\r\n value: number | null\r\n sourceIndex: number\r\n}>\r\n\r\nclass FinancialIndicator extends Indicator {\r\n values: ValuesType[] = []\r\n applyMinMaxPadding = true\r\n\r\n getComputedValuesAtDateIndex(_: number): ValuesType {\r\n throw Error('Implement getComputedValuesAtDateIndex method')\r\n }\r\n\r\n compute() {\r\n if (!isNaN(this.contentWidth) && this.isComputeNecessary()) {\r\n this.values = []\r\n\r\n if (this.data.financialAttachmentsData) {\r\n for (let i = 0; i < this.data.date.length; i++) {\r\n const computedValues = this.getComputedValuesAtDateIndex(i)\r\n this.values[i] = computedValues.length > 0 ? computedValues : (this.values[i - 1] ?? [])\r\n }\r\n }\r\n }\r\n\r\n this.lastValue = this.getLastValue()\r\n const { min, max } = this.computeVisibleMinMax()\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getLastValue() {\r\n return this.getValueAtDataIndex(this.values.length - 1)\r\n }\r\n\r\n computeVisibleMinMax() {\r\n return super.computeVisibleMinMax(this.values.map((values) => values[values.length - 1]?.value ?? Number.NaN))\r\n }\r\n\r\n getValueAtDataIndex(dataIndex: number) {\r\n const vals = this.values[dataIndex]\r\n const val = vals?.[(vals?.length ?? 0) - 1] ?? null\r\n return val?.value\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n const shouldShowDate = [TIMEFRAME.i1, TIMEFRAME.i2, TIMEFRAME.i3].includes(this.data.timeframe)\r\n const dataIndex = this.data.barToDataIndex[index]\r\n const values = this.values[dataIndex]\r\n if (!values) {\r\n return []\r\n }\r\n\r\n return values.map(({ timestamp, value, isBeforeData }) => {\r\n const valueLabel = this.getValueLabel(value)\r\n\r\n return {\r\n color: this.getChartLayoutSettings().IndicatorSettings.general.Colors.line!,\r\n text:\r\n valueLabel !== null\r\n ? `${valueLabel} ${\r\n values.length >= 2 || isBeforeData || shouldShowDate\r\n ? `(${format(dateFromUnixTimestamp(timestamp), 'MMM dd')})`\r\n : ''\r\n }`\r\n : null,\r\n }\r\n })\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n const translate = getTranslate({ context, xOffset: 0.5, yOffset: 0.5 })\r\n translate.do()\r\n context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n const val = this.getValueAtDataIndex(i)\r\n context.lineTo(x, Math.round(this.fy(val!)))\r\n },\r\n })\r\n context.stroke()\r\n translate.undo()\r\n }\r\n\r\n formatAxis(value: number) {\r\n return this.getValueLabel(value) ?? value.toString()\r\n }\r\n}\r\n\r\nexport default FinancialIndicator\r\n","import { QuoteFinancialAttachment } from '../constants/common'\r\nimport { ShrtflConfig } from './configs/shrtfl'\r\nimport FinancialIndicator from './financialIndicator'\r\n\r\nclass Shrtfl extends FinancialIndicator {\r\n static config = ShrtflConfig\r\n\r\n getComputedValuesAtDateIndex(dateIndex: number) {\r\n const { timestampToFinancialsIndexesMap, alignedFinancialAttachmentsData } = this.data\r\n const timestampKey = this.data.date[dateIndex]?.toString() ?? ''\r\n const sourceIndexes = timestampToFinancialsIndexesMap[QuoteFinancialAttachment.shortInterest]?.[timestampKey] ?? []\r\n const alignedData = alignedFinancialAttachmentsData[QuoteFinancialAttachment.shortInterest] ?? []\r\n let isBeforeData = false\r\n\r\n if (sourceIndexes.length === 0 && dateIndex === 0) {\r\n const lastBeforeDateFinancialsDataIndex = alignedData.findLastIndex(\r\n ({ timestamp }) => timestamp < this.data.date[dateIndex]\r\n )\r\n if (lastBeforeDateFinancialsDataIndex >= 0) {\r\n sourceIndexes.push(lastBeforeDateFinancialsDataIndex)\r\n isBeforeData = true\r\n }\r\n }\r\n\r\n return sourceIndexes.map((si) => {\r\n const { timestamp, shortInterest, sharesFloat } = alignedData[si]\r\n let value: number | null = null\r\n if (shortInterest !== null && sharesFloat !== null) {\r\n value = (shortInterest / sharesFloat) * 100\r\n }\r\n\r\n return {\r\n isBeforeData,\r\n timestamp,\r\n value,\r\n sourceIndex: si,\r\n }\r\n })\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D, options: { lastValueSuffix?: string } = {}) {\r\n return super.renderYAxis(context, { ...options, lastValueSuffix: '%' })\r\n }\r\n\r\n getValueLabel(value: number | null | undefined) {\r\n return super.getValueLabel(value, '%')\r\n }\r\n\r\n getIsValid(): boolean {\r\n return true\r\n }\r\n}\r\n\r\nexport default Shrtfl\r\n","import { QuoteFinancialAttachment } from '../constants/common'\r\nimport { ShrtraConfig } from './configs/shrtra'\r\nimport FinancialIndicator from './financialIndicator'\r\n\r\nclass Shrtra extends FinancialIndicator {\r\n static config = ShrtraConfig\r\n\r\n getComputedValuesAtDateIndex(dateIndex: number) {\r\n const { timestampToFinancialsIndexesMap, alignedFinancialAttachmentsData } = this.data\r\n const timestampKey = this.data.date[dateIndex]?.toString() ?? ''\r\n const sourceIndexes = timestampToFinancialsIndexesMap[QuoteFinancialAttachment.shortInterest]?.[timestampKey] ?? []\r\n const alignedData = alignedFinancialAttachmentsData[QuoteFinancialAttachment.shortInterest] ?? []\r\n let isBeforeData = false\r\n\r\n if (sourceIndexes.length === 0 && dateIndex === 0) {\r\n const lastBeforeDateFinancialsDataIndex = alignedData.findLastIndex(\r\n ({ timestamp }) => timestamp < this.data.date[dateIndex]\r\n )\r\n if (lastBeforeDateFinancialsDataIndex >= 0) {\r\n sourceIndexes.push(lastBeforeDateFinancialsDataIndex)\r\n isBeforeData = true\r\n }\r\n }\r\n\r\n return sourceIndexes.map((si) => {\r\n const { timestamp, shortInterest, averageVolume } = alignedData[si]\r\n let value: number | null = null\r\n if (shortInterest !== null && averageVolume !== null) {\r\n value = (shortInterest / averageVolume) * 1_000_000\r\n }\r\n\r\n return {\r\n isBeforeData,\r\n timestamp,\r\n value,\r\n sourceIndex: si,\r\n }\r\n })\r\n }\r\n\r\n getIsValid(): boolean {\r\n return true\r\n }\r\n}\r\n\r\nexport default Shrtra\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: string | number\r\n dPeriod: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n kPeriod: number\r\n}\r\n\r\nexport class StofaConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Stofa\r\n static abbreviation = 'stofa'\r\n static label = 'Stochastics FAST'\r\n static shortLabel = 'Stochastics FAST'\r\n static optionsOrder = ['period', 'dPeriod']\r\n\r\n static optionsLabels = { period: 'Period', dPeriod: 'D Period' }\r\n\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: string | number\r\n dPeriod: number\r\n kPeriod: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class StofuConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Stofu\r\n static abbreviation = 'stofu'\r\n static label = 'Stochastics FULL'\r\n static shortLabel = 'Stochastics FULL'\r\n static optionsOrder = ['period', 'dPeriod', 'kPeriod']\r\n\r\n static optionsLabels = { period: 'Period', kPeriod: 'K Period', dPeriod: 'D Period' } as { [key: string]: string }\r\n\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import Line from '../canvas/line'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport { Attrs, StofuConfig } from './configs/stofu'\r\nimport Indicator from './indicator'\r\n\r\nclass Stochastics extends Indicator {\r\n static config = StofuConfig\r\n\r\n k: number[] = []\r\n k1: number[] = []\r\n d: number[] = []\r\n declare kPeriod: number\r\n declare period: number\r\n declare dPeriod: number\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period = 0, kPeriod = 0, dPeriod = 0] = getParsedIntegersFromPeriodString(values.period)\r\n super.set({ ...values, period, dPeriod, kPeriod })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary()) return\r\n\r\n const period = Math.min(this.period, this.data.close.length - 1)\r\n let dCount, dSum, k\r\n this.k1 = []\r\n this.k = []\r\n this.d = []\r\n let kSum = (dSum = 0)\r\n let kCount = (dCount = 0)\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n let highestHigh = this.data.high[i]\r\n let lowestLow = this.data.low[i]\r\n\r\n for (let j = i - period + 1; j <= i; j++) {\r\n if (this.data.high[j] > highestHigh) {\r\n highestHigh = this.data.high[j]\r\n }\r\n if (this.data.low[j] < lowestLow) {\r\n lowestLow = this.data.low[j]\r\n }\r\n }\r\n\r\n k = ((this.data.close[i] - lowestLow) / (highestHigh - lowestLow)) * 100\r\n if (highestHigh === lowestLow) {\r\n k = 100\r\n }\r\n this.k1[i] = k\r\n if (this.kPeriod > 1) {\r\n kSum += k\r\n kCount++\r\n if (kCount > this.kPeriod) {\r\n kSum -= this.k1[i - this.kPeriod]\r\n kCount--\r\n }\r\n k = kSum / kCount\r\n }\r\n\r\n dSum += k\r\n dCount++\r\n if (dCount > this.dPeriod) {\r\n dSum -= this.k[i - this.dPeriod]\r\n dCount--\r\n }\r\n\r\n const d = dSum / dCount\r\n this.k[i] = k\r\n this.d[i] = d\r\n }\r\n\r\n this.lastValue = this.k.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getLineColors() {\r\n return {\r\n k: this.getChartLayoutSettings().IndicatorSettings.general.Colors.line,\r\n d: '#c80000',\r\n }\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n const lineColors = this.getLineColors()\r\n const dataIndex = this.data.barToDataIndex[index]\r\n return [\r\n { color: lineColors.k, text: this.getValueLabel(this.k[dataIndex]) },\r\n { color: lineColors.d, text: this.getValueLabel(this.d[dataIndex]) },\r\n ]\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (this.data.close.length === 0) return\r\n\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(50)),\r\n y2: Math.round(this.fy(50)),\r\n strokeStyle: '#ff8787',\r\n dashLength: 3,\r\n },\r\n this.model\r\n ).render(context)\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(20)),\r\n y2: Math.round(this.fy(20)),\r\n strokeStyle: '#69c1ea',\r\n },\r\n this.model\r\n ).render(context)\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(80)),\r\n y2: Math.round(this.fy(80)),\r\n strokeStyle: '#d386df',\r\n },\r\n this.model\r\n ).render(context)\r\n\r\n const lineColors = this.getLineColors()\r\n context.set('strokeStyle', lineColors.k)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n const drawInVisibleAreaProps = {\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n fromIndexOffset: this.period,\r\n }\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.k[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n context.set('strokeStyle', lineColors.d)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.d[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n kPeriod: {\r\n type: 'number',\r\n label: 'K Period',\r\n name: 'kPeriod',\r\n value: this.kPeriod ?? 3,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n dPeriod: {\r\n type: 'number',\r\n label: 'D Period',\r\n name: 'dPeriod',\r\n value: this.dPeriod ?? 3,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: StofuConfig.label,\r\n inputs: StofuConfig.inputsOrder.map((item) => options[item as keyof Attrs]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n dPeriod: `${options.dPeriod.label} must be a whole number between ${options.dPeriod.min} and ${options.dPeriod.max}`,\r\n kPeriod: `${options.kPeriod.label} must be a whole number between ${options.kPeriod.min} and ${options.kPeriod.max}`,\r\n } as {\r\n period: string\r\n dPeriod: string\r\n kPeriod?: string\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n case 'dPeriod':\r\n case 'kPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default Stochastics\r\n","import Pane from '../models/pane'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport { Attrs, Options, StofaConfig } from './configs/stofa'\r\nimport Stochastics from './stofu'\r\n\r\nclass StochasticsFast extends Stochastics {\r\n static config = StofaConfig\r\n\r\n declare kPeriod: number\r\n declare period: number\r\n declare dPeriod: number\r\n\r\n constructor(attrs: Attrs, model: Pane) {\r\n super(attrs, model)\r\n this.kPeriod = 1\r\n }\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period = 0, dPeriod = 0] = getParsedIntegersFromPeriodString(values.period)\r\n super.set({ ...values, period, dPeriod, kPeriod: 1 })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n dPeriod: {\r\n type: 'number',\r\n label: 'D Period',\r\n name: 'dPeriod',\r\n value: this.dPeriod ?? 3,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: StofaConfig.label,\r\n inputs: StofaConfig.inputsOrder.map((item) => options[item as keyof Options]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n dPeriod: `${options.dPeriod.label} must be a whole number between ${options.dPeriod.min} and ${options.dPeriod.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n case 'dPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default StochasticsFast\r\n","import { IndicatorType } from '../../constants/common'\r\nimport { StofaConfig } from './stofa'\r\n\r\nexport type Options = {\r\n period: string | number\r\n dPeriod: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n kPeriod: number\r\n}\r\n\r\nexport class StoslConfig extends StofaConfig {\r\n static type = IndicatorType.Stosl\r\n static abbreviation = 'stosl'\r\n static label = 'Stochastics SLOW'\r\n static shortLabel = 'Stochastics SLOW'\r\n}\r\n","import { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport { Attrs, Options, StoslConfig } from './configs/stosl'\r\nimport Stochastics from './stofu'\r\n\r\nclass StochasticsSlow extends Stochastics {\r\n static config = StoslConfig\r\n\r\n kPeriod = 3\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period = 0, dPeriod = 0] = getParsedIntegersFromPeriodString(values.period)\r\n super.set({ ...values, period, dPeriod, kPeriod: 3 })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n dPeriod: {\r\n type: 'number',\r\n label: 'D Period',\r\n name: 'dPeriod',\r\n value: this.dPeriod ?? 3,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: StoslConfig.label,\r\n inputs: StoslConfig.inputsOrder.map((item) => options[item as keyof Options]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n dPeriod: `${options.dPeriod.label} must be a whole number between ${options.dPeriod.min} and ${options.dPeriod.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n case 'dPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default StochasticsSlow\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class TRIXConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Trix\r\n static abbreviation = 'trix'\r\n static label = 'TRIX'\r\n static shortLabel = 'TRIX'\r\n static description =\r\n 'The TRIX indicator is a momentum oscillator that shows the percent rate of change of a triple.smoothed EMA. Positive TRIX values indicate upward momentum, while negative values suggest downward momentum, helping to identify trend reversals.'\r\n\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n static calculatedValuesOrder = ['trix'] as const\r\n static calculatedValuesLabels = { trix: 'TRIX' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { Attrs, TRIXConfig } from '../indicators/configs/trix'\r\nimport { ExponentialMovingAverage } from './ema'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n trix: number[]\r\n}\r\n\r\nexport class TrixCalculation extends MainCalculation {\r\n static config = TRIXConfig\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { close } = this.quote\r\n const { period } = this.options\r\n const trippleEmaPeriod = period * 3 - 2\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n if (close.length <= trippleEmaPeriod) return\r\n\r\n const ema1 = new ExponentialMovingAverage(period)\r\n const ema2 = new ExponentialMovingAverage(period)\r\n const ema3 = new ExponentialMovingAverage(period)\r\n\r\n let prev = 0\r\n let ema1Count = 0\r\n let ema2Count = 0\r\n let ema3Count = 0\r\n for (let index = 0; index < close.length; index++) {\r\n ema1.add(close[index])\r\n ema1Count += 1\r\n\r\n if (ema1Count < period) continue\r\n ema2.add(ema1.value)\r\n ema2Count += 1\r\n\r\n if (ema2Count < period) continue\r\n ema3.add(ema2.value)\r\n ema3Count += 1\r\n\r\n if (ema3Count < period) continue\r\n\r\n if (prev > 0) {\r\n this.calculatedValues.trix[index] = (ema3.value * 100) / prev - 100\r\n }\r\n prev = ema3.value\r\n\r\n if (onValueCalculated?.(this.calculatedValues, index) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import Line from '../canvas/line'\r\nimport { TrixCalculation } from '../indicator-calculation/trix'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { Attrs, TRIXConfig } from './configs/trix'\r\nimport Indicator from './indicator'\r\n\r\nclass Trix extends Indicator {\r\n static config = TRIXConfig\r\n\r\n trixCalculation: TrixCalculation | null = null\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.trixCalculation = new TrixCalculation({\r\n quote: this.data,\r\n options: {\r\n period: this.period,\r\n },\r\n })\r\n this.trixCalculation.calculate()\r\n this.lastValue = this.trixCalculation.calculatedValues.trix.last() ?? null\r\n }\r\n const trix = this.trixCalculation?.calculatedValues.trix ?? []\r\n const { min, max } = trix.length > 0 ? this.computeVisibleMinMax(trix) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(0)),\r\n y2: Math.round(this.fy(0)),\r\n strokeStyle: '#ff8787',\r\n dashLength: 3,\r\n },\r\n this.model\r\n ).render(context)\r\n context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n const value = this.trixCalculation?.calculatedValues.trix[i]\r\n if (value) context.lineTo(x, ~~this.fy(value))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n const dataIndex = this.data.barToDataIndex[index]\r\n return [\r\n {\r\n color: this.getChartLayoutSettings().IndicatorSettings.general.Colors.line!,\r\n text: this.getValueLabel(this.trixCalculation?.calculatedValues.trix[dataIndex]),\r\n },\r\n ]\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 9,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: TRIXConfig.label,\r\n inputs: TRIXConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default Trix\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period1: number\r\n period2: number\r\n period3: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n period: string\r\n}\r\n\r\nexport class UltConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Ult\r\n static abbreviation = 'ult'\r\n static label = 'Ultimate Oscillator'\r\n static shortLabel = 'ULT'\r\n static optionsOrder = ['period1', 'period2', 'period3'] as const\r\n static optionsLabels = {\r\n period1: 'Period 1',\r\n period2: 'Period 2',\r\n period3: 'Period 3',\r\n }\r\n\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport { Attrs, UltConfig } from './configs/ult'\r\nimport Indicator from './indicator'\r\n\r\nclass UltimateOscillator extends Indicator {\r\n static config = UltConfig\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [period1 = 0, period2 = 0, period3 = 0] = getParsedIntegersFromPeriodString(period)\r\n return Math.max(period1, period2, period3)\r\n }\r\n\r\n declare period1: number\r\n declare period2: number\r\n declare period3: number\r\n ult: number[] = []\r\n tr: number[] = []\r\n bp: number[] = []\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period1 = 0, period2 = 0, period3 = 0] = getParsedIntegersFromPeriodString(values.period)\r\n super.set({ ...values, period1, period2, period3 })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary()) return\r\n\r\n this.ult = []\r\n let bpSum2, bpSum3, count2, count3, trSum2, trSum3\r\n const tr = []\r\n const bp = []\r\n let bpSum1 = (bpSum2 = bpSum3 = 0)\r\n let trSum1 = (trSum2 = trSum3 = 0)\r\n let count1 = (count2 = count3 = 0)\r\n let avg2, avg3\r\n for (let i = 1; i < this.data.close.length; i++) {\r\n bp[i] = this.data.close[i] - Math.min(this.data.low[i], this.data.close[i - 1])\r\n tr[i] = Math.max(this.data.high[i], this.data.close[i - 1]) - Math.min(this.data.low[i], this.data.close[i - 1])\r\n\r\n bpSum1 += bp[i]\r\n trSum1 += tr[i]\r\n count1++\r\n if (count1 > this.period1) {\r\n bpSum1 -= bp[i - this.period1]\r\n trSum1 -= tr[i - this.period1]\r\n }\r\n\r\n bpSum2 += bp[i]\r\n trSum2 += tr[i]\r\n count2++\r\n if (count2 > this.period2) {\r\n bpSum2 -= bp[i - this.period2]\r\n trSum2 -= tr[i - this.period2]\r\n }\r\n\r\n bpSum3 += bp[i]\r\n trSum3 += tr[i]\r\n count3++\r\n if (count3 > this.period3) {\r\n bpSum3 -= bp[i - this.period3]\r\n trSum3 -= tr[i - this.period3]\r\n }\r\n\r\n let avg1 = (avg2 = avg3 = 0)\r\n if (trSum1 > 0) {\r\n avg1 = bpSum1 / trSum1\r\n }\r\n if (trSum2 > 0) {\r\n avg2 = bpSum2 / trSum2\r\n }\r\n if (trSum3 > 0) {\r\n avg3 = bpSum3 / trSum3\r\n }\r\n\r\n this.ult[i] = (100 * (4 * avg1 + 2 * avg2 + avg3)) / 7\r\n }\r\n\r\n this.lastValue = this.ult.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n return this.getOversoldOverboughtValueLabelsAtIndex(index, this.ult)\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.ult, 1, 30, 50, 70)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period1: {\r\n type: 'number',\r\n label: 'Period 1',\r\n name: 'period1',\r\n value: this.period1 ?? 7,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n period2: {\r\n type: 'number',\r\n label: 'Period 2',\r\n name: 'period2',\r\n value: this.period2 ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n period3: {\r\n type: 'number',\r\n label: 'Period 3',\r\n name: 'period3',\r\n value: this.period3 ?? 28,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: UltConfig.label,\r\n inputs: UltConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period1: `${options.period1.label} must be a whole number between ${options.period1.min} and ${options.period1.max}`,\r\n period2: `${options.period2.label} must be a whole number between ${options.period2.min} and ${options.period2.max}`,\r\n period3: `${options.period3.label} must be a whole number between ${options.period3.min} and ${options.period3.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period1':\r\n case 'period2':\r\n case 'period3':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default UltimateOscillator\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport class VolConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Vol\r\n static abbreviation = 'vol'\r\n static label = 'Volume'\r\n static shortLabel = 'Volume'\r\n}\r\n","import math from '../helpers/math'\r\nimport { getBarWidthWithMarginByParts } from '../utils/chart'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { VolConfig } from './configs/vol'\r\nimport Indicator from './indicator'\r\n\r\nclass Volume extends Indicator {\r\n static config = VolConfig\r\n\r\n compute() {\r\n const { min, max } =\r\n this.data.volume.length > 0 ? this.computeVisibleMinMax(this.data.volume) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n this.lastValue = this.data.volume.last() ?? null\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n const { Colors } = this.getChartLayoutSettings().ChartSettings.general\r\n const dataIndex = this.data.barToDataIndex[index]\r\n return [\r\n {\r\n color: this.data.close[dataIndex] < this.data.open[dataIndex] ? Colors.volumeTrendDown : Colors.volumeTrendUp,\r\n text: this.getValueLabel(this.data.volume[dataIndex]),\r\n },\r\n ]\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const chartModel = this.model.chart()\r\n const { zoomFactor } = chartModel\r\n const { barFillWidth, barBorderWidth } = getBarWidthWithMarginByParts({\r\n zoomFactor,\r\n chartLayout: chartModel.chart_layout(),\r\n })\r\n const barWidthWithoutMargin = barFillWidth + barBorderWidth * 2\r\n const halfBarWidth = ~~Math.max(1, barWidthWithoutMargin / 2)\r\n\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i, x) => {\r\n context.fillStyle = this.data.close[i] < this.data.open[i] ? Colors.volumeTrendDown : Colors.volumeTrendUp\r\n const y = Math.round(this.fy(this.data.volume[i]))\r\n context.fillRect(x - halfBarWidth, y, barWidthWithoutMargin, context.canvas.height - y)\r\n },\r\n })\r\n }\r\n\r\n formatAxis(value: number) {\r\n return math.formatBigNumber(value, 2)\r\n }\r\n\r\n getModalConfig() {\r\n return {\r\n title: VolConfig.label,\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n}\r\n\r\nexport default Volume\r\n","import { IndicatorType } from '../../constants/common'\r\nimport IndicatorBaseConfig from './indicatorBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport type Attrs = Options\r\n\r\nexport class WRConfig extends IndicatorBaseConfig {\r\n static type = IndicatorType.Wr\r\n static abbreviation = 'wr'\r\n static label = 'Williams %R'\r\n static shortLabel = 'W%R'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = this.optionsOrder\r\n static inputsLabels = this.optionsLabels\r\n}\r\n","import { Attrs, WRConfig } from './configs/wr'\r\nimport Indicator from './indicator'\r\n\r\nclass WilliamsR extends Indicator {\r\n static config = WRConfig\r\n\r\n declare period: number\r\n r: number[] = []\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.r = []\r\n for (let i = this.period; i < this.data.close.length; i++) {\r\n let highestHigh = this.data.high[i]\r\n let lowestLow = this.data.low[i]\r\n for (let j = i - this.period + 1; j <= i; j++) {\r\n if (this.data.high[j] > highestHigh) {\r\n highestHigh = this.data.high[j]\r\n }\r\n if (this.data.low[j] < lowestLow) {\r\n lowestLow = this.data.low[j]\r\n }\r\n }\r\n\r\n this.r[i] = 0\r\n if (highestHigh - lowestLow > 0) {\r\n this.r[i] = ((highestHigh - this.data.close[i]) / (highestHigh - lowestLow)) * -100\r\n }\r\n }\r\n\r\n this.lastValue = this.r.last() ?? null\r\n }\r\n const { min, max } = this.r.length > 0 ? this.computeVisibleMinMax(this.r) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n getValueLabelsAtIndex(index: number) {\r\n return this.getOversoldOverboughtValueLabelsAtIndex(index, this.r)\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.r, this.period, -80, -50, -20)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n }\r\n\r\n return {\r\n title: WRConfig.label,\r\n inputs: WRConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nexport default WilliamsR\r\n","import { IndicatorType } from '../constants/common'\r\nimport adx from './adx'\r\nimport aro from './aro'\r\nimport aroosc from './aroosc'\r\nimport atr from './atr'\r\nimport cci from './cci'\r\nimport cot from './cot'\r\nimport fi from './fi'\r\nimport indicator from './indicator'\r\nimport macd from './macd'\r\nimport mfi from './mfi'\r\nimport none from './none'\r\nimport obv from './obv'\r\nimport perf from './perf'\r\nimport rmi from './rmi'\r\nimport roc from './roc'\r\nimport rsi from './rsi'\r\nimport rvol from './rvol'\r\nimport rwi from './rwi'\r\nimport shrtfl from './shrtfl'\r\nimport shrtra from './shrtra'\r\nimport stofa from './stofa'\r\nimport stofu from './stofu'\r\nimport stosl from './stosl'\r\nimport trix from './trix'\r\nimport ult from './ult'\r\nimport vol from './vol'\r\nimport wr from './wr'\r\n\r\n// TODO check if this doesn't break saved charts\r\nexport const indicatorsByType = Object.freeze({\r\n [IndicatorType.Indicator]: indicator,\r\n [IndicatorType.None]: none,\r\n [IndicatorType.Adx]: adx,\r\n [IndicatorType.Aro]: aro,\r\n [IndicatorType.Aroosc]: aroosc,\r\n [IndicatorType.Atr]: atr,\r\n [IndicatorType.Cci]: cci,\r\n [IndicatorType.Cot]: cot,\r\n [IndicatorType.Fi]: fi,\r\n [IndicatorType.Macd]: macd,\r\n [IndicatorType.Mfi]: mfi,\r\n [IndicatorType.Obv]: obv,\r\n [IndicatorType.Perf]: perf,\r\n [IndicatorType.Rmi]: rmi,\r\n [IndicatorType.Roc]: roc,\r\n [IndicatorType.Rsi]: rsi,\r\n [IndicatorType.Rvol]: rvol,\r\n [IndicatorType.Rwi]: rwi,\r\n [IndicatorType.Stofa]: stofa,\r\n [IndicatorType.Stofu]: stofu,\r\n [IndicatorType.Stosl]: stosl,\r\n [IndicatorType.Trix]: trix,\r\n [IndicatorType.Ult]: ult,\r\n [IndicatorType.Vol]: vol,\r\n [IndicatorType.Wr]: wr,\r\n [IndicatorType.Shrtfl]: shrtfl,\r\n [IndicatorType.Shrtra]: shrtra,\r\n})\r\n\r\nexport const financialIndicators = Object.freeze([IndicatorType.Shrtfl, IndicatorType.Shrtra])\r\nexport const indicatorsWithoutPeriod = Object.freeze([IndicatorType.Obv, IndicatorType.Vol, ...financialIndicators])\r\n","export const publishModalAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"modals-publish\" */ './module-entry'),\r\n cacheKey: 'modals-publish',\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport * as React from 'react'\r\n\r\nimport { DefaultSpineEvents } from '../../types/shared'\r\nimport ElementModule from '../canvas/element'\r\nimport IndicatorModule from '../indicators/indicator'\r\nimport { useForceUpdate } from '../utils/force-update'\r\nimport { getJSONReplacerFunc } from '../utils/helpers'\r\n\r\ninterface UseModelStateOptions {\r\n watchProperties?: T extends null ? never[] : Array\r\n listenOnEvents?: string[]\r\n}\r\n\r\nconst getIsSpineObject = (value: any) =>\r\n [Spine.Model, Spine.Module, Spine.Collection].some((spineObject) => value instanceof spineObject)\r\n\r\nconst getWatchedPropValue = (\r\n watchedProp: Model[keyof Model] | ElementModule | IndicatorModule | undefined,\r\n model: Model | null\r\n) => {\r\n if (typeof watchedProp === 'function') {\r\n const value = watchedProp.call(model)\r\n\r\n if (value && !getIsSpineObject(value)) {\r\n throw Error('Watched prop should have a primitive value or a spine object')\r\n }\r\n\r\n if (typeof value?.all === 'function') {\r\n return value.all()\r\n }\r\n\r\n return value\r\n }\r\n\r\n if (typeof watchedProp === 'object') {\r\n const hasToObject = !!watchedProp && 'toObject' in watchedProp\r\n return JSON.stringify(hasToObject ? watchedProp.toObject() : watchedProp, getJSONReplacerFunc())\r\n }\r\n\r\n return watchedProp\r\n}\r\n\r\nconst getWatchedProps = (model: Model | null, props?: Array) =>\r\n props?.reduce(\r\n (acc, propKey) => ({\r\n ...acc,\r\n [propKey]: getWatchedPropValue(model?.[propKey], model),\r\n }),\r\n {} as Partial\r\n )\r\n\r\nconst getAreWatchedPropsEqual = (\r\n currentValue: Value,\r\n previousValue: Value\r\n) => {\r\n if (currentValue instanceof Spine.Model) {\r\n return currentValue.eql(previousValue)\r\n }\r\n\r\n return currentValue === previousValue\r\n}\r\n\r\nconst DEFAULT_SPINE_EVENTS = Object.values(DefaultSpineEvents)\r\n\r\nexport function useModelState(\r\n model: Model,\r\n options: UseModelStateOptions = {}\r\n) {\r\n const { watchProperties = [], listenOnEvents = DEFAULT_SPINE_EVENTS } = options\r\n const stringifiedOptions = JSON.stringify(options)\r\n const { forceUpdate } = useForceUpdate()\r\n const watchedPropertiesRef = React.useRef(getWatchedProps(model, watchProperties))\r\n\r\n React.useEffect(() => {\r\n const handleModelChange = () => {\r\n const hasChange = watchProperties.some((propKey) => {\r\n const currentValue = getWatchedPropValue(model?.[propKey], model)\r\n const previousValue = watchedPropertiesRef.current?.[propKey]\r\n\r\n if (Array.isArray(currentValue)) {\r\n return (\r\n !Array.isArray(previousValue) ||\r\n currentValue.length !== previousValue.length ||\r\n currentValue.some((record, index) => !getAreWatchedPropsEqual(record, previousValue[index]))\r\n )\r\n }\r\n\r\n return !getAreWatchedPropsEqual(currentValue, previousValue)\r\n })\r\n\r\n if (hasChange) {\r\n watchedPropertiesRef.current = getWatchedProps(model, watchProperties)\r\n forceUpdate()\r\n }\r\n }\r\n\r\n const spineEvents = listenOnEvents.join(' ')\r\n\r\n model?.bind(spineEvents, handleModelChange)\r\n\r\n forceUpdate()\r\n\r\n return () => {\r\n model?.unbind(spineEvents, handleModelChange)\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [model?.cid, stringifiedOptions, forceUpdate])\r\n\r\n return model\r\n}\r\n","import Spine, { Collection } from '@finviz/spine'\r\nimport omit from 'lodash.omit'\r\n\r\nimport {\r\n ChartConfigChartPane,\r\n CustomSpineEvents,\r\n Instrument,\r\n ObjectHash,\r\n TodoObjectHashAnyType,\r\n} from '../../types/shared'\r\nimport BaseChart from '../charts/base_chart'\r\nimport PerfChart from '../charts/perf_chart'\r\nimport {\r\n DateRangeType,\r\n IndicatorType,\r\n QuotePollingIntervalInMs,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n} from '../constants/common'\r\nimport { getCanvasElementByType } from '../helpers/get-canvas-element-by-type'\r\nimport IndicatorBaseConfig from '../indicators/configs/indicatorBaseConfig'\r\nimport COT from '../indicators/cot'\r\nimport PricePerformance from '../indicators/perf'\r\nimport Utils from '../utils'\r\nimport { IDividends, IEarnings, ISplit } from '../utils/chart-events-utils'\r\nimport ChartEventElement from './chart-event-element'\r\nimport { ChartPartToAttrsSyncMap, ChartSyncablePart } from './chart/contstants'\r\nimport ChartLayout from './chart_layout'\r\nimport Pane from './pane'\r\nimport Quote from './quote'\r\nimport { getChartLayoutSettings } from './settings'\r\n\r\nclass Chart extends Spine.Model {\r\n static initClass(paneModel: typeof Pane, quoteModel: typeof Quote, chartLayoutModel: typeof ChartLayout) {\r\n this.configure(\r\n 'Chart',\r\n 'width',\r\n 'height',\r\n 'timeframe',\r\n 'dateRange',\r\n 'scale',\r\n 'leftOffset',\r\n 'ticker',\r\n 'instrument',\r\n 'fx',\r\n 'fy',\r\n 'zoomFactor',\r\n 'refreshData',\r\n 'stretch',\r\n 'isHideDrawingsActive',\r\n 'isScrolled',\r\n 'firstBarClose',\r\n 'premarket',\r\n 'aftermarket',\r\n 'hasChartEvents'\r\n )\r\n this.hasMany('panes', paneModel)\r\n this.belongsTo('quote', quoteModel)\r\n this.belongsTo('chart_layout', chartLayoutModel)\r\n }\r\n\r\n declare stretch: boolean\r\n declare chart_layout_id: string\r\n declare chart_layout: () => ChartLayout\r\n declare quote_id: string\r\n declare quote: () => Quote\r\n declare panes: () => Collection\r\n declare refreshData: boolean | number\r\n declare dateRange: DateRangeType\r\n declare width: number\r\n declare height: number\r\n declare timeframe: TIMEFRAME\r\n declare leftOffset: number\r\n declare ticker: string\r\n declare instrument: Instrument\r\n declare fx: (x: number) => number\r\n declare fy: (x: number) => number\r\n declare zoomFactor: number\r\n declare isHideDrawingsActive: boolean\r\n declare isScrolled: boolean\r\n declare scale: ScaleType\r\n declare firstBarClose: number\r\n declare premarket: boolean\r\n declare aftermarket: boolean\r\n declare hasChartEvents: boolean\r\n\r\n getChartPane() {\r\n return this.panes()\r\n .all()\r\n .find((pane: Pane) =>\r\n pane\r\n .elements()\r\n .all()\r\n .some((el) => el.isChart())\r\n )\r\n }\r\n\r\n getChartElement() {\r\n for (const pane of this.panes().all()) {\r\n for (const el of pane.elements().all()) {\r\n if (el.isChart()) {\r\n return el\r\n }\r\n }\r\n }\r\n }\r\n\r\n getChartType() {\r\n return this.getChartElement()?.instance.type\r\n }\r\n\r\n getRefreshInterval() {\r\n let defaultRefreshInterval: number | null = null\r\n if (typeof this.refreshData === 'number') {\r\n defaultRefreshInterval = this.refreshData\r\n } else if (this.refreshData === true) {\r\n defaultRefreshInterval = QuotePollingIntervalInMs.Default\r\n }\r\n\r\n const isStock = this.instrument === Instrument.Stock\r\n const isPremium = window.FinvizSettings.hasUserPremium\r\n let customRefreshInterval = QuotePollingIntervalInMs.Elite\r\n if (!isPremium) {\r\n customRefreshInterval = QuotePollingIntervalInMs.Free\r\n } else if (isStock && !Utils.isStockFastRefreshAvailable()) {\r\n customRefreshInterval = QuotePollingIntervalInMs.EliteStocksReduced\r\n }\r\n\r\n return defaultRefreshInterval && Math.max(defaultRefreshInterval, customRefreshInterval)\r\n }\r\n\r\n toObject() {\r\n const panes = this.panes()\r\n .all()\r\n .map((pane) => pane.toObject())\r\n return {\r\n width: this.width,\r\n dateRange: this.dateRange,\r\n height: this.height,\r\n timeframe: this.timeframe,\r\n scale: this.scale,\r\n leftOffset: this.leftOffset,\r\n ticker: this.ticker,\r\n instrument: this.instrument,\r\n zoomFactor: this.zoomFactor,\r\n refreshData: this.refreshData,\r\n stretch: this.stretch,\r\n chartId: this.cid,\r\n panes,\r\n isHideDrawingsActive: this.isHideDrawingsActive,\r\n isScrolled: this.isScrolled,\r\n premarket: this.premarket,\r\n aftermarket: this.aftermarket,\r\n hasChartEvents: this.hasChartEvents,\r\n }\r\n }\r\n\r\n toConfig(omitKeys = [] as string[]) {\r\n const panes = this.panes()\r\n .all()\r\n .map((pane) => pane.toConfig(omitKeys))\r\n return omit(\r\n {\r\n width: this.width,\r\n height: this.height,\r\n timeframe: this.timeframe,\r\n scale: this.scale,\r\n leftOffset: this.leftOffset,\r\n ticker: this.ticker,\r\n instrument: this.instrument,\r\n zoomFactor: this.zoomFactor,\r\n refreshData: this.refreshData,\r\n stretch: this.stretch,\r\n chartId: this.cid,\r\n panes,\r\n isHideDrawingsActive: this.isHideDrawingsActive,\r\n isScrolled: this.isScrolled,\r\n premarket: this.premarket,\r\n aftermarket: this.aftermarket,\r\n hasChartEvents: this.hasChartEvents,\r\n },\r\n omitKeys\r\n )\r\n }\r\n\r\n destroyCascade(options?: TodoObjectHashAnyType) {\r\n this.panes()\r\n .all()\r\n .forEach((pane) => {\r\n pane.destroyCascade()\r\n })\r\n return this.destroy(options)\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.chart_layout())\r\n }\r\n\r\n getIsDisabled() {\r\n return this.quote()?.close.length === 0\r\n }\r\n\r\n getIsScrollable() {\r\n return this.chart_layout().scrollable\r\n }\r\n\r\n getAllPanes() {\r\n return this.panes().all()\r\n }\r\n\r\n getAllValidPanes() {\r\n const cotKeys = Object.keys(this.quote().COTs ?? {})\r\n return this.getAllPanes().filter((pane) => {\r\n const mainElement = pane.mainElement()\r\n if (mainElement?.instance.type === IndicatorType.Cot) {\r\n // Type of mainElement is `Element` but it can be an indicator too\r\n return cotKeys.includes((mainElement.instance as unknown as COT).attrs.code)\r\n }\r\n return true\r\n })\r\n }\r\n\r\n getAllElements() {\r\n return this.getAllPanes().flatMap((pane) => pane.getAllElements())\r\n }\r\n\r\n getAllQuotes(): Quote[] {\r\n const perfQuotes = this.getAllElements()\r\n .filter(({ instance }) => instance.type === IndicatorType.Perf)\r\n .flatMap(({ instance }) => Object.values((instance as unknown as PricePerformance).quotes))\r\n\r\n let quotePerfTickers: Quote[] = []\r\n if (this.chart_layout().specificChartFunctionality === SpecificChartFunctionality.quotePerf) {\r\n const perfChart = this.getChartElement()?.instance as PerfChart | undefined\r\n if (perfChart) {\r\n quotePerfTickers = Quote.select(\r\n (q: Quote) => perfChart.attrs.tickers.includes(q.ticker) && [TIMEFRAME.d, TIMEFRAME.m].includes(q.timeframe)\r\n )\r\n }\r\n }\r\n\r\n return [...perfQuotes, ...quotePerfTickers, this.quote()].filter(\r\n (quote, index, quotes) => quote && quotes.findIndex((q) => q?.id === quote.id) === index\r\n )\r\n }\r\n\r\n createPaneCascade(paneProperties: ChartConfigChartPane) {\r\n const paneModel = this.panes().create(paneProperties)\r\n\r\n paneProperties.elements?.forEach(({ zIndex, elementId, ...element }) => {\r\n const instance = getCanvasElementByType(element.type).fromObject(element, paneModel)\r\n paneModel.elements().create({ instance, zIndex, elementId })\r\n paneModel.chart().trigger(CustomSpineEvents.IndicatorsChange)\r\n })\r\n\r\n const chartOrIndicator = paneModel.getChartOrIndicatorElement()\r\n if (paneModel.mainElement()?.elementId !== chartOrIndicator?.elementId) {\r\n paneModel.updateAttributes({ mainElement: chartOrIndicator })\r\n }\r\n\r\n return paneModel\r\n }\r\n\r\n updateAttributesAndSync(value: T) {\r\n const attrsInSync = Object.entries(ChartPartToAttrsSyncMap)\r\n .filter(([key]) => this.getIsChartPartInSync(key as unknown as ChartSyncablePart))\r\n .flatMap(([_, modelAttr]) => modelAttr)\r\n this.updateAttributes(value)\r\n\r\n if (attrsInSync.length > 0) {\r\n this.chart_layout()\r\n .getAllCharts()\r\n .forEach((chartModel) => {\r\n if (this.eql(chartModel)) {\r\n return\r\n }\r\n const newAttrs: ObjectHash = {}\r\n attrsInSync.forEach((modelAttr) => {\r\n if (value.hasOwnProperty(modelAttr)) {\r\n newAttrs[modelAttr] = value[modelAttr]\r\n }\r\n })\r\n chartModel.updateAttributes(newAttrs)\r\n })\r\n }\r\n }\r\n\r\n setSyncChartParts(chartParts: ChartSyncablePart | ChartSyncablePart[], isInSync: boolean) {\r\n this.chart_layout().setSyncChartParts(chartParts, isInSync)\r\n }\r\n\r\n getIsChartPartInSync(chartPart: ChartSyncablePart) {\r\n return this.chart_layout().getIsChartPartInSync(chartPart)\r\n }\r\n\r\n getHasPatterns() {\r\n return this.getAllElements().some((element) => {\r\n if ('hasOverlay' in element.instance) {\r\n return (element.instance as BaseChart).hasOverlay?.('patterns')\r\n }\r\n\r\n return false\r\n })\r\n }\r\n\r\n getQuoteFinancialAttachments() {\r\n return this.getAllElements()\r\n .filter((el) => el.isFinancialIndicator())\r\n .flatMap(\r\n (indicatorElement) =>\r\n ((indicatorElement.instance as unknown as any).config as typeof IndicatorBaseConfig).quoteFinancialAttachments\r\n )\r\n .filter((quoteFinancialAttachment, index, arr) => arr.indexOf(quoteFinancialAttachment) === index)\r\n }\r\n\r\n getQuoteRawTicker(): string | null {\r\n return this.quote()?.getRawTicker() ?? null\r\n }\r\n\r\n setChartEvents(chartEvents?: Array, shouldClear = false) {\r\n const chartPane = this.getChartPane()\r\n if (!chartPane) {\r\n return\r\n }\r\n const allChartEvents = chartPane.chartEvents().all()\r\n if (shouldClear) {\r\n allChartEvents.forEach((chartEvent) => chartEvent.destroyCascade())\r\n }\r\n\r\n const events = shouldClear\r\n ? chartEvents\r\n : chartEvents?.filter((chartEvent) => !allChartEvents.some(({ elementId }) => chartEvent.elementId === elementId))\r\n\r\n events?.forEach(({ elementId, eventType, dateTimestamp }) => {\r\n const newChartEvent = chartPane.chartEvents().create({\r\n instance: getCanvasElementByType(eventType).fromObject({ positionTimestamps: { x: dateTimestamp } }, chartPane),\r\n elementId,\r\n })\r\n newChartEvent.instance.updateScales()\r\n })\r\n\r\n chartPane.updateChartEventsZIndexes()\r\n }\r\n}\r\n\r\nexport default Chart\r\n","/*\r\n * it converts it to numbered index and it causes problems later on\r\n * the reason it's not just numbered enum is that it when used in const below\r\n * */\r\nexport enum ChartSyncablePart {\r\n Crosshair = 'crosshair',\r\n Ticker = 'ticker',\r\n Timeframe = 'timeframe',\r\n}\r\n\r\nexport const ChartPartToAttrsSyncMap = {\r\n [ChartSyncablePart.Ticker]: ['ticker'],\r\n [ChartSyncablePart.Timeframe]: ['timeframe', 'dateRange'],\r\n}\r\n\r\nexport const ChartSyncableParts = [\r\n { value: ChartSyncablePart.Ticker, label: 'Ticker' },\r\n { value: ChartSyncablePart.Timeframe, label: 'Timeframe' },\r\n { value: ChartSyncablePart.Crosshair, label: 'Crosshair' },\r\n]\r\n","import Spine, { Collection } from '@finviz/spine'\r\nimport omit from 'lodash.omit'\r\n\r\nimport { IIdea, RootChartConfigObject, Theme, TodoObjectHashAnyType } from '../../types/shared'\r\nimport { ChartEditorEnum, IndicatorType, LayoutType, SpecificChartFunctionality } from '../constants/common'\r\nimport { DrawingSetting } from '../controllers/toolbar/interfaces'\r\nimport Indicator from '../indicators/indicator'\r\nimport { getIsSSr } from '../utils/helpers'\r\nimport Chart from './chart'\r\nimport ChartEventElement from './chart-event-element'\r\nimport { ChartSyncablePart } from './chart/contstants'\r\nimport { ISettings } from './chart_settings/interfaces'\r\nimport DrawingsInternalStore from './drawings-internal-store'\r\nimport Pane from './pane'\r\nimport { QuoteFetchType } from './quote/constants'\r\n\r\nclass ChartLayout extends Spine.Model {\r\n static initClass(chartModel: typeof Chart, drawingsInternalStoreModel: typeof DrawingsInternalStore) {\r\n this.configure(\r\n 'ChartLayout',\r\n 'layout',\r\n 'activeChart',\r\n 'activePane',\r\n 'activeChartEvent',\r\n 'width',\r\n 'height',\r\n 'editable',\r\n 'canChangeTicker',\r\n 'scrollable',\r\n 'initialScrollable',\r\n 'cross',\r\n 'editors',\r\n 'theme',\r\n 'settings',\r\n 'isWheelZoomEnabled',\r\n 'specificChartFunctionality',\r\n 'isLargeChart',\r\n 'isHideDrawingsActive',\r\n 'isPreserveDrawingsActive',\r\n 'isLockDrawingsActive',\r\n 'isDrawingModeContinuousActive',\r\n 'uuid',\r\n 'isTouchCrossActive',\r\n 'defaultZoomFactor',\r\n 'syncChartParts',\r\n 'isInit',\r\n 'willDestroy',\r\n 'idea'\r\n )\r\n this.hasMany('charts', chartModel)\r\n this.belongsTo('drawingsInternalStore', drawingsInternalStoreModel)\r\n }\r\n\r\n declare layout: LayoutType\r\n declare activeChart: Chart\r\n declare activePane?: Pane\r\n declare activeChartEvent?: ChartEventElement\r\n declare width: number\r\n declare height: number\r\n declare editable: boolean\r\n declare canChangeTicker: boolean\r\n declare scrollable: boolean\r\n declare readonly initialScrollable: boolean\r\n declare cross: boolean\r\n declare editors: ChartEditorEnum[]\r\n declare theme: Theme\r\n declare settings: ISettings\r\n declare isWheelZoomEnabled: boolean\r\n declare specificChartFunctionality: SpecificChartFunctionality\r\n declare isLargeChart?: boolean\r\n declare charts: () => Collection\r\n declare isHideDrawingsActive: boolean\r\n declare isPreserveDrawingsActive: boolean\r\n declare isLockDrawingsActive: boolean\r\n declare isDrawingModeContinuousActive: boolean\r\n declare uuid: string\r\n declare isTouchCrossActive?: boolean\r\n declare defaultZoomFactor: number\r\n declare syncChartParts: ChartSyncablePart[]\r\n declare idea?: IIdea\r\n declare isInit?: boolean\r\n declare willDestroy?: boolean\r\n declare drawingsInternalStore: () => DrawingsInternalStore\r\n\r\n constructor(...args: any[]) {\r\n super(...args)\r\n\r\n if (!getIsSSr()) {\r\n this.bind('update', (model: ChartLayout) => {\r\n if (!window.FinvizSettings.toolsState) {\r\n window.FinvizSettings.toolsState = {}\r\n }\r\n window.FinvizSettings.toolsState[DrawingSetting.PreserveDrawings] = model.isPreserveDrawingsActive\r\n })\r\n }\r\n }\r\n\r\n getPaneWithSelection() {\r\n for (const pane of this.getAllPanes()) {\r\n if (pane.selection) {\r\n return pane\r\n }\r\n }\r\n }\r\n\r\n toObject() {\r\n const charts = this.getAllCharts().map((chart) => chart.toObject())\r\n return {\r\n layout: this.layout,\r\n width: this.width,\r\n height: this.height,\r\n charts,\r\n isHideDrawingsActive: this.isHideDrawingsActive,\r\n isPreserveDrawingsActive: this.isPreserveDrawingsActive,\r\n }\r\n }\r\n\r\n toConfig = RootChartConfigObject>(omitKeys = [] as string[]): T {\r\n const charts = this.getAllCharts().map((chart) => chart.toConfig(omitKeys))\r\n return JSON.parse(\r\n JSON.stringify(\r\n omit(\r\n {\r\n ...this.settings.ChartSettings.center,\r\n layout: this.layout,\r\n width: this.width,\r\n height: this.height,\r\n charts,\r\n isHideDrawingsActive: this.isHideDrawingsActive,\r\n isPreserveDrawingsActive: this.isPreserveDrawingsActive,\r\n colors: this.settings.ChartSettings.general.Colors,\r\n specificChartFunctionality: this.specificChartFunctionality,\r\n editors: this.editors,\r\n editable: this.editable,\r\n scrollable: this.scrollable,\r\n theme: this.theme,\r\n newCharts: /\\bcharts\\b/.test(window.location.pathname),\r\n },\r\n omitKeys\r\n )\r\n )\r\n )\r\n }\r\n\r\n destroy(options?: TodoObjectHashAnyType) {\r\n this.updateAttribute('willDestroy', true)\r\n return super.destroy(options)\r\n }\r\n\r\n destroyCascade(options?: TodoObjectHashAnyType) {\r\n this.updateAttribute('willDestroy', true)\r\n this.getAllCharts().forEach((chart) => {\r\n chart.destroyCascade()\r\n })\r\n return this.destroy(options)\r\n }\r\n\r\n getAllCharts() {\r\n return this.charts().all()\r\n }\r\n\r\n getAllPanes() {\r\n return this.getAllCharts().flatMap((chart) => chart.getAllPanes())\r\n }\r\n\r\n getAllElements() {\r\n return this.getAllCharts().flatMap((chart) => chart.getAllElements())\r\n }\r\n\r\n setSyncChartParts(chartParts: ChartSyncablePart | ChartSyncablePart[], isInSync: boolean) {\r\n const chartPartsToSync = Array.isArray(chartParts) ? chartParts : [chartParts]\r\n\r\n const newSyncedChartParts = this.syncChartParts?.filter((chartPart) => !chartPartsToSync.includes(chartPart)) ?? []\r\n\r\n if (isInSync) {\r\n newSyncedChartParts.push(...chartPartsToSync)\r\n }\r\n\r\n this.updateAttributes({ syncChartParts: newSyncedChartParts })\r\n }\r\n\r\n getIsChartPartInSync(chartPart: ChartSyncablePart) {\r\n return !!this.syncChartParts?.includes(chartPart)\r\n }\r\n\r\n getIsIndicatorPresent(type: IndicatorType) {\r\n return !!this.charts()\r\n .first()\r\n ?.getAllElements()\r\n .some((element) => element.isIndicator() && (element.instance as unknown as Indicator).type === type)\r\n }\r\n\r\n getHTMLElementId() {\r\n return `chart-layout-${this.id}`\r\n }\r\n\r\n exitIdea() {\r\n this.updateAttribute('idea', undefined)\r\n this.getAllCharts().forEach((chart) => {\r\n // Change all idea quotes to non idea quotes and refetch because we don't need them anymore, but they may cause inconsistencies if they are in cache\r\n chart.getAllQuotes().forEach((quote) => {\r\n if (quote.ideaID) {\r\n quote.updateAttributes({ ideaID: undefined })\r\n quote.fetchData({ fetchType: QuoteFetchType.Refetch })\r\n }\r\n })\r\n\r\n chart.updateAttributes({ refreshData: true })\r\n })\r\n }\r\n\r\n isIdeaId(id: number | null = null) {\r\n return (this.idea?.id ?? null) === id\r\n }\r\n}\r\n\r\nexport default ChartLayout\r\n","import { ObjectHash, Theme } from '../../../types/shared'\r\nimport { IChartThemeColors, chartDarkTheme, chartLightTheme } from '../constants'\r\n\r\nfunction normalizeHexAlpha(hexString = '') {\r\n const hexValue = hexString.replace('#', '')\r\n if (hexValue.length === 6) {\r\n return `${hexString}FF`\r\n }\r\n return hexString\r\n}\r\n\r\nexport const getColorOverwrites = ({\r\n theme,\r\n colors,\r\n}: {\r\n theme: Theme\r\n colors: ObjectHash, Theme>\r\n}) => {\r\n const customColors = colors[theme]\r\n const customColorKeys = Object.keys(customColors) as Array>\r\n const defaultColors = theme === Theme.light ? chartLightTheme : chartDarkTheme\r\n\r\n return customColorKeys.reduce((acc, colorKey) => {\r\n const isDefaultOverWritten =\r\n normalizeHexAlpha(customColors[colorKey]).toLowerCase() !==\r\n normalizeHexAlpha(defaultColors[colorKey]).toLowerCase()\r\n\r\n return isDefaultOverWritten\r\n ? {\r\n ...acc,\r\n [colorKey]: customColors[colorKey],\r\n }\r\n : acc\r\n }, {})\r\n}\r\n","import tailwindColors from '../constants/colors'\r\nimport { getHEXWithSpecificAplha } from '../utils/colors'\r\n\r\nexport interface IChartThemeColors {\r\n aftermarketFade: string\r\n background: string\r\n borderDown: string\r\n borderUp: string\r\n canvasFill: string\r\n cross: string\r\n crossText: string\r\n crossTextBackground: string\r\n currentBackground: string\r\n currentText: string\r\n grid: string\r\n gridSecondary: string\r\n indicatorCurrentBackground: string\r\n indicatorCurrentText: string\r\n line: string\r\n marketDown: string\r\n marketUp: string\r\n negativeChange: string\r\n ohlcTrendDown: string\r\n ohlcTrendUp: string\r\n overlayTransparentBackground: string\r\n percentageZeroLineText: string\r\n performanceIndicatorLabel: string\r\n positiveChange: string\r\n premarketFade: string\r\n prevClose: string\r\n text: string\r\n textSecondary: string\r\n trendDown: string\r\n trendUp: string\r\n volumeTrendDown: string\r\n volumeTrendUp: string\r\n wickDown: string\r\n wickUp: string\r\n zeroChange: string\r\n}\r\n\r\nexport interface IIndicatorThemeColors {\r\n line: string\r\n signalLine: string\r\n}\r\n\r\nexport interface IElementThemeColors {\r\n line: string\r\n border: string\r\n textWithoutBackground: string\r\n}\r\n\r\ninterface IDarkerWickColors {\r\n borderUp: string\r\n wickUp: string\r\n borderDown: string\r\n wickDown: string\r\n}\r\n\r\nexport const chartLightTheme: IChartThemeColors = {\r\n aftermarketFade: '#FFFFFF99',\r\n background: '#008CFF0E',\r\n borderDown: '#000000FF',\r\n borderUp: '#000000FF',\r\n canvasFill: '#FFFFFFFF',\r\n cross: '#0000004C',\r\n crossText: '#fff',\r\n crossTextBackground: '#111',\r\n currentBackground: tailwindColors.brightYellow[100],\r\n currentText: tailwindColors.gray[800],\r\n grid: '#D2D2D2FF',\r\n gridSecondary: '#ECECEC',\r\n indicatorCurrentBackground: tailwindColors.gray[600],\r\n indicatorCurrentText: '#fff',\r\n line: '#1E6DC0FF',\r\n marketDown: tailwindColors.red[500],\r\n marketUp: tailwindColors.green[500],\r\n negativeChange: '#C80000FF',\r\n ohlcTrendDown: '#E54040FF',\r\n ohlcTrendUp: '#40A140FF',\r\n overlayTransparentBackground: getHEXWithSpecificAplha('#C9CCD6', 0.25),\r\n percentageZeroLineText: '#111',\r\n performanceIndicatorLabel: tailwindColors.gray[600],\r\n positiveChange: '#009600FF',\r\n premarketFade: '#FFFFFF99',\r\n prevClose: '#C80000FF',\r\n text: '#828282',\r\n textSecondary: '#dedede',\r\n trendDown: '#FF0000FF',\r\n trendUp: '#00FF00FF',\r\n volumeTrendDown: '#ffc0c0',\r\n volumeTrendUp: '#a8e0a8',\r\n wickDown: '#000000FF',\r\n wickUp: '#000000FF',\r\n zeroChange: '#000',\r\n}\r\n\r\nexport const chartDarkTheme: IChartThemeColors = {\r\n aftermarketFade: '#4C526133',\r\n background: '#1E6DC019',\r\n borderDown: '#F63538FF',\r\n borderUp: '#30CC5AFF',\r\n canvasFill: tailwindColors.gray[800],\r\n cross: '#404553',\r\n crossText: '#fff',\r\n crossTextBackground: '#111',\r\n currentBackground: tailwindColors.yellow[200],\r\n currentText: tailwindColors.gray[700],\r\n grid: '#363A46FF',\r\n gridSecondary: '#2C303A',\r\n indicatorCurrentBackground: tailwindColors.gray[500],\r\n indicatorCurrentText: '#fff',\r\n line: '#1E6DC0FF',\r\n marketDown: tailwindColors.red[300],\r\n marketUp: tailwindColors.green[300],\r\n negativeChange: tailwindColors.red[400],\r\n ohlcTrendDown: '#E54040FF',\r\n ohlcTrendUp: '#40A140FF',\r\n overlayTransparentBackground: getHEXWithSpecificAplha('#0C0E13', 0.35),\r\n percentageZeroLineText: '#fff',\r\n performanceIndicatorLabel: tailwindColors.gray[300],\r\n positiveChange: tailwindColors.green[400],\r\n premarketFade: '#4C526133',\r\n prevClose: '#C80000FF',\r\n text: '#929cb3',\r\n textSecondary: '#929CB399',\r\n trendDown: '#F63538FF',\r\n trendUp: '#30CC5AFF',\r\n volumeTrendDown: '#F635387F',\r\n volumeTrendUp: '#30CC5A7F',\r\n wickDown: '#F63538FF',\r\n wickUp: '#30CC5AFF',\r\n zeroChange: '#929cb3',\r\n}\r\n\r\nexport const darkerWickColors: IDarkerWickColors = {\r\n borderUp: '#006400FF',\r\n wickUp: '#006400',\r\n borderDown: '#6E0000FF',\r\n wickDown: '#6E0000FF',\r\n}\r\n\r\nexport const indicatorLightTheme: IIndicatorThemeColors = {\r\n line: '#000000',\r\n signalLine: tailwindColors.red[400],\r\n}\r\n\r\nexport const indicatorDarkTheme: IIndicatorThemeColors = {\r\n line: '#D07933',\r\n signalLine: tailwindColors.red[400],\r\n}\r\n\r\nexport const elementLightTheme: IElementThemeColors = {\r\n line: '#000000',\r\n border: '#000000',\r\n textWithoutBackground: '#000000',\r\n}\r\n\r\nexport const elementDarkTheme: IElementThemeColors = {\r\n line: '#5faaf4',\r\n border: '#5192D1',\r\n textWithoutBackground: '#929cb3',\r\n}\r\nexport const generalColors: Array = [\r\n '#1f77b4',\r\n '#ff7f0e',\r\n '#2ca02c',\r\n '#d62728',\r\n '#9467bd',\r\n '#8c564b',\r\n '#e377c2',\r\n '#7f7f7f',\r\n '#bcbd22',\r\n '#17becf',\r\n]\r\n\r\n// node chart with thin bars color override\r\nexport const thinBarColorsOverride = {\r\n trendUp: '#00b400',\r\n trendDown: '#b40000',\r\n}\r\n\r\nexport enum AutoSaveState {\r\n Off,\r\n Saved,\r\n Unsaved,\r\n Saving,\r\n}\r\n\r\nexport const CHART_EVENT_BADGE_SIZE = 24\r\n","import Spine from '@finviz/spine'\r\n\r\nimport { AutoSaveElement } from '../controllers/autosave/constants'\r\nimport { getUuid } from '../utils/helpers'\r\nimport { HLC, initHlc } from '../utils/hlc'\r\nimport { AutoSaveState } from './constants'\r\n\r\ninterface DrawingsInternalStateAttrs {\r\n elements: AutoSaveElement[]\r\n latestRemoteUpdateTimestamp: HLC\r\n latestLocalUpdateTimestamp: HLC\r\n instanceUUID: string\r\n autoSaveState: AutoSaveState\r\n}\r\n\r\nclass DrawingsInternalStore extends Spine.Model {\r\n static initClass() {\r\n this.configure(\r\n 'DrawingsInternalState',\r\n 'elements',\r\n 'latestRemoteUpdateTimestamp',\r\n 'latestLocalUpdateTimestamp',\r\n 'autoSaveState',\r\n 'instanceUUID'\r\n )\r\n }\r\n\r\n elements: AutoSaveElement[]\r\n latestRemoteUpdateTimestamp: HLC\r\n latestLocalUpdateTimestamp: HLC\r\n instanceUUID: string\r\n autoSaveState: AutoSaveState\r\n\r\n constructor(attrs: Partial = {}) {\r\n super(attrs)\r\n\r\n this.elements = attrs.elements ?? []\r\n this.instanceUUID = attrs.instanceUUID ?? getUuid()\r\n this.latestLocalUpdateTimestamp = attrs.latestLocalUpdateTimestamp ?? initHlc(this.instanceUUID, 0)\r\n this.latestRemoteUpdateTimestamp = attrs.latestRemoteUpdateTimestamp ?? initHlc(this.instanceUUID, 0)\r\n this.autoSaveState = attrs.autoSaveState ?? AutoSaveState.Off\r\n }\r\n\r\n setAutoSaveState = (newAutoSaveState: AutoSaveState) => {\r\n if (this.autoSaveState !== newAutoSaveState) {\r\n this.updateAttributes({ autoSaveState: newAutoSaveState })\r\n }\r\n }\r\n}\r\n\r\nexport default DrawingsInternalStore\r\n","import Spine from '@finviz/spine'\r\nimport merge from 'lodash.merge'\r\n\r\nimport { TodoObjectHashAnyType } from '../../types/shared'\r\nimport { drawingToolsByType } from '../canvas/drawingTools'\r\nimport CanvasElement from '../canvas/element'\r\nimport { CanvasElementType, ChartElementType, IndicatorType } from '../constants/common'\r\nimport { financialIndicators } from '../indicators/indicators'\r\nimport { getIsSSr, getUuid } from '../utils/helpers'\r\nimport Pane from './pane'\r\nimport { changeElementZIndexes } from './utils'\r\n\r\nclass Element extends Spine.Model {\r\n static initClass(paneModel: typeof Pane) {\r\n this.configure('Element', 'instance', 'lastChange', 'zIndex', 'elementId')\r\n this.belongsTo('pane', paneModel)\r\n }\r\n\r\n declare instance: CanvasElement\r\n declare pane_id: string\r\n declare destroyed: true | undefined\r\n declare pane: () => Pane\r\n lastChange: number | null = null\r\n elementId: string | null = null\r\n zIndex = -1\r\n\r\n generateUuid = getIsSSr() ? undefined : getUuid\r\n\r\n constructor(...args: any[]) {\r\n super(...args)\r\n const elementAttrs = args[0]\r\n this.elementId = elementAttrs?.elementId ?? this.generateUuid?.()\r\n this.one('create', () => {\r\n this.updateAttributes({\r\n zIndex: elementAttrs?.zIndex ?? this.pane().getElementZIndexRange().max + 1,\r\n })\r\n })\r\n }\r\n\r\n replace(instance: CanvasElement) {\r\n const oldInstance = this.instance\r\n this.updateAttribute('instance', instance)\r\n this.trigger('replace', this, oldInstance)\r\n }\r\n\r\n makeClone() {\r\n const { instance, pane_id } = this\r\n const { attrs } = instance\r\n const { scale } = instance.model\r\n const clonedObj = merge({ pane_id }, attrs)\r\n const cloned = drawingToolsByType[instance.type as CanvasElementType].fromObject(clonedObj, instance.model)\r\n const { ThumbSettings } = this.pane().getChartLayoutSettings()\r\n const offset = ThumbSettings.size + ThumbSettings.borderWidth * 2\r\n cloned.moveBy(scale.x.invert(offset), scale.y.invert(offset) - scale.y.invert(0))\r\n cloned.cachePointPositionTimestamp()\r\n Element.create({ instance: cloned, pane_id })\r\n this.trigger('makeClone', this, cloned)\r\n }\r\n\r\n moveToZIndex(zIndex: number) {\r\n const currentZIndex = this.zIndex\r\n const directionCoef = zIndex > currentZIndex ? 1 : -1\r\n\r\n if (this.isChart() || this.isIndicator()) {\r\n if (this.zIndex !== 0) {\r\n this.updateAttributes({ zIndex: 0 })\r\n }\r\n this.pane()\r\n .getAllElements()\r\n .filter((element) => {\r\n const shouldMove = directionCoef === 1 ? element.zIndex <= zIndex : element.zIndex >= zIndex\r\n return shouldMove && element.isDrawing()\r\n })\r\n .forEach((element) => element.moveToZIndex(directionCoef * -1))\r\n\r\n return\r\n }\r\n\r\n const newZIndex = zIndex === 0 ? directionCoef : zIndex // 0 is protected value for chart/indicator element\r\n const { min, max } = this.pane().getElementZIndexRange()\r\n if (\r\n currentZIndex === newZIndex ||\r\n (currentZIndex === min && directionCoef === -1) ||\r\n (currentZIndex === max && directionCoef === 1)\r\n ) {\r\n return\r\n }\r\n const { elementsBelowZero, elementsAboveZero } = this.pane().getBelowAboveZeroElements()\r\n\r\n changeElementZIndexes({\r\n elementsArray: elementsBelowZero,\r\n addElement: newZIndex < 0 ? this : undefined,\r\n oldZIndex: currentZIndex,\r\n newZIndex,\r\n isBelowZero: true,\r\n })\r\n\r\n changeElementZIndexes({\r\n elementsArray: elementsAboveZero,\r\n addElement: newZIndex > 0 ? this : undefined,\r\n oldZIndex: currentZIndex,\r\n newZIndex,\r\n })\r\n }\r\n\r\n bringToFront() {\r\n this.moveToZIndex(this.pane().getElementZIndexRange().max + 1)\r\n }\r\n\r\n sendToBack() {\r\n this.moveToZIndex(this.pane().getElementZIndexRange().min - 1)\r\n }\r\n\r\n bringForward() {\r\n this.moveToZIndex(this.zIndex + 1)\r\n }\r\n\r\n sendBackward() {\r\n this.moveToZIndex(this.zIndex - 1)\r\n }\r\n\r\n isChart() {\r\n return !!this.instance?.type.startsWith('charts/')\r\n }\r\n\r\n getIsChartType(chartType: ChartElementType) {\r\n return this.instance?.type === chartType\r\n }\r\n\r\n isFinancialIndicator() {\r\n return this.isIndicator() && financialIndicators.includes(this.instance!.type as IndicatorType)\r\n }\r\n\r\n isIndicator() {\r\n return !!this.instance?.type.startsWith('indicators/')\r\n }\r\n\r\n isOverlay() {\r\n return !!this.instance?.type.startsWith('overlays/')\r\n }\r\n\r\n isDrawing() {\r\n return !!this.instance?.type.startsWith('canvas/')\r\n }\r\n\r\n isChartEvent() {\r\n return !!this.instance?.type.startsWith('chartEvent/')\r\n }\r\n\r\n isMouseDown() {\r\n return !!this.instance?.isMouseDown\r\n }\r\n\r\n hasOngoingInteraction() {\r\n return this.isMouseDown() || this.instance.isEditInProgress\r\n }\r\n\r\n toObject() {\r\n return {\r\n ...this.instance.toObject(),\r\n elementId: this.elementId,\r\n zIndex: this.zIndex,\r\n }\r\n }\r\n\r\n toConfig() {\r\n return {\r\n ...this.instance.toConfig(),\r\n elementId: this.elementId,\r\n zIndex: this.zIndex,\r\n }\r\n }\r\n\r\n destroyCascade(options?: TodoObjectHashAnyType) {\r\n return this.destroy(options)\r\n }\r\n\r\n refreshElementId() {\r\n this.updateAttribute('elementId', this.generateUuid?.())\r\n }\r\n}\r\n\r\nexport default Element\r\n","import endOfDay from 'date-fns/endOfDay'\r\nimport lastDayOfMonth from 'date-fns/lastDayOfMonth'\r\nimport lastDayOfWeek from 'date-fns/lastDayOfWeek'\r\nimport setDate from 'date-fns/set'\r\n\r\nimport { TIMEFRAME, TIMEFRAMES_WITH_PRE_MARKET } from '../../constants/common'\r\nimport { convertLocalToNyTime, dateFromUnixTimestamp } from '../../utils'\r\nimport Chart from '../chart'\r\n\r\nconst MARKET_START = { hours: 9, minutes: 30 }\r\nconst END_OF_DAY = { hours: 23, minutes: 59 }\r\n\r\nfunction getIsDateBeforeMarketStart(date: Date) {\r\n const hours = date.getHours()\r\n const minutes = date.getMinutes()\r\n return hours < MARKET_START.hours || (hours === MARKET_START.hours && minutes < MARKET_START.minutes)\r\n}\r\n\r\nexport function roundTimeForSyncedPane({\r\n sourceChart,\r\n targetChart,\r\n timestamp,\r\n}: {\r\n sourceChart: Chart\r\n targetChart: Chart\r\n timestamp: number\r\n}) {\r\n let dateToReturn = dateFromUnixTimestamp(timestamp)\r\n const sourceChartHasPremarket =\r\n sourceChart.quote().premarket && TIMEFRAMES_WITH_PRE_MARKET.includes(sourceChart.timeframe)\r\n const targetChartHasPremarket =\r\n targetChart.quote().premarket && TIMEFRAMES_WITH_PRE_MARKET.includes(targetChart.timeframe)\r\n\r\n if ([TIMEFRAME.d, TIMEFRAME.w, TIMEFRAME.m].includes(sourceChart.timeframe)) {\r\n dateToReturn = setDate(dateToReturn, MARKET_START)\r\n }\r\n\r\n if (targetChart.timeframe === TIMEFRAME.m) {\r\n dateToReturn = setDate(lastDayOfMonth(dateToReturn), END_OF_DAY)\r\n } else if (targetChart.timeframe === TIMEFRAME.w) {\r\n dateToReturn = setDate(lastDayOfWeek(dateToReturn, { weekStartsOn: 1 }), END_OF_DAY)\r\n } else if (targetChart.timeframe === TIMEFRAME.d && targetChart.quote().instrument !== 'stock') {\r\n dateToReturn = endOfDay(dateToReturn)\r\n }\r\n\r\n if (sourceChartHasPremarket && !targetChartHasPremarket && targetChart.quote().instrument === 'stock') {\r\n dateToReturn = getIsDateBeforeMarketStart(dateToReturn) ? setDate(dateToReturn, MARKET_START) : dateToReturn\r\n }\r\n\r\n return ~~(convertLocalToNyTime(dateToReturn, false).getTime() / 1000)\r\n}\r\n","import Spine from '@finviz/spine'\r\n\r\nimport { ChartSyncablePart } from '../chart/contstants'\r\nimport Pane from '../pane'\r\nimport { roundTimeForSyncedPane } from './mouse-utils'\r\n\r\nexport class Mouse extends Spine.Model {\r\n static initClass() {\r\n this.configure('Mouse', 'position')\r\n this.belongsTo('pane', Pane)\r\n }\r\n\r\n declare position: { x: number; y: number } | undefined\r\n declare pane: () => Pane | null\r\n\r\n getIsCrossSyncOn = () => !!this.pane()?.chart().getIsChartPartInSync(ChartSyncablePart.Crosshair)\r\n\r\n getIsMouseInChartOfPane = (pane: Pane) => !!this.pane()?.chart().eql(pane.chart())\r\n\r\n getShouldRenderCrossInPane = (pane: Pane) => this.getIsCrossSyncOn() || this.getIsMouseInChartOfPane(pane)\r\n\r\n getCrossIndexForPane = (pane: Pane) => {\r\n if (this.position) {\r\n if (this.getIsMouseInChartOfPane(pane)) {\r\n return Math.round(this.position.x)\r\n }\r\n const paneOfMouse = this.pane()\r\n if (this.getIsCrossSyncOn() && paneOfMouse) {\r\n const mouseInChart = paneOfMouse.chart()\r\n const currentPaneChart = pane.chart()\r\n const mousePositionTimestamp = mouseInChart.quote().getTimestampFomPositionX(Math.round(this.position.x))\r\n const currentPanePositionX = currentPaneChart.quote().getPositionXFromTimestamp(\r\n roundTimeForSyncedPane({\r\n sourceChart: mouseInChart,\r\n targetChart: currentPaneChart,\r\n timestamp: mousePositionTimestamp,\r\n })\r\n )\r\n return Math.floor(currentPanePositionX)\r\n }\r\n }\r\n\r\n return Number.NaN\r\n }\r\n\r\n getPriceForPane = (pane: Pane) => {\r\n const positionY = this.position?.y ?? null\r\n\r\n if (this.pane()?.eql(pane)) {\r\n return positionY\r\n }\r\n\r\n if (this.getIsCrossSyncOn() && this.pane()) {\r\n const mousePaneIndex = this.pane()?.getIndexInChart()\r\n const currentPaneIndex = pane.getIndexInChart()\r\n return mousePaneIndex === currentPaneIndex ? positionY : null\r\n }\r\n\r\n return null\r\n }\r\n}\r\n\r\n/**\r\n * Mouse is a singleton, so `initClass` must be called before we create the instance\r\n * otherwise it wouldn’t work\r\n */\r\nMouse.initClass()\r\n\r\nconst mouse = Mouse.create()\r\nmouse.save()\r\n\r\nexport default mouse as Mouse\r\n","import Spine, { Collection } from '@finviz/spine'\r\nimport omit from 'lodash.omit'\r\n\r\nimport { Position, TodoObjectHashAnyType } from '../../types/shared'\r\nimport CanvasElement from '../canvas/element'\r\nimport { ChartEventBadgeType, PANE_HEIGHT_DEFAULT } from '../constants/common'\r\nimport { getIsSSr } from '../utils/helpers'\r\nimport Chart from './chart'\r\nimport ChartEventElement from './chart-event-element'\r\nimport Element from './element'\r\nimport { getChartLayoutSettings } from './settings'\r\nimport { rebuildElementZIndexes } from './utils'\r\n\r\nexport interface ScaleAxis {\r\n (index: number): number\r\n invert: (x: number) => number\r\n domain: () => [currentDomainMax: number, currentDomainMin: number]\r\n width: (x: number) => number\r\n height: (y: number) => number\r\n ticks: (y: number) => number[]\r\n}\r\n\r\nconst CHART_EVENT_BADGE_TYPE_ORDER = [\r\n ChartEventBadgeType.Split,\r\n ChartEventBadgeType.Dividends,\r\n ChartEventBadgeType.EarningsPositive,\r\n ChartEventBadgeType.EarningsNegative,\r\n ChartEventBadgeType.EarningsNeutral,\r\n ChartEventBadgeType.EarningsFuture,\r\n]\r\n\r\nclass Pane extends Spine.Model {\r\n static initClass(\r\n elementModel: typeof Element,\r\n chartEventElementModel: typeof ChartEventElement,\r\n chartModel: typeof Chart\r\n ) {\r\n this.configure('Pane', 'height', 'scale', 'scaleRange', 'instance', 'selection')\r\n this.hasMany('elements', elementModel)\r\n this.hasMany('chartEvents', chartEventElementModel)\r\n this.belongsTo('mainElement', elementModel)\r\n this.belongsTo('chart', chartModel)\r\n }\r\n\r\n declare id: string\r\n declare chart_id: string\r\n declare height: number\r\n declare scale: {\r\n x: ScaleAxis\r\n y: ScaleAxis\r\n }\r\n\r\n declare instance: any\r\n declare chart: () => Chart\r\n declare mainElement: () => T | null\r\n declare elements: () => Collection\r\n declare chartEvents: () => Collection\r\n selection: CanvasElement | null = null\r\n scaleRange: { min: number; max: number } | null = null\r\n\r\n destroyCascade(options?: TodoObjectHashAnyType) {\r\n this.elements()\r\n .all()\r\n .forEach((element) => {\r\n element.destroyCascade()\r\n })\r\n return this.destroy(options)\r\n }\r\n\r\n toObject() {\r\n const elements = this.elements()\r\n .all()\r\n .map((el) => el.toObject())\r\n return {\r\n height: this.height,\r\n scale: this.scale,\r\n scaleRange: this.scaleRange,\r\n elements,\r\n }\r\n }\r\n\r\n toConfig(omitKeys = [] as string[]) {\r\n const elements = this.elements()\r\n .all()\r\n .map((el) => el.toConfig())\r\n return omit(\r\n {\r\n height: this.height,\r\n scaleRange: this.scaleRange,\r\n elements,\r\n },\r\n omitKeys\r\n )\r\n }\r\n\r\n move(direction: Position) {\r\n const chartPanes = this.chart().getAllPanes()\r\n const chartPane = chartPanes.find((pane) => !pane.getIsIndicatorPane())\r\n const targetPane = chartPanes.find((pane) => this.eql(pane))\r\n\r\n if (!chartPane || !targetPane) return\r\n\r\n const currentChartPaneRecords = Pane.records.filter((pane) => pane.chart_id === targetPane.chart_id)\r\n const ohterChartPaneRecords = Pane.records.filter((pane) => pane.chart_id !== targetPane.chart_id)\r\n\r\n const targetRecordIndex = currentChartPaneRecords.findIndex((record) => record.id === targetPane.id)\r\n const arrayWithoutTargetRecord = currentChartPaneRecords.filter((_, index) => index !== targetRecordIndex)\r\n const chartRecordIndex = arrayWithoutTargetRecord.findIndex((record) => record.id === chartPane.id)\r\n\r\n const panesAbove = arrayWithoutTargetRecord.slice(0, chartRecordIndex)\r\n const panesBelow = arrayWithoutTargetRecord.slice(chartRecordIndex + 1)\r\n if (direction === Position.Above) {\r\n panesAbove.push(currentChartPaneRecords[targetRecordIndex])\r\n panesAbove.sort((a, b) => a.getNumericId() - b.getNumericId())\r\n }\r\n if (direction === Position.Below) {\r\n panesBelow.push(currentChartPaneRecords[targetRecordIndex])\r\n panesBelow.sort((a, b) => a.getNumericId() - b.getNumericId())\r\n }\r\n\r\n Pane.records = ohterChartPaneRecords.concat([\r\n ...panesAbove,\r\n arrayWithoutTargetRecord[chartRecordIndex],\r\n ...panesBelow,\r\n ])\r\n this.chart().trigger('change', this.chart())\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.chart().chart_layout())\r\n }\r\n\r\n getAllElements() {\r\n return this.elements()\r\n .all()\r\n .sort((a, b) => a.zIndex - b.zIndex)\r\n }\r\n\r\n getAllChartEvents(isSorted = true) {\r\n const chartEvents = [...this.chartEvents().all()]\r\n return isSorted ? chartEvents.sort((a, b) => a.zIndex - b.zIndex) : chartEvents\r\n }\r\n\r\n getChartOrIndicatorElement() {\r\n return this.getAllElements().find((el) => el.isChart() || el.isIndicator()) ?? null\r\n }\r\n\r\n getIsIndicatorPane() {\r\n let mainElement = this.mainElement()\r\n\r\n // @todo Fix - In SSR we don't have mainElement because it's not assigned to pane when it's created\r\n if (getIsSSr()) {\r\n mainElement = this.getChartOrIndicatorElement()\r\n }\r\n\r\n return !!mainElement?.isIndicator()\r\n }\r\n\r\n getIsChartPane() {\r\n return !!this.mainElement()?.isChart()\r\n }\r\n\r\n resetHeight() {\r\n if (this.getIsIndicatorPane()) {\r\n this.updateAttribute('height', PANE_HEIGHT_DEFAULT.indicator)\r\n }\r\n if (this.getIsChartPane()) {\r\n this.updateAttribute('height', PANE_HEIGHT_DEFAULT.chart)\r\n }\r\n }\r\n\r\n getIndexInChart() {\r\n return this.chart()\r\n .getAllPanes()\r\n .findIndex((chartPane) => chartPane.eql(this))\r\n }\r\n\r\n getElementZIndexRange() {\r\n let max = -1\r\n let min = 1\r\n this.getAllElements().forEach((el) => {\r\n if (el.zIndex > max) {\r\n max = el.zIndex\r\n }\r\n if (el.zIndex < min) {\r\n min = el.zIndex\r\n }\r\n })\r\n return { min, max }\r\n }\r\n\r\n getBelowAboveZeroElements() {\r\n const allPaneElements = this.getAllElements()\r\n const elementsBelowZero: Element[] = []\r\n const elementsAboveZero: Element[] = []\r\n allPaneElements.forEach((el) => {\r\n if (el.zIndex < 0) {\r\n elementsBelowZero.push(el)\r\n }\r\n if (el.zIndex > 0) {\r\n elementsAboveZero.push(el)\r\n }\r\n })\r\n\r\n return { elementsBelowZero, elementsAboveZero }\r\n }\r\n\r\n normalizeZIndexes() {\r\n const { elementsBelowZero, elementsAboveZero } = this.getBelowAboveZeroElements()\r\n rebuildElementZIndexes({ elementsArray: elementsBelowZero, isBelowZero: true })\r\n rebuildElementZIndexes({ elementsArray: elementsAboveZero, isBelowZero: false })\r\n }\r\n\r\n getQuoteRawTicker() {\r\n return this.chart().getQuoteRawTicker()\r\n }\r\n\r\n getNumericId() {\r\n return Number(this.id.replace('c-', ''))\r\n }\r\n\r\n updateChartEventsZIndexes() {\r\n if (!this.scale || !this.scale.hasOwnProperty('x')) {\r\n return\r\n }\r\n\r\n const chartEvents = this.getAllChartEvents(false).sort(\r\n (a, b) => a.instance.attrs.positionTimestamps!.x - b.instance.attrs.positionTimestamps!.x\r\n )\r\n const hoveredChartEvent = chartEvents.find((chartEvent) => chartEvent.instance.isHovered)\r\n const openedChartEvent = chartEvents.find((chartEvent) => chartEvent.instance.isOpen)\r\n\r\n const hoveredTypeChartEventElements: ChartEventElement[] = []\r\n const openedTypeChartEventElements: ChartEventElement[] = []\r\n const nonActiveChartEventElements: ChartEventElement[] = []\r\n\r\n chartEvents.forEach((chartEvent, index) => {\r\n const chartEventsOnSameXPoint = chartEvents.filter(\r\n (chartEvent_B, i) =>\r\n i < index && Math.round(chartEvent.instance.attrs.x) === Math.round(chartEvent_B!.instance.attrs.x)\r\n )\r\n chartEvent.updateAttributes({ yIndex: chartEventsOnSameXPoint.length })\r\n const isHovered = chartEvent.instance === hoveredChartEvent?.instance\r\n const isOpened = chartEvent.instance === openedChartEvent?.instance\r\n const isHoveredType = chartEvent.instance.type === hoveredChartEvent?.instance.type\r\n const isOpenType = chartEvent.instance.type === openedChartEvent?.instance.type\r\n if (!isHovered || !isOpened) {\r\n if (isHoveredType) {\r\n hoveredTypeChartEventElements.push(chartEvent)\r\n } else if (isOpenType) {\r\n openedTypeChartEventElements.push(chartEvent)\r\n } else {\r\n nonActiveChartEventElements.push(chartEvent)\r\n }\r\n }\r\n })\r\n\r\n nonActiveChartEventElements.sort(\r\n (a, b) =>\r\n CHART_EVENT_BADGE_TYPE_ORDER.indexOf(a.instance.getChartEvenBadgeType()) -\r\n CHART_EVENT_BADGE_TYPE_ORDER.indexOf(b.instance.getChartEvenBadgeType())\r\n )\r\n\r\n const chartEventElements = [\r\n ...nonActiveChartEventElements,\r\n ...openedTypeChartEventElements,\r\n openedChartEvent,\r\n ...hoveredTypeChartEventElements,\r\n hoveredChartEvent,\r\n ].filter(Boolean)\r\n chartEventElements.forEach((chartEvent, index) => {\r\n chartEvent!.updateAttributes({ zIndex: index })\r\n })\r\n }\r\n}\r\n\r\nexport default Pane\r\n","import { ObjectHash, RequireByKey } from '../../types/shared'\r\n\r\ninterface HeikinAshiData {\r\n HAOpen: number[]\r\n HAClose: number[]\r\n}\r\n\r\ninterface QuoteValues {\r\n cachedAt: null | number\r\n dayToOffset: ObjectHash[]\r\n dateToIndex: ObjectHash[]\r\n heikinAshiData?: HeikinAshiData\r\n daysInQuote: Date[]\r\n}\r\n\r\ninterface QuoteCacheFunctionProps {\r\n cid: string\r\n key: keyof QuoteValues\r\n fetchedAt: number\r\n value: any\r\n}\r\n\r\nconst quoteCache = {} as ObjectHash\r\n\r\nexport function getCachedQuote({\r\n cid,\r\n key,\r\n fetchedAt,\r\n}: RequireByKey>, 'cid'>) {\r\n const quote = quoteCache[cid]\r\n if (quote?.cachedAt === fetchedAt && key) {\r\n return quote[key]\r\n } else if (!key) {\r\n return quote\r\n }\r\n return null\r\n}\r\n\r\nexport function setCachedQuote({\r\n cid,\r\n key,\r\n value,\r\n fetchedAt,\r\n}: Pick) {\r\n quoteCache[cid] = {\r\n ...(quoteCache[cid]?.cachedAt === fetchedAt ? quoteCache[cid] : {}),\r\n [key]: value,\r\n cachedAt: fetchedAt,\r\n } as QuoteValues\r\n}\r\n\r\nexport function deleteCachedQuote({ cid }: Pick) {\r\n delete quoteCache[cid]\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport { isSameDay, isSameMonth, isSameWeek } from 'date-fns'\r\nimport omit from 'lodash.omit'\r\nimport queryString from 'query-string'\r\n\r\nimport { Instrument, ObjectHash, RootChartConfigObject, TodoObjectHashAnyType } from '../../types/shared'\r\nimport {\r\n ChartEventDbType,\r\n ChartEventType,\r\n IntradayTimeframeInterval,\r\n QuoteFinancialAttachment,\r\n TIMEFRAME,\r\n} from '../constants/common'\r\nimport type { ICOT } from '../indicators/cot'\r\nimport { convertLocalToNyTime, dateFromUnixTimestamp, dateStringFromDate } from '../utils'\r\nimport { getIsAbortError } from '../utils/abort_controller'\r\nimport { getPositionXFromTimestamp, getTimestampFromPositionX } from '../utils/chart'\r\nimport { IDividends, IEarnings, ISplit } from '../utils/chart-events-utils'\r\nimport fetchApi, { NotFoundError } from '../utils/fetch_api'\r\nimport { getIsSSr } from '../utils/helpers'\r\nimport { QuoteFetchType, QuoteFetchTypeUrlOption, QuoteUrlOptions } from './quote/constants'\r\nimport { FinancialAttachmentsData, ShortInterestData } from './quote/financialAttachmentsData'\r\nimport { deleteCachedQuote, getCachedQuote, setCachedQuote } from './quoteCache'\r\nimport { getRawTickerForInstrument } from './utils'\r\n\r\nconst quoteRefreshChecksBeforeFullRefresh = 15\r\n\r\ntype TodoPattern = TodoObjectHashAnyType\r\n\r\nexport interface TickerTimeframesProps {\r\n ticker: string\r\n instrument: string\r\n timeframe: string\r\n}\r\n\r\ninterface QuoteFetchOptions {\r\n aftermarket?: boolean\r\n premarket?: boolean\r\n patterns?: boolean\r\n events?: boolean\r\n maxBars?: number\r\n financialAttachments?: string[]\r\n}\r\n\r\ninterface QuoteInternalOptions {\r\n cachePredicate?: (quote: Quote) => boolean\r\n fetchNewDataOnCachedQuote?: boolean\r\n}\r\n\r\ninterface UrlOptions extends Omit {\r\n ticker: string\r\n instrument: string\r\n timeframe: string\r\n financialAttachments?: string\r\n}\r\n\r\ntype ChartEventDataRaw = Omit & { eventType: ChartEventDbType }\r\n\r\nexport interface DataResponse {\r\n COTs: COTData\r\n name: string\r\n ticker: string\r\n instrument: string\r\n interval: number\r\n timeframe: string\r\n open: number[]\r\n high: number[]\r\n low: number[]\r\n close: number[]\r\n date: number[]\r\n volume: number[]\r\n lastOpen: number\r\n lastHigh: number\r\n lastLow: number\r\n lastClose: number\r\n lastDate: number\r\n lastTime: string | null\r\n lastVolume: number\r\n dataId: string\r\n prevClose: number\r\n afterClose: number\r\n afterChange: number\r\n afterTime: string | null\r\n drawMinutesPerDay: number\r\n marketStartMinutes: number\r\n premarketLengthMinutes: number\r\n aftermarketLengthMinutes: number\r\n aftermarket: boolean\r\n premarket: boolean\r\n hasPatterns: boolean\r\n patterns: Array\r\n patternsMinRange: number\r\n patternsMaxRange: number\r\n relativeVolume: number\r\n isIntraday: boolean\r\n noNewData?: boolean\r\n chartEvents?: ChartEventDataRaw[]\r\n financialAttachmentsData?: FinancialAttachmentsData\r\n}\r\n\r\ninterface COTData {\r\n [code: string]: ICOT\r\n}\r\n\r\nconst getEmptyQuote = () => ({\r\n open: [],\r\n high: [],\r\n low: [],\r\n close: [],\r\n volume: [],\r\n date: [],\r\n fetchedAt: -1,\r\n numberOfRefreshChecks: 0,\r\n isFetching: false,\r\n is404: false,\r\n COTs: undefined,\r\n name: undefined,\r\n drawMinutesPerDay: undefined,\r\n marketStartMinutes: undefined,\r\n premarketLengthMinutes: undefined,\r\n aftermarketLengthMinutes: undefined,\r\n patterns: [],\r\n patternsMinRange: undefined,\r\n patternsMaxRange: undefined,\r\n relativeVolume: undefined,\r\n lastOpen: undefined,\r\n lastHigh: undefined,\r\n lastLow: undefined,\r\n lastClose: undefined,\r\n lastVolume: undefined,\r\n dataId: undefined,\r\n lastDate: undefined,\r\n prevClose: undefined,\r\n afterClose: undefined,\r\n afterChange: undefined,\r\n chartEvents: [],\r\n financialAttachments: [],\r\n financialAttachmentsData: null,\r\n})\r\n\r\ninterface ICacheAvailabilityCheckFunctionsArguments {\r\n quote: Quote\r\n options?: QuoteFetchOptions & QuoteInternalOptions\r\n}\r\n\r\nconst doesQuoteAndOptionsMatch = ({ quote, options }: ICacheAvailabilityCheckFunctionsArguments) =>\r\n !quote.premarket === !options?.premarket &&\r\n !quote.aftermarket === !options?.aftermarket &&\r\n !quote.hasPatterns === !options?.patterns &&\r\n // if options.events is false we can reuse quote with events\r\n (!options?.events || !!quote.events) &&\r\n // Either has no financialAttachments or require all of them to match\r\n ((options?.financialAttachments?.length ?? 0) === 0 ||\r\n options!.financialAttachments!.every((financialAttachment) =>\r\n quote.financialAttachments?.includes(financialAttachment as QuoteFinancialAttachment)\r\n ))\r\n\r\nconst doesQuoteAndFetchParamsMatch = ({\r\n quote,\r\n ticker,\r\n instrument,\r\n timeframe,\r\n}: {\r\n quote: Quote\r\n ticker: string\r\n instrument: Instrument\r\n timeframe: TIMEFRAME\r\n}) => quote.ticker === ticker && quote.instrument === instrument && quote.timeframe === timeframe\r\n\r\n// either we don't care about matching uuid at all, or they have to match\r\nconst isSameOrNoChartUuid = ({ quote, uuid }: { quote: Quote; uuid?: string }) => !uuid || quote.chartUuid === uuid\r\n\r\nconst isCacheAllowed = ({ quote, options }: ICacheAvailabilityCheckFunctionsArguments) =>\r\n !options?.cachePredicate || options.cachePredicate(quote)\r\n\r\nconst isNotEmptyQuote = (quote: Quote) => quote.fetchedAt !== -1 || quote.isFetching || !!quote.is404\r\n\r\nexport type QuoteGetParams = {\r\n ticker: string\r\n instrument: Instrument\r\n timeframe: TIMEFRAME\r\n options?: QuoteFetchOptions & QuoteInternalOptions\r\n abortController?: null | AbortController\r\n shouldUseCache?: boolean\r\n canBeEmptyQuote?: boolean\r\n chartUuid?: string\r\n}\r\n\r\nfunction getChartEventsWithId({ ticker, chartEvents }: { ticker: string; chartEvents?: ChartEventDataRaw[] }) {\r\n return (\r\n chartEvents?.map((item) => {\r\n let eventType: ChartEventType\r\n switch (item.eventType) {\r\n case ChartEventDbType.Dividends:\r\n eventType = ChartEventType.Dividends\r\n break\r\n case ChartEventDbType.Split:\r\n eventType = ChartEventType.Split\r\n break\r\n case ChartEventDbType.Earnings:\r\n eventType = ChartEventType.Earnings\r\n break\r\n }\r\n return {\r\n ...item,\r\n elementId: `${ticker.toLowerCase()}-${item.eventType}-${item.dateTimestamp}`,\r\n eventType,\r\n }\r\n }) ?? []\r\n )\r\n}\r\n\r\nclass Quote extends Spine.Model {\r\n static computableKeys = [\r\n 'isIntraday',\r\n 'interval',\r\n 'drawDays',\r\n 'barIndex',\r\n 'barToDataIndex',\r\n 'alignedFinancialAttachmentsData',\r\n 'timestampToFinancialsIndexesMap',\r\n ]\r\n\r\n static initClass() {\r\n this.configure(\r\n 'Quote',\r\n 'ticker',\r\n 'name',\r\n 'instrument',\r\n 'timeframe',\r\n 'open',\r\n 'high',\r\n 'low',\r\n 'close',\r\n 'date',\r\n 'volume',\r\n 'lastOpen',\r\n 'lastHigh',\r\n 'lastLow',\r\n 'lastClose',\r\n 'lastDate',\r\n 'lastVolume',\r\n 'lastTime',\r\n 'dataId',\r\n 'prevClose',\r\n 'COTs',\r\n 'chartEvents',\r\n 'afterClose',\r\n 'afterChange',\r\n 'afterTime',\r\n 'drawMinutesPerDay',\r\n 'marketStartMinutes',\r\n 'premarketLengthMinutes',\r\n 'aftermarketLengthMinutes',\r\n 'aftermarket',\r\n 'premarket',\r\n 'events',\r\n 'financialAttachments',\r\n 'financialAttachmentsData',\r\n 'hasPatterns',\r\n 'patterns',\r\n 'patternsMinRange',\r\n 'patternsMaxRange',\r\n 'relativeVolume',\r\n 'fetchedAt',\r\n 'fetchingPromise',\r\n 'isFetching',\r\n 'wasFetchAborted',\r\n 'chartUuid',\r\n 'numberOfRefreshChecks',\r\n 'maxBars',\r\n 'ideaID',\r\n 'is404',\r\n ...Quote.computableKeys\r\n )\r\n }\r\n\r\n static getFromCacheSync({\r\n ticker: tickerRaw,\r\n instrument,\r\n timeframe,\r\n options,\r\n chartUuid,\r\n canBeEmptyQuote,\r\n }: Omit): Quote | null {\r\n const ticker = tickerRaw.replace('@', '')\r\n return (\r\n Quote.select(\r\n (q) =>\r\n doesQuoteAndFetchParamsMatch({ quote: q, ticker, instrument, timeframe }) &&\r\n isSameOrNoChartUuid({ quote: q, uuid: chartUuid }) &&\r\n (canBeEmptyQuote || isNotEmptyQuote(q)) &&\r\n isCacheAllowed({ quote: q, options }) &&\r\n (q.instrument !== Instrument.Stock ||\r\n Number.isInteger(q.ideaID) ||\r\n doesQuoteAndOptionsMatch({ quote: q, options }))\r\n )[0] ?? null\r\n )\r\n }\r\n\r\n static async get({\r\n ticker: tickerRaw,\r\n instrument,\r\n timeframe,\r\n options,\r\n abortController,\r\n shouldUseCache = true,\r\n canBeEmptyQuote = false,\r\n chartUuid,\r\n }: QuoteGetParams): Promise {\r\n const ticker = tickerRaw.replace('@', '')\r\n const quote = shouldUseCache\r\n ? this.getFromCacheSync({ ticker: tickerRaw, instrument, timeframe, options, chartUuid, canBeEmptyQuote })\r\n : null\r\n\r\n if (quote) {\r\n if (quote.isFetching) {\r\n await quote.getResolvedFetchingPromise()\r\n } else if (options?.fetchNewDataOnCachedQuote) {\r\n await quote.fetchData({ fetchType: QuoteFetchType.NewerData, abortController })\r\n }\r\n return quote\r\n }\r\n\r\n const newQuote = Quote.create({\r\n ...getEmptyQuote(),\r\n ticker,\r\n timeframe,\r\n instrument,\r\n chartUuid,\r\n maxBars: options?.maxBars,\r\n premarket: !!options?.premarket,\r\n aftermarket: !!options?.aftermarket,\r\n hasPatterns: !!options?.patterns,\r\n events: !!options?.events,\r\n financialAttachments: options?.financialAttachments ?? [],\r\n })\r\n\r\n await newQuote.fetchData({ fetchType: QuoteFetchType.Refetch, abortController })\r\n\r\n return newQuote\r\n }\r\n\r\n static async getAll(\r\n tickersAndTimeframes: Array>\r\n ) {\r\n // TODO: fetch in 1 request\r\n if (tickersAndTimeframes.length === 0) {\r\n return {}\r\n }\r\n\r\n try {\r\n const quotes = await Promise.all(tickersAndTimeframes.map((props) => this.get(props)))\r\n const data = quotes.reduce(\r\n (accumulator, quote) => ({\r\n ...accumulator,\r\n [quote.ticker]: quote,\r\n }),\r\n {}\r\n )\r\n return data\r\n } catch {\r\n // TODO: handle somehow\r\n }\r\n }\r\n\r\n declare ticker: string\r\n declare name: string\r\n declare instrument: Instrument\r\n declare interval: number\r\n declare timeframe: TIMEFRAME\r\n declare open: number[]\r\n declare high: number[]\r\n declare low: number[]\r\n declare close: number[]\r\n declare date: number[]\r\n declare volume: number[]\r\n declare lastOpen: number\r\n declare lastHigh: number\r\n declare lastLow: number\r\n declare lastClose: number\r\n declare lastDate: number\r\n declare lastVolume: number\r\n declare dataId: string\r\n declare prevClose: number\r\n declare COTs: COTData\r\n declare afterClose: number\r\n declare afterChange: number\r\n declare drawMinutesPerDay: number\r\n declare marketStartMinutes: number\r\n declare premarketLengthMinutes: number\r\n declare aftermarketLengthMinutes: number\r\n declare hasPatterns: boolean\r\n declare patterns: Array\r\n declare patternsMinRange: number\r\n declare patternsMaxRange: number\r\n declare relativeVolume: number\r\n declare isIntraday: boolean\r\n declare drawDays?: number\r\n declare barIndex: number[]\r\n /**\r\n * Array of length the same as number of bars\r\n *\r\n * If there's a gap and a bar index has no corresponding data index,\r\n * the last data index is used (or 0 if there's no last data index)\r\n *\r\n * @type {number[]}\r\n */\r\n declare barToDataIndex: number[]\r\n declare chartUuid?: string\r\n declare aftermarket: boolean\r\n declare premarket: boolean\r\n declare fetchedAt: number\r\n declare numberOfRefreshChecks: number\r\n declare isFetching: boolean\r\n declare fetchingPromise?: Promise\r\n declare wasFetchAborted: boolean\r\n declare maxBars?: number\r\n declare ideaID?: number\r\n declare is404?: boolean\r\n declare chartEvents: Array\r\n declare events?: boolean\r\n declare financialAttachments?: QuoteFinancialAttachment[]\r\n declare financialAttachmentsData?: FinancialAttachmentsData\r\n declare alignedFinancialAttachmentsData: {\r\n [QuoteFinancialAttachment.shortInterest]?: Array\r\n }\r\n\r\n declare timestampToFinancialsIndexesMap: {\r\n [QuoteFinancialAttachment.shortInterest]?: ObjectHash\r\n }\r\n\r\n async fetchRequest({\r\n abortController,\r\n options = { type: QuoteFetchTypeUrlOption.New },\r\n }: {\r\n abortController?: null | AbortController\r\n options?: QuoteUrlOptions\r\n }) {\r\n let data: DataResponse | null = null\r\n let is404 = false\r\n let wasFetchAborted = false\r\n\r\n const fetchingPromise = fetchApi({\r\n location: this.getUrl(options),\r\n throwOnStatusCodes: [404],\r\n abortController,\r\n })\r\n\r\n this.updateAttributes({\r\n isFetching: true,\r\n fetchingPromise,\r\n })\r\n\r\n try {\r\n data = await fetchingPromise\r\n } catch (err) {\r\n is404 = err instanceof NotFoundError\r\n if (getIsAbortError(err as Error)) {\r\n wasFetchAborted = true\r\n } else if (!is404 && process.env.IS_E2E_TESTING) {\r\n throw new Error('Quote fetch error', { cause: err })\r\n }\r\n // Ignore network/notfound errors\r\n }\r\n\r\n const shouldUseEmptyQuote = !data && !wasFetchAborted && options.type === QuoteFetchTypeUrlOption.New\r\n\r\n this.updateAttributes({\r\n ...(shouldUseEmptyQuote ? getEmptyQuote() : {}),\r\n is404,\r\n wasFetchAborted,\r\n isFetching: false,\r\n })\r\n\r\n return data\r\n }\r\n\r\n async isPossibleToFetchSequentialData({\r\n abortController,\r\n }: {\r\n abortController?: null | AbortController\r\n } = {}) {\r\n const data = await this.fetchRequest({ abortController })\r\n if (data && data.date.length > 0 && this.date.length > 0) {\r\n return this.date[this.date.length - 1] >= data.date[0]\r\n }\r\n return false\r\n }\r\n\r\n async fetchData({\r\n fetchType,\r\n abortController,\r\n }: {\r\n fetchType: QuoteFetchType\r\n abortController?: null | AbortController\r\n }) {\r\n let options: QuoteUrlOptions\r\n if (fetchType === QuoteFetchType.Refetch) {\r\n options = { type: QuoteFetchTypeUrlOption.New }\r\n } else if (fetchType === QuoteFetchType.NewerData) {\r\n options = { type: QuoteFetchTypeUrlOption.Newer }\r\n if ((this.numberOfRefreshChecks ?? 0) < quoteRefreshChecksBeforeFullRefresh) {\r\n options.dataId = this.dataId\r\n }\r\n } else {\r\n return\r\n }\r\n if (this.instrument === Instrument.Stock) {\r\n options.events = this.events == null ? true : this.events\r\n }\r\n\r\n const data = await this.fetchRequest({ abortController, options })\r\n\r\n if (!data || data.noNewData === true) {\r\n this.updateAttributes({\r\n numberOfRefreshChecks: (this.numberOfRefreshChecks ?? 0) + 1,\r\n })\r\n return\r\n }\r\n if (this.timeframe !== data.timeframe || this.ticker.toLowerCase() !== data.ticker?.toLowerCase()) {\r\n return\r\n }\r\n\r\n const newQuoteData = {\r\n COTs: data.COTs,\r\n name: data.name,\r\n open: data.open,\r\n high: data.high,\r\n low: data.low,\r\n close: data.close,\r\n volume: data.volume,\r\n date: data.date,\r\n drawMinutesPerDay: data.drawMinutesPerDay,\r\n marketStartMinutes: data.marketStartMinutes,\r\n premarketLengthMinutes: data.premarketLengthMinutes,\r\n aftermarketLengthMinutes: data.aftermarketLengthMinutes,\r\n patterns: data.patterns ?? [],\r\n patternsMinRange: data.patternsMinRange,\r\n patternsMaxRange: data.patternsMaxRange,\r\n relativeVolume: data.relativeVolume,\r\n lastOpen: data.lastOpen,\r\n lastHigh: data.lastHigh,\r\n lastLow: data.lastLow,\r\n lastClose: data.lastClose,\r\n lastVolume: data.lastVolume,\r\n dataId: data.dataId,\r\n lastDate: data.lastDate,\r\n lastTime: data.lastTime,\r\n prevClose: data.prevClose,\r\n afterClose: data.afterClose,\r\n afterChange: data.afterChange,\r\n afterTime: data.afterTime,\r\n numberOfRefreshChecks: 0,\r\n chartEvents: data.chartEvents ?? [],\r\n fetchedAt: Date.now(),\r\n financialAttachmentsData: data.financialAttachmentsData,\r\n }\r\n\r\n if (\r\n !(\r\n fetchType === QuoteFetchType.Refetch ||\r\n [Instrument.Futures, Instrument.Forex, Instrument.Crypto].includes(this.instrument)\r\n )\r\n ) {\r\n /*\r\n * Merges current and new data taking date as index\r\n */\r\n let AIndex = 0\r\n let BIndex = 0\r\n let mergeIndex = -1\r\n while (AIndex < this.date.length || BIndex < data.date.length) {\r\n const ADate = this.date[AIndex]\r\n const BDate = data.date[BIndex]\r\n if (BDate === undefined) {\r\n break\r\n } else if (ADate === BDate) {\r\n // Same date, update OHLCV\r\n this.open[AIndex] = data.open[BIndex]\r\n this.high[AIndex] = data.high[BIndex]\r\n this.low[AIndex] = data.low[BIndex]\r\n this.close[AIndex] = data.close[BIndex]\r\n this.volume[AIndex] = data.volume[BIndex]\r\n AIndex++\r\n BIndex++\r\n } else if (ADate > BDate || ADate === undefined) {\r\n // New bar for a date not yet in our dataset\r\n // If weekly or monthly timeframe & wasn't merged on AIndex\r\n if (mergeIndex === -1 && [TIMEFRAME.w, TIMEFRAME.m].includes(this.timeframe)) {\r\n const prevAIndex = AIndex - 1\r\n const prevDate = dateFromUnixTimestamp(this.date[prevAIndex])\r\n const newDate = dateFromUnixTimestamp(data.date[BIndex])\r\n // If merge bar for weekly is sameWeek or for monthly is sameMonth perform merge on AIndex\r\n if (\r\n (TIMEFRAME.w === this.timeframe && isSameWeek(prevDate, newDate, { weekStartsOn: 1 })) ||\r\n (TIMEFRAME.m === this.timeframe && isSameMonth(prevDate, newDate))\r\n ) {\r\n this.date[prevAIndex] = data.date[BIndex]\r\n this.open[prevAIndex] = data.open[BIndex]\r\n this.high[prevAIndex] = data.high[BIndex]\r\n this.low[prevAIndex] = data.low[BIndex]\r\n this.close[prevAIndex] = data.close[BIndex]\r\n this.volume[prevAIndex] = data.volume[BIndex]\r\n mergeIndex = prevAIndex\r\n // Incrementing BIndex only because we're mergin arrays on AIndex\r\n BIndex++\r\n continue\r\n }\r\n }\r\n this.date.splice(AIndex, 0, data.date[BIndex])\r\n this.open.splice(AIndex, 0, data.open[BIndex])\r\n this.high.splice(AIndex, 0, data.high[BIndex])\r\n this.low.splice(AIndex, 0, data.low[BIndex])\r\n this.close.splice(AIndex, 0, data.close[BIndex])\r\n this.volume.splice(AIndex, 0, data.volume[BIndex])\r\n // Incrementing AIndex because we're changing the array in-place\r\n AIndex++\r\n BIndex++\r\n } else if (ADate < BDate) {\r\n AIndex++\r\n } else {\r\n console.warn('fetchNewerData merge warning')\r\n window.Sentry?.captureMessage('quote.ts fetchNewerData merge warning', {\r\n extra: {\r\n thisDateLength: this.date.length,\r\n dataDateLength: data.date.length,\r\n AIndex,\r\n BIndex,\r\n ADate,\r\n BDate,\r\n },\r\n })\r\n }\r\n }\r\n\r\n newQuoteData.date = this.date\r\n newQuoteData.open = this.open\r\n newQuoteData.high = this.high\r\n newQuoteData.low = this.low\r\n newQuoteData.close = this.close\r\n newQuoteData.volume = this.volume\r\n }\r\n\r\n const hasUpdatedSuccessfully = this.updateAttributes(newQuoteData)\r\n // https://github.com/finvizhq/charts/issues/510\r\n if (!hasUpdatedSuccessfully) {\r\n // attempt to find if this.model.quote() => null is comming from this.save() validation fail\r\n window.Sentry?.captureMessage('quote.ts fetchNewerData save() validation failed', { extra: this })\r\n }\r\n if (!this) {\r\n // or this somehow became null / falsy\r\n window.Sentry?.captureMessage('quote.ts fetchNewerData this is falsy', { extra: this })\r\n }\r\n this.trigger(fetchType, this, fetchType)\r\n }\r\n\r\n async getResolvedFetchingPromise() {\r\n try {\r\n return await this.fetchingPromise\r\n } catch {\r\n // do nothing\r\n }\r\n }\r\n\r\n fetchOlderData() {\r\n return // not yet implemented\r\n // TODO cancel previous request\r\n }\r\n\r\n load(atts: ObjectHash) {\r\n super.load(atts)\r\n // This has to be here to prevent recalculations if atts.fetchedAt is not provided\r\n const fetchedAt = atts.fetchedAt ?? this.fetchedAt ?? 0\r\n const { cachedAt } = (getCachedQuote({ cid: this.cid }) as { cachedAt: number } | null) || {}\r\n if (this.timeframe && cachedAt !== fetchedAt) {\r\n setCachedQuote({ cid: this.cid, key: 'cachedAt', value: fetchedAt, fetchedAt })\r\n this.isIntraday = [\r\n TIMEFRAME.i1,\r\n TIMEFRAME.i2,\r\n TIMEFRAME.i3,\r\n TIMEFRAME.i5,\r\n TIMEFRAME.i10,\r\n TIMEFRAME.i15,\r\n TIMEFRAME.i30,\r\n TIMEFRAME.h,\r\n TIMEFRAME.h2,\r\n TIMEFRAME.h4,\r\n ].includes(this.timeframe)\r\n this.interval = this.isIntraday\r\n ? IntradayTimeframeInterval[this.timeframe as keyof typeof IntradayTimeframeInterval]\r\n : 0\r\n this.drawDays = this.getDrawDays()\r\n this.barIndex = this.getBarIndexes()\r\n this.patterns = this.patterns ?? []\r\n this.barToDataIndex = this.barIndex.flatMap((barIndex, index) => {\r\n const lastIndex = this.barIndex[index - 1] ?? -1\r\n return [...Array.from({ length: barIndex - lastIndex - 1 }).fill(Math.max(0, index - 1)), index] as number[]\r\n })\r\n this.alignAllFinancialAttachmentsDataWithQuoteDates()\r\n }\r\n if (this.timeframe && this.ticker) {\r\n this.chartEvents = getChartEventsWithId({\r\n ticker: this.ticker,\r\n chartEvents: this.chartEvents as unknown as ChartEventDataRaw[],\r\n })\r\n }\r\n return this\r\n }\r\n\r\n alignAllFinancialAttachmentsDataWithQuoteDates() {\r\n this.alignedFinancialAttachmentsData = {}\r\n this.timestampToFinancialsIndexesMap = {}\r\n this.financialAttachments?.forEach((quoteFinancialAttachment) => {\r\n this.alignFinancialAttachmentsDataWithQuoteDates(quoteFinancialAttachment)\r\n })\r\n }\r\n\r\n alignFinancialAttachmentsDataWithQuoteDates(quoteFinancialAttachment: QuoteFinancialAttachment) {\r\n const timestampToFinancialsIndexesMap: ObjectHash = {}\r\n const financialAttachmentsData = this.financialAttachmentsData?.[quoteFinancialAttachment]\r\n\r\n if (financialAttachmentsData) {\r\n let lastDateIndex = 0\r\n const firstDate = this.date[0]\r\n this.alignedFinancialAttachmentsData[quoteFinancialAttachment] = financialAttachmentsData.map((data, index) => {\r\n let matchingQuoteTimestamp: number | null = null\r\n\r\n const parsedDate = dateFromUnixTimestamp(data.timestamp)\r\n const convertedDateToNyTimestamp = convertLocalToNyTime(parsedDate, false).getTime() / 1000\r\n\r\n if (firstDate < convertedDateToNyTimestamp) {\r\n for (let dateIndex = lastDateIndex; dateIndex < this.date.length; dateIndex += 1) {\r\n const timestamp = this.date[dateIndex]\r\n const dateDate = dateFromUnixTimestamp(timestamp)\r\n if (this.isIntraday || this.timeframe === TIMEFRAME.d) {\r\n if (isSameDay(parsedDate, dateDate)) {\r\n lastDateIndex = dateIndex\r\n matchingQuoteTimestamp = timestamp\r\n break\r\n }\r\n } else if (this.timeframe === TIMEFRAME.w) {\r\n if (isSameWeek(parsedDate, dateDate, { weekStartsOn: 1 })) {\r\n lastDateIndex = dateIndex\r\n matchingQuoteTimestamp = timestamp\r\n break\r\n }\r\n } else if (this.timeframe === TIMEFRAME.m) {\r\n if (isSameMonth(parsedDate, dateDate)) {\r\n lastDateIndex = dateIndex\r\n matchingQuoteTimestamp = timestamp\r\n break\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (matchingQuoteTimestamp !== null) {\r\n const key = matchingQuoteTimestamp.toString()\r\n timestampToFinancialsIndexesMap[key] ??= []\r\n timestampToFinancialsIndexesMap[key].push(index)\r\n }\r\n\r\n return { ...data, matchingQuoteTimestamp }\r\n })\r\n\r\n this.timestampToFinancialsIndexesMap = {\r\n [quoteFinancialAttachment]: timestampToFinancialsIndexesMap,\r\n }\r\n }\r\n }\r\n\r\n clearCachedData() {\r\n deleteCachedQuote({ cid: this.cid })\r\n }\r\n\r\n destroy(options?: ObjectHash) {\r\n super.destroy(options)\r\n this.clearCachedData()\r\n return this\r\n }\r\n\r\n getDrawDays() {\r\n if (this.instrument !== Instrument.Stock) {\r\n return Infinity\r\n }\r\n switch (this.timeframe) {\r\n case TIMEFRAME.i1:\r\n case TIMEFRAME.i2:\r\n case TIMEFRAME.i3:\r\n case TIMEFRAME.i5:\r\n case TIMEFRAME.i10:\r\n return 10\r\n case TIMEFRAME.i15:\r\n case TIMEFRAME.i30:\r\n case TIMEFRAME.h:\r\n case TIMEFRAME.h2:\r\n case TIMEFRAME.h4:\r\n return 15\r\n default:\r\n break\r\n }\r\n }\r\n\r\n getHeikinAshiData() {\r\n const cachedHeikinAshiData = getCachedQuote({ cid: this.cid, key: 'heikinAshiData', fetchedAt: this.fetchedAt })\r\n if (cachedHeikinAshiData) {\r\n return cachedHeikinAshiData as unknown as { open: number[]; close: number[] }\r\n }\r\n\r\n const HAClose = this.open.map((_, i) => (this.open[i] + this.high[i] + this.close[i] + this.low[i]) / 4)\r\n const HAOpen = this.open.reduce(\r\n (acc, open, i) => [...acc, (i === 0 ? open + HAClose[0] : acc[i - 1] + HAClose[i - 1]) / 2],\r\n [] as number[]\r\n )\r\n\r\n const heikAshiData = { open: HAOpen, close: HAClose }\r\n\r\n setCachedQuote({ cid: this.cid, key: 'heikinAshiData', value: heikAshiData, fetchedAt: this.fetchedAt })\r\n\r\n return heikAshiData\r\n }\r\n\r\n getDayToOffset(): ObjectHash {\r\n const cachedDayToOffset = getCachedQuote({ cid: this.cid, key: 'dayToOffset', fetchedAt: this.fetchedAt })\r\n if (cachedDayToOffset) {\r\n return cachedDayToOffset as unknown as ObjectHash\r\n }\r\n const dayToOffset: ObjectHash = {}\r\n let day = 0\r\n let lastDay\r\n for (let i = 0, end = this.date.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n const date = dateFromUnixTimestamp(this.date[i])\r\n const dateString = dateStringFromDate(date)\r\n if (dateString !== lastDay) {\r\n dayToOffset[dateString] = day\r\n day++\r\n lastDay = dateString\r\n }\r\n }\r\n // for ofscreen renderer we need to add lastDate to have correct dayToOffset because if\r\n // premarket=false in fetch query there isn't other way to distinguish that\r\n if (getIsSSr() && this.lastDate) {\r\n // YYYYMMDD / 20211118 => YYYY-MM-DD\r\n const [yyyy, mm, dd] = [~~(this.lastDate / 10000), ~~(this.lastDate / 100) % 100, this.lastDate % 100]\r\n const lastDate = `${yyyy}-${String(mm).padStart(2, '0')}-${String(dd).padStart(2, '0')}`\r\n\r\n if (lastDay !== lastDate) {\r\n dayToOffset[lastDate] = day\r\n }\r\n }\r\n\r\n setCachedQuote({ cid: this.cid, key: 'dayToOffset', value: dayToOffset, fetchedAt: this.fetchedAt })\r\n return dayToOffset\r\n }\r\n\r\n getDaysInQuote() {\r\n const cachedDayToOffset = getCachedQuote({ cid: this.cid, key: 'daysInQuote', fetchedAt: this.fetchedAt })\r\n if (cachedDayToOffset) {\r\n return cachedDayToOffset as unknown as Date[]\r\n }\r\n const dayToOffset = this.getDayToOffset()\r\n const daysInQuote = Object.keys(dayToOffset)\r\n .map((dateString) => {\r\n const [year, month, day] = dateString.split('-')\r\n return new Date(Number.parseInt(year), Number.parseInt(month) - 1, Number.parseInt(day))\r\n })\r\n .sort((a, b) => a.getTime() - b.getTime())\r\n\r\n setCachedQuote({ cid: this.cid, key: 'daysInQuote', value: daysInQuote, fetchedAt: this.fetchedAt })\r\n return daysInQuote\r\n }\r\n\r\n getBarIndexes() {\r\n if (!this.isIntraday || this.instrument !== Instrument.Stock) {\r\n return Array.from({ length: this.date.length }).map((_, index) => index)\r\n }\r\n\r\n const barIndex = []\r\n const dayToOffset = this.getDayToOffset()\r\n\r\n for (let i = 0; i < this.date.length; i += 1) {\r\n const date = dateFromUnixTimestamp(this.date[i])\r\n let x = Math.ceil((date.getHours() * 60 + date.getMinutes() - this.marketStartMinutes) / this.interval)\r\n x += dayToOffset[dateStringFromDate(date)] * this.getBarsInDay()! // add days\r\n barIndex[i] = x\r\n }\r\n\r\n return barIndex\r\n }\r\n\r\n getBarIndex(i: number) {\r\n if (!this.isIntraday || this.instrument !== Instrument.Stock) {\r\n return i\r\n }\r\n return this.barIndex[i]\r\n }\r\n\r\n getBarsInDay() {\r\n if (!this.isIntraday || this.instrument !== Instrument.Stock) {\r\n return\r\n }\r\n return Math.ceil(this.drawMinutesPerDay / this.interval)\r\n }\r\n\r\n getDataIndexByBarIndex(index: number) {\r\n if (this.barIndex) {\r\n for (let i = 0; i < this.barIndex.length; i++) {\r\n if (this.barIndex[i] === index) {\r\n return i\r\n }\r\n }\r\n }\r\n return -1\r\n }\r\n\r\n getDataByBarIndex(key: keyof Quote, index: number) {\r\n const dataIndex = this.getDataIndexByBarIndex(index)\r\n if (dataIndex > -1) {\r\n const quoteData = this[key as keyof Quote]! as number[]\r\n return quoteData[dataIndex] ?? null\r\n }\r\n return null\r\n }\r\n\r\n getDateToIndex() {\r\n const cachedDateToIndex = getCachedQuote({ cid: this.cid, key: 'dateToIndex', fetchedAt: this.fetchedAt })\r\n if (cachedDateToIndex) {\r\n return cachedDateToIndex as unknown as ObjectHash\r\n }\r\n const dateToIndex: ObjectHash = {}\r\n for (let i = 0; i < this.date.length; i++) {\r\n dateToIndex[this.date[i]] = i\r\n }\r\n setCachedQuote({ cid: this.cid, key: 'dateToIndex', value: dateToIndex, fetchedAt: this.fetchedAt })\r\n return dateToIndex\r\n }\r\n\r\n getTimestampFomPositionX(positionX: number) {\r\n if (this.date.length === 0) {\r\n return 0\r\n }\r\n return getTimestampFromPositionX({\r\n positionX,\r\n quote: this,\r\n })\r\n }\r\n\r\n getPositionXFromTimestamp(timestamp: number) {\r\n if (this.date.length === 0) {\r\n return 0\r\n }\r\n return getPositionXFromTimestamp({\r\n timestamp,\r\n quote: this,\r\n })\r\n }\r\n\r\n getUrl(options: QuoteUrlOptions) {\r\n const config: UrlOptions = {\r\n ticker: this.ticker,\r\n instrument: this.instrument,\r\n timeframe: this.timeframe || 'd1',\r\n aftermarket: this.aftermarket,\r\n premarket: this.premarket,\r\n patterns: this.hasPatterns,\r\n maxBars: this.maxBars,\r\n ...options,\r\n financialAttachments: this.financialAttachments?.join(','),\r\n }\r\n\r\n const isStock = config.instrument === Instrument.Stock\r\n const isBrowserElite = !getIsSSr() && document.location.host === 'elite.finviz.com'\r\n let domain = isBrowserElite && isStock ? 'https://api.finviz.com' : ''\r\n\r\n if (getIsSSr()) {\r\n domain = process.env.BE_API_URL!\r\n }\r\n\r\n return `${domain}/api/quote.ashx?${queryString.stringify({ rev: Date.now(), ...config })}`\r\n }\r\n\r\n getRawTicker() {\r\n return getRawTickerForInstrument(this.instrument, this.ticker)\r\n }\r\n\r\n clearData() {\r\n this.updateAttributes(getEmptyQuote())\r\n }\r\n\r\n toConfig = RootChartConfigObject>(omitKeys = [] as string[]): T {\r\n return JSON.parse(JSON.stringify(omit(this.toJSON(), [...Quote.computableKeys, ...omitKeys])))\r\n }\r\n}\r\n\r\nQuote.initClass()\r\n\r\nexport default Quote\r\n","import { QuoteFinancialAttachment } from '../../constants/common'\r\n\r\nexport enum QuoteFetchType {\r\n Refetch = 'refetch',\r\n NewerData = 'newerData',\r\n}\r\n\r\nexport enum QuoteFetchTypeUrlOption {\r\n New = 'new',\r\n Newer = 'newer',\r\n}\r\n\r\nexport interface QuoteUrlOptions {\r\n type: QuoteFetchTypeUrlOption\r\n dataId?: string\r\n events?: boolean\r\n financialAttachments?: QuoteFinancialAttachment[]\r\n}\r\n","export const largeChartFontSize = {\r\n S: 8,\r\n M: 10,\r\n XXL: 16,\r\n XXXL: 24,\r\n}\r\n","import { Theme } from '../../../types/shared'\r\nimport {\r\n CHART_MARGIN,\r\n FONT_SIZE,\r\n LINE_HEIGHT,\r\n OFFSET,\r\n PADDING,\r\n SETTINGS_HEIGHT,\r\n TICKER_TIMEFRAME_CHANGE_HEIGHT,\r\n TextBaseline,\r\n} from '../../constants/common'\r\nimport {\r\n chartDarkTheme,\r\n chartLightTheme,\r\n elementDarkTheme,\r\n elementLightTheme,\r\n generalColors,\r\n indicatorDarkTheme,\r\n indicatorLightTheme,\r\n} from '../constants'\r\nimport { ISettings } from './interfaces'\r\n\r\nexport const INTERACTIVE_CHART_SETTINGS = (theme: Theme): ISettings => ({\r\n ChartSettings: {\r\n general: {\r\n Colors: {\r\n ...(theme === Theme.light ? chartLightTheme : chartDarkTheme),\r\n [Theme.light]: chartLightTheme,\r\n [Theme.dark]: chartDarkTheme,\r\n },\r\n settingsHeight: SETTINGS_HEIGHT,\r\n tickerTimeframeChangeHeight: TICKER_TIMEFRAME_CHANGE_HEIGHT,\r\n },\r\n center: {\r\n barWidth: 3,\r\n barMargin: 1,\r\n border: 1,\r\n },\r\n top: {\r\n height: CHART_MARGIN.XL,\r\n baseline: TextBaseline.alphabetic,\r\n ticker: {\r\n margin: {\r\n top: 30,\r\n left: 0,\r\n },\r\n font: {\r\n size: FONT_SIZE.XXXL,\r\n style: 'bold',\r\n },\r\n },\r\n ohlc: {\r\n margin: {\r\n top: 30,\r\n left: 30,\r\n right: 30,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n },\r\n },\r\n change: {\r\n margin: {\r\n top: 30,\r\n right: 0,\r\n },\r\n font: {\r\n size: FONT_SIZE.M,\r\n style: 'bold',\r\n },\r\n },\r\n },\r\n right: {\r\n width: CHART_MARGIN.XXL,\r\n axis: {\r\n margin: {\r\n left: 0,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n lineHeight: LINE_HEIGHT.S,\r\n padding: {\r\n top: PADDING.XXS,\r\n bottom: PADDING.XXS,\r\n left: PADDING.XXS,\r\n right: PADDING.XXS,\r\n },\r\n },\r\n },\r\n },\r\n bottom: {\r\n height: CHART_MARGIN.M,\r\n baseline: TextBaseline.top,\r\n axis: {\r\n margin: {\r\n top: 8,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n },\r\n },\r\n },\r\n left: {\r\n width: CHART_MARGIN.L,\r\n overlayLabel: {\r\n labelSpacing: 12,\r\n margin: {\r\n top: -8,\r\n left: 6,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n weight: 'bold',\r\n },\r\n },\r\n timeframe: {\r\n margin: {\r\n top: 0,\r\n left: 28,\r\n },\r\n font: {\r\n size: FONT_SIZE.M,\r\n weight: '900',\r\n family: 'Lato, sans-serif',\r\n },\r\n },\r\n volumeAxis: {\r\n margin: {\r\n left: 33,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n },\r\n },\r\n },\r\n },\r\n IndicatorSettings: {\r\n general: {\r\n height: 140,\r\n Colors: theme === Theme.light ? indicatorLightTheme : indicatorDarkTheme,\r\n },\r\n center: {\r\n barWidth: 3,\r\n barMargin: 2,\r\n border: 1,\r\n },\r\n top: {\r\n height: CHART_MARGIN.S,\r\n },\r\n right: {\r\n width: CHART_MARGIN.XXL,\r\n axis: {\r\n margin: {\r\n left: 0,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n lineHeight: LINE_HEIGHT.S,\r\n padding: {\r\n top: PADDING.XXS,\r\n bottom: PADDING.XXS,\r\n left: PADDING.XXS,\r\n right: PADDING.XXS,\r\n },\r\n },\r\n },\r\n },\r\n bottom: {\r\n height: CHART_MARGIN.S,\r\n },\r\n left: {\r\n width: CHART_MARGIN.L,\r\n indicatorLabel: {\r\n labelSpacing: 4,\r\n margin: {\r\n top: OFFSET.S,\r\n left: OFFSET.M,\r\n },\r\n font: {\r\n size: FONT_SIZE.M,\r\n style: 'bold',\r\n lineHeight: LINE_HEIGHT.M,\r\n },\r\n },\r\n },\r\n },\r\n MarketSentimentSettings: {\r\n general: {\r\n Colors: theme === Theme.light ? chartLightTheme : chartDarkTheme,\r\n },\r\n center: {\r\n barWidth: 3,\r\n barMargin: 1,\r\n border: 1,\r\n },\r\n top: {\r\n height: 0,\r\n },\r\n bottom: {\r\n height: 12,\r\n },\r\n left: {\r\n width: 0,\r\n },\r\n right: {\r\n width: 30,\r\n },\r\n },\r\n ColorsSettings: generalColors,\r\n ThumbSettings: {\r\n size: 8,\r\n touchSize: 16,\r\n color: '#ddd',\r\n borderWidth: 1,\r\n borderColor: '#999',\r\n },\r\n ElementSettings: {\r\n Colors: theme === Theme.light ? elementLightTheme : elementDarkTheme,\r\n defaultFill: '#1e6dc066',\r\n defaultTransparentFill: '#1e6dc000',\r\n },\r\n})\r\n","import merge from 'lodash.merge'\r\n\r\nimport { ChartConfigChart } from '../../server/chartConfig'\r\nimport { Instrument, ObjectHash, Theme } from '../../types/shared'\r\nimport { SpecificChartFunctionality } from '../constants/common'\r\nimport Utils, { isRedesignedPage } from '../utils'\r\nimport LayoutModel from './chart_layout'\r\nimport { getColorOverwrites } from './chart_settings'\r\nimport { largeChartFontSize } from './chart_settings/constants'\r\nimport { INTERACTIVE_CHART_SETTINGS } from './chart_settings/interactive_chart_settings'\r\nimport { ISettings } from './chart_settings/interfaces'\r\nimport {\r\n IChartThemeColors,\r\n chartDarkTheme,\r\n chartLightTheme,\r\n elementDarkTheme,\r\n elementLightTheme,\r\n indicatorDarkTheme,\r\n indicatorLightTheme,\r\n} from './constants'\r\n\r\ninterface Config {\r\n theme: Theme\r\n barMargin?: number\r\n barWidth?: number\r\n border?: number\r\n charts?: ChartConfigChart[]\r\n colorsOverride?: Array\r\n volumeHeight?: number\r\n colors?: ObjectHash, Theme>\r\n specificChartFunctionality?: SpecificChartFunctionality\r\n isOurSiteRequest?: boolean\r\n}\r\n\r\nexport function getSettings(config: Config, chartSettings?: ISettings): ISettings {\r\n const settings = merge({}, chartSettings ?? INTERACTIVE_CHART_SETTINGS(config.theme))\r\n\r\n if (config.barWidth != null) {\r\n settings.ChartSettings.center.barWidth = config.barWidth\r\n settings.IndicatorSettings.center.barWidth = config.barWidth\r\n }\r\n if (config.barMargin != null) {\r\n settings.ChartSettings.center.barMargin = config.barMargin\r\n settings.IndicatorSettings.center.barMargin = config.barMargin\r\n }\r\n if (config.border != null) {\r\n settings.ChartSettings.center.border = config.border\r\n settings.IndicatorSettings.center.border = config.border\r\n }\r\n if (config.colorsOverride) {\r\n settings.ColorsSettings = config.colorsOverride\r\n }\r\n if (config.volumeHeight) {\r\n settings.ChartSettings.center.volumeHeight = config.volumeHeight\r\n }\r\n if (config.colors) {\r\n const settingColors = settings.ChartSettings.general.Colors\r\n settings.ChartSettings.general.Colors = {\r\n ...settingColors,\r\n [Theme.light]: {\r\n ...settingColors[Theme.light],\r\n ...getColorOverwrites({ theme: Theme.light, colors: config.colors }),\r\n },\r\n [Theme.dark]: {\r\n ...settingColors[Theme.dark],\r\n ...getColorOverwrites({ theme: Theme.dark, colors: config.colors }),\r\n },\r\n }\r\n }\r\n if (config.specificChartFunctionality === SpecificChartFunctionality.chartPage && Utils.isMobile()) {\r\n settings.ChartSettings.left.width = 0\r\n settings.ChartSettings.top.ticker.margin.left = settings.ChartSettings.left.overlayLabel.margin.left\r\n settings.IndicatorSettings.left.width = 0\r\n }\r\n if (SpecificChartFunctionality.chartPage === config.specificChartFunctionality || isRedesignedPage(config)) {\r\n settings.ChartSettings.top.height = 10\r\n }\r\n\r\n if (config.specificChartFunctionality === SpecificChartFunctionality.offScreen) {\r\n const isGroupInstrument = config.charts?.some(({ instrument }) => instrument === Instrument.Group)\r\n if (isGroupInstrument) {\r\n settings.ChartSettings.top.ohlc.margin.top = 4\r\n settings.ChartSettings.top.ticker.margin.top = 0\r\n settings.ChartSettings.top.ticker.font = {\r\n size: largeChartFontSize.XXL,\r\n style: 'bold',\r\n }\r\n settings.ChartSettings.left.timeframe.margin.top = 12\r\n settings.ChartSettings.left.timeframe.font = {\r\n size: largeChartFontSize.S,\r\n style: 'bold',\r\n }\r\n }\r\n }\r\n\r\n if (config.isOurSiteRequest !== undefined) {\r\n settings.isOurSiteRequest = config.isOurSiteRequest\r\n }\r\n\r\n return settings\r\n}\r\n\r\nexport function updateSettings(chart_layout: LayoutModel, theme: string): ISettings {\r\n const settings = merge({}, chart_layout.settings)\r\n const isLight = theme === Theme.light\r\n settings.MarketSentimentSettings.general.Colors = isLight ? { ...chartLightTheme } : { ...chartDarkTheme }\r\n settings.IndicatorSettings.general.Colors = isLight ? { ...indicatorLightTheme } : { ...indicatorDarkTheme }\r\n settings.ElementSettings.Colors = isLight ? { ...elementLightTheme } : { ...elementDarkTheme }\r\n\r\n return settings\r\n}\r\n\r\nexport function getChartLayoutSettings(chart_layout: LayoutModel): ISettings {\r\n const settings = chart_layout.settings\r\n\r\n return {\r\n ...settings,\r\n ChartSettings: {\r\n ...settings.ChartSettings,\r\n general: {\r\n ...settings.ChartSettings.general,\r\n Colors: {\r\n ...settings.ChartSettings.general.Colors,\r\n ...settings.ChartSettings.general.Colors[chart_layout.theme],\r\n },\r\n },\r\n },\r\n }\r\n}\r\n","import { Instrument } from '../../types/shared'\r\nimport ChartLayoutModel from './chart_layout'\r\nimport Element from './element'\r\n\r\nexport const handleRemoveIndicatorPane = ({\r\n paneIndex,\r\n chartLayoutModel,\r\n}: {\r\n paneIndex: number\r\n chartLayoutModel: ChartLayoutModel\r\n}) => {\r\n const charts = chartLayoutModel.getAllCharts()\r\n charts.forEach((chart) => chart.getAllPanes()[paneIndex].destroyCascade())\r\n}\r\n\r\nexport function getNormalizedZIndex({ index, isBelowZero }: { index: number; isBelowZero: boolean }) {\r\n return (index + 1) * (isBelowZero ? -1 : 1)\r\n}\r\n\r\nexport function rebuildElementZIndexes({\r\n elementsArray,\r\n isBelowZero,\r\n}: {\r\n elementsArray: Element[]\r\n isBelowZero: boolean\r\n}) {\r\n const elements = isBelowZero ? [...elementsArray].reverse() : elementsArray\r\n elements.forEach((element, index) => {\r\n const newZIndex = getNormalizedZIndex({ index, isBelowZero })\r\n if (newZIndex !== element.zIndex) {\r\n element.updateAttributes({ zIndex: newZIndex })\r\n }\r\n })\r\n}\r\n\r\nexport function changeElementZIndexes({\r\n elementsArray,\r\n addElement,\r\n oldZIndex,\r\n newZIndex,\r\n isBelowZero = false,\r\n}: {\r\n elementsArray: Element[]\r\n addElement: Element | undefined\r\n oldZIndex: number\r\n newZIndex: number\r\n isBelowZero?: boolean\r\n}) {\r\n const array = isBelowZero ? [...elementsArray].reverse() : elementsArray\r\n const elements =\r\n elementsArray.length === 0 && addElement\r\n ? [...array, addElement]\r\n : array\r\n .filter((_, index) => getNormalizedZIndex({ index, isBelowZero }) !== oldZIndex)\r\n .flatMap((el, index) =>\r\n getNormalizedZIndex({ index, isBelowZero }) === newZIndex && addElement ? [addElement, el] : el\r\n )\r\n\r\n // If there are only 2 drawings and we move a drawing from index 1 to index 2 to have to push it to the array because it's the last element and it didn't get into the array in the flatMap above\r\n if (elements.length < Math.abs(newZIndex) && addElement) {\r\n elements.push(addElement)\r\n }\r\n\r\n rebuildElementZIndexes({ elementsArray: isBelowZero ? [...elements].reverse() : elements, isBelowZero })\r\n}\r\n\r\nexport function getRawTickerForInstrument(instrument: Instrument, ticker: string) {\r\n return `${\r\n [Instrument.Crypto, Instrument.Forex, Instrument.Futures].includes(instrument) && !ticker.includes('@') ? '@' : ''\r\n }${ticker}`\r\n}\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n color: string\r\n}\r\n\r\nexport class EMAConfig extends BaseConfig {\r\n static type = OverlayType.Ema\r\n static abbreviation = 'ema'\r\n static label = 'Exponential Moving Average'\r\n static shortLabel = 'EMA'\r\n static description =\r\n 'The EMA is a moving average that gives more weight to recent prices, making it more responsive to price changes. A rising EMA suggests an uptrend, while a falling EMA indicates a downtrend, helping to identify the direction of the trend.'\r\n\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = ['period', 'color'] as Array\r\n static inputsLabels = { period: 'Period', color: 'Color' }\r\n static calculatedValuesOrder = ['ema'] as const\r\n static calculatedValuesLabels = { ema: 'EMA' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import type { ObjectHash } from '../../../types/shared'\r\nimport ElementBaseConfig from '../../canvas/ElementBaseConfig'\r\nimport { OverlayType } from '../../constants/common'\r\n\r\nexport default class OverlayBaseConfig extends ElementBaseConfig {\r\n static type = OverlayType.Overlay\r\n static abbreviation = 'ovl'\r\n static label = 'Overlay'\r\n static shortLabel = 'Overlay'\r\n static optionsOrder = [] as readonly string[]\r\n static optionsLabels = {}\r\n static inputsOrder = [] as readonly string[]\r\n static inputsLabels = {}\r\n static calculatedValuesOrder = [] as readonly string[]\r\n static calculatedValuesLabels = {}\r\n static defaultCalculatedValueOption = undefined as undefined | string\r\n\r\n get defaultCalculatedValueOption() {\r\n return (this.constructor as typeof OverlayBaseConfig).defaultCalculatedValueOption\r\n }\r\n\r\n static getShortLabelWithAttrs(attrs: ObjectHash) {\r\n return `${this.shortLabel} ${this.optionsOrder.map((item) => attrs[item]).join(',')}`\r\n }\r\n\r\n get getShortLabelWithAttrs() {\r\n return (this.constructor as typeof OverlayBaseConfig).getShortLabelWithAttrs\r\n }\r\n\r\n static getDefaultCalculatedValues() {\r\n return this.calculatedValuesOrder.reduce((prev, curr) => ({ ...prev, [curr]: [] }), {})\r\n }\r\n\r\n get getDefaultCalculatedValues() {\r\n return (this.constructor as typeof OverlayBaseConfig).getDefaultCalculatedValues\r\n }\r\n}\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n deviations: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n topColor?: string\r\n bottomColor?: string\r\n}\r\n\r\nexport class BBConfig extends BaseConfig {\r\n static type = OverlayType.Bb\r\n static abbreviation = 'bb'\r\n static label = 'Bollinger Bands'\r\n static shortLabel = 'BB'\r\n static description =\r\n 'Bollinger Bands are a volatility indicator that consists of three lines: a middle line (20 period simple moving average), an upper band (2 standard deviations above the SMA), and a lower band (2 standard deviations below the SMA). They help identify overbought or oversold conditions; prices near the upper band may indicate overbought, while prices near the lower band may suggest oversold conditions.'\r\n\r\n static optionsOrder = ['period', 'deviations'] as const\r\n static optionsLabels = { period: 'Period', deviations: 'Deviations' }\r\n static inputsOrder = ['period', 'deviations', 'topColor', 'bottomColor'] as Array\r\n static inputsLabels = {\r\n period: 'Period',\r\n deviations: 'Deviations',\r\n topColor: 'Top Color',\r\n bottomColor: 'Bottom Color',\r\n }\r\n\r\n static calculatedValuesOrder = ['upperBand', 'sma', 'lowerBand'] as const\r\n static calculatedValuesLabels = {\r\n sma: 'SMA',\r\n upperBand: 'Upper Band',\r\n lowerBand: 'Lower Band',\r\n }\r\n\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[1]\r\n}\r\n","import { BBConfig, Options } from '../overlays/configs/bb'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n sma: number[]\r\n upperBand: number[]\r\n lowerBand: number[]\r\n}\r\n\r\nexport class BbCalculation extends MainCalculation {\r\n static config = BBConfig\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period, deviations } = this.options\r\n const { close } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n if (close.length < period) return\r\n\r\n let sum = 0\r\n const stdDev = []\r\n\r\n for (let i = 0; i < period; i++) {\r\n sum += close[i]\r\n }\r\n const initialPeriodIndex = period - 1\r\n for (let i = initialPeriodIndex; i < close.length; i++) {\r\n if (i > initialPeriodIndex) sum = sum - close[i - period] + close[i]\r\n this.calculatedValues.sma[i] = sum / period\r\n\r\n let stdDevSum = 0\r\n for (let j = i - period + 1; j <= i; j++) {\r\n stdDevSum += Math.pow(close[j] - this.calculatedValues.sma[i], 2)\r\n }\r\n stdDev[i] = Math.sqrt(stdDevSum / period)\r\n\r\n this.calculatedValues.upperBand[i] = this.calculatedValues.sma[i] + stdDev[i] * deviations\r\n this.calculatedValues.lowerBand[i] = this.calculatedValues.sma[i] - stdDev[i] * deviations\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import {\r\n ChartConfigChartPaneElement,\r\n IModalConfig,\r\n IModalConfigInput,\r\n ObjectHash,\r\n RequireByKey,\r\n} from '../../types/shared'\r\nimport Element from '../canvas/element'\r\nimport BaseChart from '../charts/base_chart'\r\nimport { OverlayType } from '../constants/common'\r\nimport Quote from '../models/quote'\r\nimport { convertColorToHEX, getRGBAValueFromValidColorString } from '../utils/colors'\r\nimport { getParsedIntegersFromPeriodString, isInRange, isPositiveInteger } from '../utils/helpers'\r\nimport OverlayConfig from './configs/overlayBaseConfig'\r\n\r\nexport interface IOverlayIsValid {\r\n getIsValid(key: string): boolean | void\r\n}\r\n\r\nconst DEFAULT_LABEL_COLOR = '#0587cd'\r\n\r\nclass Overlay extends Element implements IOverlayIsValid {\r\n static config = OverlayConfig\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt] = getParsedIntegersFromPeriodString(period)\r\n return periodInt\r\n }\r\n\r\n declare data: Quote\r\n declare chart: BaseChart\r\n\r\n get type() {\r\n return (this.constructor as typeof Overlay).config.type as OverlayType\r\n }\r\n\r\n get label() {\r\n return (this.constructor as typeof Overlay).config.label\r\n }\r\n\r\n get config() {\r\n return (this.constructor as typeof Overlay).config\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.color ? convertColorToHEX(this.attrs.color) : DEFAULT_LABEL_COLOR\r\n }\r\n\r\n getFreeColor() {\r\n return this.getChartLayoutSettings().ColorsSettings[0]\r\n // TODO proper implementation - example how this could be done:\r\n // let colorsUsed = []\r\n // for (let overlay of this.chart.overlays) {\r\n // let object = overlay.getModalConfig().inputs\r\n // for (let _ in object) {\r\n // let input = object[_]\r\n // if (input.type === 'color') {\r\n // colorsUsed.push(input.value)\r\n // }\r\n // }\r\n // }\r\n // for (let color of colors) {\r\n // if (!colorsUsed.includes(color)) {\r\n // return color\r\n // }\r\n // }\r\n // return colors[0]\r\n }\r\n\r\n renderContent(_?: RenderingContext2DType) {\r\n this.data = this.model.chart().quote()\r\n }\r\n\r\n fx = (x: number) => this.model.scale.x(this.data.barIndex[x])\r\n\r\n getIsValid(_: string): boolean | undefined {\r\n throw Error('Implement')\r\n }\r\n\r\n getIsNumberInputValid({ key, integerOnly = true }: { key: string; integerOnly?: boolean }): boolean {\r\n const input = this.getModalConfig().inputs.find(({ name }: { name: string }) => key === name)\r\n return !!input && isInRange(input) && (!integerOnly || isPositiveInteger(input.value))\r\n }\r\n\r\n isRendered() {\r\n return true\r\n }\r\n\r\n isRenderedOverlaysLabel() {\r\n return this.isRendered()\r\n }\r\n\r\n getModalConfig(): IModalConfig {\r\n return {\r\n title: '',\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n toConfig() {\r\n const colors: string[] = []\r\n const periods: string[] = []\r\n\r\n this.getModalConfig().inputs.forEach((input: IModalConfigInput) => {\r\n if (input.type === 'color') {\r\n colors.push(getRGBAValueFromValidColorString(input.value.toString()))\r\n } else {\r\n periods.push(input.value.toString())\r\n }\r\n })\r\n\r\n return { type: this.type, period: periods.join(','), color: colors.join('|') }\r\n }\r\n\r\n toString() {\r\n return this.config.getShortLabelWithAttrs(this.attrs)\r\n }\r\n}\r\n\r\nexport default Overlay\r\n","import { ChartConfigChartPaneElement, RequireByKey, Theme } from '../../types/shared'\r\nimport { BbCalculation } from '../indicator-calculation/bb'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport { Attrs, BBConfig } from './configs/bb'\r\nimport Overlay from './overlay'\r\n\r\nconst BB_COLORS = {\r\n [Theme.light]: {\r\n TOP: '#D386DF',\r\n BOTTOM: '#69C1EA',\r\n MIDDLE: '#CFD2F2',\r\n },\r\n [Theme.dark]: {\r\n TOP: '#D38BFB',\r\n BOTTOM: '#57AEFB',\r\n MIDDLE: '#E1B6FC',\r\n },\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Period: 20,\r\n Deviations: 2.0,\r\n}\r\n\r\nfunction parsePeriod(periodStr: string) {\r\n const values = periodStr.split(',')\r\n const period = parseInt(values[0]) || DEFAULT_PARAMETERS.Period\r\n const deviations = parseFloat(values[1]) || DEFAULT_PARAMETERS.Deviations\r\n\r\n return [period, deviations]\r\n}\r\n\r\nclass BollingerBands extends Overlay {\r\n static config = BBConfig\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt = 0] = getParsedIntegersFromPeriodString(period)\r\n return periodInt + 1 // +1 offsets rendering so it doesn't start on first bar which doesn't look OK in SSR rendered charts\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n const [periodInt, deviations] = parsePeriod(period)\r\n this.attrs.period = periodInt\r\n this.attrs.deviations = deviations\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n if (typeof this.attrs.period !== 'number') {\r\n return\r\n }\r\n super.renderContent()\r\n const { Colors } = this.getChartLayoutSettings().ChartSettings.general\r\n const theme = this.model.chart().chart_layout().theme as Theme\r\n const { leftOffset, width } = this.model.chart()\r\n const [top, bottom] = this.model.scale.y.domain()\r\n const scaledTop = this.fy(top)\r\n const scaledBottom = this.fy(bottom)\r\n const { close } = this.data\r\n const period = Math.min(this.attrs.period, close.length - 1)\r\n\r\n let firstBarToRender: number | undefined\r\n let lastBarToRender = 0\r\n\r\n // middle line && find first & last bar to render\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', BB_COLORS[theme].MIDDLE)\r\n\r\n const bbCalculation = new BbCalculation({\r\n quote: this.data,\r\n options: {\r\n period,\r\n deviations: this.attrs.deviations,\r\n },\r\n })\r\n\r\n bbCalculation.calculate(({ sma }, dataIndex) => {\r\n if (this.fx(dataIndex + 1) + leftOffset < 0) {\r\n return\r\n }\r\n if (firstBarToRender === undefined) firstBarToRender = dataIndex\r\n\r\n context.lineTo(this.fx(dataIndex), Math.round(this.fy(sma[dataIndex])))\r\n\r\n if (this.fx(dataIndex - 1) + leftOffset > width) {\r\n return false\r\n }\r\n lastBarToRender = dataIndex\r\n })\r\n\r\n if (firstBarToRender === undefined) return\r\n context.stroke()\r\n context.set('fillStyle', Colors.overlayTransparentBackground)\r\n\r\n // top line\r\n context.beginPath()\r\n context.moveTo(this.fx(firstBarToRender), scaledTop)\r\n context.set('strokeStyle', BB_COLORS[theme].TOP)\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(bbCalculation.calculatedValues.upperBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), scaledTop)\r\n context.fill()\r\n\r\n // bottom line\r\n context.beginPath()\r\n context.moveTo(this.fx(firstBarToRender), scaledBottom)\r\n context.set('strokeStyle', BB_COLORS[theme].BOTTOM)\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(bbCalculation.calculatedValues.lowerBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), scaledBottom)\r\n context.fill()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: BBConfig.inputsLabels.period,\r\n name: 'period',\r\n value: this.attrs.period ?? DEFAULT_PARAMETERS.Period,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n deviations: {\r\n type: 'number',\r\n label: BBConfig.inputsLabels.deviations,\r\n name: 'deviations',\r\n value: this.attrs.deviations ?? DEFAULT_PARAMETERS.Deviations,\r\n required: true,\r\n min: 0.1,\r\n max: 999,\r\n step: 0.1,\r\n },\r\n topColor: {\r\n type: 'color',\r\n label: BBConfig.inputsLabels.topColor,\r\n name: 'topColor',\r\n value: this.attrs.topColor ?? this.getFreeColor(),\r\n },\r\n bottomColor: {\r\n type: 'color',\r\n label: BBConfig.inputsLabels.bottomColor,\r\n name: 'bottomColor',\r\n value: this.attrs.bottomColor ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: BBConfig.label,\r\n inputs: BBConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n deviations: `${options.deviations.label} must be a number between ${options.deviations.min} and ${options.deviations.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'deviations':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n case 'topColor':\r\n case 'bottomColor':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n const theme = this.model.chart().chart_layout().theme as Theme\r\n return this.attrs.topColor || BB_COLORS[theme].TOP\r\n }\r\n}\r\n\r\nBollingerBands.prototype.defaults = { topColor: '#69c1ea', bottomColor: '#d386df' }\r\n\r\nexport default BollingerBands\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n channelStrokeColor: string\r\n channelFillColor: string\r\n medianBandColor: string\r\n}\r\n\r\nexport class DchConfig extends BaseConfig {\r\n static type = OverlayType.Dch\r\n static abbreviation = 'dch'\r\n static label = 'Donchian Channels'\r\n static shortLabel = 'Donchian'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = ['period', 'channelStrokeColor', 'channelFillColor', 'medianBandColor'] as Array\r\n static inputsLabels = {\r\n period: 'Period',\r\n channelStrokeColor: 'Channels Stroke Color',\r\n channelFillColor: 'Channels Fill Color',\r\n medianBandColor: 'Median Band Color',\r\n }\r\n}\r\n","import utils from '../utils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { Attrs, DchConfig } from './configs/dch'\r\nimport Overlay from './overlay'\r\n\r\nconst DEFAULT_PERIOD = 20\r\n\r\nconst COLORS = {\r\n ChannelStroke: '#69c1ea',\r\n ChannelFill: '#69C1EA12',\r\n MedianBandStroke: '#ffa75f',\r\n}\r\n\r\nclass DonchianChannels extends Overlay {\r\n static config = DchConfig\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n this.attrs.period = parseInt(period, 10)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const { period } = this.attrs\r\n const upperBand: number[] = []\r\n const lowerBand: number[] = []\r\n const medianBand: number[] = []\r\n let firstBarToRender = -1\r\n let lastBarToRender = 0\r\n if (this.data.close.length === undefined) {\r\n return\r\n }\r\n\r\n context.save()\r\n context.translate(0.5, 0.5)\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', COLORS.ChannelStroke)\r\n context.set('fillStyle', COLORS.ChannelFill)\r\n\r\n //upper band + clip\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset,\r\n width,\r\n drawBarCallback: (i, x) => {\r\n firstBarToRender = firstBarToRender === -1 ? i : firstBarToRender\r\n upperBand[i] = utils.max(this.data.high.slice(Math.max(0, i - period), i + 1))\r\n lowerBand[i] = utils.min(this.data.low.slice(Math.max(0, i - period), i + 1))\r\n medianBand[i] = (upperBand[i] + lowerBand[i]) / 2\r\n\r\n context.lineTo(x, Math.round(this.fy(upperBand[i])))\r\n lastBarToRender = i\r\n },\r\n })\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), context.canvas.height)\r\n context.lineTo(this.fx(firstBarToRender), context.canvas.height)\r\n context.clip()\r\n\r\n // lower band + fill\r\n context.beginPath()\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(lowerBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), 0)\r\n context.lineTo(0, 0)\r\n context.fill()\r\n\r\n // median band\r\n context.set('strokeStyle', COLORS.MedianBandStroke)\r\n context.beginPath()\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(medianBand[i])))\r\n }\r\n context.stroke()\r\n context.restore()\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? DEFAULT_PERIOD,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n channelStrokeColor: {\r\n type: 'color',\r\n label: 'Channels Stroke Color',\r\n name: 'channelStrokeColor',\r\n value: this.attrs.channelStrokeColor ?? this.getFreeColor(),\r\n },\r\n channelFillColor: {\r\n type: 'color',\r\n label: 'Channels Fill Color',\r\n name: 'channelFillColor',\r\n value: this.attrs.channelFillColor ?? this.getFreeColor(),\r\n },\r\n medianBandColor: {\r\n type: 'color',\r\n label: 'Median Band Color',\r\n name: 'medianBandColor',\r\n value: this.attrs.medianBandColor ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: DchConfig.label,\r\n inputs: DchConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'channelStrokeColor':\r\n case 'channelFillColor':\r\n case 'medianBandColor':\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.medianBandColor\r\n }\r\n}\r\n\r\nDonchianChannels.prototype.defaults = {\r\n medianBandColor: COLORS.MedianBandStroke,\r\n channelStrokeColor: COLORS.ChannelStroke,\r\n channelFillColor: COLORS.ChannelFill,\r\n}\r\n\r\nexport default DonchianChannels\r\n","import { EMACalculation } from '../indicator-calculation/ema'\r\nimport { Attrs, EMAConfig } from './configs/ema'\r\nimport Overlay from './overlay'\r\n\r\nclass EMA extends Overlay {\r\n static config = EMAConfig\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n this.attrs.period = parseInt(period, 10)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', this.attrs.color)\r\n const emaCalculation = new EMACalculation({\r\n quote: this.data,\r\n options: {\r\n period: this.attrs.period,\r\n },\r\n })\r\n emaCalculation.calculate(({ ema }, dataIndex) => {\r\n const x = this.fx(dataIndex)\r\n if (this.fx(dataIndex + 1) + leftOffset < 0) {\r\n return\r\n }\r\n if (this.fx(dataIndex - 1) + leftOffset > width) {\r\n return false\r\n }\r\n context.lineTo(x, Math.round(this.fy(ema[dataIndex])))\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? 5,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n color: {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: this.config.label,\r\n inputs: this.config.inputsOrder.map((item) => options[item as keyof Attrs]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'color':\r\n return !!this.attrs[key] // use real color validation, we got isValidHexColor but it might be also RGBA\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nEMA.prototype.defaults = { color: '#ffa75f' }\r\n\r\nexport default EMA\r\n","import { OverlayType } from '../../constants/common'\r\nimport { EMAConfig } from './ema'\r\n\r\nexport class EMA2Config extends EMAConfig {\r\n static type = OverlayType.Ema2\r\n}\r\n","import { EMA2Config } from './configs/ema2'\r\nimport EMA from './ema'\r\n\r\nclass EMA2 extends EMA {\r\n static config = EMA2Config\r\n}\r\n\r\nEMA2.prototype.defaults = { color: '#ff6400' }\r\n\r\nexport default EMA2\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n lowColor: string\r\n highColor: string\r\n}\r\n\r\nexport class HILOConfig extends BaseConfig {\r\n static type = OverlayType.Hilo\r\n static abbreviation = 'hilo'\r\n static label = 'High/Low'\r\n static shortLabel = 'HILO'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = ['period', 'highColor', 'lowColor'] as Array\r\n static inputsLabels = {\r\n period: 'Period',\r\n highColor: 'High Color',\r\n lowColor: 'Low Color',\r\n }\r\n}\r\n","import PaneModel from '../models/pane'\r\nimport { getBarWidthWithMargin } from '../utils/chart'\r\nimport { Attrs, HILOConfig } from './configs/hilo'\r\nimport Overlay from './overlay'\r\n\r\nclass HighLow extends Overlay {\r\n static config = HILOConfig\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.renderContent = this.renderContent.bind(this)\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n this.attrs.period = parseInt(period, 10)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const chartModel = this.model.chart()\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const { leftOffset, width, zoomFactor } = chartModel\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor,\r\n chartLayout: chartModel.chart_layout(),\r\n })\r\n const halfWidth = barWidth / 2\r\n const period = Math.min(this.attrs.period, this.data.close.length - 1)\r\n let firstBarToRender\r\n let lastBarToRender = 0\r\n context.translate(0.5, 0.5)\r\n context.set('fillStyle', Colors.overlayTransparentBackground)\r\n context.beginPath()\r\n context.set('strokeStyle', this.attrs.highColor)\r\n let prevHigh = -1\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n let highestHigh = this.data.high[i]\r\n for (let j = i - period + 1; j <= i; j++) {\r\n if (this.data.high[j] > highestHigh) {\r\n highestHigh = this.data.high[j]\r\n }\r\n }\r\n\r\n const x = this.fx(i)\r\n if (this.fx(i + 1) + leftOffset < -10) {\r\n prevHigh = highestHigh\r\n continue\r\n }\r\n if (firstBarToRender === undefined) firstBarToRender = i\r\n if (this.fx(i - 1) + leftOffset > width) {\r\n break\r\n }\r\n\r\n const diff = this.data.barIndex[i] - this.data.barIndex[lastBarToRender]\r\n if (diff > 1 && prevHigh !== highestHigh && prevHigh > 0) {\r\n context.lineTo(Math.round(x - halfWidth), Math.round(this.fy(prevHigh)))\r\n }\r\n context.lineTo(Math.round(x - halfWidth), Math.round(this.fy(highestHigh)))\r\n context.lineTo(Math.round(x + halfWidth), Math.round(this.fy(highestHigh)))\r\n\r\n prevHigh = highestHigh\r\n lastBarToRender = i\r\n }\r\n context.stroke()\r\n if (firstBarToRender === undefined) return\r\n\r\n // return to start and fill with background color\r\n context.lineTo(this.fx(lastBarToRender) + halfWidth, 0)\r\n context.lineTo(this.fx(firstBarToRender) - halfWidth, 0)\r\n context.fill()\r\n\r\n context.beginPath()\r\n context.set('strokeStyle', this.attrs.lowColor)\r\n let prevLow = -1\r\n let prevBar = firstBarToRender\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n let lowestLow = this.data.low[i]\r\n for (let j = i - period + 1; j <= i; j++) {\r\n if (this.data.low[j] < lowestLow) {\r\n lowestLow = this.data.low[j]\r\n }\r\n }\r\n\r\n const x = this.fx(i)\r\n const diff = this.data.barIndex[i] - this.data.barIndex[prevBar]\r\n if (diff > 1 && prevLow !== lowestLow && prevLow > 0) {\r\n context.lineTo(Math.round(x - halfWidth), Math.round(this.fy(prevLow)))\r\n }\r\n context.lineTo(Math.round(x - halfWidth), Math.round(this.fy(lowestLow)))\r\n context.lineTo(Math.round(x + halfWidth), Math.round(this.fy(lowestLow)))\r\n\r\n prevLow = lowestLow\r\n prevBar = i\r\n }\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n\r\n // return to start and fill with background color\r\n context.lineTo(this.fx(lastBarToRender), context.canvas.height)\r\n context.lineTo(this.fx(firstBarToRender) - halfWidth, context.canvas.height)\r\n context.fill()\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? 50,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n highColor: {\r\n type: 'color',\r\n label: 'High Color',\r\n name: 'highColor',\r\n value: this.attrs.highColor ?? this.getFreeColor(),\r\n },\r\n lowColor: {\r\n type: 'color',\r\n label: 'Low Color',\r\n name: 'lowColor',\r\n value: this.attrs.lowColor ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: HILOConfig.label,\r\n inputs: HILOConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'highColor':\r\n case 'lowColor':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.highColor\r\n }\r\n}\r\n\r\nHighLow.prototype.defaults = {\r\n lowColor: '#69c1ea',\r\n highColor: '#d386df',\r\n}\r\n\r\nexport default HighLow\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = {\r\n price: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n period: number\r\n color: string\r\n}\r\n\r\nexport class HLineConfig extends BaseConfig {\r\n static type = OverlayType.Hline\r\n static abbreviation = 'hline'\r\n static label = 'Horizontal Line'\r\n static shortLabel = 'HL'\r\n static optionsOrder = ['price'] as const\r\n static optionsLabels = { price: 'Price' }\r\n static inputsOrder = ['price', 'color'] as Array>\r\n static inputsLabels = {\r\n price: 'Price',\r\n color: 'Color',\r\n }\r\n}\r\n","import { isPositiveFloat } from '../utils/helpers'\r\nimport { Attrs, HLineConfig } from './configs/hline'\r\nimport Overlay from './overlay'\r\n\r\nclass HorizontalLine extends Overlay {\r\n static config = HLineConfig\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (typeof this.attrs.period === 'string' && this.attrs.price === undefined) {\r\n this.attrs.price = parseFloat(this.attrs.period)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const y = Math.round(this.fy(this.attrs.price))\r\n context.set('strokeStyle', this.attrs.color)\r\n context.translate(0, 0.5)\r\n context.beginPath()\r\n context.moveTo(-this.model.chart().leftOffset, y)\r\n context.lineTo(-this.model.chart().leftOffset + this.model.chart().width, y)\r\n context.stroke()\r\n context.translate(0, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n price: {\r\n type: 'number',\r\n label: 'Price',\r\n name: 'price',\r\n value: this.attrs.price || this.model?.scale?.y?.domain().reduce((a: number, b: number) => a + b, 0) / 2,\r\n required: true,\r\n step: 0.1,\r\n },\r\n color: {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: HLineConfig.label,\r\n inputs: HLineConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n price: `${options.price.label} must be number`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'price':\r\n return isPositiveFloat(this.attrs[key])\r\n case 'color':\r\n return !!this.attrs[key] // use real color validation, we got isValidHexColor but it might be also RGBA\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nHorizontalLine.prototype.defaults = { color: '#0587cd' }\r\n\r\nexport default HorizontalLine\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = {\r\n conversion: number\r\n base: number\r\n spanB: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n period?: string\r\n spanAStrokeColor: string\r\n spanAFillColor: string\r\n spanBStrokeColor: string\r\n spanBFillColor: string\r\n conversionLineColor: string\r\n baseLineColor: string\r\n laggingSpanColor: string\r\n}\r\n\r\nexport class ICConfig extends BaseConfig {\r\n static type = OverlayType.Ic\r\n static abbreviation = 'ic'\r\n static label = 'Ichimoku Cloud'\r\n static shortLabel = 'Ichimoku'\r\n static optionsOrder = ['conversion', 'base', 'spanB'] as const\r\n\r\n static optionsLabels = {\r\n conversion: 'Conversion Line',\r\n base: 'Base Line Length',\r\n spanB: 'Leading Span B Length',\r\n }\r\n\r\n static inputsOrder = [\r\n ...this.optionsOrder,\r\n 'spanAStrokeColor',\r\n 'spanAFillColor',\r\n 'spanBStrokeColor',\r\n 'spanBFillColor',\r\n 'conversionLineColor',\r\n 'baseLineColor',\r\n 'laggingSpanColor',\r\n ] as Array>\r\n\r\n static inputsLabels = {\r\n ...this.optionsLabels,\r\n spanAStrokeColor: 'Span A Stroke Color',\r\n spanAFillColor: 'Span A Fill Color',\r\n spanBStrokeColor: 'Span B Stroke Color',\r\n spanBFillColor: 'Span B Fill Color',\r\n conversionLineColor: 'Conversion Line Color',\r\n baseLineColor: 'Base Line Color',\r\n laggingSpanColor: 'Lagging Span Color',\r\n }\r\n}\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport { Attrs, ICConfig } from './configs/ic'\r\nimport Overlay from './overlay'\r\n\r\nconst COLORS = {\r\n SpanA: {\r\n Stroke: '#009600',\r\n Fill: '#00960022',\r\n },\r\n SpanB: {\r\n Stroke: '#C80000',\r\n Fill: '#C8000022',\r\n },\r\n ConversionLine: '#69C1EA',\r\n BaseLine: '#E54040',\r\n LaggingSpan: '#FFA75F',\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Conversion: 9,\r\n Base: 26,\r\n SpanB: 52,\r\n}\r\n\r\nfunction parsePeriod(period: string) {\r\n const [conversion = DEFAULT_PARAMETERS.Conversion, base = DEFAULT_PARAMETERS.Base, spanB = DEFAULT_PARAMETERS.SpanB] =\r\n getParsedIntegersFromPeriodString(period)\r\n return [conversion, base, spanB]\r\n}\r\n\r\nclass IchimokuCloud extends Overlay {\r\n static config = ICConfig\r\n static renderFull = false\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n return Math.max(...parsePeriod(period))\r\n }\r\n\r\n get renderFull() {\r\n return (this.constructor as typeof IchimokuCloud).renderFull\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (\r\n typeof this.attrs.period === 'string' &&\r\n (this.attrs.conversion === undefined || this.attrs.base === undefined || this.attrs.spanB === undefined)\r\n ) {\r\n const [conversion, base, spanB] = parsePeriod(this.attrs.period)\r\n this.attrs.conversion = conversion\r\n this.attrs.base = base\r\n this.attrs.spanB = spanB\r\n }\r\n this.trigger('change')\r\n return this\r\n }\r\n\r\n fx = (x: number) => {\r\n const lastIndex = this.data.close.length - 1\r\n const outsideBar = this.data.barIndex[lastIndex] + x - lastIndex\r\n\r\n return this.model.scale.x(this.data.barIndex[x] ?? outsideBar)\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const { high, low, close } = this.data\r\n\r\n const {\r\n conversion,\r\n base,\r\n spanB,\r\n spanAFillColor,\r\n spanAStrokeColor,\r\n spanBFillColor,\r\n spanBStrokeColor,\r\n baseLineColor,\r\n conversionLineColor,\r\n laggingSpanColor,\r\n } = this.attrs\r\n\r\n const conversionLine: number[] = []\r\n const baseLine: number[] = []\r\n const senkouSpanA: number[] = []\r\n const senkouSpanB: number[] = []\r\n const conversionStartIndex = conversion - 1\r\n const baseStartIndex = base - 1\r\n const spanBIndex = spanB - 1\r\n const start = Math.min(baseStartIndex, conversionStartIndex)\r\n const end = close.length + baseStartIndex\r\n\r\n if (this.data.close.length === 0) return\r\n\r\n // Calculation\r\n for (let i = start; i < end; i++) {\r\n if (i >= conversionStartIndex && i < close.length) {\r\n const highestHi = Math.max(...high.slice(i - conversionStartIndex, i + 1))\r\n const lowestLo = Math.min(...low.slice(i - conversionStartIndex, i + 1))\r\n conversionLine[i] = (highestHi + lowestLo) / 2\r\n }\r\n\r\n if (i >= baseStartIndex && i < close.length) {\r\n const highestHi = Math.max(...high.slice(i - baseStartIndex, i + 1))\r\n const lowestLo = Math.min(...low.slice(i - baseStartIndex, i + 1))\r\n baseLine[i] = (highestHi + lowestLo) / 2\r\n\r\n senkouSpanA[i + baseStartIndex] = (baseLine[i] + conversionLine[i]) / 2 // + baseStart because it needs to be shifted to the future\r\n }\r\n\r\n if (i >= spanBIndex) {\r\n const highestHi = Math.max(...high.slice(i - spanBIndex, i + 1))\r\n const lowestLo = Math.min(...low.slice(i - spanBIndex, i + 1))\r\n senkouSpanB[i + baseStartIndex] = (highestHi + lowestLo) / 2 // + baseStart because it needs to be shifted to the future\r\n }\r\n }\r\n\r\n let lastSpanAX = 0\r\n let lastSpanBX = 0\r\n const cloudStartingX = this.fx(spanBIndex + baseStartIndex)\r\n\r\n const drawInVisibleAreaProps = {\r\n toIndexOffset: baseStartIndex,\r\n leftOffset,\r\n paneModel: this.model,\r\n quote: this.data,\r\n width,\r\n fxOverride: this.fx,\r\n }\r\n\r\n context.set('lineWidth', 1)\r\n context.translate(0.5, 0.5)\r\n context.save()\r\n // 1. Senkou Span A\r\n // 1.1 Stroke\r\n context.set('strokeStyle', spanAStrokeColor)\r\n context.set('fillStyle', spanAFillColor)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(senkouSpanA[i])))\r\n lastSpanAX = x\r\n },\r\n })\r\n context.stroke()\r\n // 1.2 Clipping area\r\n context.lineTo(lastSpanAX, context.canvas.height)\r\n context.lineTo(cloudStartingX, context.canvas.height)\r\n context.clip()\r\n // 1.3 Fill\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n if (i >= senkouSpanA.length) return\r\n context.lineTo(x, Math.round(this.fy(senkouSpanB[i])))\r\n lastSpanBX = x\r\n },\r\n })\r\n context.lineTo(lastSpanBX, 0)\r\n context.lineTo(cloudStartingX, 0)\r\n context.fill()\r\n context.restore()\r\n\r\n // 2. Senkou Span B\r\n // 2.1 Stroke\r\n context.save()\r\n context.set('strokeStyle', spanBStrokeColor)\r\n context.set('fillStyle', spanBFillColor)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n if (i >= senkouSpanA.length) return\r\n context.lineTo(x, Math.round(this.fy(senkouSpanB[i])))\r\n },\r\n })\r\n context.stroke()\r\n // 2.2 Clipping area\r\n context.lineTo(lastSpanBX, context.canvas.height)\r\n context.lineTo(cloudStartingX, context.canvas.height)\r\n context.clip()\r\n // 2.3 Fill\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(senkouSpanA[i])))\r\n },\r\n })\r\n context.lineTo(lastSpanBX, 0)\r\n context.lineTo(cloudStartingX, 0)\r\n context.fill()\r\n context.restore()\r\n context.translate(-0.5, -0.5)\r\n\r\n if (this.renderFull) {\r\n // conversion line\r\n context.set('strokeStyle', conversionLineColor)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(conversionLine[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n // base line\r\n context.set('strokeStyle', baseLineColor)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(baseLine[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n // lagging span\r\n context.set('strokeStyle', laggingSpanColor)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n fxOverride: (x: number) => this.fx(x - base),\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.data.close[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n conversion: {\r\n type: 'number',\r\n label: 'Conversion Line',\r\n name: 'conversion',\r\n value: this.attrs.conversion ?? DEFAULT_PARAMETERS.Conversion,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n base: {\r\n type: 'number',\r\n label: 'Base Line Length',\r\n name: 'base',\r\n value: this.attrs.base ?? DEFAULT_PARAMETERS.Base,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n spanB: {\r\n type: 'number',\r\n label: 'Leading Span B Length',\r\n name: 'spanB',\r\n value: this.attrs.spanB ?? DEFAULT_PARAMETERS.SpanB,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n\r\n spanAStrokeColor: {\r\n type: 'color',\r\n label: 'Span A Stroke Color',\r\n name: 'spanAStrokeColor',\r\n value: this.attrs.spanAStrokeColor ?? this.getFreeColor(),\r\n },\r\n spanAFillColor: {\r\n type: 'color',\r\n label: 'Span A Fill Color',\r\n name: 'spanAFillColor',\r\n value: this.attrs.spanAFillColor ?? this.getFreeColor(),\r\n },\r\n spanBStrokeColor: {\r\n type: 'color',\r\n label: 'Span B Stroke Color',\r\n name: 'spanBStrokeColor',\r\n value: this.attrs.spanBStrokeColor ?? this.getFreeColor(),\r\n },\r\n spanBFillColor: {\r\n type: 'color',\r\n label: 'Span B Fill Color',\r\n name: 'spanBFillColor',\r\n value: this.attrs.spanBFillColor ?? this.getFreeColor(),\r\n },\r\n conversionLineColor: {\r\n type: 'color',\r\n label: 'Conversion Line Color',\r\n name: 'conversionLineColor',\r\n value: this.attrs.conversionLineColor ?? this.getFreeColor(),\r\n },\r\n baseLineColor: {\r\n type: 'color',\r\n label: 'Base Line Color',\r\n name: 'baseLineColor',\r\n value: this.attrs.baseLineColor ?? this.getFreeColor(),\r\n },\r\n laggingSpanColor: {\r\n type: 'color',\r\n label: 'Lagging Span Color',\r\n name: 'laggingSpanColor',\r\n value: this.attrs.laggingSpanColor ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: this.config.label,\r\n inputs: this.config.inputsOrder.map((item) => options[item as keyof Omit]),\r\n inputsErrorMessages: {\r\n conversion: `${options.conversion.label} must be a whole number between ${options.conversion.min} and ${options.conversion.max}`,\r\n base: `${options.base.label} must be a whole number between ${options.base.min} and ${options.base.max}`,\r\n spanB: `${options.spanB.label} must be a whole number between ${options.spanB.min} and ${options.spanB.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'conversion':\r\n case 'base':\r\n case 'spanB':\r\n case 'lagging':\r\n return this.getIsNumberInputValid({ key })\r\n case 'spanAStrokeColor':\r\n case 'spanAFillColor':\r\n case 'spanBStrokeColor':\r\n case 'spanBFillColor':\r\n case 'conversionLineColor':\r\n case 'baseLineColor':\r\n case 'laggingSpanColor':\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.spanAStrokeColor\r\n }\r\n}\r\n\r\nIchimokuCloud.prototype.defaults = {\r\n spanAStrokeColor: COLORS.SpanA.Stroke,\r\n spanAFillColor: COLORS.SpanA.Fill,\r\n spanBStrokeColor: COLORS.SpanB.Stroke,\r\n spanBFillColor: COLORS.SpanB.Fill,\r\n conversionLineColor: COLORS.ConversionLine,\r\n baseLineColor: COLORS.BaseLine,\r\n laggingSpanColor: COLORS.LaggingSpan,\r\n}\r\n\r\nexport default IchimokuCloud\r\n","import { OverlayType } from '../../constants/common'\r\nimport { ICConfig } from './ic'\r\n\r\nexport class ICFConfig extends ICConfig {\r\n static type = OverlayType.Icf\r\n static abbreviation = 'icf'\r\n static label = 'Ichimoku Cloud (Full)'\r\n static shortLabel = 'Ichimoku Full'\r\n}\r\n","import { ICFConfig } from './configs/icf'\r\nimport IchimokuCloud from './ic'\r\n\r\nclass IchimokuCloudFull extends IchimokuCloud {\r\n static config = ICFConfig\r\n static renderFull = true\r\n}\r\n\r\nexport default IchimokuCloudFull\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = {\r\n emaPeriod: number\r\n multiplier: number\r\n atrPeriod: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n period?: string\r\n strokeColor: string\r\n fillColor: string\r\n}\r\n\r\nexport class KCHConfig extends BaseConfig {\r\n static type = OverlayType.Kch\r\n static abbreviation = 'kch'\r\n static label = 'Keltner Channel'\r\n static shortLabel = 'Keltner Channel'\r\n static optionsOrder = ['emaPeriod', 'multiplier', 'atrPeriod'] as const\r\n\r\n static optionsLabels = {\r\n emaPeriod: 'EMA Period',\r\n multiplier: 'Multiplier',\r\n atrPeriod: 'ATR Period',\r\n }\r\n\r\n static inputsOrder = [...this.optionsOrder, 'strokeColor', 'fillColor'] as Array>\r\n\r\n static inputsLabels = {\r\n ...this.optionsLabels,\r\n strokeColor: 'Stroke Color',\r\n fillColor: 'Fill Color',\r\n }\r\n}\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport AverageTrueRange from '../helpers/atr'\r\nimport { ExponentialMovingAverage } from '../indicator-calculation/ema'\r\nimport { Attrs, KCHConfig } from './configs/kch'\r\nimport Overlay from './overlay'\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n emaPeriod: 20,\r\n multiplier: 2.0,\r\n atrPeriod: 10,\r\n}\r\n\r\nconst COLORS = {\r\n Stroke: '#69C1EA',\r\n Fill: '#69C1EA33',\r\n}\r\n\r\nfunction parsePeriod(period: string) {\r\n const values = period.split(',')\r\n const emaPeriod = parseInt(values[0])\r\n const multiplier = parseFloat(values[1])\r\n const atrPeriod = parseInt(values[2])\r\n\r\n return [emaPeriod, multiplier, atrPeriod]\r\n}\r\n\r\nclass KeltnerChannel extends Overlay {\r\n static config = KCHConfig\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n return Math.max(...parsePeriod(period)) * 2\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (\r\n typeof this.attrs.period === 'string' &&\r\n (this.attrs.emaPeriod === undefined || this.attrs.multiplier === undefined || this.attrs.atrPeriod === undefined)\r\n ) {\r\n const [emaPeriod, multiplier, atrPeriod] = parsePeriod(this.attrs.period)\r\n this.attrs.emaPeriod = emaPeriod\r\n this.attrs.multiplier = multiplier\r\n this.attrs.atrPeriod = atrPeriod\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const { emaPeriod, multiplier, atrPeriod, strokeColor, fillColor } = this.attrs\r\n const ema = new ExponentialMovingAverage(emaPeriod)\r\n const atr = new AverageTrueRange(atrPeriod)\r\n const middleLine: number[] = []\r\n const upperBand: number[] = []\r\n const lowerBand: number[] = []\r\n const start = Math.max(emaPeriod, atrPeriod)\r\n let firstBarToRender\r\n let lastBarToRender = 0\r\n\r\n context.save()\r\n context.translate(0.5, 0.5)\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', strokeColor)\r\n context.set('fillStyle', fillColor)\r\n\r\n //top line + clip\r\n context.beginPath()\r\n for (let i = 1; i < this.data.close.length; i++) {\r\n ema.add(this.data.close[i])\r\n atr.add(this.data.high[i], this.data.low[i], this.data.close[i - 1])\r\n if (i < start) {\r\n continue\r\n }\r\n\r\n const x = this.fx(i)\r\n if (this.fx(i + 1) + leftOffset < 0) {\r\n continue\r\n }\r\n if (this.fx(i - 1) + leftOffset > width) {\r\n break\r\n }\r\n if (firstBarToRender === undefined) firstBarToRender = i\r\n\r\n middleLine[i] = ema.value\r\n upperBand[i] = ema.value + multiplier * atr.value\r\n lowerBand[i] = ema.value - multiplier * atr.value\r\n\r\n context.lineTo(x, Math.round(this.fy(upperBand[i])))\r\n lastBarToRender = i\r\n }\r\n if (firstBarToRender === undefined) {\r\n context.restore()\r\n return\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), context.canvas.height)\r\n context.lineTo(this.fx(firstBarToRender), context.canvas.height)\r\n context.clip()\r\n\r\n // bottom line + fill\r\n context.beginPath()\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(lowerBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), 0)\r\n context.lineTo(0, 0)\r\n context.fill()\r\n\r\n // middle line\r\n context.beginPath()\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(middleLine[i])))\r\n }\r\n context.stroke()\r\n context.restore()\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n emaPeriod: {\r\n type: 'number',\r\n label: 'EMA Period',\r\n name: 'emaPeriod',\r\n value: this.attrs.emaPeriod ?? DEFAULT_PARAMETERS.emaPeriod,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n multiplier: {\r\n type: 'number',\r\n label: 'Multiplier',\r\n name: 'multiplier',\r\n value: this.attrs.multiplier ?? DEFAULT_PARAMETERS.multiplier,\r\n required: true,\r\n step: 0.1,\r\n min: 0.0,\r\n max: 999,\r\n },\r\n atrPeriod: {\r\n type: 'number',\r\n label: 'ATR Period',\r\n name: 'atrPeriod',\r\n value: this.attrs.atrPeriod ?? DEFAULT_PARAMETERS.atrPeriod,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n strokeColor: {\r\n type: 'color',\r\n label: 'Stroke Color',\r\n name: 'strokeColor',\r\n value: this.attrs.strokeColor ?? this.getFreeColor(),\r\n },\r\n fillColor: {\r\n type: 'color',\r\n label: 'Fill Color',\r\n name: 'fillColor',\r\n value: this.attrs.fillColor ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: KCHConfig.label,\r\n inputs: KCHConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n emaPeriod: `${options.emaPeriod.label} must be a whole number between ${options.emaPeriod.min} and ${options.emaPeriod.max}`,\r\n multiplier: `${options.multiplier.label} must be a number between ${options.multiplier.min} and ${options.multiplier.max}`,\r\n atrPeriod: `${options.atrPeriod.label} must be a whole number between ${options.atrPeriod.min} and ${options.atrPeriod.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'emaPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n case 'multiplier':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n case 'atrPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n case 'strokeColor':\r\n case 'fillColor':\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.strokeColor\r\n }\r\n}\r\n\r\nKeltnerChannel.prototype.defaults = { strokeColor: COLORS.Stroke, fillColor: COLORS.Fill }\r\n\r\nexport default KeltnerChannel\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport class NoneConfig extends BaseConfig {\r\n static type = OverlayType.None\r\n static abbreviation = 'none'\r\n static label = 'None'\r\n static shortLabel = 'None'\r\n}\r\n","import { NoneConfig } from './configs/none'\r\nimport Overlay from './overlay'\r\n\r\n// This indicator is used as a placeholder when we need to render TA like chart but don't need any overlay or indicator in the chart\r\nclass None extends Overlay {\r\n static config = NoneConfig\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n isRendered() {\r\n return false\r\n }\r\n\r\n getIsValid() {\r\n return true\r\n }\r\n}\r\n\r\nexport default None\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\ninterface Attrs {\r\n supportColor: string\r\n resistColor: string\r\n}\r\n\r\nexport class PatternsConfig extends BaseConfig {\r\n static type = OverlayType.Patterns\r\n static abbreviation = 'patterns'\r\n static label = 'Patterns (daily charts)'\r\n static shortLabel = ''\r\n static inputsOrder = ['supportColor', 'resistColor'] as Array\r\n static inputsLabels = { supportColor: 'Support Color', resistColor: 'Resist Color' }\r\n}\r\n","import Text from '../canvas/text'\r\nimport { TextAlign, TextBaseline } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport { PatternsConfig } from './configs/patterns'\r\nimport Overlay from './overlay'\r\n\r\ntype aboveBelowType = 'above' | 'below'\r\n\r\nclass Patterns extends Overlay {\r\n static config = PatternsConfig\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const data = this.data\r\n if (data.patterns.length === 0) {\r\n return\r\n }\r\n\r\n const originalScale = {\r\n width: 600,\r\n height: 300,\r\n barsInDay: Math.min(data.close.length, 200),\r\n high: data.patternsMaxRange,\r\n low: data.patternsMinRange,\r\n barWidth: 0,\r\n }\r\n originalScale.barWidth = originalScale.width / 200\r\n\r\n const scaleY = (originalScale.high - originalScale.low) / originalScale.height\r\n const fx = (x: number) => {\r\n if (x === 0) {\r\n return this.fx(0)\r\n }\r\n return this.fx(data.close.length - 1 - ~~(originalScale.barsInDay - x / originalScale.barWidth))\r\n }\r\n const fy = (y: number) => this.fy(originalScale.high - y * scaleY)\r\n const line = (color: string, x1: number, y1: number, x2: number, y2: number) => {\r\n const roundedXY = getRoundedObject({\r\n x1: fx(x1),\r\n y1: fy(y1),\r\n x2: fx(x2),\r\n y2: fy(y2),\r\n })\r\n const translateXY = getXYOffsetFromLine({ lineWidth: 1, ...roundedXY })\r\n context.translate(translateXY.x, translateXY.y)\r\n\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', color)\r\n context.lineTo(roundedXY.x1, roundedXY.y1)\r\n context.lineTo(roundedXY.x2, roundedXY.y2)\r\n context.stroke()\r\n\r\n context.translate(translateXY.x * -1, translateXY.y * -1)\r\n }\r\n const text = (text: string, aboveBelow: aboveBelowType, color: string, x1: number, x2: number, y1: number) => {\r\n new Text(\r\n {\r\n x: fx((x1 + x2) / 2),\r\n y: fy(y1) + (aboveBelow === 'above' ? -1 : 2),\r\n font: { size: 8, style: 'bold' },\r\n textBaseline: aboveBelow === 'above' ? TextBaseline.bottom : TextBaseline.top,\r\n fillStyle: color,\r\n textAlign: TextAlign.center,\r\n text,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n const textHS = (text: string, aboveBelow: aboveBelowType, color: string, x1: number, y1: number) => {\r\n new Text(\r\n {\r\n x: fx(x1) + 5,\r\n y: fy(y1) + (aboveBelow === 'above' ? -1 : 2),\r\n font: { size: 9, style: 'bold' },\r\n textBaseline: aboveBelow === 'above' ? TextBaseline.bottom : TextBaseline.top,\r\n fillStyle: color,\r\n textAlign: TextAlign.center,\r\n text,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n const above = (y: number) =>\r\n fy(y) + 10 >= this.model.height - ChartSettings.top.height - ChartSettings.bottom.height ? 'above' : 'below'\r\n const below = (y: number) => (fy(y) <= 15 ? 'below' : 'above')\r\n\r\n const supportColor = 'rgb(0, 150, 220)'\r\n const resistColor = 'rgb(180, 50, 200)'\r\n\r\n for (const pattern of data.patterns) {\r\n const { x1, x2, x3, y3 } = pattern\r\n let { y1, y2 } = pattern\r\n switch (pattern.kind) {\r\n case 1: // Horiz S/R\r\n line('rgba(50, 50, 180, 0.588)', x1, y1, x2, y2)\r\n break\r\n\r\n case 2: // tl resist\r\n line(resistColor, x1, y1, x2, y2)\r\n break\r\n\r\n case 3: // tl support\r\n if (y1 === originalScale.height && y2 === originalScale.height) {\r\n y1 = y2 = originalScale.height - 1\r\n // Maybe just need to check on the new scale?\r\n } // support \"pod grafom\"\r\n line(supportColor, x1, y1, x2, y2)\r\n break\r\n\r\n case 12: // double top\r\n text('Double Top', below(y1), resistColor, x1, x2, y1)\r\n break\r\n\r\n case 13: // double bottom\r\n text('Double Bottom', above(y1), supportColor, x1, x2, y1)\r\n break\r\n\r\n case 14: // multi top\r\n text('Multiple Top', below(y1), resistColor, x1, x2, y1)\r\n break\r\n\r\n case 15: // multi bottom\r\n text('Multiple Bottom', above(y1), supportColor, x1, x2, y1)\r\n break\r\n\r\n case 16: // h&s top\r\n textHS('L', below(y1), resistColor, x1, y1)\r\n textHS('H', below(y2), resistColor, x2, y2)\r\n textHS('R', below(y3), resistColor, x3, y3)\r\n break\r\n\r\n case 17: // h&s bot\r\n textHS('L', above(y1), supportColor, x1, y1)\r\n textHS('H', above(y2), supportColor, x2, y2)\r\n textHS('R', above(y3), supportColor, x3, y3)\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n supportColor: {\r\n type: 'color',\r\n label: 'Support Color',\r\n name: 'supportColor',\r\n value: this.attrs.supportColor ?? this.getFreeColor(),\r\n },\r\n resistColor: {\r\n type: 'color',\r\n label: 'Resist Color',\r\n name: 'resistColor',\r\n value: this.attrs.resistColor ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: PatternsConfig.label,\r\n inputs: PatternsConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n getIsValid() {\r\n return true\r\n }\r\n\r\n isRenderedOverlaysLabel() {\r\n return false\r\n }\r\n}\r\n\r\nPatterns.prototype.defaults = { supportColor: '#69c1ea', resistColor: '#d386df' }\r\n\r\nexport default Patterns\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport enum Calculation {\r\n standard = 'Standard',\r\n fibonacci = 'Fibonacci',\r\n}\r\nexport type CalculationType = keyof typeof Calculation\r\n\r\nexport type Options = {\r\n calculationType: CalculationType\r\n}\r\nexport interface Attrs extends Options {\r\n period?: string\r\n color: string\r\n}\r\n\r\nexport class PPConfig extends BaseConfig {\r\n static type = OverlayType.Pp\r\n static abbreviation = 'pp'\r\n static label = 'Pivot Points'\r\n static shortLabel = 'Pivot Points'\r\n static optionsOrder = ['calculationType'] as const\r\n static optionsLabels = { calculationType: 'Calculation Type' }\r\n static inputsOrder = ['calculationType', 'color'] as Array>\r\n static inputsLabels = { calculationType: 'Calculation Type', color: 'Color' }\r\n}\r\n","import * as dateFns from 'date-fns'\r\n\r\nimport { Instrument } from '../../types/shared'\r\nimport Text from '../canvas/text'\r\nimport { TIMEFRAME, TextBaseline } from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport Utils from '../utils'\r\nimport { getBarWidthWithMargin, round } from '../utils/chart'\r\nimport { getAreNoBarsVisible, getVisibleBarToRenderIndex } from '../utils/draw_in_visible_area'\r\nimport { Attrs, Calculation, CalculationType, PPConfig } from './configs/pp'\r\nimport Overlay from './overlay'\r\n\r\nenum PivotPeriod {\r\n day,\r\n week,\r\n month,\r\n year,\r\n}\r\n\r\ntype PivotPointType = {\r\n pivot: number\r\n res1: number\r\n res2: number\r\n res3: number\r\n sup1: number\r\n sup2: number\r\n sup3: number\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n CalculationType: 'standard' as CalculationType,\r\n Color: '#FFA75F',\r\n}\r\nconst FIB_LVL_1 = 0.382\r\nconst FIB_LVL_2 = 0.618\r\nconst DAY_SECONDS = 86400\r\nconst MINUTES_PER_DAY = 1440\r\n\r\nclass PivotPoints extends Overlay {\r\n static config = PPConfig\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (period) {\r\n this.attrs.calculationType = period as CalculationType\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n getPeriodType() {\r\n switch (this.data.timeframe) {\r\n case TIMEFRAME.i30:\r\n case TIMEFRAME.h:\r\n case TIMEFRAME.h2:\r\n return PivotPeriod.week\r\n case TIMEFRAME.h4:\r\n case TIMEFRAME.d:\r\n return PivotPeriod.month\r\n case TIMEFRAME.w:\r\n case TIMEFRAME.m:\r\n return PivotPeriod.year\r\n default:\r\n return PivotPeriod.day\r\n }\r\n }\r\n\r\n getIsEnoughData(startIndex: number, endIndex: number, periodType: PivotPeriod) {\r\n let dayGap = 7 // one week for week period\r\n if (periodType === PivotPeriod.month) dayGap = 28 // shortest month\r\n if (periodType === PivotPeriod.year) dayGap = 365\r\n\r\n if (startIndex !== endIndex) {\r\n if (startIndex === 0) {\r\n const daysDiff = (this.data.date[endIndex] - this.data.date[startIndex]) / DAY_SECONDS\r\n // we need to somehow determine if we have data if it starts from index 0\r\n // and we can't easily check if day before is different (different month/week/year)\r\n // so we are at least checking if it is [dayGap] days between start and end date\r\n return daysDiff >= dayGap\r\n } else {\r\n const startDay = Utils.dateFromUnixTimestamp(this.data.date[startIndex])\r\n const beforeDay = Utils.dateFromUnixTimestamp(this.data.date[startIndex - 1])\r\n if (periodType === PivotPeriod.week) {\r\n return beforeDay.getDate() !== startDay.getDate()\r\n } else {\r\n return beforeDay.getMonth() !== startDay.getMonth()\r\n }\r\n }\r\n }\r\n return false\r\n }\r\n\r\n fx = (x: number) => {\r\n const lastIndex = this.data.close.length - 1\r\n const outsideBar = this.data.barIndex[lastIndex] + x - lastIndex\r\n\r\n return this.model.scale.x(this.data.barIndex[x] ?? outsideBar)\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n if (this.data.close.length === 0) return\r\n\r\n const chartModel = this.model.chart() as Chart\r\n const { leftOffset, width, zoomFactor } = chartModel\r\n const { left, right } = chartModel.getChartLayoutSettings().ChartSettings\r\n const chartWidth = width - left.width - right.width\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor,\r\n chartLayout: chartModel.chart_layout(),\r\n })\r\n\r\n const firstBarToRender = getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset,\r\n })\r\n const lastBarToRender = getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset,\r\n chartWidth,\r\n })\r\n\r\n const areNoBarsVisible = getAreNoBarsVisible(firstBarToRender, lastBarToRender)\r\n if (areNoBarsVisible) return\r\n\r\n const text = (label: string, price: number, calculatedX: number) => {\r\n new Text(\r\n {\r\n x: calculatedX,\r\n y: this.fy(price) - 13,\r\n font: { size: 8, weight: '900' },\r\n textBaseline: TextBaseline.top,\r\n fillStyle: this.attrs.color,\r\n text: `${label} (${round({ data: this.data, num: price })})`,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n const line = (fromX: number, toX: number, y: number) => {\r\n context.moveTo(fromX, this.fy(y))\r\n context.lineTo(toX, this.fy(y))\r\n }\r\n\r\n let startIndex = -1\r\n let endIndex = -1\r\n const isStock = this.data.instrument === Instrument.Stock\r\n const periodType = this.getPeriodType()\r\n let currentDate = new Date()\r\n let lastDate: Date | undefined\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', this.attrs.color)\r\n\r\n for (let index = firstBarToRender.index; index <= lastBarToRender.index; index++) {\r\n currentDate = Utils.dateFromUnixTimestamp(this.data.date[index])\r\n\r\n // check if new calculation/render is necessary\r\n switch (periodType) {\r\n case PivotPeriod.day: // only if it is a new day\r\n if (currentDate.getDate() === lastDate?.getDate()) {\r\n continue\r\n }\r\n break\r\n case PivotPeriod.week: // only if it is a new week\r\n if (lastDate && dateFns.isSameWeek(lastDate, currentDate, { weekStartsOn: 1 })) {\r\n continue\r\n }\r\n break\r\n case PivotPeriod.month: // only if it is a new month\r\n if (currentDate.getMonth() === lastDate?.getMonth()) {\r\n continue\r\n }\r\n break\r\n case PivotPeriod.year: // only if it is a new year\r\n if (currentDate.getFullYear() === lastDate?.getFullYear()) {\r\n continue\r\n }\r\n break\r\n }\r\n lastDate = currentDate\r\n\r\n // Find start/end indexes for the entire previous period\r\n switch (periodType) {\r\n case PivotPeriod.day:\r\n if (index > 0) {\r\n let previousTradingDay = new Date()\r\n for (let i = index - 1; i >= 0; i--) {\r\n previousTradingDay = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (previousTradingDay.getDate() !== currentDate.getDate()) break\r\n }\r\n previousTradingDay.setHours(0, 0, 0, 0)\r\n const previousNYMidnightTimestamp = Utils.convertLocalToNyTime(previousTradingDay, false).getTime() / 1000\r\n const currentMidnight = new Date(currentDate)\r\n currentMidnight.setHours(0, 0, 0, 0)\r\n const currentNYMidnightTimestamp = Utils.convertLocalToNyTime(currentMidnight, false).getTime() / 1000\r\n\r\n startIndex = this.data.date.findIndex((ts) => ts >= previousNYMidnightTimestamp)\r\n endIndex = this.data.date.findIndex((ts) => ts > currentNYMidnightTimestamp)\r\n\r\n // check if we have data for entire day\r\n if (startIndex !== endIndex) {\r\n const diff = this.data.date[endIndex] - this.data.date[startIndex]\r\n const isNonStockFullDay = !isStock && diff >= DAY_SECONDS\r\n const isStockFullDay = isStock && previousTradingDay.getDate() !== currentDate.getDate()\r\n if (!isNonStockFullDay && !isStockFullDay) {\r\n startIndex = endIndex = Number.MIN_SAFE_INTEGER\r\n }\r\n }\r\n }\r\n break\r\n case PivotPeriod.week:\r\n const firstDayCurrentWeek = dateFns.startOfWeek(currentDate, { weekStartsOn: 1 })\r\n const firstDayCurrentWeekTimestamp = Utils.convertLocalToNyTime(firstDayCurrentWeek, false).getTime() / 1000\r\n const firstDayPreviousWeek = dateFns.sub(firstDayCurrentWeek, { weeks: 1 })\r\n const firstDayPreviousWeekTimestamp = Utils.convertLocalToNyTime(firstDayPreviousWeek, false).getTime() / 1000\r\n\r\n startIndex = this.data.date.findIndex((ts) => ts >= firstDayPreviousWeekTimestamp)\r\n endIndex = this.data.date.findIndex((ts) => ts > firstDayCurrentWeekTimestamp)\r\n\r\n if (!this.getIsEnoughData(startIndex, endIndex, periodType)) {\r\n startIndex = endIndex = Number.MIN_SAFE_INTEGER\r\n }\r\n break\r\n case PivotPeriod.month:\r\n const firstDayCurrentMonth = dateFns.startOfMonth(currentDate)\r\n const firstDayCurrentMonthTimestamp = Utils.convertLocalToNyTime(firstDayCurrentMonth, false).getTime() / 1000\r\n const firstDayPreviousMonth = dateFns.sub(firstDayCurrentMonth, { months: 1 })\r\n const firstDayPreviousMonthTimestamp =\r\n Utils.convertLocalToNyTime(firstDayPreviousMonth, false).getTime() / 1000\r\n\r\n startIndex = this.data.date.findIndex((ts) => ts >= firstDayPreviousMonthTimestamp)\r\n endIndex = this.data.date.findIndex((ts) => ts > firstDayCurrentMonthTimestamp)\r\n\r\n if (!this.getIsEnoughData(startIndex, endIndex, periodType)) {\r\n startIndex = endIndex = Number.MIN_SAFE_INTEGER\r\n }\r\n break\r\n case PivotPeriod.year:\r\n const firstDayCurrentYear = dateFns.startOfYear(currentDate)\r\n const firstDayCurrentYearTimestamp = Utils.convertLocalToNyTime(firstDayCurrentYear, false).getTime() / 1000\r\n const firstDayPreviousYear = dateFns.sub(firstDayCurrentYear, { years: 1 })\r\n const firstDayPreviousYearTimestamp = Utils.convertLocalToNyTime(firstDayPreviousYear, false).getTime() / 1000\r\n\r\n startIndex = this.data.date.findIndex((ts) => ts >= firstDayPreviousYearTimestamp)\r\n endIndex = this.data.date.findIndex((ts) => ts > firstDayCurrentYearTimestamp)\r\n\r\n if (!this.getIsEnoughData(startIndex, endIndex, periodType)) {\r\n startIndex = endIndex = Number.MIN_SAFE_INTEGER\r\n }\r\n break\r\n }\r\n\r\n // calculate pivot point if it was found\r\n if (!(startIndex !== -1 && endIndex !== -1 && startIndex < endIndex)) continue\r\n\r\n let pivot, sup1, sup2, sup3, res1, res2, res3\r\n const previousHigh = Math.max(...this.data.high.slice(startIndex, endIndex))\r\n const previousLow = Math.min(...this.data.low.slice(startIndex, endIndex))\r\n const previousClose = this.data.close[endIndex - 1] // endIndex is the beginning of the next period\r\n\r\n if (this.attrs.calculationType === 'standard') {\r\n pivot = (previousHigh + previousLow + previousClose) / 3\r\n sup1 = 2 * pivot - previousHigh\r\n sup2 = pivot - (previousHigh - previousLow)\r\n sup3 = previousLow - 2 * (previousHigh - pivot)\r\n res1 = 2 * pivot - previousLow\r\n res2 = pivot + (previousHigh - previousLow)\r\n res3 = previousHigh + 2 * (pivot - previousLow)\r\n } else {\r\n pivot = (previousHigh + previousLow + previousClose) / 3\r\n sup1 = pivot - (previousHigh - previousLow) * FIB_LVL_1\r\n sup2 = pivot - (previousHigh - previousLow) * FIB_LVL_2\r\n sup3 = pivot - (previousHigh - previousLow)\r\n res1 = pivot + (previousHigh - previousLow) * FIB_LVL_1\r\n res2 = pivot + (previousHigh - previousLow) * FIB_LVL_2\r\n res3 = pivot + (previousHigh - previousLow)\r\n }\r\n\r\n const pivotPoint: PivotPointType = { pivot, sup1, sup2, sup3, res1, res2, res3 }\r\n\r\n // prepare x coordinates for lines rendering\r\n let fromX = this.fx(index)\r\n let toX = this.fx(index)\r\n switch (periodType) {\r\n case PivotPeriod.day:\r\n const interval = this.data.interval\r\n const currentX = fromX\r\n\r\n const toDate = new Date(currentDate)\r\n toDate.setHours(16, 0, 0, 0)\r\n if (this.data.aftermarket && interval <= 5) toDate.setHours(18, 30, 0, 0)\r\n if (interval <= 15 && !isStock) toDate.setHours(23, 59, 59, 99)\r\n const toTimestamp = toDate.getTime() / 1000\r\n const toDiffMinutes = (toTimestamp - currentDate.getTime() / 1000) / 60\r\n const toBars = toDiffMinutes / interval\r\n toX = Math.min(currentX + toBars * barWidth, -leftOffset + width)\r\n\r\n const fromDate = new Date(currentDate)\r\n fromDate.setHours(9, 30, 0, 0)\r\n if (this.data.premarket && interval <= 5) fromDate.setHours(7, 0, 0, 0)\r\n if (interval <= 15 && !isStock) fromDate.setHours(0, 0, 0, 0)\r\n const fromTimestamp = fromDate.getTime() / 1000\r\n const fromDiffMinutes = (fromTimestamp - currentDate.getTime() / 1000) / 60\r\n const fromBars = fromDiffMinutes / interval\r\n fromX = currentX + fromBars * barWidth\r\n break\r\n\r\n case PivotPeriod.week:\r\n for (let i = index + 1; i <= lastBarToRender.index; i++) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (!dateFns.isSameWeek(currentDate, nextDate, { weekStartsOn: 1 })) {\r\n toX = this.fx(i)\r\n break\r\n }\r\n }\r\n for (let i = index - 1; i >= firstBarToRender.index; i--) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (!dateFns.isSameWeek(currentDate, nextDate, { weekStartsOn: 1 })) {\r\n fromX = this.fx(i + 1) // because we need start from current week\r\n break\r\n }\r\n }\r\n\r\n if (fromX === toX) {\r\n // we need line to imaginary end of the week\r\n const barsPerDay = Math.ceil((this.data.drawMinutesPerDay ?? MINUTES_PER_DAY) / this.data.interval)\r\n toX += (isStock ? 5 : 7) * barsPerDay * barWidth\r\n }\r\n break\r\n\r\n case PivotPeriod.month:\r\n for (let i = index + 1; i <= lastBarToRender.index; i++) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (nextDate.getMonth() !== currentDate.getMonth()) {\r\n toX = this.fx(i)\r\n break\r\n }\r\n }\r\n for (let i = index - 1; i >= firstBarToRender.index; i--) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (nextDate.getMonth() !== currentDate.getMonth()) {\r\n fromX = this.fx(i + 1) // because we need start from current month\r\n break\r\n }\r\n }\r\n\r\n if (fromX === toX) {\r\n // we need line to imaginary end of the month\r\n const barsPerDay = this.data.isIntraday\r\n ? Math.ceil((this.data.drawMinutesPerDay ?? MINUTES_PER_DAY) / this.data.interval)\r\n : 1\r\n toX += (isStock ? 20 : 30) * barsPerDay * barWidth\r\n }\r\n break\r\n default:\r\n for (let i = index + 1; i <= lastBarToRender.index; i++) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (nextDate.getFullYear() !== currentDate.getFullYear()) {\r\n toX = this.fx(i)\r\n break\r\n }\r\n }\r\n for (let i = index - 1; i >= firstBarToRender.index; i--) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (nextDate.getFullYear() !== currentDate.getFullYear()) {\r\n fromX = this.fx(i + 1) // because we need start from current year\r\n break\r\n }\r\n }\r\n\r\n if (fromX === toX) {\r\n // we need line to imaginary end of the year\r\n toX += (this.data.timeframe === TIMEFRAME.w ? 49 : 12) * barWidth\r\n }\r\n break\r\n }\r\n fromX = Math.max(fromX, -leftOffset)\r\n\r\n // render pivot line\r\n context.beginPath()\r\n line(fromX, toX, pivotPoint.pivot)\r\n context.stroke()\r\n\r\n // render resistance and support lines\r\n context.save()\r\n context.setLineDash([3, 3])\r\n context.beginPath()\r\n line(fromX, toX, pivotPoint.res1)\r\n line(fromX, toX, pivotPoint.res2)\r\n line(fromX, toX, pivotPoint.res3)\r\n line(fromX, toX, pivotPoint.sup1)\r\n line(fromX, toX, pivotPoint.sup2)\r\n line(fromX, toX, pivotPoint.sup3)\r\n context.stroke()\r\n context.restore()\r\n\r\n // render labels if there is enough space\r\n if (toX - fromX >= 48) {\r\n text('P', pivotPoint.pivot, fromX)\r\n text('R1', pivotPoint.res1, fromX)\r\n text('R2', pivotPoint.res2, fromX)\r\n text('R3', pivotPoint.res3, fromX)\r\n text('S1', pivotPoint.sup1, fromX)\r\n text('S2', pivotPoint.sup2, fromX)\r\n text('S3', pivotPoint.sup3, fromX)\r\n }\r\n }\r\n\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n calculationType: {\r\n type: 'select',\r\n label: 'Calculation Type',\r\n name: 'calculationType',\r\n value: this.attrs.calculationType ?? DEFAULT_PARAMETERS.CalculationType,\r\n required: true,\r\n items: [\r\n {\r\n value: 'standard',\r\n label: 'Standard',\r\n },\r\n {\r\n value: 'fibonacci',\r\n label: 'Fibonacci',\r\n },\r\n ],\r\n },\r\n color: {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: PPConfig.label,\r\n inputs: PPConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'calculationType':\r\n case 'color':\r\n return !!this.attrs[key]\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `${PPConfig.shortLabel} (${Calculation[this.attrs.calculationType]})`\r\n }\r\n}\r\n\r\nPivotPoints.prototype.defaults = {\r\n calculationType: DEFAULT_PARAMETERS.CalculationType,\r\n color: DEFAULT_PARAMETERS.Color,\r\n}\r\n\r\nexport default PivotPoints\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = {\r\n step: number\r\n maxStep: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n period: string\r\n risingColor: string\r\n fallingColor: string\r\n}\r\n\r\nexport class SARConfig extends BaseConfig {\r\n static type = OverlayType.Sar\r\n static abbreviation = 'sar'\r\n static label = 'Parabolic SAR'\r\n static shortLabel = 'SAR'\r\n static optionsOrder = ['step', 'maxStep'] as const\r\n static optionsLabels = {\r\n step: 'Step',\r\n maxStep: 'Maximum Step',\r\n }\r\n\r\n static inputsOrder = [...this.optionsOrder, 'risingColor', 'fallingColor'] as Array>\r\n static inputsLabels = { ...this.optionsLabels, risingColor: 'Rising Color', fallingColor: 'Falling Color' }\r\n}\r\n","import { Attrs, SARConfig } from './configs/sar'\r\nimport Overlay from './overlay'\r\n\r\nclass SAR extends Overlay {\r\n static config = SARConfig\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (typeof this.attrs.period === 'string' && (this.attrs.step === undefined || this.attrs.maxStep === undefined)) {\r\n const [step = 0, maxStep = 0] = this.attrs.period.split(',').map((x) => parseFloat(x))\r\n this.attrs.step = step\r\n this.attrs.maxStep = maxStep\r\n }\r\n this.trigger('change')\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const data = this.data\r\n const deltaHigh = data.high[1] - data.high[0]\r\n const deltaLow = data.low[0] - data.low[1]\r\n const pdm = deltaHigh > 0 && deltaHigh > deltaLow ? deltaHigh : 0\r\n const mdm = deltaLow > 0 && deltaLow > deltaHigh ? deltaLow : 0\r\n let isLong = pdm >= mdm\r\n\r\n let sar = isLong ? data.low[0] : data.high[0]\r\n let ep = isLong ? data.high[1] : data.low[1]\r\n let newHigh = data.high[0]\r\n let newLow = data.low[0]\r\n let af = this.attrs.step\r\n\r\n for (let i = 1, end = data.close.length, asc = end >= 1; asc ? i < end : i > end; asc ? i++ : i--) {\r\n let sarToDraw\r\n const prevHigh = newHigh\r\n const prevLow = newLow\r\n newHigh = data.high[i]\r\n newLow = data.low[i]\r\n\r\n if (isLong) {\r\n if (newLow <= sar) {\r\n isLong = false\r\n sar = ep\r\n\r\n if (sar < prevHigh) {\r\n sar = prevHigh\r\n }\r\n if (sar < newHigh) {\r\n sar = newHigh\r\n }\r\n\r\n sarToDraw = sar\r\n\r\n af = this.attrs.step\r\n ep = newLow\r\n\r\n sar = sar + af * (ep - sar)\r\n\r\n if (sar < prevHigh) {\r\n sar = prevHigh\r\n }\r\n if (sar < newHigh) {\r\n sar = newHigh\r\n }\r\n } else {\r\n sarToDraw = sar\r\n\r\n if (newHigh > ep) {\r\n ep = newHigh\r\n af += this.attrs.step\r\n if (af > this.attrs.maxStep) {\r\n af = this.attrs.maxStep\r\n }\r\n }\r\n\r\n sar = sar + af * (ep - sar)\r\n\r\n if (sar > prevLow) {\r\n sar = prevLow\r\n }\r\n if (sar > newLow) {\r\n sar = newLow\r\n }\r\n }\r\n } else {\r\n if (newHigh >= sar) {\r\n isLong = true\r\n sar = ep\r\n\r\n if (sar > prevLow) {\r\n sar = prevLow\r\n }\r\n if (sar > newLow) {\r\n sar = newLow\r\n }\r\n\r\n sarToDraw = sar\r\n\r\n af = this.attrs.step\r\n ep = newHigh\r\n\r\n sar = sar + af * (ep - sar)\r\n\r\n if (sar > prevLow) {\r\n sar = prevLow\r\n }\r\n if (sar > newLow) {\r\n sar = newLow\r\n }\r\n } else {\r\n sarToDraw = sar\r\n\r\n if (newLow < ep) {\r\n ep = newLow\r\n af += this.attrs.step\r\n if (af > this.attrs.maxStep) {\r\n af = this.attrs.maxStep\r\n }\r\n }\r\n\r\n sar = sar + af * (ep - sar)\r\n\r\n if (sar < prevHigh) {\r\n sar = prevHigh\r\n }\r\n if (sar < newHigh) {\r\n sar = newHigh\r\n }\r\n }\r\n }\r\n\r\n const x = Math.round(this.fx(i) - 1.5)\r\n const y = Math.round(this.fy(sarToDraw) - 1.5)\r\n context.set('fillStyle', isLong ? this.attrs.risingColor : this.attrs.fallingColor)\r\n context.fillRect(x, y, 3, 3)\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n step: {\r\n type: 'number',\r\n step: 0.01,\r\n min: 0.01,\r\n max: 999,\r\n label: 'Step',\r\n name: 'step',\r\n value: this.attrs.step ?? 0.02,\r\n required: true,\r\n },\r\n maxStep: {\r\n type: 'number',\r\n step: 0.01,\r\n min: 0.01,\r\n max: 999,\r\n label: 'Maximum Step',\r\n name: 'maxStep',\r\n value: this.attrs.maxStep ?? 0.2,\r\n required: true,\r\n },\r\n risingColor: {\r\n type: 'color',\r\n label: 'Rising Color',\r\n name: 'risingColor',\r\n value: this.attrs.risingColor ?? this.getFreeColor(),\r\n customizable: false,\r\n },\r\n fallingColor: {\r\n type: 'color',\r\n label: 'Falling Color',\r\n name: 'fallingColor',\r\n value: this.attrs.fallingColor ?? this.getFreeColor(),\r\n customizable: false,\r\n },\r\n }\r\n\r\n return {\r\n title: SARConfig.label,\r\n inputs: SARConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n step: `${options.step.label} must be a number between ${options.step.min} and ${options.step.max}`,\r\n maxStep: `${options.maxStep.label} must be a number between ${options.maxStep.min} and ${options.maxStep.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'step':\r\n case 'maxStep': {\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n }\r\n case 'risingColor':\r\n case 'fallingColor':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.risingColor\r\n }\r\n}\r\n\r\nSAR.prototype.defaults = {\r\n risingColor: '#69c1ea',\r\n fallingColor: '#d386df',\r\n}\r\n\r\nexport default SAR\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = { period: number }\r\n\r\nexport interface Attrs extends Options {\r\n color: string\r\n}\r\n\r\nexport class SMAConfig extends BaseConfig {\r\n static type = OverlayType.Sma\r\n static abbreviation = 'sma'\r\n static label = 'Simple Moving Average'\r\n static shortLabel = 'SMA'\r\n static description =\r\n 'The Simple Moving Average (SMA) is a basic technical indicator that calculates the average price of an asset over a specific number of periods. It smooths out price data to identify trends by averaging the closing prices. A rising SMA indicates an uptrend, while a falling SMA suggests a downtrend.'\r\n\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = ['period', 'color'] as Array\r\n static inputsLabels = { period: 'Period', color: 'Color' }\r\n static calculatedValuesOrder = ['sma'] as const\r\n static calculatedValuesLabels = { sma: 'SMA' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { Options, SMAConfig } from '../overlays/configs/sma'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n sma: number[]\r\n}\r\n\r\nexport class SMACalculation extends MainCalculation {\r\n static config = SMAConfig\r\n declare options: Options\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period } = this.options\r\n const { close } = this.quote\r\n\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n if (close.length < period) return\r\n\r\n let sum = 0\r\n for (let i = 0; i < period; i++) {\r\n sum += close[i]\r\n }\r\n\r\n for (let i = period - 1; i < close.length; i++) {\r\n if (i >= period) sum = sum - close[i - period] + close[i]\r\n this.calculatedValues.sma[i] = sum / period\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { SMACalculation } from '../indicator-calculation/sma'\r\nimport { Attrs, SMAConfig } from './configs/sma'\r\nimport Overlay from './overlay'\r\n\r\nclass SMA extends Overlay {\r\n static config = SMAConfig\r\n\r\n static getNumOfBarsBuffer(chartConfig: RequireByKey) {\r\n const numOfBarsBuffer = Overlay.getNumOfBarsBuffer(chartConfig)\r\n return numOfBarsBuffer + 1 // +1 offsets rendering so it doesn't start on first bar which doesn't look OK in SSR rendered charts\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n this.attrs.period = parseInt(period, 10)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const period = Math.min(this.attrs.period, this.data.close.length - 1)\r\n context.beginPath()\r\n context.translate(0.5, 0.5)\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', this.attrs.color)\r\n\r\n const smaCalculation = new SMACalculation({\r\n quote: this.data,\r\n options: { period },\r\n })\r\n\r\n smaCalculation.calculate(({ sma }, dataIndex) => {\r\n const x = this.fx(dataIndex)\r\n if (this.fx(dataIndex + 1) + leftOffset < 0) {\r\n return\r\n }\r\n if (this.fx(dataIndex - 1) + leftOffset > width) {\r\n return false\r\n }\r\n context.lineTo(x, Math.round(this.fy(sma[dataIndex])))\r\n })\r\n\r\n context.translate(-0.5, -0.5)\r\n context.stroke()\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? 5,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n color: {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: this.config.label,\r\n inputs: this.config.inputsOrder.map((item) => options[item as keyof Attrs]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'color':\r\n return !!this.attrs[key] // use real color validation, we got isValidHexColor but it might be also RGBA\r\n default:\r\n return false\r\n }\r\n }\r\n}\r\n\r\nSMA.prototype.defaults = { color: '#ffa75f' }\r\n\r\nexport default SMA\r\n","import { OverlayType } from '../../constants/common'\r\nimport { SMAConfig } from './sma'\r\n\r\nexport class SMA2Config extends SMAConfig {\r\n static type = OverlayType.Sma2\r\n}\r\n","import { SMA2Config } from './configs/sma2'\r\nimport SMA from './sma'\r\n\r\nclass SMA2 extends SMA {\r\n static config = SMA2Config\r\n}\r\n\r\nSMA2.prototype.defaults = { color: '#ff6400' }\r\n\r\nexport default SMA2\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = {\r\n period: number\r\n multiplier: number\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n uptrendColor: string\r\n downtrendColor: string\r\n}\r\n\r\nexport class StrConfig extends BaseConfig {\r\n static type = OverlayType.Str\r\n static abbreviation = 'str'\r\n static label = 'Supertrend'\r\n static shortLabel = 'Supertrend'\r\n static optionsOrder = ['period', 'multiplier'] as const\r\n static optionsLabels = { period: 'Period', multiplier: 'Period' }\r\n static inputsOrder = [...this.optionsOrder, 'uptrendColor', 'downtrendColor'] as Array\r\n static inputsLabels = {\r\n ...this.optionsLabels,\r\n uptrendColor: 'Uptrend Color',\r\n downtrendColor: 'Downtrend Color',\r\n }\r\n}\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport AverageTrueRange from '../helpers/atr'\r\nimport { Attrs, StrConfig } from './configs/str'\r\nimport Overlay from './overlay'\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Period: 7,\r\n Multiplier: 3.0,\r\n}\r\n\r\nconst COLORS = {\r\n Uptrend: '#00a000',\r\n Downtrend: '#c80000',\r\n}\r\n\r\nfunction parsePeriod(periodStr: string) {\r\n const values = periodStr.split(',')\r\n const period = parseInt(values[0]) || DEFAULT_PARAMETERS.Period\r\n const multiplier = parseFloat(values[1]) || DEFAULT_PARAMETERS.Multiplier\r\n\r\n return [period, multiplier]\r\n}\r\n\r\nclass Supertrend extends Overlay {\r\n static config = StrConfig\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt] = parsePeriod(period)\r\n return periodInt + 1\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n const [periodInt, multiplier] = parsePeriod(period)\r\n this.attrs.period = periodInt\r\n this.attrs.multiplier = multiplier\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const { period, multiplier } = this.attrs\r\n const { high, low, close } = this.data\r\n const atr = new AverageTrueRange(period)\r\n const finalUpperBand: number[] = []\r\n const finalLowerBand: number[] = []\r\n const supertrend: boolean[] = []\r\n let firstBarToRender\r\n let lastBarToRender = 0\r\n\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', this.attrs.uptrendColor)\r\n for (let i = 1; i < close.length; i++) {\r\n atr.add(high[i], low[i], close[i - 1])\r\n\r\n // compute bands\r\n const avg = (high[i] + low[i]) / 2\r\n const upperBand = avg + multiplier * atr.value\r\n const lowerBand = avg - multiplier * atr.value\r\n\r\n finalUpperBand[i] = upperBand\r\n finalLowerBand[i] = lowerBand\r\n\r\n // identify supertrend\r\n if (close[i] > finalUpperBand[i - 1]) {\r\n supertrend[i] = true\r\n } else if (close[i] < finalLowerBand[i - 1]) {\r\n supertrend[i] = false\r\n } else {\r\n supertrend[i] = supertrend[i - 1]\r\n }\r\n\r\n // adjust bands\r\n if (supertrend[i] && finalLowerBand[i] < finalLowerBand[i - 1]) {\r\n finalLowerBand[i] = finalLowerBand[i - 1]\r\n }\r\n if (!supertrend[i] && finalUpperBand[i] > finalUpperBand[i - 1]) {\r\n finalUpperBand[i] = finalUpperBand[i - 1]\r\n }\r\n\r\n const x = this.fx(i)\r\n if (i < period || x + leftOffset < 0) {\r\n continue\r\n }\r\n if (this.fx(i - 1) + leftOffset > width) {\r\n break\r\n }\r\n if (firstBarToRender === undefined) firstBarToRender = i\r\n\r\n if (supertrend[i] && !supertrend[i - 1]) {\r\n // buy\r\n context.moveTo(this.fx(i - 1), Math.round(this.fy(finalUpperBand[i - 1])))\r\n context.lineTo(x, Math.round(this.fy(finalLowerBand[i])))\r\n } else if (supertrend[i]) {\r\n // keep buying\r\n context.lineTo(x, Math.round(this.fy(finalLowerBand[i])))\r\n } else {\r\n // keep selling\r\n context.moveTo(x, Math.round(this.fy(finalLowerBand[i])))\r\n }\r\n lastBarToRender = i\r\n }\r\n context.stroke()\r\n\r\n if (firstBarToRender === undefined) {\r\n context.translate(-0.5, -0.5)\r\n return\r\n }\r\n\r\n context.beginPath()\r\n context.set('strokeStyle', this.attrs.downtrendColor)\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n if (!supertrend[i] && supertrend[i - 1]) {\r\n // sell\r\n context.moveTo(this.fx(i - 1), Math.round(this.fy(finalLowerBand[i - 1])))\r\n context.lineTo(x, Math.round(this.fy(finalUpperBand[i])))\r\n } else if (!supertrend[i]) {\r\n // keep selling\r\n context.lineTo(x, Math.round(this.fy(finalUpperBand[i])))\r\n } else {\r\n // keep buying\r\n context.moveTo(x, Math.round(this.fy(finalUpperBand[i])))\r\n }\r\n }\r\n context.stroke()\r\n\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? DEFAULT_PARAMETERS.Period,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n multiplier: {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'multiplier',\r\n value: this.attrs.multiplier ?? DEFAULT_PARAMETERS.Multiplier,\r\n required: true,\r\n step: 0.1,\r\n min: 0.0,\r\n max: 999,\r\n },\r\n uptrendColor: {\r\n type: 'color',\r\n label: 'Uptrend Color',\r\n name: 'uptrendColor',\r\n value: this.attrs.uptrendColor ?? this.getFreeColor(),\r\n },\r\n downtrendColor: {\r\n type: 'color',\r\n label: 'Downtrend Color',\r\n name: 'downtrendColor',\r\n value: this.attrs.downtrendColor ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: StrConfig.label,\r\n inputs: StrConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n multiplier: `${options.multiplier.label} must be a number between ${options.multiplier.min} and ${options.multiplier.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'multiplier':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n case 'uptrendColor':\r\n case 'downtrendColor':\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor(): string {\r\n return this.attrs.uptrendColor\r\n }\r\n}\r\n\r\nSupertrend.prototype.defaults = {\r\n uptrendColor: COLORS.Uptrend,\r\n downtrendColor: COLORS.Downtrend,\r\n}\r\n\r\nexport default Supertrend\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = {\r\n period: number | string\r\n}\r\n\r\nexport interface Attrs extends Options {\r\n opacity: number\r\n upColor?: string\r\n downColor?: string\r\n}\r\n\r\nexport class VPConfig extends BaseConfig {\r\n static type = OverlayType.Vp\r\n static abbreviation = 'vp'\r\n static label = 'Volume Profile'\r\n static shortLabel = 'VP'\r\n static optionsOrder = ['period'] as const\r\n static optionsLabels = { period: 'Period' }\r\n static inputsOrder = ['period', 'opacity', 'upColor', 'downColor'] as Array\r\n\r\n static inputsLabels = {\r\n period: 'Zones',\r\n opacity: 'Opacity',\r\n upColor: 'Up Color',\r\n downColor: 'Down Color',\r\n }\r\n}\r\n","import * as d3 from 'd3'\r\n\r\nimport { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport Chart from '../models/chart'\r\nimport utils from '../utils'\r\nimport { convertColorToHEX, getHEXWithSpecificAplha } from '../utils/colors'\r\nimport { getAreNoBarsVisible, getVisibleBarToRenderIndex } from '../utils/draw_in_visible_area'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport { Attrs, VPConfig } from './configs/vp'\r\nimport Overlay from './overlay'\r\n\r\nconst VP_COLORS = {\r\n UP: '#00FF00',\r\n DOWN: '#FF0000',\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Period: 20,\r\n Opacity: 0.3,\r\n}\r\n\r\nfunction applyOpacityToColor(color: string, opacity: number) {\r\n return getHEXWithSpecificAplha(convertColorToHEX(color), opacity)\r\n}\r\n\r\nfunction getColorsWithAppliedOpacity(attrs: Attrs) {\r\n return [\r\n applyOpacityToColor(attrs.upColor ?? VP_COLORS.UP, attrs.opacity),\r\n applyOpacityToColor(attrs.downColor ?? VP_COLORS.DOWN, attrs.opacity),\r\n ]\r\n}\r\n\r\n// Only time when we want value to be able to equal start of segment is first segment,\r\n// because start of next segment is equal to end of previous and value would match two segments\r\nfunction isInSegment(val: number, start: number, end: number, notEqualStart: boolean) {\r\n return (notEqualStart ? val > start : val >= start) && val <= end\r\n}\r\n\r\nfunction parsePeriod(periodStr: string) {\r\n const values = periodStr.split(',')\r\n const period = parseInt(values[0]) || DEFAULT_PARAMETERS.Period\r\n const opacity = parseFloat(values[1]) || DEFAULT_PARAMETERS.Opacity\r\n\r\n return [period, opacity]\r\n}\r\n\r\nclass VolumeProfile extends Overlay {\r\n static config = VPConfig\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt = 0] = getParsedIntegersFromPeriodString(period)\r\n return periodInt + 1 // +1 offsets rendering so it doesn't start on first bar which doesn't look OK in SSR rendered charts\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n const [periodInt, opacity] = parsePeriod(period)\r\n this.attrs.period = periodInt\r\n this.attrs.opacity = opacity\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n if (typeof this.attrs.period !== 'number') {\r\n return\r\n }\r\n super.renderContent()\r\n\r\n const chartModel = this.model.chart() as Chart\r\n const { leftOffset, width } = chartModel\r\n const { left, right } = chartModel.getChartLayoutSettings().ChartSettings\r\n const chartWidth = width - left.width - right.width\r\n\r\n if (this.data.close.length === 0) return\r\n\r\n const firstBarToRender = getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset,\r\n })\r\n\r\n const lastBarToRender = getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset,\r\n chartWidth,\r\n })\r\n\r\n const areNoBarsVisible = getAreNoBarsVisible(firstBarToRender, lastBarToRender)\r\n if (areNoBarsVisible) return\r\n\r\n const [upColor, downColor] = getColorsWithAppliedOpacity(this.attrs)\r\n const [minClose, maxClose] = utils.minMax(this.data.close.slice(firstBarToRender.index, lastBarToRender.index + 1))\r\n\r\n const segment = Math.abs(maxClose - minClose) / this.attrs.period\r\n const segments = [] // create an empty array to hold the segments\r\n\r\n for (let i = 0; i < this.attrs.period; i++) {\r\n const segmentStart = minClose + segment * i // calculate start of current segment\r\n const segmentEnd = segmentStart + segment // calculate end of current segment\r\n segments.push({ start: segmentStart, end: segmentEnd, up: 0, down: 0 }) // add segment to array\r\n }\r\n\r\n // loop through visible bars and assign volumes to segments\r\n for (let i = firstBarToRender.index; i <= lastBarToRender.index; i++) {\r\n const segmentIndex: number = segments.findIndex((item, segmentIndex) =>\r\n isInSegment(this.data.close[i], item.start, item.end, !!segmentIndex)\r\n )\r\n if (segmentIndex === -1) continue\r\n const volumeTrend = this.data.close[i] < this.data.open[i] ? 'down' : 'up'\r\n segments[segmentIndex][volumeTrend] += this.data.volume[i]\r\n }\r\n\r\n const max = utils.max(segments.map((item) => item.up + item.down))\r\n const rangeMax = chartWidth * 0.4 // maximum range in pixels where longest bar would reach (now it's 40% of chart width)\r\n const volumeFX = d3.scaleLinear().range([0, rangeMax]).domain([0, max])\r\n\r\n segments.forEach((item) => {\r\n const y = Math.round(this.fy(item.start))\r\n const segmentHeightRaw = Math.round(this.fy(item.end)) - y // raw segment height without gap between segments\r\n const segmentHeight = segmentHeightRaw + (Math.abs(segmentHeightRaw) > 5 ? 2 : 1) // apply gap to segment based on how high segment is\r\n const x = Math.abs(leftOffset) // segments are alligned to left side of chart which equal to absoulute value of leftOffset\r\n const upSegmentWidth = Math.round(volumeFX(item.up))\r\n const downSegmentWidth = Math.round(volumeFX(item.down))\r\n\r\n context.fillStyle = upColor\r\n context.fillRect(x, y, upSegmentWidth, segmentHeight)\r\n context.fillStyle = downColor\r\n context.fillRect(x + upSegmentWidth, y, downSegmentWidth, segmentHeight)\r\n })\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n period: {\r\n type: 'number',\r\n label: 'Zones',\r\n name: 'period',\r\n value: this.attrs.period ?? DEFAULT_PARAMETERS.Period,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n },\r\n opacity: {\r\n type: 'number',\r\n label: 'Opacity',\r\n name: 'opacity',\r\n value: this.attrs.opacity ?? DEFAULT_PARAMETERS.Opacity,\r\n required: true,\r\n min: 0,\r\n max: 1,\r\n step: 0.1,\r\n },\r\n upColor: {\r\n type: 'color',\r\n label: 'Up Color',\r\n name: 'upColor',\r\n value: this.attrs.upColor ?? VP_COLORS.UP,\r\n },\r\n downColor: {\r\n type: 'color',\r\n label: 'Down Color',\r\n name: 'downColor',\r\n value: this.attrs.downColor ?? VP_COLORS.DOWN,\r\n },\r\n }\r\n\r\n return {\r\n title: VPConfig.label,\r\n inputs: VPConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {\r\n period: `${options.period.label} must be a whole number between ${options.period.min} and ${options.period.max}`,\r\n opacity: `${options.opacity.label} must be a number between ${options.opacity.min} and ${options.opacity.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'opacity':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n case 'upColor':\r\n case 'downColor':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.upColor || VP_COLORS.UP\r\n }\r\n}\r\n\r\nVolumeProfile.prototype.defaults = { upColor: VP_COLORS.UP, downColor: VP_COLORS.DOWN }\r\n\r\nexport default VolumeProfile\r\n","import { OverlayType } from '../../constants/common'\r\nimport BaseConfig from './overlayBaseConfig'\r\n\r\nexport type Options = { period: number }\r\n\r\nexport interface Attrs extends Options {\r\n color: string\r\n}\r\n\r\nexport class VWAPConfig extends BaseConfig {\r\n static type = OverlayType.Vwap\r\n static abbreviation = 'vwap'\r\n static label = 'VWAP (intraday charts)'\r\n static shortLabel = 'VWAP'\r\n static description =\r\n 'The VWAP measures the average price of a security, weighted by volume throughout the trading day. It helps determine the true average price, with prices above the VWAP indicating buying pressure and prices below the VWAP indicating selling pressure.'\r\n\r\n static inputsOrder = ['color'] as Array>\r\n static inputsLabels = { color: 'Color' }\r\n static calculatedValuesOrder = ['vwap'] as const\r\n static calculatedValuesLabels = { vwap: 'VWAP' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { Options, VWAPConfig } from '../overlays/configs/vwap'\r\nimport { dateFromUnixTimestamp } from '../utils'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\nconst datesAreOnSameDay = (first: Date, second: Date) =>\r\n first.getFullYear() === second.getFullYear() &&\r\n first.getMonth() === second.getMonth() &&\r\n first.getDate() === second.getDate()\r\n\r\ntype DefaultCalculatedValuesType = {\r\n vwap: number[]\r\n}\r\n\r\nexport class VWapCalculation extends MainCalculation {\r\n static config = VWAPConfig\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { date, close, low, high, volume } = this.quote\r\n const lastIndex = date.length - 1\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n let cumulativePV = 0\r\n let cumulativeVolume = 0\r\n\r\n for (let i = 0; i <= lastIndex; i++) {\r\n if (i > 0) {\r\n const prevDate = dateFromUnixTimestamp(date[i - 1])\r\n if (!datesAreOnSameDay(prevDate, dateFromUnixTimestamp(date[i]))) {\r\n cumulativePV = 0\r\n cumulativeVolume = 0\r\n }\r\n }\r\n\r\n const typicalPrice = (close[i] + low[i] + high[i]) / 3\r\n const pv = typicalPrice * volume[i]\r\n\r\n cumulativePV += pv\r\n cumulativeVolume += volume[i]\r\n\r\n this.calculatedValues.vwap[i] = cumulativePV / cumulativeVolume\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { VWapCalculation } from '../indicator-calculation/vwap'\r\nimport PaneModel from '../models/pane'\r\nimport { Attrs, VWAPConfig } from './configs/vwap'\r\nimport Overlay from './overlay'\r\n\r\nclass VWAP extends Overlay {\r\n static config = VWAPConfig\r\n\r\n static getNumOfBarsBuffer() {\r\n return 1\r\n }\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.attrs.period = 5\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n if (!this.isRendered()) {\r\n return\r\n }\r\n\r\n const { leftOffset, width } = this.model.chart()\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', this.attrs.color)\r\n\r\n const vwapCalculation = new VWapCalculation({\r\n quote: this.data,\r\n options: { period: this.attrs.period },\r\n })\r\n\r\n vwapCalculation.calculate(({ vwap }, dataIndex) => {\r\n const x = this.fx(dataIndex)\r\n if (this.fx(dataIndex + 1) + leftOffset < 0) {\r\n return // continue\r\n }\r\n if (this.fx(dataIndex - 1) + leftOffset > width) {\r\n return false // break\r\n }\r\n const y = Math.round(this.fy(vwap[dataIndex]))\r\n context.lineTo(x, y)\r\n })\r\n\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const options = {\r\n color: {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n },\r\n }\r\n\r\n return {\r\n title: VWAPConfig.label,\r\n inputs: VWAPConfig.inputsOrder.map((item) => options[item]),\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'color':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n isRendered() {\r\n return this.model.chart().quote().isIntraday\r\n }\r\n\r\n isRenderedOverlaysLabel() {\r\n return this.isRendered()\r\n }\r\n\r\n toString() {\r\n return VWAPConfig.shortLabel\r\n }\r\n}\r\n\r\nVWAP.prototype.defaults = { color: '#9467bd' }\r\n\r\nexport default VWAP\r\n","import { OverlayType } from '../constants/common'\r\nimport bb from './bb'\r\nimport dch from './dch'\r\nimport ema from './ema'\r\nimport ema2 from './ema2'\r\nimport hilo from './hilo'\r\nimport hline from './hline'\r\nimport ic from './ic'\r\nimport icf from './icf'\r\nimport kch from './kch'\r\nimport none from './none'\r\nimport overlay from './overlay'\r\nimport patterns from './patterns'\r\nimport pp from './pp'\r\nimport sar from './sar'\r\nimport sma from './sma'\r\nimport sma2 from './sma2'\r\nimport str from './str'\r\nimport vp from './vp'\r\nimport vwap from './vwap'\r\n\r\nexport const overlaysByType = Object.freeze({\r\n [OverlayType.Overlay]: overlay,\r\n [OverlayType.None]: none,\r\n [OverlayType.Bb]: bb,\r\n [OverlayType.Dch]: dch,\r\n [OverlayType.Ema]: ema,\r\n [OverlayType.Ema2]: ema2,\r\n [OverlayType.Hilo]: hilo,\r\n [OverlayType.Hline]: hline,\r\n [OverlayType.Ic]: ic,\r\n [OverlayType.Icf]: icf,\r\n [OverlayType.Kch]: kch,\r\n [OverlayType.Patterns]: patterns,\r\n [OverlayType.Pp]: pp,\r\n [OverlayType.Sar]: sar,\r\n [OverlayType.Sma]: sma,\r\n [OverlayType.Sma2]: sma2,\r\n [OverlayType.Str]: str,\r\n [OverlayType.Vp]: vp,\r\n [OverlayType.Vwap]: vwap,\r\n})\r\n","import {\r\n MOBILE_VIEW_BREAKPOINT_WIDTH,\r\n PREMARKET_AFTERMARKET_HOURS,\r\n SpecificChartFunctionality,\r\n} from './constants/common'\r\nimport { captureException, getIsSSr } from './utils/helpers'\r\n\r\nexport { getSanitizedTicker } from './utils/ticker-sanitizer'\r\n\r\nfunction getIsDstInNy(date: Date) {\r\n const dayNumber = date.getDate()\r\n const monthIndex = date.getMonth()\r\n const dayOfWeek = date.getDay()\r\n const previousSunday = dayNumber - dayOfWeek\r\n if (monthIndex < 2 || monthIndex > 10) {\r\n return false\r\n }\r\n if (monthIndex > 2 && monthIndex < 10) {\r\n return true\r\n }\r\n return monthIndex === 2 ? previousSunday >= 8 : previousSunday <= 0\r\n}\r\n\r\nclass Utils {\r\n static min(...args: T[]): number {\r\n if (typeof args[0] === 'number') {\r\n return args[0] < +args[1] ? args[0] : (args[1] as number)\r\n }\r\n let min = args[0][0]\r\n for (const arg of args) {\r\n for (const el of arg as number[]) {\r\n if (el < min) {\r\n min = el\r\n }\r\n }\r\n }\r\n return min\r\n }\r\n\r\n static max(...args: T[]): number {\r\n if (typeof args[0] === 'number') {\r\n return args[0] > +args[1] ? args[0] : (args[1] as number)\r\n }\r\n let max = args[0][0]\r\n for (const arg of args) {\r\n for (const el of arg as number[]) {\r\n if (el > max) {\r\n max = el\r\n }\r\n }\r\n }\r\n return max\r\n }\r\n\r\n static minMax(...args: number[][]) {\r\n let max\r\n let min = (max = args[0][0] as number)\r\n for (const arg of args) {\r\n for (const el of arg) {\r\n if (el < min) {\r\n min = el\r\n }\r\n if (el > max) {\r\n max = el\r\n }\r\n }\r\n }\r\n return [min, max]\r\n }\r\n\r\n static getScaleRatio() {\r\n return (typeof window !== 'undefined' && window.devicePixelRatio) || 1\r\n }\r\n\r\n static setSizeOnCanvasElement({\r\n canvasElement,\r\n width,\r\n height,\r\n ratio = Utils.getScaleRatio(),\r\n }: {\r\n canvasElement: HTMLCanvasElement | null\r\n width: number\r\n height: number\r\n ratio?: number\r\n }) {\r\n if (canvasElement) {\r\n canvasElement.width = width * ratio\r\n canvasElement.height = height * ratio\r\n canvasElement.style.width = width + 'px'\r\n canvasElement.style.height = height + 'px'\r\n }\r\n }\r\n\r\n static getQuoteDateTimestampOffsetInSeconds(referenceDate?: Date) {\r\n const date = referenceDate || new Date()\r\n const dateAsNY = new Date(\r\n date.getUTCFullYear(),\r\n date.getUTCMonth(),\r\n date.getUTCDate(),\r\n date.getUTCHours() - 5,\r\n date.getUTCMinutes(),\r\n date.getUTCSeconds()\r\n )\r\n const isDst = getIsDstInNy(dateAsNY)\r\n return (isDst ? 4 : 5) * 60 * 60\r\n }\r\n\r\n static convertLocalToNyTime(referenceDate: Date, addOffset: boolean) {\r\n const date = new Date(referenceDate)\r\n const quoteDateTimeOffsetInMs = Utils.getQuoteDateTimestampOffsetInSeconds(date) * 1000\r\n const localTimeOffsetInMs = date.getTimezoneOffset() * 60 * 1000\r\n const offsetDirectionCoefficient = addOffset ? 1 : -1\r\n date.setTime(date.getTime() + (localTimeOffsetInMs - quoteDateTimeOffsetInMs) * offsetDirectionCoefficient)\r\n return date\r\n }\r\n\r\n // Keep in sync with the clone in Website repo in shared/isStockFastRefreshAvailable.ts\r\n static isStockFastRefreshAvailable(hasPremarket = true, hasAftermarket = true, bufferMinutes = 30) {\r\n const MARKET_START = { hours: 9, minutes: 30 }\r\n const MARKET_END = { hours: 16, minutes: 0 }\r\n const getMinutes = ({ hours, minutes }: { hours: number; minutes: number }) => hours * 60 + minutes\r\n\r\n const date = convertLocalToNyTime(new Date(), true)\r\n const dayOfWeek = date.getDay()\r\n const currentDayMinutes = date.getHours() * 60 + date.getMinutes()\r\n\r\n const premarketMinutes = hasPremarket ? PREMARKET_AFTERMARKET_HOURS * 60 : 0\r\n const aftermarketMinutes = hasAftermarket ? PREMARKET_AFTERMARKET_HOURS * 60 : 0\r\n\r\n const isWeekend = dayOfWeek === 0 || dayOfWeek === 6\r\n const isOpen = getMinutes(MARKET_START) - premarketMinutes - bufferMinutes <= currentDayMinutes\r\n const isClosed = getMinutes(MARKET_END) + aftermarketMinutes + bufferMinutes <= currentDayMinutes\r\n return !isWeekend && isOpen && !isClosed\r\n }\r\n\r\n static dateFromUnixTimestamp(timestamp: number) {\r\n /*\r\n * Passing 0 as a param is needed in order to setUTCSeconds work properly.\r\n * The function adds seconds to the date instance if it exceeds 60.\r\n * For more info see the docs https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCSeconds\r\n * */\r\n const date = new Date(0)\r\n date.setUTCSeconds(timestamp)\r\n return Utils.convertLocalToNyTime(date, true)\r\n }\r\n\r\n static dateStringFromDate(date: Date) {\r\n return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(\r\n 2,\r\n '0'\r\n )}`\r\n }\r\n\r\n static dateFromDateString(dateString: string) {\r\n const [yyyy, mm, dd] = dateString.split('-')\r\n\r\n const date = new Date(Number.parseInt(yyyy), Number.parseInt(mm) - 1, Number.parseInt(dd))\r\n if (Number.isNaN(date.getTime())) {\r\n captureException(new Error('Invalid Date'), { extra: { date, dateString } })\r\n }\r\n\r\n return date\r\n }\r\n\r\n static isMobile(testTouchPoints?: boolean) {\r\n if (getIsSSr()) return false\r\n let isMobileOs = false\r\n\r\n // New iOS versions no longer report iPad in user agent\r\n if (navigator.userAgent.indexOf('Macintosh') > -1) {\r\n try {\r\n document.createEvent('TouchEvent')\r\n isMobileOs = true\r\n } catch {}\r\n } else {\r\n isMobileOs = !!navigator.userAgent.match(\r\n /\\b(Android|webOS|i(?:Phone|Pad|Pod)|BlackBerry|Windows (?:Phone|Mobile))\\b/i\r\n )\r\n }\r\n\r\n if (testTouchPoints) {\r\n try {\r\n return (\r\n isMobileOs &&\r\n (window.navigator.msMaxTouchPoints ||\r\n window.navigator.maxTouchPoints ||\r\n 'ontouchstart' in document.createElement('div'))\r\n )\r\n } catch {}\r\n }\r\n\r\n return isMobileOs\r\n }\r\n\r\n static isIPad() {\r\n const matchesIPad = navigator.userAgent.match(/iPad/i)\r\n const matchesIPhone = navigator.userAgent.match(/iPhone/i)\r\n const matchesIPod = navigator.userAgent.match(/iPod/i)\r\n const matchesIOSLike = navigator.userAgent.match(/Mac/) && navigator.maxTouchPoints > 0\r\n\r\n return (matchesIOSLike && !matchesIPhone && !matchesIPod) || matchesIPad\r\n }\r\n\r\n static getCookie(name: string) {\r\n const re = new RegExp('(?:(?:^|.*;\\\\s*)' + name + '\\\\s*\\\\=\\\\s*([^;]*).*$)|^.*$')\r\n return document.cookie.replace(re, '$1')\r\n }\r\n\r\n static setCookie(name: string, value: string, expires: Date) {\r\n let cookie = name + '=' + value + '; expires=' + expires.toUTCString()\r\n if (document.location.hostname !== 'localhost') {\r\n cookie += '; domain=.finviz.com'\r\n }\r\n document.cookie = cookie\r\n }\r\n}\r\n\r\nexport default Utils\r\nexport const convertLocalToNyTime = Utils.convertLocalToNyTime\r\nexport const dateFromUnixTimestamp = Utils.dateFromUnixTimestamp\r\nexport const dateStringFromDate = Utils.dateStringFromDate\r\nexport const dateFromDateString = Utils.dateFromDateString\r\n\r\nexport function getFullscreenStatus(): boolean {\r\n return (\r\n document.fullscreenElement ??\r\n document.webkitFullscreenElement ??\r\n document.mozFullScreenElement ??\r\n document.msFullscreenElement ??\r\n false\r\n )\r\n}\r\n\r\nexport function getRequestFullscreen(element: HTMLElement) {\r\n return (\r\n element.requestFullscreen ??\r\n element.webkitRequestFullScreen ??\r\n element.mozRequestFullScreen ??\r\n element.msRequestFullscreen\r\n )\r\n}\r\n\r\nexport function getExitFullscreen() {\r\n return (\r\n document.exitFullscreen ?? document.webkitExitFullscreen ?? document.mozExitFullScreen ?? document.msExitFullscreen\r\n )\r\n}\r\n\r\nexport function ready(fn: () => void) {\r\n if (document.readyState !== 'loading') {\r\n fn()\r\n return\r\n }\r\n\r\n document.addEventListener('DOMContentLoaded', fn)\r\n}\r\n\r\nexport function getChartsDimensions(chartElementId: string) {\r\n const PADDING = 2 // Border widths\r\n const containerElement = document.getElementById(chartElementId)\r\n\r\n const box = containerElement?.getBoundingClientRect()\r\n\r\n return {\r\n width: Math.max((box?.width ?? 0) - PADDING, 0),\r\n height: Math.max((box?.height ?? 0) - PADDING, 0),\r\n }\r\n}\r\n\r\nexport function getIsMobileScreenSize() {\r\n return window.innerWidth < MOBILE_VIEW_BREAKPOINT_WIDTH\r\n}\r\n\r\nexport function getIsMobilePortrait(isMobile?: boolean) {\r\n if (isMobile ?? Utils.isMobile()) {\r\n return window.orientation % 180 === 0\r\n }\r\n return false\r\n}\r\n\r\nexport function numberToStringWithUnitsSuffix(value: number) {\r\n let suffix = ''\r\n if (value >= 1000000000) {\r\n value /= 1000000000\r\n suffix = 'B'\r\n } else if (value >= 1000000) {\r\n value /= 1000000\r\n suffix = 'M'\r\n } else if (value >= 1000) {\r\n value /= 1000\r\n suffix = 'K'\r\n }\r\n\r\n return value.toFixed(2) + suffix\r\n}\r\n\r\nexport function isRedesignEnabled() {\r\n return typeof window !== 'undefined' && window.FinvizSettings?.hasRedesignEnabled\r\n}\r\n\r\nexport function isRedesignedPage(\r\n obj: { specificChartFunctionality?: SpecificChartFunctionality | null },\r\n matchingPages = [\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n ]\r\n) {\r\n const isQuotePage = obj.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n const isQuoteFinancials = obj.specificChartFunctionality === SpecificChartFunctionality.quoteFinancials\r\n\r\n return (\r\n (isRedesignEnabled() && matchingPages.includes(obj.specificChartFunctionality!)) ||\r\n // Legacy design on quote uses redesigned elements (page header + chart controls)\r\n isQuotePage ||\r\n isQuoteFinancials\r\n )\r\n}\r\n","import { ObjectHash } from '../../types/shared'\r\n\r\nconst requestsAbortControllersCache: ObjectHash = {}\r\n\r\nexport function removeFromAbortCache(key: string) {\r\n delete requestsAbortControllersCache[key]\r\n}\r\n\r\nexport function abortRequest(key: string) {\r\n requestsAbortControllersCache[key]?.abort()\r\n removeFromAbortCache(key)\r\n}\r\n\r\nexport function getIsAbortError(error: Error) {\r\n return error.name === 'AbortError'\r\n}\r\n\r\nexport function createRequestAbortController({\r\n key,\r\n shouldAbortRunningRequest = false,\r\n}: {\r\n key: string\r\n shouldAbortRunningRequest?: boolean\r\n}) {\r\n if (shouldAbortRunningRequest) {\r\n abortRequest(key)\r\n }\r\n const controller = 'AbortController' in window ? new AbortController() : undefined\r\n if (controller) {\r\n requestsAbortControllersCache[key] = controller\r\n }\r\n return controller\r\n}\r\n","import * as websiteShared from '@finviz/website'\r\n\r\nimport { captureException } from './helpers'\r\n\r\n/**\r\n * Hook used to asynchronously load a module\r\n *\r\n * Usage: [wiki](https://github.com/finvizhq/Finviz-Website/wiki/Loading-modules-asynchronously#useasyncmodule)\r\n */\r\nexport const useAsyncModule = (\r\n props: {\r\n importFn: () => Promise\r\n onError?: () => void\r\n cacheKey: string\r\n captureException?: (exception: Error, captureContext?: { extra: Record }) => void\r\n errorSeverity?: 'medium' | 'high'\r\n } & (websiteShared.ControlledModuleConfig | websiteShared.SuspenseModuleConfig)\r\n) =>\r\n websiteShared.useAsyncModule({ captureException, ...props }) as [\r\n SuspenseMode extends true ? T : T | null,\r\n { isLoading: boolean; loadModule: () => Promise; isError: boolean },\r\n ]\r\n","import { getIsSSr } from './helpers'\r\n\r\n// Extracted from isMobile, and modified to fit usage\r\nfunction isFirefoxDesktop() {\r\n const matchesAndroid = navigator.userAgent.match(/Android/i)\r\n const matchesWebOS = navigator.userAgent.match(/webOS/i)\r\n const matchesIPhone = navigator.userAgent.match(/iPhone/i)\r\n const matchesiPad = navigator.userAgent.match(/iPad/i)\r\n const matchesIPod = navigator.userAgent.match(/iPod/i)\r\n const matchesBlackBerry = navigator.userAgent.match(/BlackBerry/i)\r\n const matchesWindowsPhone = navigator.userAgent.match(/Windows Phone/i)\r\n const matchesIOSLike = navigator.userAgent.match(/Mac/) && navigator.maxTouchPoints > 0\r\n\r\n const isMobileDevice =\r\n matchesAndroid ||\r\n matchesWebOS ||\r\n matchesIPhone ||\r\n matchesiPad ||\r\n matchesIPod ||\r\n matchesBlackBerry ||\r\n matchesWindowsPhone ||\r\n matchesIOSLike\r\n\r\n const matchesFirefox = !!navigator.userAgent.match(/firefox/i)\r\n\r\n return matchesFirefox && !isMobileDevice\r\n}\r\n\r\n// Due bug in FireFox, when if HW acceleration is used canvas is blurry\r\n// we need to set canvas as CPU only\r\nconst shouldUseCPUOnly = getIsSSr() ? false : isFirefoxDesktop()\r\n\r\nexport function getContextWithCache(canvas: HTMLCanvasElement | null): CanvasRenderingContext2D | null {\r\n if (!canvas) {\r\n return null\r\n }\r\n\r\n const context = canvas.getContext('2d', shouldUseCPUOnly ? { willReadFrequently: true } : undefined)\r\n if (!context) {\r\n window.Sentry?.captureMessage('Context unavailable')\r\n return null\r\n }\r\n\r\n context._cache = {}\r\n\r\n const _restore = CanvasRenderingContext2D.prototype.restore\r\n context.restore = function () {\r\n this._cache = {}\r\n return _restore.apply(this)\r\n }\r\n\r\n context.set = function (key, value) {\r\n if (this._cache[key] !== value) {\r\n this[key] = value\r\n this._cache[key] = value\r\n }\r\n }\r\n\r\n return context\r\n}\r\n","import { Theme } from '../../types/shared'\r\nimport twColors from '../constants/colors'\r\nimport { ChartEventType } from '../constants/common'\r\nimport math, { BIG_NUMBER_VALUES, BigNumber } from '../helpers/math'\r\nimport utils from '../utils'\r\nimport { formatDateToStringUS, getEarningsDateSuffix } from './helpers'\r\n\r\ninterface IChartEventBase {\r\n elementId: string\r\n eventType: ChartEventType\r\n dateTimestamp: number // represent 'earningsDate' column of earnings and 'exdate' column for dividends & split\r\n}\r\n\r\nexport interface IEarnings extends IChartEventBase {\r\n epsActual?: number\r\n epsEstimate?: number\r\n epsReportedActual?: number\r\n epsReportedEstimate?: number\r\n fiscalEndDate: number\r\n fiscalPeriod: string\r\n salesActual?: number\r\n salesEstimate?: number\r\n}\r\n\r\nexport interface IDividends extends IChartEventBase {\r\n ordinary: number\r\n special: number\r\n}\r\n\r\nexport interface ISplit extends IChartEventBase {\r\n factorFrom: number\r\n factorTo: number\r\n}\r\n\r\nexport enum ChartEventBadgeState {\r\n default = 'default',\r\n hover = 'hover',\r\n selected = 'selected',\r\n}\r\n\r\nexport interface IChartEventBadgeProps {\r\n theme: Theme\r\n state: ChartEventBadgeState\r\n width: number\r\n}\r\n\r\ninterface IGetChartEventBadgeColors {\r\n theme: Theme\r\n state: ChartEventBadgeState\r\n colors: IBadgeColors\r\n}\r\n\r\ninterface IBadgeStateColors {\r\n default: string\r\n hover: string\r\n selected: string\r\n}\r\n\r\ninterface IBadgeThemeColors {\r\n outerStroke: string\r\n innerStroke: string\r\n innerFill: IBadgeStateColors\r\n textFill: IBadgeStateColors\r\n}\r\n\r\ninterface IBadgeColors {\r\n light: IBadgeThemeColors\r\n dark: IBadgeThemeColors\r\n}\r\n\r\nexport function getChartEventBadgeColors({ theme, state, colors }: IGetChartEventBadgeColors) {\r\n return {\r\n outerStroke: colors[theme].outerStroke,\r\n innerStroke: colors[theme].innerStroke,\r\n innerFill: colors[theme].innerFill[state],\r\n textFill: colors[theme].textFill[state],\r\n }\r\n}\r\n\r\nexport function getFormattedEventDate(\r\n exdate: number,\r\n hasEarningsDateSuffix = false,\r\n options: ObjectHash = {\r\n month: 'short',\r\n }\r\n) {\r\n const parsedDate = utils.dateFromUnixTimestamp(exdate)\r\n\r\n const formattedDate = formatDateToStringUS(parsedDate, options)\r\n\r\n if (hasEarningsDateSuffix) {\r\n return `${formattedDate} ${getEarningsDateSuffix(parsedDate)}`\r\n }\r\n\r\n return formattedDate\r\n}\r\n\r\nexport function getFormattedValue({\r\n value,\r\n bigNumberUnit,\r\n maxDecimalPlaces = 3,\r\n}: {\r\n value: number\r\n bigNumberUnit?: BigNumber\r\n maxDecimalPlaces?: number\r\n}) {\r\n let numberString = ''\r\n let suffix = ''\r\n\r\n if (bigNumberUnit === undefined) {\r\n numberString = math.round({ value, overridePlaces: 3 })\r\n } else {\r\n const bigNumber = math.formatBigNumber(value * BIG_NUMBER_VALUES[bigNumberUnit], 3, BigNumber.Million)\r\n numberString = parseFloat(bigNumber.substring(0, bigNumber.length - 1)).toString() // parseFloat with toString are removing trailing zeroes\r\n suffix = bigNumber.substring(bigNumber.length - 1)\r\n }\r\n\r\n const [wholeNumber, decimalNumber] = numberString.split('.')\r\n\r\n if (decimalNumber === undefined) return `${wholeNumber}${suffix}`\r\n\r\n let formattedDecimalNumber = decimalNumber\r\n if (maxDecimalPlaces === 2 || decimalNumber[decimalNumber.length - 1] === '0') {\r\n formattedDecimalNumber = decimalNumber.slice(0, -1)\r\n }\r\n\r\n return `${[wholeNumber, formattedDecimalNumber].join('.')}${suffix}`\r\n}\r\n\r\nexport function getChartEventBageColors(colorKey: 'violet' | 'blue' | 'red' | 'gray' | 'purple' | 'green') {\r\n return {\r\n light: {\r\n outerStroke: twColors.white,\r\n innerStroke: twColors[colorKey][400],\r\n innerFill: {\r\n default: twColors[colorKey][50],\r\n hover: twColors[colorKey][100],\r\n selected: twColors[colorKey][400],\r\n },\r\n textFill: {\r\n default: twColors[colorKey][500],\r\n hover: twColors[colorKey][600],\r\n selected: twColors.white,\r\n },\r\n },\r\n dark: {\r\n outerStroke: twColors.gray[900],\r\n innerStroke: twColors[colorKey][400],\r\n innerFill: {\r\n default: twColors[colorKey][800],\r\n hover: twColors[colorKey][600],\r\n selected: twColors[colorKey][400],\r\n },\r\n textFill: {\r\n default: twColors.white,\r\n hover: twColors.white,\r\n selected: twColors.white,\r\n },\r\n },\r\n } as IBadgeColors\r\n}\r\n","import { Instrument } from '../../types/shared'\r\nimport Line from '../canvas/line'\r\nimport Text from '../canvas/text'\r\nimport {\r\n CanvasElementType,\r\n ChartElementType,\r\n ChartEventType,\r\n IndicatorType,\r\n IntradayTimeframeInterval,\r\n MONTHS,\r\n OFFSET,\r\n OverlayType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n} from '../constants/common'\r\nimport { getIsSmallIndexChart, getTranslate } from '../controllers/renderUtils'\r\nimport { ISettings } from '../models/chart_settings/interfaces'\r\nimport Pane from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport utils, { dateFromDateString } from '../utils'\r\nimport { getBarWidthWithMargin, getHalfBarWidth } from './chart'\r\nimport { getVisibleBarToRenderIndex } from './draw_in_visible_area'\r\n\r\ninterface RenderXAxisProps {\r\n context: CanvasRenderingContext2D\r\n textRenderer?: Text\r\n paneModel: Pane\r\n quote: Quote\r\n type: CanvasElementType | OverlayType | ChartElementType | IndicatorType | ChartEventType\r\n}\r\n\r\ninterface RenderTimeframeXAxisProps extends Omit {\r\n startBarIndex: number\r\n endBarIndex: number\r\n fx: (x: number) => number\r\n}\r\n\r\ninterface XAxisLabel {\r\n x: number\r\n text: string\r\n textWidth: number\r\n hasPriority?: boolean\r\n allowedOverflow?: number\r\n}\r\n\r\nfunction getXLine({ paneModel, height }: { paneModel: Pane; height: number }): Line {\r\n const chartLayoutSettings = paneModel.getChartLayoutSettings()\r\n return new Line(\r\n {\r\n y1: 0,\r\n y2: height,\r\n strokeStyle: chartLayoutSettings.ChartSettings.general.Colors.grid,\r\n dashLength: 3,\r\n },\r\n paneModel\r\n )\r\n}\r\n\r\nfunction isXPointVisible({ buffer = 0, x, width }: { x: number; buffer?: number; width: number }) {\r\n return x >= 0 - buffer && x <= width + buffer\r\n}\r\n\r\nfunction getIsOverlapping({\r\n x,\r\n textWidth,\r\n renderedLabelRanges,\r\n}: {\r\n x: number\r\n textWidth: number\r\n renderedLabelRanges: Array<{ from: number; to: number }>\r\n}) {\r\n return renderedLabelRanges.some(({ from, to }) => {\r\n const minX = x - textWidth / 2\r\n const maxX = x + textWidth / 2\r\n return (from < maxX && maxX < to) || (from < minX && minX < to)\r\n })\r\n}\r\n\r\nfunction renderXAxisLabels({\r\n context,\r\n width,\r\n labels,\r\n textRenderer,\r\n allowedOverflow = 0,\r\n}: {\r\n context: CanvasRenderingContext2D\r\n width: number\r\n labels: Omit[]\r\n textRenderer: Text\r\n allowedOverflow?: number\r\n}) {\r\n const sortedLabels: XAxisLabel[] = []\r\n const renderedLabelRanges: Array<{ from: number; to: number }> = []\r\n labels.reverse().forEach((label) => {\r\n textRenderer.set({ text: label.text })\r\n const textWidth = Math.floor(textRenderer.measure(context))\r\n const newLabel = { ...label, textWidth }\r\n if (label.hasPriority) {\r\n sortedLabels.unshift(newLabel)\r\n } else {\r\n sortedLabels.push(newLabel)\r\n }\r\n })\r\n\r\n sortedLabels.forEach(({ x, text, textWidth }) => {\r\n if (!isXPointVisible({ x, width, buffer: allowedOverflow })) {\r\n return\r\n }\r\n const halfOfTextWidth = textWidth / 2\r\n const overflowLeft = x - halfOfTextWidth + allowedOverflow\r\n const overflowRight = width - (x + halfOfTextWidth) + allowedOverflow\r\n let labelX = x\r\n if (overflowLeft < 0) {\r\n labelX = Math.round(x - overflowLeft)\r\n } else if (overflowRight < 0) {\r\n labelX = Math.round(x + overflowRight)\r\n }\r\n if (getIsOverlapping({ x: labelX, textWidth, renderedLabelRanges })) {\r\n return\r\n }\r\n renderedLabelRanges.push({\r\n from: labelX - halfOfTextWidth - OFFSET.M,\r\n to: labelX + halfOfTextWidth + OFFSET.M,\r\n })\r\n textRenderer.set({ text, x: labelX })\r\n textRenderer.render(context)\r\n })\r\n}\r\n\r\nfunction getSize(paneModel: Pane) {\r\n const isIndicator = paneModel.getIsIndicatorPane()\r\n const { IndicatorSettings, ChartSettings, MarketSentimentSettings } = paneModel.getChartLayoutSettings()\r\n let settings: ISettings['IndicatorSettings' | 'ChartSettings' | 'MarketSentimentSettings'] = ChartSettings\r\n\r\n if (isIndicator) {\r\n settings = IndicatorSettings\r\n } else if (paneModel.mainElement()?.getIsChartType(ChartElementType.MarketSentiment)) {\r\n settings = MarketSentimentSettings\r\n }\r\n\r\n const paddingX = settings.left.width + settings.right.width\r\n const paddingY = settings.top.height + settings.bottom.height\r\n\r\n const chartWidth = paneModel.chart().width\r\n const paneHeight = paneModel.height\r\n return { width: chartWidth ? chartWidth - paddingX : 0, height: paneHeight ? paneHeight - paddingY : 0 }\r\n}\r\n\r\nfunction renderDailyXAxis({\r\n context,\r\n quote,\r\n paneModel,\r\n textRenderer,\r\n startBarIndex,\r\n endBarIndex,\r\n fx,\r\n}: RenderTimeframeXAxisProps) {\r\n const { width, height } = getSize(paneModel)\r\n\r\n const chartModel = paneModel.chart()\r\n let lastMonth = ''\r\n\r\n const labels = []\r\n const xLine = getXLine({ paneModel, height })\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(quote.date[i])\r\n const month = date.getMonth() + '-' + date.getFullYear()\r\n if (month !== lastMonth) {\r\n lastMonth = month\r\n const x = Math.round(fx(i) + chartModel.leftOffset)\r\n if (!isXPointVisible({ x, width })) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(context)\r\n labels.push({\r\n hasPriority: date.getMonth() === 0,\r\n text: date.getMonth() === 0 ? date.getFullYear().toString() : MONTHS[date.getMonth()],\r\n x,\r\n })\r\n }\r\n }\r\n if (textRenderer) {\r\n renderXAxisLabels({ context, width, labels, textRenderer })\r\n }\r\n}\r\n\r\nfunction render15MinXAxis({\r\n context,\r\n quote,\r\n paneModel,\r\n textRenderer,\r\n startBarIndex,\r\n endBarIndex,\r\n fx,\r\n}: RenderTimeframeXAxisProps) {\r\n const { width, height } = getSize(paneModel)\r\n const chartModel = paneModel.chart()\r\n const chartLayout = chartModel.chart_layout()\r\n let lastDay = ''\r\n let x = 0\r\n\r\n const labels = []\r\n const xLine = getXLine({ paneModel, height })\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(quote.date[i])\r\n const day = date.getDate() + '-' + date.getMonth()\r\n if (day !== lastDay) {\r\n lastDay = day\r\n if (quote.instrument === Instrument.Stock) {\r\n const barAtMinute = date.getMinutes() + date.getHours() * 60\r\n const indexOffset = (barAtMinute - quote.marketStartMinutes) / quote.interval\r\n x = Math.round(paneModel.scale.x(quote.barIndex[i] - indexOffset) + chartModel.leftOffset)\r\n } else {\r\n x = Math.round(fx(i) + chartModel.leftOffset)\r\n }\r\n if (!isXPointVisible({ x, width })) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(context)\r\n labels.push({\r\n text: MONTHS[date.getMonth()] + ' ' + date.getDate().toString().padLeft('00'),\r\n x,\r\n })\r\n }\r\n }\r\n\r\n // Offscreen only - if lastDate !== lastBarDate add tick\r\n if (chartLayout.specificChartFunctionality === SpecificChartFunctionality.offScreen) {\r\n const lastDate = `${MONTHS[(~~(quote.lastDate / 100) % 100) - 1]} ${(quote.lastDate % 100)\r\n .toString()\r\n .padLeft('00')}` // YYYYMMDD / 20211118 => Nov 18\r\n\r\n if (labels.length > 0 && labels[labels.length - 1].text !== lastDate) {\r\n const barsInDay = quote.getBarsInDay()!\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor: chartModel.zoomFactor,\r\n chartLayout,\r\n })\r\n const dayWidth = barsInDay * barWidth\r\n x += dayWidth\r\n labels.push({\r\n text: lastDate,\r\n x,\r\n })\r\n xLine.set({ x1: x, x2: x }).render(context)\r\n }\r\n }\r\n\r\n if (textRenderer) {\r\n renderXAxisLabels({ context, width, labels, textRenderer })\r\n }\r\n}\r\n\r\nconst SMALL_INDEX_CHART_LABEL_BUFFER = 15\r\n\r\nfunction renderIntradayXAxis({ context, quote, paneModel, textRenderer }: Omit) {\r\n const { width, height } = getSize(paneModel)\r\n const chartModel = paneModel.chart()\r\n const chartLayout = chartModel.chart_layout()\r\n const interval = IntradayTimeframeInterval[quote.timeframe as keyof typeof IntradayTimeframeInterval]\r\n const marketStartHour = ~~(quote.marketStartMinutes / 60)\r\n let marketEndHour = 15 + Math.ceil(quote.aftermarketLengthMinutes / 60)\r\n const labels = []\r\n const isSmallIndexChart = getIsSmallIndexChart(chartLayout.specificChartFunctionality)\r\n if (isSmallIndexChart) {\r\n marketEndHour = 16\r\n }\r\n\r\n const xLine = getXLine({ paneModel, height })\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor: chartModel.zoomFactor,\r\n chartLayout,\r\n })\r\n\r\n const dayToOffset = quote.getDayToOffset()\r\n const allowedOverflow = isSmallIndexChart ? SMALL_INDEX_CHART_LABEL_BUFFER : 0\r\n for (const day in dayToOffset) {\r\n const dayIndex = dayToOffset[day]\r\n const date = dateFromDateString(day)\r\n\r\n for (let i = marketStartHour; i <= marketEndHour; i++) {\r\n let x =\r\n ((i * 60 - quote.marketStartMinutes) / interval) * barWidth +\r\n dayIndex * (quote.drawMinutesPerDay / interval) * barWidth +\r\n chartModel.leftOffset\r\n if (!isXPointVisible({ x, width, buffer: allowedOverflow })) {\r\n continue\r\n }\r\n let roundedX = Math.round(x)\r\n\r\n if (i === marketStartHour) {\r\n if (isSmallIndexChart) {\r\n roundedX = Math.round(x - 3 + (30 / interval) * barWidth)\r\n // ~9:30AM\r\n xLine\r\n .set({\r\n x1: roundedX,\r\n x2: roundedX,\r\n })\r\n .render(context)\r\n continue\r\n }\r\n if (quote.premarketLengthMinutes === 0) {\r\n // If there is no premarket, day starts at 9:30 AM\r\n x += (30 / interval) * barWidth\r\n }\r\n roundedX = Math.round(x)\r\n xLine.set({ x1: roundedX, x2: roundedX }).render(context)\r\n labels.push({\r\n hasPriority: true,\r\n text: MONTHS[date.getMonth()] + ' ' + date.getDate().toString().padLeft('00'),\r\n x: roundedX,\r\n })\r\n } else {\r\n xLine.set({ x1: roundedX, x2: roundedX }).render(context)\r\n labels.push({\r\n text: ((i + 11) % 12) + 1 + (i < 12 ? 'AM' : 'PM'),\r\n x: roundedX,\r\n })\r\n }\r\n }\r\n }\r\n\r\n if (textRenderer) {\r\n renderXAxisLabels({ context, width, labels, textRenderer, allowedOverflow })\r\n }\r\n}\r\n\r\nfunction renderIntradayXAxisFutures({\r\n context,\r\n quote,\r\n paneModel,\r\n textRenderer,\r\n startBarIndex,\r\n endBarIndex,\r\n fx,\r\n}: RenderTimeframeXAxisProps) {\r\n const { width, height } = getSize(paneModel)\r\n const chartModel = paneModel.chart()\r\n let lastDay = ''\r\n let lastHours = NaN\r\n\r\n const labels = []\r\n const xLine = getXLine({ paneModel, height })\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(quote.date[i])\r\n const day = date.getDate() + '-' + date.getMonth()\r\n const hours = date.getHours()\r\n const x = Math.round(fx(i) + chartModel.leftOffset)\r\n\r\n if (day !== lastDay) {\r\n lastDay = day\r\n lastHours = hours\r\n if (!isXPointVisible({ x, width })) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(context)\r\n labels.push({\r\n x,\r\n text: MONTHS[date.getMonth()] + ' ' + date.getDate().toString().padLeft('00'),\r\n })\r\n } else if (hours % 2 === 0 && hours !== lastHours) {\r\n lastHours = hours\r\n if (!isXPointVisible({ x, width })) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(context)\r\n labels.push({ x, text: ((hours + 11) % 12) + 1 + (hours < 12 ? 'AM' : 'PM') })\r\n }\r\n }\r\n\r\n if (textRenderer) {\r\n renderXAxisLabels({ context, width, labels, textRenderer })\r\n }\r\n}\r\n\r\nfunction renderWeeklyXAxis({\r\n context,\r\n quote,\r\n paneModel,\r\n textRenderer,\r\n startBarIndex,\r\n endBarIndex,\r\n fx,\r\n}: RenderTimeframeXAxisProps) {\r\n const { width, height } = getSize(paneModel)\r\n const chartModel = paneModel.chart()\r\n let lastMonth = ''\r\n\r\n const labels = []\r\n const xLine = getXLine({ paneModel, height })\r\n const { Colors } = paneModel.getChartLayoutSettings().ChartSettings.general\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(quote.date[i])\r\n const month = date.getMonth() + '-' + date.getFullYear()\r\n if (month !== lastMonth) {\r\n lastMonth = month\r\n const x = Math.round(fx(i) + chartModel.leftOffset)\r\n if (!isXPointVisible({ x, width })) {\r\n continue\r\n }\r\n if (date.getMonth() % 3 === 0) {\r\n xLine.set({ x1: x, x2: x }).render(context)\r\n } else {\r\n new Line(\r\n {\r\n x1: x,\r\n x2: x,\r\n y1: 0,\r\n y2: height,\r\n strokeStyle: Colors.gridSecondary,\r\n dashLength: 3,\r\n },\r\n paneModel\r\n ).render(context)\r\n }\r\n const isYearLabel = date.getMonth() === 0\r\n labels.push({\r\n text: isYearLabel ? date.getFullYear().toString().substring(2) : MONTHS[date.getMonth()][0],\r\n hasPriority: isYearLabel,\r\n x,\r\n })\r\n }\r\n }\r\n\r\n if (textRenderer) {\r\n renderXAxisLabels({ context, width, labels, textRenderer })\r\n }\r\n}\r\n\r\nfunction renderMonthlyXAxis({\r\n context,\r\n quote,\r\n paneModel,\r\n textRenderer,\r\n startBarIndex,\r\n endBarIndex,\r\n fx,\r\n}: RenderTimeframeXAxisProps) {\r\n const { width, height } = getSize(paneModel)\r\n const chartModel = paneModel.chart()\r\n let lastYear = null\r\n\r\n const labels = []\r\n const xLine = getXLine({ paneModel, height })\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(quote.date[i])\r\n const year = date.getFullYear()\r\n const isJanuary = date.getMonth() === 0\r\n if (year !== lastYear && (labels.length !== 0 || isJanuary)) {\r\n lastYear = year\r\n const x = Math.round(fx(i) + chartModel.leftOffset)\r\n if (!isXPointVisible({ x, width })) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(context)\r\n labels.push({\r\n text: date.getFullYear().toString(),\r\n x,\r\n })\r\n }\r\n }\r\n\r\n if (textRenderer) {\r\n renderXAxisLabels({ context, width, labels, textRenderer })\r\n }\r\n}\r\n\r\nexport function renderXAxis({ context, quote, paneModel, textRenderer, type: elementType }: RenderXAxisProps) {\r\n const fx = (x: number) => paneModel.scale.x(quote.barIndex[x])\r\n const { width } = getSize(paneModel)\r\n const chartModel = paneModel.chart()\r\n const chartLayout = chartModel.chart_layout()\r\n const leftOffset = chartModel.leftOffset\r\n\r\n // Ticks are placed at the start of each timeframe period (hour/day/month/year).\r\n // The \"-1\" in the code ensures we start searching from one bar outside the visible area,\r\n // avoiding a tick on the first visible index unless it marks the start of a new timeframe period.\r\n // For example, if the start of December is on December 3rd and the first visible bar is on December 14th,\r\n // we won't display a tick.\r\n const startBarIndex = Math.max(\r\n getVisibleBarToRenderIndex({\r\n quote,\r\n paneModel,\r\n leftOffset,\r\n }).index - 1,\r\n 0\r\n )\r\n\r\n const endBarIndex = Math.min(\r\n getVisibleBarToRenderIndex({\r\n quote,\r\n paneModel,\r\n leftOffset,\r\n chartWidth: width,\r\n }).index + 1,\r\n quote.close.length - 1\r\n )\r\n\r\n const renderTimeframeXAxisProps = { context, quote, paneModel, textRenderer, startBarIndex, endBarIndex, fx }\r\n\r\n switch (quote.timeframe) {\r\n case TIMEFRAME.i1:\r\n case TIMEFRAME.i2:\r\n case TIMEFRAME.i3:\r\n case TIMEFRAME.i5:\r\n if (quote.instrument === Instrument.Stock) {\r\n if (\r\n elementType === ChartElementType.LineChart &&\r\n chartLayout.specificChartFunctionality === SpecificChartFunctionality.offScreen &&\r\n quote.timeframe === 'i5'\r\n ) {\r\n render15MinXAxis(renderTimeframeXAxisProps)\r\n } else {\r\n renderIntradayXAxis({ context, quote, paneModel, textRenderer })\r\n }\r\n } else {\r\n renderIntradayXAxisFutures(renderTimeframeXAxisProps)\r\n }\r\n break\r\n case TIMEFRAME.i10:\r\n if (getIsSmallIndexChart(chartLayout.specificChartFunctionality)) {\r\n renderIntradayXAxis({ context, quote, paneModel, textRenderer })\r\n } else {\r\n render15MinXAxis(renderTimeframeXAxisProps)\r\n }\r\n break\r\n case TIMEFRAME.i15:\r\n case TIMEFRAME.i30:\r\n case TIMEFRAME.h:\r\n case TIMEFRAME.h2:\r\n case TIMEFRAME.h4:\r\n render15MinXAxis(renderTimeframeXAxisProps)\r\n break\r\n case TIMEFRAME.d:\r\n renderDailyXAxis(renderTimeframeXAxisProps)\r\n break\r\n case TIMEFRAME.w:\r\n renderWeeklyXAxis(renderTimeframeXAxisProps)\r\n break\r\n case TIMEFRAME.m:\r\n renderMonthlyXAxis(renderTimeframeXAxisProps)\r\n break\r\n default:\r\n break\r\n }\r\n}\r\n\r\ninterface RenderFadeExtendedHoursProps {\r\n context: CanvasRenderingContext2D\r\n paneModel: Pane\r\n quote: Quote\r\n}\r\n// only for stocks on i1/i3/i5 and one day view\r\nexport function renderFadeExtendedHours({ context, paneModel, quote }: RenderFadeExtendedHoursProps) {\r\n const isIndicator = paneModel.getIsIndicatorPane()\r\n const { height } = getSize(paneModel)\r\n const { ChartSettings, IndicatorSettings } = paneModel.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const chartModel = paneModel.chart()\r\n const period = quote.timeframe\r\n if (quote.instrument !== Instrument.Stock) {\r\n return\r\n }\r\n if (![TIMEFRAME.i1, TIMEFRAME.i2, TIMEFRAME.i3, TIMEFRAME.i5].includes(period)) {\r\n return\r\n }\r\n\r\n const interval = parseInt(period.substring(1), 10)\r\n const dayToOffset = quote.getDayToOffset()\r\n const translate = getTranslate({\r\n context,\r\n xOffset: chartModel.leftOffset + (isIndicator ? IndicatorSettings : ChartSettings).left.width,\r\n yOffset: (isIndicator ? IndicatorSettings : ChartSettings).top.height,\r\n })\r\n translate.do()\r\n const halfBarWidth = getHalfBarWidth(chartModel)\r\n for (const day in dayToOffset) {\r\n // todo aftermarket\r\n const dayIndex = dayToOffset[day]\r\n let n0 = (quote.drawMinutesPerDay / interval) * dayIndex\r\n let n1 = quote.premarketLengthMinutes / interval + n0 // bars in 90mins from 8am to 9:30am\r\n let x0 = paneModel.scale.x(n0) - halfBarWidth\r\n let width = paneModel.scale.x(n1) - paneModel.scale.x(n0)\r\n context.set('fillStyle', Colors.premarketFade)\r\n context.fillRect(x0, 0, width, height + 1)\r\n\r\n if (quote.aftermarketLengthMinutes > 0) {\r\n n0 =\r\n (quote.drawMinutesPerDay / interval) * dayIndex +\r\n (quote.drawMinutesPerDay - quote.aftermarketLengthMinutes) / interval\r\n n1 = quote.aftermarketLengthMinutes / interval + n0 // bars in 90mins from 4pm to 5:30pm\r\n x0 = paneModel.scale.x(n0) - halfBarWidth\r\n width = paneModel.scale.x(n1) - paneModel.scale.x(n0)\r\n\r\n context.set('fillStyle', Colors.aftermarketFade)\r\n context.fillRect(x0, 0, width, height + 1)\r\n }\r\n }\r\n translate.undo()\r\n}\r\n","import * as dateFns from 'date-fns'\r\n\r\nimport { ChartConfigChart } from '../../server/chartConfig'\r\nimport { ChartConfigChartPane, Instrument, ObjectHash } from '../../types/shared'\r\nimport Line from '../canvas/line'\r\nimport Text from '../canvas/text'\r\nimport { chartsByType } from '../charts/charts'\r\nimport {\r\n CRYPTOS,\r\n ChartEditorEnum,\r\n ChartElementType,\r\n IndicatorType,\r\n OFFSET,\r\n PADDING,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n TIMEFRAME_SECONDS,\r\n TextBaseline,\r\n} from '../constants/common'\r\nimport { getPercentageFromValue } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport { indicatorsByType } from '../indicators/indicators'\r\nimport Chart from '../models/chart'\r\nimport ChartLayoutModel from '../models/chart_layout'\r\nimport { IChartSettings } from '../models/chart_settings/interfaces'\r\nimport { Mouse } from '../models/mouse'\r\nimport Pane from '../models/pane'\r\nimport Quote, { QuoteGetParams } from '../models/quote'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport Utils, { dateFromUnixTimestamp } from '../utils'\r\nimport { captureException } from './helpers'\r\n\r\nconst DAY_IN_SECONDS = 86400\r\nconst TWO_MIN_IN_MS = 2 * 60 * 1000\r\nconst virtualDatesCache: ObjectHash<{\r\n fromSeconds: number\r\n toSeconds: number\r\n lastUsed: number\r\n virtualDates: number[]\r\n}> = {}\r\n\r\n// The reason to use this func instead of dateFns.isSameDay is performance as this is way faster\r\nfunction areTimestampsFromSameDay({ ts1, ts2 }: { ts1: number; ts2: number }) {\r\n const ts1Utc = ts1\r\n const ts2Utc = ts2\r\n return Math.floor(ts1Utc / DAY_IN_SECONDS) === Math.floor(ts2Utc / DAY_IN_SECONDS)\r\n}\r\n\r\nfunction getVirtualDatesCacheId({\r\n idRevision,\r\n ticker,\r\n timeframe,\r\n}: {\r\n idRevision: number\r\n ticker: string\r\n timeframe: string\r\n}) {\r\n return `${ticker}-${timeframe}-${idRevision}`\r\n}\r\n\r\nfunction getCachedVirtualDates({\r\n idRevision,\r\n ticker,\r\n timeframe,\r\n fromSeconds,\r\n toSeconds,\r\n}: {\r\n idRevision: number\r\n ticker: string\r\n timeframe: string\r\n fromSeconds: number\r\n toSeconds: number\r\n}) {\r\n const id = getVirtualDatesCacheId({ idRevision, ticker, timeframe })\r\n const cache = virtualDatesCache[id]\r\n if (cache?.fromSeconds <= fromSeconds && cache?.toSeconds >= toSeconds) {\r\n cache.lastUsed = Date.now()\r\n if (cache.fromSeconds === fromSeconds && cache.toSeconds === toSeconds) {\r\n return cache.virtualDates\r\n }\r\n return cache.virtualDates.filter(\r\n (virtualDateSeconds) => virtualDateSeconds >= fromSeconds && virtualDateSeconds <= toSeconds\r\n )\r\n }\r\n return null\r\n}\r\n\r\nfunction checkVirtualCacheSize() {\r\n const now = Date.now()\r\n Object.keys(virtualDatesCache).forEach((virtualDatesCacheId) => {\r\n if (virtualDatesCache[virtualDatesCacheId].lastUsed < now - TWO_MIN_IN_MS) {\r\n delete virtualDatesCache[virtualDatesCacheId]\r\n }\r\n })\r\n}\r\n\r\nfunction setCachedVirtualDates({\r\n idRevision,\r\n ticker,\r\n timeframe,\r\n fromSeconds,\r\n toSeconds,\r\n virtualDates,\r\n}: {\r\n idRevision: number\r\n ticker: string\r\n timeframe: string\r\n fromSeconds: number\r\n toSeconds: number\r\n virtualDates: number[]\r\n}) {\r\n const id = getVirtualDatesCacheId({ idRevision, ticker, timeframe })\r\n checkVirtualCacheSize()\r\n virtualDatesCache[id] = {\r\n fromSeconds,\r\n toSeconds,\r\n virtualDates,\r\n lastUsed: Date.now(),\r\n }\r\n}\r\n\r\nconst MAX_BAR_BORDER_WIDTH = 1\r\nconst MIN_BAR_MARGIN_WIDTH = 0\r\nconst MAX_BAR_MARGIN_WIDTH = 16\r\n\r\nexport function getBarWidthWithMarginByParts({\r\n zoomFactor = 1,\r\n chartLayout,\r\n}: {\r\n zoomFactor?: number\r\n chartLayout: ChartLayoutModel\r\n}) {\r\n const { ChartSettings } = chartLayout.settings\r\n const settingsCenter = ChartSettings.center\r\n const barMargin =\r\n zoomFactor > 1 && settingsCenter.barMargin === 0\r\n ? Math.min(settingsCenter.barWidth, 1 - 1 / zoomFactor)\r\n : settingsCenter.barMargin\r\n\r\n const barFillWidth = settingsCenter.barWidth * zoomFactor\r\n const barBorderWidth = Math.min(settingsCenter.border * zoomFactor, MAX_BAR_BORDER_WIDTH)\r\n const barMarginWidth = Math.max(MIN_BAR_MARGIN_WIDTH, Math.min(barMargin * zoomFactor, MAX_BAR_MARGIN_WIDTH))\r\n\r\n return {\r\n barFillWidth,\r\n barBorderWidth,\r\n barMarginWidth,\r\n }\r\n}\r\n\r\nexport function getBarWidthWithMargin({\r\n zoomFactor = 1,\r\n chartLayout,\r\n shouldRound = true,\r\n}: {\r\n zoomFactor?: number\r\n chartLayout: ChartLayoutModel\r\n shouldRound?: boolean\r\n}) {\r\n const { barFillWidth, barBorderWidth, barMarginWidth } = getBarWidthWithMarginByParts({ zoomFactor, chartLayout })\r\n\r\n const barWidth = barFillWidth + barBorderWidth * 2 + barMarginWidth\r\n if (!shouldRound) {\r\n return barWidth\r\n }\r\n const roundDecimalPlaces = barWidth > 100 ? 10 : 10000\r\n return Math.round(barWidth * roundDecimalPlaces) / roundDecimalPlaces\r\n}\r\n\r\nexport function getBarWithoutMarginWidth(chartModel: Chart) {\r\n const { barFillWidth, barBorderWidth } = getBarWidthWithMarginByParts({\r\n chartLayout: chartModel.chart_layout(),\r\n zoomFactor: chartModel.zoomFactor,\r\n })\r\n return barFillWidth + barBorderWidth * 2\r\n}\r\n\r\nexport function getHalfBarWidth(chartModel: Chart, floor = true) {\r\n // Math.max(1, num) is kept from previous implementation, it is highly likely\r\n // that some function which use getHalfBarWidth expect return to be >= 1,\r\n // because we never render bar with width < 1 but at the same time when we have and odd\r\n // width like 5, wa want to floor because of pixel perfect rendering\r\n // but some function require raw not floored number to be able to do it's calculations\r\n // TODO: it would be good to possibly revisit this and check usage if we do need\r\n // to perform floor as well as limit result to be >= 1 but it is most likely necessary\r\n const halfBarWidthRaw = Math.max(1, getBarWithoutMarginWidth(chartModel) / 2)\r\n return floor ? ~~halfBarWidthRaw : halfBarWidthRaw\r\n}\r\n\r\nconst DEFAULT_ZOOM_GUESS_INCREMENT = 0.001\r\n\r\nconst zoomFactorForBarsToDisplayCache: ObjectHash = {}\r\nconst zoomFactorForBarsToDisplayCacheKeys: string[] = []\r\nconst NUMBER_OF_CACHED_ZOOM_FACTORS = 10\r\nconst getZoomFactorFromCache = (key: string) => zoomFactorForBarsToDisplayCache[key] ?? null\r\nconst setZoomFactorToCache = (key: string, value: number) => {\r\n if (!zoomFactorForBarsToDisplayCacheKeys.includes(key)) {\r\n zoomFactorForBarsToDisplayCacheKeys.unshift(key)\r\n if (zoomFactorForBarsToDisplayCacheKeys.length > NUMBER_OF_CACHED_ZOOM_FACTORS) {\r\n const poppedKey = zoomFactorForBarsToDisplayCacheKeys.pop()\r\n if (poppedKey) {\r\n delete zoomFactorForBarsToDisplayCache[poppedKey]\r\n }\r\n }\r\n }\r\n\r\n zoomFactorForBarsToDisplayCache[key] = value\r\n}\r\n\r\nexport function getZoomFactorForBarsToDisplay({\r\n chartVisibleWidth,\r\n numOfVisibleBars,\r\n chartLayout,\r\n}: {\r\n chartVisibleWidth: number\r\n numOfVisibleBars: number\r\n chartLayout: ChartLayoutModel\r\n}) {\r\n const defaultBarWidthWithMargin = getBarWidthWithMargin({ chartLayout })\r\n const barWidthWithMargin = chartVisibleWidth / numOfVisibleBars\r\n const cacheKey = `${defaultBarWidthWithMargin}-${barWidthWithMargin}`\r\n let zoomIncrement = 0\r\n let currentZoomFactor = 1\r\n let finalZoomFactor = getZoomFactorFromCache(cacheKey)\r\n let iteration = 0\r\n if (barWidthWithMargin <= defaultBarWidthWithMargin) {\r\n finalZoomFactor = barWidthWithMargin / defaultBarWidthWithMargin\r\n }\r\n while (finalZoomFactor === null) {\r\n iteration += 1\r\n const threshold = 0.01\r\n currentZoomFactor += zoomIncrement\r\n const barWidth = getBarWidthWithMargin({ zoomFactor: currentZoomFactor, chartLayout, shouldRound: false })\r\n const barWidthDiff = barWidthWithMargin - barWidth\r\n if (barWidthDiff > threshold) {\r\n zoomIncrement = zoomIncrement > 0 ? zoomIncrement * 2 : DEFAULT_ZOOM_GUESS_INCREMENT\r\n } else if (barWidthDiff < -threshold) {\r\n zoomIncrement = zoomIncrement < 0 ? zoomIncrement * 2 : -DEFAULT_ZOOM_GUESS_INCREMENT\r\n } else {\r\n finalZoomFactor = currentZoomFactor\r\n }\r\n\r\n if (iteration === 1000) {\r\n captureException(new Error('Invalid zoom factor from getZoomFactorForBarsToDisplay'), {\r\n extra: {\r\n iteration,\r\n zoomIncrement,\r\n barWidthWithMargin,\r\n barWidth,\r\n barWidthDiff,\r\n currentZoomFactor,\r\n chartLayout: chartLayout.toConfig(['colors', 'panes']),\r\n },\r\n })\r\n return currentZoomFactor\r\n }\r\n }\r\n\r\n setZoomFactorToCache(cacheKey, finalZoomFactor)\r\n\r\n return finalZoomFactor\r\n}\r\n\r\nexport function getTimeframeSeconds({\r\n lowerIndex,\r\n dates,\r\n timeframe,\r\n}: {\r\n lowerIndex: number\r\n dates: number[]\r\n timeframe: TIMEFRAME\r\n}) {\r\n const upperIndex = lowerIndex + 1\r\n const areBoundsDefined = ![dates[upperIndex], dates[lowerIndex]].some((index) => index === undefined)\r\n return areBoundsDefined ? dates[upperIndex] - dates[lowerIndex] : TIMEFRAME_SECONDS[timeframe]\r\n}\r\n\r\nfunction getVirtualTradedDays({\r\n dateStartSeconds,\r\n dateEndSeconds,\r\n datesSeconds,\r\n marketStartMinutes,\r\n}: {\r\n dateStartSeconds: number\r\n dateEndSeconds: number\r\n datesSeconds: number[]\r\n marketStartMinutes: number\r\n}) {\r\n const dateStart = dateFromUnixTimestamp(dateStartSeconds)\r\n const dateEnd = dateFromUnixTimestamp(dateEndSeconds)\r\n const isStartBeforeDates = dateStartSeconds < datesSeconds[0]\r\n const isEndAfterDates = datesSeconds.length > 0 && datesSeconds[datesSeconds.length - 1] < dateEndSeconds\r\n const firstDate = dateFromUnixTimestamp(datesSeconds[0])\r\n const lastDate = dateFromUnixTimestamp(datesSeconds[datesSeconds.length - 1])\r\n return dateFns\r\n .eachDayOfInterval({\r\n start:\r\n isStartBeforeDates && (dateFns.isWeekend(dateStart) || dateStart.getMinutes() < marketStartMinutes)\r\n ? dateFns.addBusinessDays(dateStart, -1)\r\n : dateStart,\r\n end: isEndAfterDates ? dateFns.addBusinessDays(dateEnd, 1) : dateEnd,\r\n })\r\n .filter((date) => {\r\n const ts2 = date.getTime() / 1000 - date.getTimezoneOffset() * 60\r\n return (\r\n !dateFns.isWithinInterval(date, { start: dateFns.startOfDay(firstDate), end: dateFns.endOfDay(lastDate) }) ||\r\n datesSeconds.some((dateTime) =>\r\n areTimestampsFromSameDay({\r\n ts1: dateTime - Utils.getQuoteDateTimestampOffsetInSeconds(new Date(dateTime * 1000)),\r\n ts2,\r\n })\r\n )\r\n )\r\n })\r\n}\r\n\r\nexport function getVirtualTimeframeTradedDates({\r\n dateStart,\r\n dateEnd,\r\n quote,\r\n}: {\r\n dateStart: number\r\n dateEnd: number\r\n quote: Quote\r\n}) {\r\n const { date: dates, ticker, timeframe, instrument, isIntraday, marketStartMinutes } = quote\r\n const barsInDay = quote.getBarsInDay() ?? 0\r\n\r\n // Currently we're passing first and last quote dates to dateStart / dateEnd so this is always true\r\n // but this function can be used on other places in the future where it will work with dates out of quote dates range\r\n const isWithinRangeOfQuoteDate = dateStart === dates[0] && dateEnd === dates[dates.length - 1]\r\n\r\n const commonVirtualCacheProps = {\r\n idRevision: dates.length,\r\n ticker,\r\n timeframe,\r\n fromSeconds: dateStart,\r\n toSeconds: dateEnd,\r\n }\r\n const cachedDates = getCachedVirtualDates(commonVirtualCacheProps)\r\n if (cachedDates) {\r\n return cachedDates\r\n }\r\n if (!isIntraday || instrument !== Instrument.Stock) {\r\n if (isWithinRangeOfQuoteDate) {\r\n return dates\r\n }\r\n const timeframeSeconds = TIMEFRAME_SECONDS[timeframe]\r\n const firstDate = dates[0]\r\n const lastDate = dates[dates.length - 1]\r\n const numOfDatesBefore = Math.ceil((firstDate - dateStart) / timeframeSeconds)\r\n const numOfDatesAfter = Math.ceil((dateEnd - lastDate) / timeframeSeconds)\r\n return [\r\n ...Array.from({ length: numOfDatesBefore })\r\n .map((_, index) => firstDate - (index + 1) * timeframeSeconds)\r\n .reverse(),\r\n ...dates,\r\n ...Array.from({ length: numOfDatesAfter }).map((_, index) => lastDate + (index + 1) * timeframeSeconds),\r\n ]\r\n }\r\n\r\n const virtualTradedDays = isWithinRangeOfQuoteDate\r\n ? quote.getDaysInQuote()\r\n : getVirtualTradedDays({\r\n dateStartSeconds: dateStart,\r\n dateEndSeconds: dateEnd,\r\n datesSeconds: dates,\r\n marketStartMinutes,\r\n })\r\n\r\n const marketStartSeconds = marketStartMinutes * 60\r\n const barTimeframeSeconds = Array.from({ length: barsInDay }).map((_, i) => i * TIMEFRAME_SECONDS[timeframe])\r\n const quoteDatesTimestampOffset = Utils.getQuoteDateTimestampOffsetInSeconds(new Date(dateStart * 1000))\r\n const virtualDates = virtualTradedDays.flatMap((date) => {\r\n const daySeconds =\r\n date.getTime() / 1000 + Utils.getQuoteDateTimestampOffsetInSeconds(date) - date.getTimezoneOffset() * 60\r\n const dayStartSeconds = daySeconds + marketStartSeconds\r\n return barTimeframeSeconds.map(\r\n // Hourly market starts at 9:30 but all other time ticks should be rounded down to :00 of the current hour\r\n (barSeconds, index) =>\r\n ([TIMEFRAME.h, TIMEFRAME.h2, TIMEFRAME.h4].includes(timeframe) && index > 0 ? -1800 : 0) +\r\n dayStartSeconds +\r\n barSeconds\r\n )\r\n })\r\n\r\n if (!isWithinRangeOfQuoteDate) {\r\n virtualDates.filter((date, index, virtualTimeframeTradedDates) => {\r\n const isLowerBounded =\r\n date >= dateStart ||\r\n areTimestampsFromSameDay({\r\n ts1: date - Utils.getQuoteDateTimestampOffsetInSeconds(new Date(date * 1000)),\r\n ts2: dateStart - quoteDatesTimestampOffset,\r\n })\r\n const isOneBeforeLowerBoundStarts = dateStart > date && dateStart < virtualTimeframeTradedDates[index + 1]\r\n return isLowerBounded || isOneBeforeLowerBoundStarts\r\n })\r\n }\r\n\r\n setCachedVirtualDates({\r\n ...commonVirtualCacheProps,\r\n virtualDates,\r\n })\r\n\r\n return virtualDates\r\n}\r\n\r\ninterface TimestampPositionGettersProps {\r\n quote: Quote\r\n}\r\n\r\nexport function getTimestampFromPositionX({ positionX, quote }: TimestampPositionGettersProps & { positionX: number }) {\r\n const { date, timeframe } = quote\r\n const dates = getVirtualTimeframeTradedDates({\r\n dateStart: date[0],\r\n dateEnd: date[date.length - 1],\r\n quote,\r\n })\r\n const dateStart = dates[0]\r\n const dateEnd = dates[dates.length - 1]\r\n const lastDateIndex = dates.length - 1\r\n if (positionX >= 0 && positionX <= lastDateIndex) {\r\n const lowerIndex = Math.floor(positionX)\r\n const timeframeSeconds = getTimeframeSeconds({ lowerIndex, dates, timeframe })\r\n return dates[lowerIndex] + (positionX - lowerIndex) * timeframeSeconds\r\n }\r\n const isLookingBack = positionX < 0\r\n const averageBarDate = (dateEnd - dateStart) / dates.length\r\n const numOfSecondsOutOfBounds = isLookingBack\r\n ? Math.abs(positionX) * averageBarDate\r\n : (positionX - lastDateIndex) * averageBarDate\r\n return Math.round(isLookingBack ? dateStart - numOfSecondsOutOfBounds : dateEnd + numOfSecondsOutOfBounds)\r\n}\r\n\r\nexport function getPositionXFromTimestamp({ timestamp, quote }: TimestampPositionGettersProps & { timestamp: number }) {\r\n const { date, timeframe } = quote\r\n const dates = getVirtualTimeframeTradedDates({\r\n dateStart: date[0],\r\n dateEnd: date[date.length - 1],\r\n quote,\r\n })\r\n const dateStart = dates[0]\r\n const dateEnd = dates[dates.length - 1]\r\n const lastDateIndex = dates.length - 1\r\n if (timestamp >= dates[0] && timestamp <= dates[dates.length - 1]) {\r\n const upperIndex = timestamp === dateEnd ? lastDateIndex : dates.findIndex((date) => date > timestamp)\r\n const timeframeSeconds = getTimeframeSeconds({ lowerIndex: upperIndex - 1, dates, timeframe })\r\n const positionDiffUpperTimestamp = (dates[upperIndex] - timestamp) / timeframeSeconds\r\n return upperIndex - positionDiffUpperTimestamp\r\n }\r\n const isLookingBack = timestamp < dateStart\r\n const averageBarDate = (dateEnd - dateStart) / dates.length\r\n return isLookingBack\r\n ? -((dateStart - timestamp) / averageBarDate)\r\n : lastDateIndex + (timestamp - dateEnd) / averageBarDate\r\n}\r\n\r\n// counterpart in Finviz-Website 'Finviz-Website/js/main/util.ts'\r\nexport function getInstrument(tickerRaw: string) {\r\n if (tickerRaw.indexOf('@') === 0) {\r\n const ticker = tickerRaw.substring(1) as keyof typeof CRYPTOS\r\n\r\n if (CRYPTOS[ticker]) {\r\n return Instrument.Crypto\r\n } else if (ticker.length === 6) {\r\n return Instrument.Forex\r\n } else {\r\n return Instrument.Futures\r\n }\r\n }\r\n return Instrument.Stock\r\n}\r\n\r\nexport function getPerfIndicatorTickerAndTimeframes({\r\n paneWithPerfIndicator,\r\n timeframe,\r\n}: {\r\n paneWithPerfIndicator: ChartConfigChartPane\r\n timeframe: TIMEFRAME\r\n}) {\r\n const { elements } = paneWithPerfIndicator\r\n const perfIndicatorElement = elements.find(({ type }) => type === 'indicators/perf')\r\n const tickers = perfIndicatorElement?.period?.split(',') ?? []\r\n return tickers.map((ticker) => ({\r\n ticker,\r\n instrument: getInstrument(ticker),\r\n timeframe,\r\n }))\r\n}\r\n\r\ninterface PrefetchPerfIndicatorAllQuotesProps extends Pick {\r\n paneWithPerfIndicator: ChartConfigChartPane\r\n chartUuid?: string\r\n}\r\n\r\nexport async function prefetchPerfIndicatorAllQuotes({\r\n paneWithPerfIndicator,\r\n timeframe,\r\n options,\r\n chartUuid,\r\n}: PrefetchPerfIndicatorAllQuotesProps) {\r\n const tickersAndTimeframes = getPerfIndicatorTickerAndTimeframes({ paneWithPerfIndicator, timeframe })\r\n\r\n if (tickersAndTimeframes.length > 0) {\r\n const promises = tickersAndTimeframes.map(({ ticker, instrument, timeframe }) =>\r\n Quote.get({\r\n ticker,\r\n instrument,\r\n timeframe,\r\n options,\r\n chartUuid,\r\n })\r\n )\r\n return Promise.all(promises)\r\n }\r\n return Promise.resolve([])\r\n}\r\n\r\ninterface RenderCrossProps {\r\n context: CanvasRenderingContext2D\r\n mouseModel: Mouse\r\n paneModel: Pane\r\n quote: Quote\r\n contentWidth: number\r\n contentHeight: number\r\n onRenderCrossText?: (context: CanvasRenderingContext2D, crossIndex: number) => void\r\n getRoundDecimalPlaces?: (price?: number) => number | undefined\r\n isIndicator?: boolean\r\n isPerfIndicator?: boolean\r\n}\r\n\r\nexport function renderCross({\r\n context,\r\n mouseModel,\r\n paneModel,\r\n quote,\r\n contentWidth,\r\n contentHeight,\r\n onRenderCrossText,\r\n getRoundDecimalPlaces,\r\n isIndicator = false,\r\n isPerfIndicator = false,\r\n}: RenderCrossProps) {\r\n const crossIndex = mouseModel.getCrossIndexForPane(paneModel)\r\n const chartModel = paneModel.chart()\r\n const { ChartSettings, IndicatorSettings } = getChartLayoutSettings(chartModel.chart_layout())\r\n const settings = isIndicator ? IndicatorSettings : ChartSettings\r\n const { Colors } = ChartSettings.general\r\n\r\n if (!mouseModel.getShouldRenderCrossInPane(paneModel)) {\r\n return false\r\n }\r\n\r\n const price = mouseModel.getPriceForPane(paneModel)\r\n const middle = paneModel.scale.x(crossIndex) + chartModel.leftOffset\r\n const isXAxisInView = middle > 0 && middle <= contentWidth\r\n if (isXAxisInView) {\r\n const x = middle + settings.left.width\r\n new Line(\r\n {\r\n x1: x,\r\n x2: x,\r\n y1: settings.top.height,\r\n y2: settings.top.height + contentHeight,\r\n strokeStyle: Colors.cross,\r\n },\r\n paneModel\r\n ).render(context)\r\n\r\n onRenderCrossText?.(context, crossIndex)\r\n }\r\n\r\n const domainRange = paneModel.scale.y\r\n .domain()\r\n .slice()\r\n .sort((a, b) => a - b)\r\n\r\n if (price === null || !(domainRange[0] <= price && price <= domainRange[1])) {\r\n return isXAxisInView\r\n }\r\n\r\n const priceFy = paneModel.scale.y(price)\r\n const y = Math.round(priceFy + settings.top.height)\r\n new Line(\r\n {\r\n x1: settings.left.width,\r\n x2: settings.left.width + contentWidth,\r\n y1: y,\r\n y2: y,\r\n strokeStyle: Colors.cross,\r\n },\r\n paneModel\r\n ).render(context)\r\n const YAxisLeftMargin = quote.instrument === Instrument.Crypto && quote.lastClose <= 0.001 ? 3 : 8\r\n\r\n const getCrossText = () => {\r\n if (chartModel.scale === ScaleType.Percentage && !isIndicator) {\r\n return `${math.round({\r\n value: getPercentageFromValue({ number: price, base: chartModel.firstBarClose }),\r\n lastClose: quote.lastClose,\r\n instrument: quote.instrument,\r\n overridePlaces: 2,\r\n })}%`\r\n }\r\n return `${math.round({\r\n value: price,\r\n lastClose: quote.lastClose,\r\n instrument: quote.instrument,\r\n overridePlaces: getRoundDecimalPlaces?.(price) ?? (paneModel.getIsChartPane() ? undefined : 2),\r\n })}${isPerfIndicator ? '%' : ''}`\r\n }\r\n\r\n new Text(\r\n {\r\n text: getCrossText(),\r\n x:\r\n settings.left.width +\r\n settings.right.axis.margin.left! +\r\n contentWidth +\r\n (isIndicator ? OFFSET.S : YAxisLeftMargin - PADDING.XXS),\r\n padding: isIndicator\r\n ? Text.getMergedPropsWithDefaults('padding', IndicatorSettings.right.axis.font.padding)\r\n : {\r\n top: PADDING.XXS,\r\n right: PADDING.XXS,\r\n bottom: PADDING.XXS,\r\n left: PADDING.XXS,\r\n },\r\n ...{\r\n y,\r\n textBaseline: TextBaseline.middle,\r\n fillStyle: Colors.crossText,\r\n background: Colors.crossTextBackground,\r\n font: Text.getMergedPropsWithDefaults('font', { ...settings.right.axis.font, style: 'bold' }),\r\n lineHeight: settings.right.axis.font.lineHeight,\r\n },\r\n },\r\n paneModel\r\n ).render(context)\r\n\r\n return true\r\n}\r\n\r\n/**\r\n * Set canvas width and height to 0 which fixes Safari memory problems\r\n *\r\n * @see https://stackoverflow.com/questions/52532614/total-canvas-memory-use-exceeds-the-maximum-limit-safari-12\r\n */\r\nexport function unmountCanvas(canvas?: HTMLCanvasElement | null) {\r\n if (!canvas) return\r\n\r\n canvas.width = 0\r\n canvas.height = 0\r\n canvas.style.width = '0px'\r\n canvas.style.height = '0px'\r\n}\r\n\r\nexport function getChangeColor({ change, ChartSettings }: { change: number; ChartSettings: IChartSettings }) {\r\n const { Colors } = ChartSettings.general\r\n if (change === 0) {\r\n return Colors.zeroChange\r\n }\r\n return change > 0 ? Colors.positiveChange : Colors.negativeChange\r\n}\r\n\r\nexport function round({ data, num, overridePlaces }: { data: Quote; num: number; overridePlaces?: number }) {\r\n return math.round({\r\n value: num,\r\n lastClose: data.lastClose,\r\n instrument: data.instrument,\r\n overridePlaces: overridePlaces,\r\n })\r\n}\r\n\r\nexport interface ITickerChange {\r\n points: number\r\n string: string\r\n percentString: string\r\n}\r\ninterface ITickerChangeResult {\r\n tickerChange: ITickerChange | null\r\n tickerAfterChange: ITickerChange | null\r\n}\r\n\r\nexport function getTickerChangeFromCloseValues({\r\n anchorClose,\r\n prevClose,\r\n data,\r\n}: {\r\n anchorClose: number\r\n prevClose: number\r\n data: Quote\r\n}): ITickerChange {\r\n const changePoints = anchorClose - prevClose\r\n const changePercent = (anchorClose / prevClose - 1) * 100\r\n const sign = changePoints < 0 ? '-' : changePoints > 0 ? '+' : ''\r\n const changePercentString = `${round({\r\n data,\r\n num: Math.abs(changePercent),\r\n overridePlaces: 2,\r\n })}%`\r\n const changePointsString = `${sign}${round({\r\n data,\r\n num: Math.abs(changePoints),\r\n })} (${changePercentString})`\r\n\r\n return {\r\n points: changePoints,\r\n string: changePointsString,\r\n percentString: `${sign}${changePercentString}`,\r\n }\r\n}\r\nexport function getTickerChange({ data }: { data: Quote }) {\r\n const result: ITickerChangeResult = { tickerChange: null, tickerAfterChange: null }\r\n const isChange = Number.isFinite(data.prevClose) // if not new stock always present\r\n if (isChange) {\r\n result.tickerChange = getTickerChangeFromCloseValues({\r\n data,\r\n anchorClose: data.lastClose,\r\n prevClose: data.prevClose,\r\n })\r\n }\r\n\r\n const isAfterChange = Number.isFinite(data.afterClose) && data.afterClose !== data.lastClose\r\n if (isAfterChange) {\r\n const tickerAfterChange = getTickerChangeFromCloseValues({\r\n data,\r\n anchorClose: data.afterClose,\r\n prevClose: data.lastClose,\r\n })\r\n result.tickerAfterChange = {\r\n ...tickerAfterChange,\r\n string: `AH: ${tickerAfterChange.string}`,\r\n }\r\n }\r\n\r\n return result\r\n}\r\n\r\nexport function isForexFuturesCryptoPage(specificChartFunctionality: SpecificChartFunctionality) {\r\n return [\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n SpecificChartFunctionality.futuresPage,\r\n ].includes(specificChartFunctionality)\r\n}\r\n\r\nexport function isQuoteForexFuturesCryptoPage(specificChartFunctionality: SpecificChartFunctionality) {\r\n return (\r\n isForexFuturesCryptoPage(specificChartFunctionality) ||\r\n specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n )\r\n}\r\n\r\nexport function getShouldUseDarkerWickColors({\r\n specificChartFunctionality,\r\n totalBarWidth,\r\n}: {\r\n specificChartFunctionality: SpecificChartFunctionality\r\n timeFrame?: TIMEFRAME\r\n totalBarWidth: number\r\n}) {\r\n const isForexFuturesCrypto = isForexFuturesCryptoPage(specificChartFunctionality)\r\n const isOffscreenChartWithNarrowBars =\r\n specificChartFunctionality === SpecificChartFunctionality.offScreen && totalBarWidth < 5\r\n const isQuoteOrQuoteFinancials = [\r\n SpecificChartFunctionality.quotePage,\r\n SpecificChartFunctionality.quoteFinancials,\r\n ].includes(specificChartFunctionality)\r\n const isQuoteChartWithNarrowBars = isQuoteOrQuoteFinancials && totalBarWidth < 5\r\n\r\n return isForexFuturesCrypto || isOffscreenChartWithNarrowBars || isQuoteChartWithNarrowBars\r\n}\r\n\r\nexport const DRAWING_COOKIE_NAME = 'charts-draw'\r\nexport function getIsDrawingEnabled() {\r\n return Utils.getCookie(DRAWING_COOKIE_NAME) === 'on'\r\n}\r\n\r\nexport function setIsDrawingEnabled(value: boolean) {\r\n const expires = new Date()\r\n expires.setMonth(expires.getMonth() + 1)\r\n Utils.setCookie(DRAWING_COOKIE_NAME, value ? 'on' : 'off', expires)\r\n}\r\n\r\nexport function getIsSidebarEnabled(specificChartFunctionality?: SpecificChartFunctionality) {\r\n return specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n}\r\n\r\nexport const handleTypeChange = ({\r\n type,\r\n chartLayoutModel,\r\n}: {\r\n type: ChartElementType\r\n chartLayoutModel: ChartLayoutModel\r\n}) => {\r\n const elements = chartLayoutModel.getAllElements()\r\n elements.forEach((element) => {\r\n if (element.isChart() && element.instance.attrs.type !== type) {\r\n const pane = element.pane()\r\n const instance = chartsByType[type].fromObject(\r\n {\r\n ...element.instance.attrs,\r\n type,\r\n },\r\n pane\r\n )\r\n element.replace(instance)\r\n }\r\n })\r\n}\r\n\r\nexport const getIsPreserveDrawingsAndAutosaveAvailable = (args: {\r\n specificChartFunctionality: SpecificChartFunctionality\r\n editable: boolean\r\n editors: ChartEditorEnum[]\r\n}) => {\r\n const { specificChartFunctionality, editable, editors } = args\r\n\r\n return (\r\n editable &&\r\n editors?.includes(ChartEditorEnum.tools) &&\r\n specificChartFunctionality &&\r\n [\r\n SpecificChartFunctionality.chartPage,\r\n SpecificChartFunctionality.quotePage,\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n ].includes(specificChartFunctionality)\r\n )\r\n}\r\n\r\nexport function getQuoteFinancialAttachmentsFromChartConfig({ panes }: Pick) {\r\n return panes\r\n .flatMap((pane) =>\r\n pane.elements?.flatMap(\r\n (element) => indicatorsByType[element.type as IndicatorType]?.config.quoteFinancialAttachments ?? []\r\n )\r\n )\r\n .filter((quoteFinancialAttachment, index, arr) => arr.indexOf(quoteFinancialAttachment) === index)\r\n}\r\n","/**\r\n * Keep this file in sync with `Website/js/main/components/color-picker/util.ts` in website repo\r\n * */\r\n\r\nexport interface RGBA {\r\n r: number\r\n g: number\r\n b: number\r\n a: number\r\n}\r\n\r\nexport interface HSVA {\r\n h: number\r\n s: number\r\n v: number\r\n a: number\r\n}\r\n\r\nexport interface HSLA {\r\n h: number\r\n s: number\r\n l: number\r\n a: number\r\n}\r\n\r\n/**\r\n * Convert Hex string to RGBA object.\r\n * @see https://css-tricks.com/converting-color-spaces-in-javascript/\r\n *\r\n * Input: color in hex3, hex4, hex6 or hex8 format (#fff)\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hexStringToRGBA(hexString: string): RGBA {\r\n const hexColor = removeHashSymbol(hexString)\r\n let r: string | number = 0\r\n let g: string | number = 0\r\n let b: string | number = 0\r\n let a: string | number = 255\r\n\r\n // 3 digits\r\n if (hexColor.length === 3 || hexColor.length === 4) {\r\n r = '0x' + hexColor[0] + hexColor[0]\r\n g = '0x' + hexColor[1] + hexColor[1]\r\n b = '0x' + hexColor[2] + hexColor[2]\r\n // Get channel if defined\r\n a = hexColor.length === 4 ? '0x' + hexColor[3] + hexColor[3] : a\r\n\r\n // 6 digits\r\n } else if (hexColor.length === 6 || hexColor.length === 8) {\r\n r = '0x' + hexColor[0] + hexColor[1]\r\n g = '0x' + hexColor[2] + hexColor[3]\r\n b = '0x' + hexColor[4] + hexColor[5]\r\n // Get channel if defined\r\n a = hexColor.length === 8 ? '0x' + hexColor[6] + hexColor[7] : a\r\n }\r\n\r\n return { r: Number(r), g: Number(g), b: Number(b), a: Math.min(Math.round((Number(a) / 255) * 100) / 100, 1) }\r\n}\r\n\r\n/**\r\n * Convert HEX string to HSVA color representation.\r\n *\r\n * Input: color in hex3, hex4, hex6 or hex8 format (#fff)\r\n *\r\n * Output: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n */\r\nexport function hexStringToHSVA(hexString: string) {\r\n return rgbaToHSVA(hexStringToRGBA(hexString))\r\n}\r\n\r\n/**\r\n * Convert HEX string to HSLA color representation.\r\n *\r\n * Input: color in hex3, hex4, hex6 or hex8 format (#fff)\r\n *\r\n * Output: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n */\r\nexport function hexStringToHSLA(hexString: string) {\r\n return rgbaToHSLA(hexStringToRGBA(hexString))\r\n}\r\n\r\n/**\r\n * Convert alpha value to hex value\r\n *\r\n * Input: [0,1]\r\n *\r\n * Output: alpha in HEX format\r\n */\r\nexport function alphaToHex(alpha: number) {\r\n return Math.max(Math.min(Math.round(alpha * 255), 255), 0)\r\n .toString(16)\r\n .padStart(2, '0')\r\n}\r\n\r\n/**\r\n * Convert RGBA color to HEX string.\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: color in hex6 or hex8 depending on whether or not alpha is enabled\r\n */\r\nexport function rgbaToHexString(color: RGBA, alpha = false) {\r\n const r = color.r.toString(16)\r\n const g = color.g.toString(16)\r\n const b = color.b.toString(16)\r\n const hexString = '#' + r.padStart(2, '0') + g.padStart(2, '0') + b.padStart(2, '0')\r\n\r\n if (!alpha || color.a === 1) {\r\n return hexString\r\n }\r\n\r\n return `${hexString}${alphaToHex(color.a)}`\r\n}\r\n\r\n/**\r\n * Convert HSVA object to HEX string\r\n *\r\n * @see https://css-tricks.com/converting-color-spaces-in-javascript/\r\n *\r\n * Input: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hsvaToHEXString(color: HSVA, alpha = false) {\r\n const rgbaColor = hsvaToRGBA(color)\r\n\r\n return rgbaToHexString(rgbaColor, alpha)\r\n}\r\n\r\n/**\r\n * Convert HSLA object to HEX string\r\n *\r\n * @see https://css-tricks.com/converting-color-spaces-in-javascript/\r\n *\r\n * Input: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hslaToHexString(color: HSLA, alpha = false) {\r\n const rgbaColor = hslaToRGBA(color)\r\n\r\n return rgbaToHexString(rgbaColor, alpha)\r\n}\r\n\r\n/**\r\n * Convert RGBA color to HSVA\r\n * @see https://stackoverflow.com/a/54070620/6662683\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n */\r\nexport function rgbaToHSVA(color: RGBA): HSVA {\r\n const r = color.r / 255\r\n const g = color.g / 255\r\n const b = color.b / 255\r\n\r\n const v = Math.max(r, g, b)\r\n const c = v - Math.min(r, g, b)\r\n const h = c && (v === r ? (g - b) / c : v === g ? 2 + (b - r) / c : 4 + (r - g) / c)\r\n\r\n return {\r\n h: 60 * (h < 0 ? h + 6 : h),\r\n s: v ? c / v : 0,\r\n v: v,\r\n a: color.a,\r\n }\r\n}\r\n\r\n/**\r\n * Convert RGBA to HSLA\r\n * @see https://stackoverflow.com/a/54071699/6662683\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n */\r\nexport function rgbaToHSLA(color: RGBA): HSLA {\r\n const r = color.r / 255\r\n const g = color.g / 255\r\n const b = color.b / 255\r\n\r\n const v = Math.max(r, g, b)\r\n const c = v - Math.min(r, g, b)\r\n const f = 1 - Math.abs(v + v - c - 1)\r\n const h = c && (v === r ? (g - b) / c : v === g ? 2 + (b - r) / c : 4 + (r - g) / c)\r\n\r\n return {\r\n h: 60 * (h < 0 ? h + 6 : h),\r\n s: f ? c / f : 0,\r\n l: (v + v - c) / 2,\r\n a: color.a,\r\n }\r\n}\r\n\r\n/**\r\n * Convert HSVA color to RGBA\r\n * @see https://stackoverflow.com/a/54024653/6662683\r\n *\r\n * Input: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hsvaToRGBA(color: HSVA): RGBA {\r\n const f = (n: number, k = (n + color.h / 60) % 6) => color.v - color.v * color.s * Math.max(Math.min(k, 4 - k, 1), 0)\r\n\r\n return {\r\n r: Math.round(f(5) * 255),\r\n g: Math.round(f(3) * 255),\r\n b: Math.round(f(1) * 255),\r\n a: Math.round(color.a * 100) / 100,\r\n }\r\n}\r\n\r\n/**\r\n * Convert HSLA color to RGBA\r\n * @see https://stackoverflow.com/a/54014428/6662683\r\n *\r\n * Input: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hslaToRGBA(color: HSLA): RGBA {\r\n const a = color.s * Math.min(color.l, 1 - color.l)\r\n const f = (n: number, k = (n + color.h / 30) % 12) => color.l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)\r\n\r\n return {\r\n r: Math.round(f(0) * 255),\r\n g: Math.round(f(8) * 255),\r\n b: Math.round(f(4) * 255),\r\n a: color.a,\r\n }\r\n}\r\n\r\n/**\r\n * Convert RGBA color to rgba() string\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: rgba(r, g, b, a)\r\n */\r\nexport function rgbaToRGBAString(color: RGBA) {\r\n return `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`\r\n}\r\n\r\n/**\r\n * Convert rgba() string to RGBA color\r\n *\r\n * Input: rgba(r, g, b, a)\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function rgbaStringToObject(color: string) {\r\n const colorParts = /^rgba?\\(([0-9]{1,3})[ ,]+([0-9]{1,3})[ ,]+([0-9]{1,3})[ ,]*([01].?[0-9]*)?\\)$/.exec(color)\r\n const [red, green, blue, alpha = '1'] = colorParts?.slice(1) || [0, 0, 0, 1].map(String)\r\n return {\r\n r: Number.parseInt(red),\r\n g: Number.parseInt(green),\r\n b: Number.parseInt(blue),\r\n a: Number.parseFloat(alpha),\r\n }\r\n}\r\n\r\n/**\r\n * Convert HSLA color to hsla() string\r\n *\r\n * Input: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n *\r\n * Output: hsla(h, s, l, a)\r\n */\r\nexport function hslaToHSLAString(color: HSLA) {\r\n return `hsla(${Math.round(color.h)}, ${Math.round(color.s * 10000) / 100}%, ${Math.round(color.l * 10000) / 100}%, ${\r\n color.a\r\n })`\r\n}\r\n\r\nexport function removeHashSymbol(strColor: string) {\r\n return strColor.replace(/#/g, '')\r\n}\r\n\r\n/**\r\n * Check if the param is a valid color by setting it as style\r\n */\r\nexport function isValidColor(strColor: string) {\r\n const isRgb = strColor.startsWith('rgba')\r\n const s = new Option().style\r\n\r\n s.color = isRgb ? strColor : `#${removeHashSymbol(strColor)}`\r\n\r\n return s.color !== ''\r\n}\r\n\r\n/**\r\n * Normalize color to be a hex value\r\n */\r\nexport function convertColorToHEX(strColor: string, allowAlpha = true) {\r\n const isRgb = getIsRgb(strColor)\r\n const hexColor = isRgb ? rgbaToHexString(rgbaStringToObject(strColor), allowAlpha) : strColor\r\n\r\n if (allowAlpha) {\r\n return hexColor\r\n }\r\n return hexColor.slice(0, 7)\r\n}\r\n\r\n/**\r\n * Returns true if color is rgb or rgba\r\n */\r\nexport function getIsRgb(strColor: string, isAlphaAllowed = true) {\r\n const rgbKeys = ['rgb']\r\n if (isAlphaAllowed) {\r\n rgbKeys.push('rgba')\r\n }\r\n return rgbKeys.some((startsWith) => strColor.startsWith(startsWith))\r\n}\r\n\r\n/**\r\n * Convert any color format to HSVA (internal color picker representation)\r\n */\r\nexport function getHSVAFromColor(strColor: string) {\r\n if (getIsRgb(strColor)) {\r\n return rgbaToHSVA(rgbaStringToObject(strColor))\r\n }\r\n\r\n return hexStringToHSVA(strColor)\r\n}\r\n\r\n/**\r\n * Stringify HSVA color representation into a output format\r\n */\r\nexport function stringifyHSVAColor(color: HSVA, output: 'rgba' | 'hex', canSelectAlpha?: boolean) {\r\n switch (output) {\r\n case 'rgba':\r\n return rgbaToRGBAString(hsvaToRGBA(color))\r\n default:\r\n return hsvaToHEXString(color, canSelectAlpha)\r\n }\r\n}\r\n\r\n/**\r\n * Get luma value from RGBA color using the Rec. 709 coefficients\r\n * @see https://en.wikipedia.org/wiki/Luma_%28video%29\r\n *\r\n * If luma is >= 165 the foreground color should be dark\r\n */\r\nexport function getLumaFromRGBA(color: RGBA) {\r\n return 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b\r\n}\r\n\r\n/**\r\n * Checks if luma is >= 165 or alpha < 0.3\r\n */\r\nexport function getIsColorTooLightOrTransparent(color: RGBA) {\r\n return getLumaFromRGBA(color) >= 165 || color.a < 0.5\r\n}\r\n\r\n/**\r\n * Set specific alpha for a hex color\r\n */\r\nexport function getHEXWithSpecificAplha(color: string, alpha = 1) {\r\n const rgbaColor = hexStringToRGBA(color)\r\n return rgbaToHexString({ ...rgbaColor, a: alpha }, true)\r\n}\r\n\r\n/**\r\n * Get rgba from valid color string\r\n */\r\nexport function getRGBAValueFromValidColorString(value: string) {\r\n if (getIsRgb(value)) return rgbaToRGBAString(rgbaStringToObject(value))\r\n return rgbaToRGBAString(hexStringToRGBA(value))\r\n}\r\n","// if conditionalCursor provided, cursor is set only if current cursor !== conditionalCursor\r\n// otherwise cursor is set if element exists\r\nexport const setElementCursor = ({\r\n elementId,\r\n cursor,\r\n conditionalCursor,\r\n}: {\r\n elementId: string\r\n cursor: string\r\n conditionalCursor?: string\r\n}) => {\r\n const element = document.getElementById(elementId)\r\n if (element && (conditionalCursor ? element.style.cursor !== conditionalCursor : true)) {\r\n element.style.cursor = cursor\r\n }\r\n}\r\n","/*\r\n * We want to be able to render only bars/parts of line that are visible to users,\r\n * but without introducing visual artifacts like bars missing in front of users while scrolling\r\n * or lines that start in middle of chart for sparse intraday stock data.\r\n *\r\n * In general we want to start rendering lines one bar sooner than what is visible to user and stop rendering\r\n * one bar outside of visible area to create a continuous line.\r\n */\r\nimport type Pane from '../models/pane'\r\nimport type Quote from '../models/quote'\r\nimport { getHalfBarWidth } from './chart'\r\n\r\ninterface IBarToRender {\r\n index: number\r\n isBarVisible: boolean\r\n}\r\n\r\nexport const drawInVisibleArea = ({\r\n drawBarCallback,\r\n fromIndexOffset = 0,\r\n fxOverride,\r\n leftOffset,\r\n paneModel,\r\n quote,\r\n toIndexOffset = 0,\r\n width,\r\n}: {\r\n drawBarCallback: (i: number, x: number) => void\r\n fromIndexOffset?: number\r\n fxOverride?: (index: number) => number\r\n leftOffset: number\r\n paneModel: Pane\r\n quote: Quote\r\n toIndexOffset?: number\r\n width: number\r\n}) => {\r\n const fx = fxOverride ?? ((index: number) => paneModel.scale.x(quote.barIndex[index]))\r\n\r\n // We want to start rendering one bar outside of the visible area for two reasons:\r\n // 1. To create a seamless transition for bars entering/leaving the view, avoiding them from\r\n // abruptly dis/appearing when half the bar is outside.\r\n // 2. To prevent disconnected lines in case there's a bar gap.\r\n // However, if a `fromIndex` is provided and it's higher than the first visible bar,\r\n // we need to start rendering from that specific index. This ensures correct starting\r\n // points for elements like indicators that rely on this value.\r\n const firstBarToRenderIndex = getCompensatedFirstBarToRenderIndex({ quote, paneModel, leftOffset, fromIndexOffset })\r\n\r\n let lastBarToRender = -1\r\n for (let i = firstBarToRenderIndex; i < quote.close.length + toIndexOffset; i++) {\r\n const x = fx(i)\r\n if (x + leftOffset > width) {\r\n lastBarToRender = i\r\n break\r\n }\r\n drawBarCallback(i, x)\r\n }\r\n\r\n if (lastBarToRender > -1) {\r\n const x = fx(lastBarToRender)\r\n drawBarCallback(lastBarToRender, x)\r\n }\r\n}\r\n\r\n/**\r\n * Get first or last visible bar index.\r\n * IMPORTANT: If chartWidth provided return is lastVisibleBarIndex\r\n */\r\nexport function getVisibleBarToRenderIndex({\r\n chartWidth,\r\n leftOffset,\r\n paneModel,\r\n quote,\r\n}: {\r\n chartWidth?: number\r\n leftOffset: number\r\n paneModel: Pane\r\n quote: Quote\r\n}) {\r\n const chartModel = paneModel.chart()\r\n\r\n // not all the time there is bar present on barIndex calculated via inverted leftOffset\r\n // there might be a gap between bars, if there is, barToDataIndex on that gap spot will have value of\r\n // previous bar which isn't visible\r\n\r\n const barIndex = Math.round(paneModel.scale.x.invert(-leftOffset + (chartWidth !== undefined ? chartWidth : 0)))\r\n const dataBarIndex = quote.barToDataIndex[Math.min(Math.max(barIndex, 0), quote.barToDataIndex.length - 1)]\r\n const halfBarWidth = getHalfBarWidth(chartModel, false)\r\n\r\n const isBarVisible = Math.round(paneModel.scale.x(quote.barIndex[dataBarIndex]) + halfBarWidth) + leftOffset > 0\r\n\r\n return {\r\n barIndex,\r\n index:\r\n chartWidth === undefined\r\n ? isBarVisible\r\n ? dataBarIndex\r\n : Math.max(Math.min(dataBarIndex + 1, quote.barIndex.length - 1), 0)\r\n : dataBarIndex,\r\n isBarVisible,\r\n }\r\n}\r\n\r\n// Get first bar to render compensated for fromIndexOffset\r\nexport function getCompensatedFirstBarToRenderIndex({\r\n fromIndexOffset = 0,\r\n leftOffset,\r\n paneModel,\r\n quote,\r\n}: {\r\n fromIndexOffset?: number\r\n leftOffset: number\r\n paneModel: Pane\r\n quote: Quote\r\n}) {\r\n return Math.max(0, getVisibleBarToRenderIndex({ quote, leftOffset, paneModel }).index - 1, fromIndexOffset)\r\n}\r\n\r\n/**\r\n * Checks if there are no visible bars between the specified first and last bars to render.\r\n * IMPORTANT: Provided indexes should be without bar gap compensation.\r\n *\r\n * @param {IBarToRender} firstBarToRenderIndex The index of the first bar to render.\r\n * @param {IBarToRender} lastBarToRenderIndex The index of the last bar to render.\r\n * @returns {boolean} True if there are no visible bars between the first and last bars, false otherwise.\r\n */\r\nexport function getAreNoBarsVisible(firstBarToRenderIndex: IBarToRender, lastBarToRenderIndex: IBarToRender): boolean {\r\n return !firstBarToRenderIndex.isBarVisible && !lastBarToRenderIndex.isBarVisible\r\n}\r\n","import queryString from 'query-string'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\n\r\ninterface FetchApiProps {\r\n location: string\r\n queryParameters?: ObjectHash\r\n method?: string\r\n body?: RequestInit['body']\r\n contentType?: ContentType\r\n abortController?: null | AbortController\r\n throwOnStatusCodes?: number[]\r\n throwOnPredicate?: (response: Response) => boolean\r\n keepalive?: boolean\r\n}\r\n\r\nexport const getFormDataFromObject = (object: ObjectHash) =>\r\n Object.keys(object).reduce((formData, key) => {\r\n formData.append(key, object[key])\r\n return formData\r\n }, new FormData())\r\n\r\n// Keep in sync with ContentType in https://github.com/finvizhq/Finviz-Website/blob/master/Website/js/main/services/api.ts\r\n// START\r\nexport enum ContentType {\r\n ApplicationJson = 'application/json',\r\n ApplicationJsonUTF = 'application/json; charset=utf-8', // WriteAsJsonAsync\r\n FormUrlEncoded = 'application/x-www-form-urlencoded',\r\n Html = 'text/html; charset=utf-8',\r\n}\r\n\r\nfunction parseResponseForContentType(response: string, contentType: ContentType) {\r\n switch (contentType) {\r\n case ContentType.ApplicationJson:\r\n case ContentType.ApplicationJsonUTF:\r\n case ContentType.FormUrlEncoded:\r\n return JSON.parse(response)\r\n default:\r\n return response\r\n }\r\n}\r\n// END\r\n\r\nconst fetchApi = async ({\r\n location,\r\n queryParameters,\r\n method,\r\n body,\r\n contentType,\r\n abortController,\r\n throwOnStatusCodes,\r\n throwOnPredicate,\r\n keepalive = false,\r\n}: FetchApiProps) => {\r\n const url = `${location}${queryParameters ? `?${queryString.stringify(queryParameters)}` : ''}`\r\n const parameters: RequestInit = {\r\n method: method || 'GET',\r\n credentials: 'include',\r\n headers: contentType && {\r\n 'Content-Type': contentType,\r\n },\r\n signal: abortController?.signal,\r\n body: body,\r\n keepalive,\r\n }\r\n try {\r\n const response = await fetch(url, parameters)\r\n const responseContentType: ContentType = (response.headers.get('Content-Type') as any) ?? ContentType.Html\r\n const responseData = parseResponseForContentType(await response.text(), responseContentType)\r\n if (throwOnStatusCodes?.includes(response.status) || throwOnPredicate?.(response)) {\r\n const StatusCodeError = getStatusCodeError(response.status)\r\n throw new StatusCodeError(`${url} returned ${response.status}`, responseData as T, response.status)\r\n }\r\n return responseData as T\r\n } catch (err) {\r\n throw err\r\n }\r\n}\r\n\r\nfunction getStatusCodeError(statusCode: number): typeof GenericStatusCodeError {\r\n switch (statusCode) {\r\n case 403:\r\n return ForbiddenError\r\n case 404:\r\n return NotFoundError\r\n case 410:\r\n return GoneError\r\n case 500:\r\n return InternalServerError\r\n default:\r\n return GenericStatusCodeError\r\n }\r\n}\r\n\r\nexport class GenericStatusCodeError extends Error {\r\n response: ObjectHash | string\r\n statusCode: number\r\n\r\n constructor(message: string, response: ObjectHash | string, statusCode: number) {\r\n super(message)\r\n this.response = response\r\n this.statusCode = statusCode\r\n }\r\n}\r\nexport class ForbiddenError extends GenericStatusCodeError {}\r\nexport class NotFoundError extends GenericStatusCodeError {}\r\nexport class InternalServerError extends GenericStatusCodeError {}\r\nexport class GoneError extends GenericStatusCodeError {}\r\n\r\nexport default fetchApi\r\n","import React from 'react'\r\n\r\nexport function useForceUpdate() {\r\n const [forceUpdateKey, increment] = React.useState(0)\r\n const forceUpdate = React.useCallback(() => {\r\n increment((prev) => prev + 1)\r\n }, [])\r\n return { forceUpdate, forceUpdateKey }\r\n}\r\n","import { EmptyObject, ObjectHash } from '../../types/shared'\r\n\r\nexport function getRoundedString({ number, numOfDecimalPlaces }: { number: number; numOfDecimalPlaces: number }) {\r\n const precision = Math.pow(10, numOfDecimalPlaces)\r\n return String(Math.round(number * precision) / precision)\r\n}\r\n\r\nexport function getIsSSr() {\r\n return typeof process !== 'undefined' && !!process?.env.IS_OFFSCREEN_RENDERER\r\n}\r\n\r\nexport function isValidHexColor(color: string) {\r\n const regex = /^#([\\da-f]{3}){1,2}$|^#([\\da-f]{4}){1,2}$/i\r\n return !!color && regex.test(color)\r\n}\r\n\r\nexport function getParsedIntegersFromPeriodString(periodString: string) {\r\n const periodParts = periodString.split(',')\r\n return periodParts.map((part) => Number.parseInt(part, 10))\r\n}\r\n\r\nexport function captureException(exception: Error, captureContext?: { extra: ObjectHash }) {\r\n if (process.env.NODE_ENV === 'development' || process.env.IS_E2E_TESTING) {\r\n console.error(exception)\r\n } else if (process.env.IS_OFFSCREEN_RENDERER) {\r\n import('@sentry/node').then((client) => {\r\n client.captureException(exception, captureContext)\r\n })\r\n } else {\r\n window.Sentry.captureException(exception, captureContext)\r\n }\r\n}\r\n\r\nexport function isPositiveFloat(value: string | number) {\r\n const parsedNumber = Number.parseFloat(`${value}`)\r\n return !Number.isNaN(parsedNumber) && isFinite(parsedNumber) && parsedNumber > 0\r\n}\r\n\r\nexport function isPositiveInteger(value: string | number) {\r\n const string = `${value}`\r\n return isPositiveFloat(value) && Number.parseInt(string, 10) === Number.parseFloat(string)\r\n}\r\n\r\nexport function isInRange({\r\n value,\r\n min = Number.MIN_SAFE_INTEGER,\r\n max = Number.MAX_SAFE_INTEGER,\r\n}: {\r\n value: string | number\r\n min?: number\r\n max?: number\r\n}) {\r\n const parsedNumber = Number.parseFloat(`${value}`)\r\n return !Number.isNaN(parsedNumber) && parsedNumber >= min && parsedNumber <= max\r\n}\r\n\r\nexport function tryJsonParse(json: string | null = '') {\r\n try {\r\n return JSON.parse(json ?? '') as Result\r\n } catch {\r\n return null\r\n }\r\n}\r\n\r\nexport function getValueInRange({ value, min, max }: { value: number; min: number; max: number }) {\r\n return Math.min(Math.max(value, min), max)\r\n}\r\n\r\nexport function isPrimaryClick(e: React.Touch | React.TouchEvent | React.MouseEvent) {\r\n // cypress trigger mouseevent has button: undefined if button option isn't explicitly specified\r\n // as cy.get('.target').trigger('mousedown', { button: 0 })\r\n if (e.hasOwnProperty('button') && (e as unknown as MouseEvent).button !== undefined) {\r\n return (e as unknown as MouseEvent).button === 0\r\n } else {\r\n return true\r\n }\r\n}\r\n\r\n// this function is used to fix the issue with circular reference when stringifying an object using JSON.stringify\r\nexport function getJSONReplacerFunc() {\r\n const visited = new WeakSet()\r\n return (key: string, value: any) => {\r\n if (typeof value === 'object' && value !== null) {\r\n if (visited.has(value)) {\r\n return\r\n }\r\n visited.add(value)\r\n }\r\n return value\r\n }\r\n}\r\n\r\n// This is a duplicate from Website repo which is accessible on window.FLibs but this doesn't work on SSR charts\r\nexport const formatDateToStringUS = (date: Date, options?: Intl.DateTimeFormatOptions | undefined) =>\r\n date.toLocaleDateString('en-US', {\r\n day: '2-digit',\r\n month: '2-digit',\r\n year: 'numeric',\r\n ...options,\r\n })\r\n\r\n// randomUUID source: https://stackoverflow.com/questions/105034/how-do-i-create-a-guid-uuid/2117523#2117523\r\nexport function randomUUID() {\r\n return `${1e7}-${1e3}-${4e3}-${8e3}-${1e11}`.replace(/[018]/g, (substring) => {\r\n const c = Number(substring)\r\n return (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)\r\n })\r\n}\r\n\r\nexport function getUuid() {\r\n return window.crypto?.randomUUID?.() ?? randomUUID()\r\n}\r\n\r\n// duplicate from Website/js/app/header/utils.ts , will be refactored in next PR\r\nexport function getEarningsDateSuffix(date: Date) {\r\n const hours = date.getHours()\r\n\r\n if (hours <= 9) {\r\n return 'BMO'\r\n } else if (hours >= 16) {\r\n return 'AMC'\r\n }\r\n\r\n return ''\r\n}\r\n","export type HLC = {\r\n ts: number\r\n count: number\r\n uuid: string\r\n}\r\n\r\nexport const serializeHlc = ({ ts, count, uuid }: HLC) =>\r\n ts.toString().padStart(15, '0') + ':' + count.toString(36).padStart(5, '0') + ':' + uuid\r\n\r\nexport const parseHlc = (serialized: string) => {\r\n const [ts, count, uuid] = serialized.split(':')\r\n return {\r\n ts: Number.parseInt(ts),\r\n count: Number.parseInt(count, 36),\r\n uuid,\r\n }\r\n}\r\n\r\nexport const initHlc = (uuid: string, now: number): HLC => ({\r\n ts: now,\r\n count: 0,\r\n uuid,\r\n})\r\n\r\nexport const compareHlc = (one: HLC, two: HLC) => {\r\n if (one.ts === two.ts) {\r\n if (one.count === two.count) {\r\n if (one.uuid === two.uuid) {\r\n return 0\r\n }\r\n return one.uuid < two.uuid ? -1 : 1\r\n }\r\n return one.count - two.count\r\n }\r\n return one.ts - two.ts\r\n}\r\n\r\nexport const incrementHlc = (local: HLC, now: number): HLC => {\r\n if (now > local.ts) {\r\n return { ts: now, count: 0, uuid: local.uuid }\r\n }\r\n\r\n return { ...local, count: local.count + 1 }\r\n}\r\n\r\nexport const receiveHlc = (local: HLC, remote: HLC): HLC => {\r\n if (compareHlc(local, remote) >= 0) {\r\n return local\r\n }\r\n return { ...local, ts: remote.ts, count: remote.count }\r\n}\r\n","import { useChartLayoutGlobalModelAsyncModule } from '../controllers/chart-settings/async-modules'\r\nimport { useAsyncModule } from './async-modules-utils'\r\n\r\nexport function useChartLayoutGlobalModelAsync() {\r\n const [useChartLayoutGlobalModelModule] = useAsyncModule({\r\n ...useChartLayoutGlobalModelAsyncModule,\r\n isSuspenseMode: true,\r\n })\r\n return useChartLayoutGlobalModelModule.useChartLayoutGlobalModel()\r\n}\r\n","import { CanvasRenderingContext2D as NodeCanvasRenderingContext2D } from 'skia-canvas'\r\n\r\nimport {\r\n CanvasElementType,\r\n ChartEditorEnum,\r\n ChartElementType,\r\n ChartEventType,\r\n IndicatorType,\r\n LayoutType,\r\n OverlayType,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n TextAlign,\r\n TextBaseline,\r\n} from '../app/constants/common'\r\nimport ChartModel from '../app/models/chart'\r\nimport ChartLayout from '../app/models/chart_layout'\r\nimport { IChartThemeColors } from '../app/models/constants'\r\n\r\ninterface ISentry {\r\n captureException: (exception: any, captureContext?: { extra: ObjectHash }) => any\r\n captureMessage: (message: string, captureContext?: { extra: ObjectHash }) => any\r\n}\r\n\r\ndeclare global {\r\n interface Window {\r\n Sentry: ISentry\r\n FinvizSettings: ObjectHash\r\n FinvizChartsSettings: ObjectHash\r\n globalChartConfig: RootChartConfigObject\r\n isRenderInProgress: boolean | number\r\n rendersInProgress: number[]\r\n FinvizQuoteTypeCurrent: string\r\n handleScriptNotLoaded: () => void\r\n renderScriptNotLoaded: () => void\r\n gtag?: any\r\n }\r\n\r\n interface Document {\r\n fullscreenElement: any\r\n webkitFullscreenElement?: () => void\r\n mozFullScreenElement?: () => void\r\n msFullscreenElement?: () => void\r\n\r\n webkitExitFullscreen?: () => void\r\n mozExitFullScreen?: () => void\r\n msExitFullscreen?: () => void\r\n }\r\n\r\n interface HTMLElement {\r\n webkitRequestFullScreen?: () => void\r\n mozRequestFullScreen?: () => void\r\n msRequestFullscreen?: () => void\r\n }\r\n\r\n interface Navigator {\r\n msMaxTouchPoints: any\r\n }\r\n\r\n interface Array {\r\n last(): T | undefined\r\n }\r\n\r\n interface String {\r\n padLeft(paddingValue: string): string\r\n startsWith(str: string): boolean\r\n }\r\n\r\n type CanvasCache = Partial>\r\n\r\n interface CanvasRenderingContext2D {\r\n _cache: CanvasCache\r\n // We need to omit `canvas` because it is read only\r\n set>(\r\n key: Key,\r\n value: CanvasRenderingContext2D[Key]\r\n ): void\r\n }\r\n\r\n interface HTMLCanvasElement {\r\n _cache: CanvasCache\r\n }\r\n\r\n interface ImageBitmapRenderingContext {\r\n _cache: CanvasCache\r\n }\r\n\r\n type RenderingContext2DType = CanvasRenderingContext2D | NodeCanvasRenderingContext2D\r\n}\r\n\r\ndeclare module 'skia-canvas' {\r\n interface CanvasRenderingContext2D {\r\n _cache: CanvasCache\r\n\r\n set>(\r\n key: Key,\r\n value: CanvasRenderingContext2D[Key]\r\n ): void\r\n }\r\n}\r\n\r\nexport type TodoObjectHashAnyType = Record\r\nexport type TodoAreaObject = Record\r\nexport type ObjectHash = Record\r\nexport type EmptyObject = Record\r\n\r\nexport type TodoAnyType = any\r\n\r\nexport type ThumbType = string\r\n\r\nexport type PaneArea = {\r\n mouseDown?: boolean\r\n x: number\r\n y: number\r\n scaled: {\r\n x: number\r\n y: number\r\n }\r\n width: number\r\n height: number\r\n cursorX: number\r\n cursorY: number\r\n isCursorInChartWidthBoundaries: boolean\r\n} & T\r\n\r\nexport type Maybe = T | null | undefined\r\n\r\nexport interface DrawingBorder {\r\n color: string\r\n width: number\r\n}\r\n\r\nexport interface TextAttrs {\r\n text?: string\r\n background: string\r\n border?: { width: number; color: string }\r\n lineWidth?: number\r\n font: {\r\n size: number\r\n family?: string\r\n style?: string\r\n weight?: string\r\n }\r\n fillStyle?: string\r\n strokeStyle?: string\r\n angle?: number\r\n lineHeight: number\r\n textAlign?: TextAlign\r\n textBaseline: TextBaseline\r\n padding: {\r\n top: number\r\n right: number\r\n bottom: number\r\n left: number\r\n }\r\n}\r\n\r\nexport interface Point {\r\n x: number\r\n y: number\r\n}\r\n\r\nexport type RequireByKey = Omit & Required>\r\n\r\nexport interface ResizeByThumbFuncProps {\r\n type: ThumbType\r\n difX: number\r\n difY: number\r\n area: PaneArea\r\n}\r\n\r\nexport type ResizeByThumbWithTypeAndDifs = RequireByKey\r\n\r\nexport interface ChartConfigChartPaneElement {\r\n type: ChartElementType | CanvasElementType | IndicatorType | OverlayType | ChartEventType\r\n overlays?: OverlayConfigObject[]\r\n period?: string\r\n code?: string\r\n elementId?: string | null\r\n zIndex?: number\r\n}\r\n\r\nexport interface RendererChartBarProps {\r\n index: number\r\n chartSettingsColors: IChartThemeColors\r\n hasFillAndBorder?: boolean\r\n}\r\n\r\nexport interface ChartConfigChartPane {\r\n elements: ChartConfigChartPaneElement[]\r\n height: number\r\n chart?: ChartConfigObject | ChartModel\r\n}\r\n\r\nexport interface IIdea {\r\n id?: number\r\n date?: string\r\n note: string\r\n}\r\n\r\nexport interface ChartConfigObjectExtended {\r\n editable: boolean\r\n canChangeTicker: boolean\r\n scrollable: boolean\r\n cross: boolean\r\n ideas: boolean\r\n editors: ChartEditorEnum[]\r\n specificChartFunctionality: SpecificChartFunctionality\r\n theme: Theme\r\n layout: LayoutType\r\n uuid?: string\r\n idea?: IIdea\r\n}\r\n\r\nexport interface ChartConfigObject {\r\n width: number\r\n height: number\r\n panes: ChartConfigChartPane[]\r\n premarket: boolean\r\n aftermarket: boolean\r\n dateRange: string | null\r\n hasChartEvents?: boolean\r\n stretch?: boolean\r\n ticker: string\r\n instrument: Instrument\r\n timeframe: TIMEFRAME\r\n chart_layout: ChartLayout\r\n zoomFactor: number\r\n leftOffset: number | null\r\n refreshData: boolean | number\r\n isHideDrawingsActive: boolean\r\n isScrolled?: boolean\r\n scale: ScaleType\r\n}\r\n\r\nexport type RootChartConfigObjectChart = Omit<\r\n ChartConfigObject,\r\n 'chart_layout' | 'leftOffset' | 'zoomFactor' | 'isHideDrawingsActive'\r\n>\r\nexport interface RootChartConfigObject extends Partial {\r\n charts: Array\r\n width: number\r\n height: number\r\n newCharts?: boolean\r\n useGrid?: boolean\r\n}\r\n\r\nexport interface OverlayConfigObject {\r\n color: string\r\n period: string\r\n type: OverlayType\r\n}\r\n\r\nexport enum Instrument {\r\n Stock = 'stock',\r\n Crypto = 'crypto',\r\n MarketSentiment = 'market_sentiment',\r\n Futures = 'futures',\r\n Forex = 'forex',\r\n Group = 'group',\r\n}\r\n\r\nexport enum Theme {\r\n light = 'light',\r\n dark = 'dark',\r\n}\r\n\r\nexport interface IModalConfig {\r\n title: string\r\n inputs: IModalConfigInput[]\r\n inputsErrorMessages: ObjectHash\r\n}\r\nexport interface IOptionType {\r\n value: string | number\r\n label: string\r\n}\r\nexport interface IModalConfigInput {\r\n type: React.HTMLInputTypeAttribute\r\n label: string\r\n name: string\r\n value: number | string\r\n required?: boolean\r\n min?: number\r\n color?: string\r\n step?: number\r\n items?: IOptionType[]\r\n}\r\n\r\n// Keep in sync with config/types/globals.d.ts\r\nexport enum Position {\r\n Above = 'above',\r\n Below = 'below',\r\n}\r\n\r\nexport enum DefaultSpineEvents {\r\n Change = 'change',\r\n Destroy = 'destroy',\r\n Refresh = 'refresh',\r\n Update = 'update',\r\n}\r\n\r\nexport enum CustomSpineEvents {\r\n IndicatorsChange = 'indicatorsChange',\r\n ManualChange = 'manualChange',\r\n}\r\n\r\nexport enum DrawingSpineOptionsEvent {\r\n Remove = 'remove',\r\n}\r\n\r\nexport interface DrawingSpineOptions {\r\n eventType: DrawingSpineOptionsEvent\r\n}\r\n\r\nexport type TodoButtonProps = ObjectHash\r\nexport type TodoButtonTheme = string\r\n"],"names":["Array","prototype","last","this","length","String","padLeft","paddingValue","slice","startsWith","str","indexOf","_callbackCache","Spine","bind","ev","callback","that","cb","record","fkey","id","_len","arguments","rest","_key","push","newCb","origCb","model","unbind","item","findIndex","element","iterable","all","index","el","eql","defaults","enabled","collapsed","duration","timestamp","logErrors","withStackTrace","level","logger","console","filterChanges","attrs","props","Object","keys","constructor","name","errorTransformer","error","titleFormatter","title","time","took","parts","toFixed","join","colors","prevState","action","nextState","pad","num","maxLength","repeat","times","toString","printLogEntry","logEntry","options","startedTime","data","formattedTime","getHours","getMinutes","getSeconds","getMilliseconds","titleCSS","headerCSS","formattedTitle","groupCollapsed","group","log","styles","trace","groupEnd","initialize","window","protoModelLoad","load","started","Date","now","cid","attributes","returnedValue","apply","e","badgeImages","getSvgImageCacheKey","badgeType","theme","state","ChartEventElement","ElementModel","initClass","paneModel","configure","belongsTo","yIndex","getChartEventBadgeImage","cacheKey","badgeImage","isLoaded","image","width","height","async","_ref","onBadgeInitLoad","importWithRetry","chartBadgeSvgByType","chartEventsAsyncModule","importFn","handleImageResolve","values","some","_ref2","undefined","ChartEventBadgeState","forEach","badgeState","ChartEventBadgeType","Theme","svgHTML","CHART_EVENT_BADGE_SIZE","img","Image","onload","onerror","captureException","Error","extra","src","encodeURIComponent","fetchAndCacheChartEventBadges","trigger","getChartEventData","instance","chart","quote","chartEvents","find","stockEvent","elementId","toObject","super","toConfig","Indicator","chartModel","Overlay","Chart","Pane","Quote","ChartLayout","DrawingsInternalStore","Element","document","location","hostname","isIPad","Utils","IPAD_FULLSCREEN_CLASS","FullscreenButton","isFullscreen","setIsFullscreen","React","getFullscreenStatus","requestFullscreen","getRequestFullscreen","documentElement","exitFullscreen","getExitFullscreen","onClick","call","checkFullscreen","body","classList","add","remove","addEventListener","removeEventListener","_jsx","Button","leftContent","contentClass","current","children","SORTED_LAYOUT_KEYS","arr","sort","a","b","reduce","acc","option","sortBy","sortDirection","SORT_DIRECTION","ASC","directionMultiplier","sortObjects","entries","LAYOUTS","map","key","value","ChartLayoutDropdown","_ref3","useLocation","navigate","useNavigate","parsedQuery","decodeQueryString","search","chartLayoutModel","useModelState","watchProperties","getChartsToPath","useChartsPathLocation","Dropdown","placement","orientation","l","_jsxs","className","layout","DropdownItem","appearance","Icon","MenuGroup","Paragraph","size","ChartSyncableParts","_ref4","label","isChartPartInSync","getIsChartPartInSync","active","setSyncChartParts","gtag","event_label","ThemeToggleButton","isDarkMode","updateAttributes","settings","updateSettings","setCookieRequest","catch","BREAKPOINTS","minWidth","Infinity","marketBadgeText","timeFormat","ChartLayoutHeaderComponent","onSettingsOpen","hasPublish","chartLayout","_Fragment","IdeasDropdown","TourButton","page","specificChartFunctionality","Publish","disabled","idea","Time","breakpointMode","breakpoints","ChartLayoutHeader","prevProps","nextProps","hasRedesign","isRedesignEnabled","StockDetailTimeframeBar","withSuspense","chartIndex","isDateRangeAvailable","isPremium","isLoadingOverride","isScrollIntoViewEnabled","onTimeframeSelect","onDateRangeSelect","useChartLayoutGlobalModelAsync","chartModelUnwatched","getAllCharts","favoriteTimeframes","toggleFavoriteTimeframe","useFavoriteTimeframes","instrument","Instrument","Stock","isLoading","useChartControls","isInteractive","anchorDate","generateChartLayoutRouterPath","timeframeGroupsWithHref","dateRangeGroupsWithHref","isFetching","handleCustomDateRangeValidation","useChartModelCustomDateRangeValues","onDialogSubmit","customDateRangeDialogState","handleDateRangeSelect","getDateRangeTimeframe","useCustomDateRangeDialog","pathGenerator","dateRangeGroups","customRange","dateRange","timeFrameGroups","selectedTimeframe","timeframe","TimeframeBar","rounding","selectedDateRange","loadingTimeframe","onCustomDateRangeClick","show","onFavoriteTimeframeToggle","containerElement","isFavoritesEnabled","CustomDateRange","dialogState","dateRangeTimeframe","pushIndicators","panes","indicator","cotKeys","COTs","code","elements","type","IndicatorType","Cot","hasPaneWithCOTCode","PANE_HEIGHT_DEFAULT","period","parameters","getChartTypeByTaConfigStyle","style","candlestick","ChartElementType","CandleStick","heikinashi","HeikinAshi","hollowcandlestick","HollowCandleStick","line","LineChart","ohlc","OhlcChart","mergeChartAndTAConfig","chartConfig","taConfig","charts","scale","linear","ScaleType","Linear","percentage","Percentage","logarithmic","Logarithmic","indicators","filter","position","Position","Above","overlays","overlay","color","Below","getPanes","SettingsTab","SidebarDirection","createAlertAsyncModule","saveToPortfolioAsyncModule","AdsProvider","getAdsProvider","FinvizSettings","hasUserPremium","None","adsProvider","Freestar","InvestingChannel","trackPageView","pathname","query","freestarPageView","replace","freestar","queue","trackPageview","portfolioWatchlistTableAsyncModule","assets","logo","logo_light","useTrackPageView","trackInitial","trackAutomatically","initialRender","handleTrackView","tracking","cache","errorsCache","ErrorSeverity","defaultCaptureException","exception","captureContext","Sentry","useAsyncModule","onError","errorSeverity","shouldLoadModule","isSuspenseMode","notificationContext","useNotification","setIsLoading","isError","setIsError","getIsMounted","useIsMounted","handleError","high","handleScriptNotLoaded","renderScriptNotLoaded","medium","Notification","timeoutInMs","reload","loadModule","cachedModule","then","mod","err","Component","fallback","NUM_OF_RETRIES","retries","Promise","r","setTimeout","ElementBaseConfig","static","abbreviation","shortLabel","description","optionsOrder","optionsLabels","inputsOrder","inputsLabels","calculatedValuesOrder","calculatedValuesLabels","defaultCalculatedValueOption","getShortLabelWithAttrs","getDefaultCalculatedValues","Arrow","CanvasElementType","arrow","renderContent","resize","_thumbs","Thumb","x1","y1","x2","y2","getBoundingPointKeys","getDefaults","border","getChartLayoutSettings","ElementSettings","Colors","x","y","context","scaled","roundedXY","getRoundedObject","translateXY","getXYOffsetFromLine","lineWidth","translate","beginPath","set","angle","Math","PI","moveTo","lineTo","stroke","lineAngle","atan2","h","abs","cos","angle1","topx","topy","sin","angle2","botx","boty","getShouldRenderThumbs","renderThumbs","moveBy","difX","difY","isInArea","area","isDrawingElementLockedOrInvisible","math","distanceToSegment","modalConfig","inputs","Brush","brushV1","untranslatedContext","brushPath","cachedFill","previousFill","shouldRenderFill","getContextWithCache","createElement","setFillCache","fill","defaultTransparentFill","isPolyLineClosed","getShouldRenderFill","Path2D","points","i","fx","fy","xc","yc","quadraticCurveTo","point","closePath","getThumbs","firstX","firstY","lastX","lastY","moveByThumb","getIsCreator","onMouseUp","currentDomainMax","currentDomainMin","domain","roundToFixed","roundY","isPointInPath","cachePointPositionTimestamp","positionPointsTimestamps","getTimestampFomPositionX","updateScales","getPositionXFromTimestamp","places","Number","parseFloat","round","overridePlaces","domainDiff","numberOfLeadingZeros","floor","log10","getAutosaveOmittedProperties","getEdgeXYValues","edgeXYValues","minX","min","minY","maxX","max","maxY","default","TailDirection","getTailHalfWidth","halfWidth","p1","p2","dist","distance","Callout","Text","calloutV1","getModalConfigBase","required","textWithoutBackground","text","font","family","weight","fillStyle","lineHeight","textAlign","textBaseline","padding","top","right","bottom","left","background","defaultFill","setupContext","setupTextMetricsCache","ctx","lastAttrs","JSON","stringify","merge","lines","getLines","metrics","measureText","measuredHeight","currentIndex","actualBoundingBoxAscent","actualBoundingBoxDescent","PADDING","S","render","renderText","previousDescent","fillText","getCalloutProperties","textWidth","requiredTailHalfWidth","radius","rectangleSides","topLeft","topRight","rightTop","rightBottom","bottomRight","bottomLeft","leftBottom","leftTop","getRectangleSidesCoordinates","tail","tailRoot","tailTip","getTailCoordinates","tailDirection","twoSegmentLinesIntersection","topLeftCorner","topRightCorner","bottomLeftCorner","bottomRightCorner","topSide","rightSide","bottomSide","leftSide","noTail","getTailToSideIntersection","renderBackground","lineJoin","arcTo","tailLineToTopLineIntersection","tailHalfWidth","tailLineToRightLineIntersection","tailLineToBottomLineIntersection","tailLineToLeftLineIntersection","renderCallout","renderBorder","tailP1","perpendicularPointToLine","pointOffsetX","pointOffsetY","tailP2","polygon","pointInPolygon","getIsInChartView","leftOffset","Curve","curve","x3","y3","drawQuadraticCurve","Bezier","quadraticFromPoints","cp1x","cp2x","cp1y","cp2y","project","d","thumbsAreInArea","Ellipse","ellipse","invert","getCoordinates","centerLeftX","centerLeftY","centerRightX","centerRightY","boundingPointKeys","c","bottomCenterX","bottomCenterY","bezierCurveTo","bottomRightX","bottomRightY","topRightX","topRightY","topCenterX","topCenterY","topLeftX","topLeftY","bottomLeftX","bottomLeftY","rotationAngle","atan","sign","radiusX","radiusY","width_two_thirds","dx1","dy1","dx2","dy2","RotatedRectangle","rotatedRectangle","getRectCoordinates","coords","mx1","mx2","my1","my2","nk","dx","sqrt","dy","x4","y4","SymbolElement","symbol","sx","getRotatedCoordinates","scaleX","sy","textHeight","scaleY","xScale","yScale","xOffset","yOffset","save","rotate","restore","cx","cy","halfHeight","drawingToolsByType","freeze","brush_v1","callout_v1","elliottWaves","ellipseV1","ellipse_v1","fibonacciRetracements","fibonacci","horizontalLine","measure","pitchforkV1","pitchfork_v1","rectangle","rotatedRectangleV1","rotatedRectangle_v1","scaledLine","scaledText","symbolElement","triangle","verticalLine","xabcd","fromObject","obj","getNumOfBarsBuffer","_","isCreator","isCreatorDialogOpen","activeThumb","isMouseDown","isSelected","isHovered","isEditInProgress","onMouseDown","onMouseMove","getIsChartEvent","findByAttribute","__","setIsEditInProgress","shouldTriggerChange","setIsSelected","setIsHovered","getIsPaneSelection","pane","selection","attrsSubset","customizer","objValue","srcValue","getIsDrawing","mergewith","get","defineProperty","globalAlpha","thumb","startEditing","mouseDown","xPointKeys","positionTimestamps","positionX","pointPoitionsFromTimestamp","chart_layout","isLockDrawingsActive","getIsVisible","getModalConfig","config","input","toAutosaveConfig","omit","replaceMyself","captureMessage","oldElement","newElement","getIsCreatorDialogOpen","release","micro","macro","MicroMacroTimeframe","visibility","isInRange","from","to","setVisibilityTo","setTo","MacroTimeframe","timeframesToSet","attrsToSet","SetVisibilityTo","currentAndAbove","currentAndBelow","currentOnly","assign","xPoints","yPoints","positionY","omitX","isMaxXInvalid","isNaN","isMinXInvalid","omitY","topBound","bottomBound","ElliottWaves","waves","offset","getOffsetFromLineWidth","p","TextBaseline","middle","TextAlign","center","wave","positionWavesTimestamps","EllipseV1","getEllipsePoints","P2","P4","coordinates","P3","P1","CP4","CP1","CP2","CP3","ellipsePath","inverted","cursorTargetX","cursorTargetY","perpendicularPoint","cursor","distanceToLine","lineCenterX","lineCenterY","invertX","invertY","perpendicularPointEllipseOffsetX","perpendicularPointEllipseOffsetY","P1WithOffsetX","P1WithOffsetY","P3WithOffsetX","P3WithOffsetY","controlPointOffsetX","controlPointOffsetY","getRotatedPointCoordinates","rotationAxisPoint","pointToRotate","oldLinePoint","newLinePoint","sharedPointLinesAngle","sharedPoint","rotatedPoinCoordinates","rotatedPointCoordinates","newLeftPoint","leftRotatedCursorPoint","newRightPoint","rightRotatedCursorPoint","FibonacciRetracements","parseCoefficients","coefficients","parsed","split","trim","getMaxCoefficientUnscaledY","getMinCoefficientUnscaledY","includes","_ref5","_ref6","_ref7","maxCoefficientY","minCoefficientY","allYValues","HorizontalLine","ScaledLine","decimalPlaces","updateDecimalPlaces","step","getInstrumentDecimalPlaces","lastClose","ChartSettings","getBarIndex","close","renderLabels","IndicatorSettings","isIndicator","allowDecimal","Line","strokeStyle","dashLength","setLineDash","Measure","x1Dif","x2Dif","startingX1","startingX2","getVolumeSumString","volume","barIndex","roundedX1","roundedX2","minIndexLimit","maxIndexLimit","volMinIndex","volMaxIndex","volumeSum","volumeIndex","numberToStringWithUnitsSuffix","fillRect","priceDif","heightStr","getRoundedString","number","numOfDecimalPlaces","baseX","baseY","getHeight","addToCoordinates","difs","newX1","newX2","paneArea","getEdgeIntersectionPoint","sides","rayOrigin","rayDirection","intersection","intersectionDistance","rayToLineIntersection","getRayToLineSegmentIntersection","getPitchforkCoordinates","rayDirectionControlPoint1","rayDirectionControlPoint2","trend1","trend2","chartVisibleAreaLeftX","chartVisibleAreaRightX","chartVisibleAreaBottomY","chartVisibleAreaTopLeftPoint","chartVisibleAreaTopRightPoint","chartVisibleAreaBottomLeftPoint","chartVisibleAreaBottomRightPoint","getChartVisibleAreaBoundaries","medianRay","trend1Ray1","trend2Ray1","trend1Ray2","trend2Ray2","medianRayDirectionPoint","getMiddlePointOnLineSegment","rayOriginToRayDirectionVector","rayDirectionControlPoint1ToPoint2Vector","normalizedRayDirectionControlPoint1ToPoint2Vector","normalizeVector","medianRayDirectionPointToRayDirectionControlPoint1Distance","trend1Ray","getTrendRayCoordinates","trend","medianToControlPointDistance","normalizedControlToControlPointVector","trendRay1","trendRay2","trend2Ray","medianToTrendLineDistance","trendRayPoint1Origin","addPoints","multiplyVectorByScalar","trendPoint2RayOriginPoint2","subtractPoints","trendRayPoint1DirectionPoint","trendPoint2RayDirectionPoint","Pitchfork","median","trendLines","line1","line2","trendLine","trendLineIndex","solidTrendColor","getHEXWithSpecificAplha","nextTrendLine","outerTrendLines","Polygon","isPolygon","scaledPoints","xPoint","yPoint","targetY","stopY","centerY","stopBaseline","targetBaseline","targetColor","stopColor","targetDif","targetPerc","targetStr","stopDif","stopPerc","stopStr","middle1","result","roundDif","coordType","coordIndex","t","s","Rectangle","strokeRect","RotatedRectangleV1","newMiddleLeftPoint","middleLeftRotatedCursorPoint","newMiddleRightPoint","middleRightRotatedCursorPoint","ScaledText","XXXS","XXS","rect","textBoxX","textBoxY","textBoxWidth","textBoxHeight","DEFAULTS","alphabetic","getMergedPropsWithDefaults","propKey","count","f","MIN_SAFE_INTEGER","testArea","convertArea","rawHight","getFontHeight","fontBoundingBoxAscent","fontBoundingBoxDescent","borderWidth","ThumbSettings","borderColor","thumbWidth","getThumbWidth","Triangle","VerticalLine","XABCD","xx","xy","ax","ay","bx","by","start","toUpperCase","retLabel","len","ret","xab","bcd","result1","canvas","rendered","refresh","ratio","drawImage","cWidth","cHeight","sWidth","screen","sHeight","getScaleRatio","setSizeOnCanvasElement","canvasElement","OHLCType","ChartMinWidthBreakpoints","getChartBreakpoints","chartWidthInPx","isXs","xs","isS","isM","m","isL","getDateString","date","dateString","month","getMonth","year","getFullYear","day","getDate","TIMEFRAME","i1","i2","i3","i5","i10","i15","i30","h2","h4","MONTHS","w","getClosestDifferentMinMaxValueIndices","currentMinIndex","currentMaxIndex","low","hasPreviousIndex","hasNextIndex","minIndex","maxIndex","gray300","tailwindColors","BaseChart","overlaysByType","tickerWidth","changeWidth","lastOhlc","isLargeChart","shouldRenderVolume","afterChange","isMobile","utils","overlayDefinition","convertColorToHEX","addOverlay","renderYAxis","renderCrossText","setupCache","renderOverlaysLabels","CustomSpineEvents","IndicatorsChange","handleIndicatorsChange","mouseModelChangeHandler","mouseModel","unmountCanvas","baseCache","updateShouldRenderVolume","renderChart","renderChartNotAvailable","getIsRedesignedChart","renderTicker","clip","renderVolume","renderOverlays","renderPrevClose","renderFadeExtendedHours","renderGrid","renderXAxis","tickerText","getIsSmallIndexChart","ticker","general","margin","FONT_SIZE","OFFSET","baseline","renderTimeframe","volumeFY","range","Group","getTimeframeLabel","textSecondary","isOurSiteRequest","L","SpecificChartFunctionality","offScreen","XS","M","blue","renderChange","getOHLC","directRender","changePercentage","lastDate","renderOHLC","isSmallIndexChart","isNewestOHLC","open","afterHour","isFinite","afterClose","roundOhlc","lastVolume","toLocaleTimeString","hour","minute","getRoundedLastData","lastOpen","lastHigh","lastLow","renderOverlaysLabelsChartsPage","renderOverlaysLabelsQuotePage","overlayLabel","isRenderedOverlaysLabel","labelSpacing","getLabelColor","getYAxisLeftMargin","Crypto","getYAxisLastCloseLabel","firstVisibleClose","getPercentageFromValue","base","lineTicks","textTicks","lastCloseLabel","getTranslate","do","tickCount","minMax","getMinMax","placesAxis","stepPrice","scaleRange","updateAttribute","minPerc","maxPerc","d3","nice","ticks","tick","getValueFromPercentage","pixelGap","negativeScale","previousNegativeTick","unshift","positiveScale","previousTick","positiveScaleY","getYLineText","val","yTickText","axis","yTickLine","getYLine","resetYTicksStyles","percentageZeroLineText","undo","renderYAxisLabel","yCoordinate","getSecondaryLabelBackgroundColor","stringifyHSVAColor","getHSVAFromColor","currentBackground","getYAxisSecondaryLabelYCoordinate","mainLabelValue","secondaryLabelValue","direction","LINE_HEIGHT","mainLabelValuePosition","secondaryLabelValuePosition","offsetedY","currentText","getDrawDays","MarketSentiment","textRenderer","getIsIndicatorPresent","Vol","getVolumeTicks","maxHeight","fontHeight","renderVolumeAxis","relativeVolume","grid","rangeMax","volumeAxisFontSize","volumeAxis","format","tickFormat","domainFrom","domainTo","setupAxisTimeFrame","halfBarWidth","getHalfBarWidth","barWidthWithoutMargin","getBarWithoutMarginWidth","drawInVisibleArea","drawBarCallback","volumeTrendDown","volumeTrendUp","renderCross","isRendered","contentWidth","contentHeight","getRoundDecimalPlaces","price","getPlacesLastClose","onRenderCrossText","getCrossIndexForPane","setElementCursor","getHTMLElementId","conditionalCursor","getDataByCrossIndex","crossIndex","shouldReturnRoundedString","n","getDataByBarIndex","getCrossIndexChange","crossDataIndex","getDataIndexByBarIndex","crossClose","previousClose","getTickerChangeFromCloseValues","anchorClose","prevClose","dateByBarIndex","virtualTradedDates","getVirtualTimeframeTradedDates","dateStart","dateEnd","change","tickerChange","tickerAfterChange","getTickerChange","isOffscreen","isGroupInstrument","finvizWatermarkOffset","changeText","percentString","string","getChangeColor","afterChangeText","afterChangeTextWidth","oneLineAHChangeWidth","renderOHLCChartsPage","renderOHLCQuotePage","_ref8","chartBreakpoints","OhlcText","canvasFill","dateElements","trendColor","oElements","hElements","lElements","cElements","volElements","changeElements","getFlatLineArrayWithSpaces","lineElements","flatMap","startX","lineElement","LabelsText","numberOfNewOhlcLines","_ref9","dateOnly","timeOnly","lineTopY","OHLCFontSize","centerXOffset","leftXOffset","OHLC","ohlcString","singleLine","OHLC_TEXT","getOHLCType","ohlcSettings","getOHLCSettings","CHART_MARGIN","XXL","alignTop","renderOHLCToCanvas","_ref10","ohlcSet","isSingleLineWithChange","shouldShowPrevClose","isStock","isIntradayWithPreMarket","TIMEFRAMES_WITH_PRE_MARKET","isIndexChart","smallIndex","Cache","getIsMobileChartPage","setupAxis","volumeHeight","firstBarToRenderIndex","getVisibleBarToRenderIndex","lastBarToRenderIndex","chartWidth","volumes","getAreNoBarsVisible","addMarginBottom","marginBottom","setOverlays","removeOverlay","splice","MAX_VALUE","MIN_VALUE","prevMin","closestMinMaxIndices","placesLastClose","priceAbs","hasOverlay","getXLine","chartPage","getCandleLikeChartsRenderingColors","overwrittenColors","getColorOverwrites","overwrittenColorKeys","hasOverwrittenCandleColor","colorKey","light","getShouldUseDarkerWickColors","totalBarWidth","barWidth","darkerWickColors","thinBarColorsOverride","isRedesignedPage","getRenderChartBarProps","chartSettingsColors","hasFillAndBorder","trendDown","trendUp","borderDown","borderUp","wickDown","wickUp","wickColor","barFillColor","barFillWidth","barBorderWidth","getBarWidthWithMarginByParts","zoomFactor","shouldRenderFillAndBorder","translateForWick","WICK_WIDTH","candleBodyHigh","candleBodyLow","candleWickHigh","candleWickLow","candleBodyHeight","candleBodyLeftX","halfBorderWidth","getIsSSr","isBodyHeightGreaterOrEqualBorders","isWickLineCandleLessThanOnePixel","hasBorder","fillHeight","hasFill","isHollow","generalTrendColor","ohlcTrendUp","ohlcTrendDown","zeroChange","haData","getHeikinAshiData","getLastValues","originalLatestClose","heikinLatestCloseLabel","originalLatestCloseLabel","first","redLine","greenLine","MarketSentimentSettings","sum","_data","lastIndex","_dataLastIndex","drawMinutesPerDay","marketStartMinutes","renderLineBullBear","array","oversold","overbought","isRedesign","marketDown","marketUp","xLine","_compute","computeVisibleMinMax","yLine","fillUp","fillDown","percent","months","MultiLineChart","tickersDimensions","ColorsSettings","quotes","getQuotes","tickers","end","asc","barToDataIndex","maxTickerLength","isLastDate","closeValue","NaN","arrays","q","select","isIdeaId","ideaID","OHLCChart","barWithoutMarginWidth","lineThickness","handleLengthFromWick","lineOffset","barX","PerfChart","overlayLabelWidth","perf","dates","getCompleteChartNumOfBars","shouldRenderDate","tickerData","MARGIN","percentageText","lastCrossIndex","findLastIndex","fromDate","toDate","timestampe","dateToIndex","getDateToIndex","lastValue","dataIndex","lastMonth","monthsInData","availableTickSpots","monthsToAvail","renderMonth","chartsByType","candleStick","heikinAshi","hollowCandleStick","lineChart","marketSentiment","multiLineCharts","ohlcChart","perfChart","XXXL","XL","SETTINGS_HEIGHT","TICKER_TIMEFRAME_CHANGE_HEIGHT","ChartEditorEnum","LayoutType","OverlayType","ChartEventDbType","ChartEventType","ChartEventLabels","Dividends","Split","EarningsPositive","EarningsNegative","EarningsNeutral","EarningsFuture","columns","rows","gridAreas","DESC","IntradayTimeframeInterval","TimeframeLabelShort","DateRangeType","QuoteFinancialAttachment","TIMEFRAME_SECONDS","CRYPTOS","BTCUSD","LTCUSD","ETHUSD","XRPUSD","BCHUSD","BTCEUR","LTCEUR","ETHEUR","XRPEUR","BCHEUR","LTCBTC","ETHBTC","XRPBTC","BCHBTC","QuotePollingIntervalInMs","EXTRA_MARKET_BUFFER_MINUTES","ScaleLabel","INDICATOR_LABEL_HEIGHT","MOBILE_BARS_TO_VIEW","MOBILE_VIEW_BREAKPOINT_WIDTH","FREE_DATE_RANGES","QuotePageQueryChartTypes","minutes","hours","days","weeks","MicroTimeframeRange","prev","curr","QUOTE_FETCH_EVENT","PREMARKET_AFTERMARKET_HOURS","CHART_ELEMENT_ID","CHART_SETTINGS_DIALOG_TEST_ID","getContainerTypeFromPaneConfig","indicatorElement","getContainerType","mainElement","indicatorType","isChart","updateInternalStoreWithChangedElement","changeType","currentInternalStore","lastUpdateTimestamp","getQuoteRawTicker","containerType","destroyed","instanceJson","newDrawing","zIndex","lastChange","elementAttrs","newInternalStore","updateDrawingIndex","drawingElement","shouldSyncAndSave","updatedRecord","hasChangedZIndex","hasChangedType","hasChangedAttrs","hasChange","getTickersAndContainerTypesInLayoutModel","containerTypes","getAllPanes","mergeUpdatedDrawingsToInternalStore","updatedDrawings","isRefetchAll","newLastUpdateTimestamp","updatedElementIds","drawing","receiveHlc","drawingIndex","currentDrawing","currentNote","getElementNoteText","autoSavedNote","incrementHlc","parse","compareHlc","getInitialStoreDrawings","initialDrawings","initialDrawingsStore","FinvizChartsSettings","drawings","getAutosaveElementFromDBRecord","handleCallMethodOnAllDrawings","elementMethod","getAllElements","isDrawing","getNoteElementId","noteElement","getTickerNoteText","ts","lastChangeTimestamp","lastChangeCounter","uuid","lastChangeNodeUUID","getDBRecordFromAutosaveElement","ChartTypesSelect","specificFunctionality","chartTypes","currentType","setSelectedChartTypeOverwrite","selectedChartTypeOverwrite","ta","ty","taInt","parseInt","isQuoteOrQuoteFinancials","quotePage","quoteFinancials","generateRouterPath","FREE_TYPES_QUOTE_VALUES","encodeQueryString","QuoteNodeChartTypes","candlesticksimple","QuoteLongToShortType","utm_source","utm_medium","utm_campaign","DEFAULT_TYPES","FREE_TYPES_QUOTE","href","reloadDocument","defaultType","QuoteShortToLongType","FinvizQuoteTypeCurrent","useChartTypes","Select","items","icon","nativeSelect","onChange","utmCampaign","futuresPage","forexPage","cryptoPage","PopoverInner","hidePopover","chartSettingsModule","chartSettingsAsyncModule","onClose","ScrollableChartSettingsPopover","isOpen","forceGlobalRerender","getIsConfigChanged","confirmationDialogState","usePopoverState","hide","checkChangesAndOpenDiscard","preventDefault","discardChangesAndHide","buttonPosition","popoverContentElement","getState","disclosureElement","getBoundingClientRect","scrollY","chartHeight","chartElement","getElementById","clientHeight","Popover","minHeight","ZIndexContext","Provider","classNames","PopoverRounding","regular","PopoverTheme","Delayed","Spinner","ConfirmationDialog","actions","as","DialogDismiss","ChartSettingsButton","settingsPopoverState","useState","buttonProps","PopoverTrigger","focusRing","getQuoteRequestKey","unwatchedChartModel","chartModelRef","modelRef","useModelRef","abortControllerKeyRef","isIdeaChart","updateChartModelWithNewQuote","isSameTicker","getRawTicker","getChartOrIndicatorElement","getLeftOffset","isScrolled","getAllQuotes","chartQuote","fetchData","fetchType","QuoteFetchType","NewerData","chartPane","getChartPane","activeChartEvent","toggleIsOpen","getAllChartEvents","isChartEvent","isPreserveDrawingsActive","destroyCascade","setChartEvents","updateChartEventsZIndexes","fetchQuote","hasChartEvents","premarket","aftermarket","patterns","getHasPatterns","currentQuote","abortController","createRequestAbortController","shouldAbortRunningRequest","events","financialAttachments","getQuoteFinancialAttachments","cachePredicate","fetchNewDataOnCachedQuote","wasFetchAborted","isQuoteUsedInOtherCharts","fetchedAt","destroy","removeFromAbortCache","decodedQueryString","rangesArray","ranges","every","shouldRecalculateOnCharts","barMargin","hasSameBarWidth","hasSameBarMargin","setIsFetching","dateFromUnixTimestamp","generatePathForTimeframeDateRange","timeframeUtm","getTimeframeGroupsWithHref","generatePath","timeFrame","getDateRangeGroupsWithHref","dateRangeState","numOfVisibleBars","getVisibleBarsNumber","getChartStartEndDates","unwatchedChartLayoutModel","hasSyncedTimeframe","ChartSyncablePart","Timeframe","syncChartParts","hasSyncedTicker","Ticker","decodedSearch","urlTickers","urlTimeframes","urlDateRanges","chartsArrayPlaceholder","currentTicker","timeframes","currentTimeframe","currentDaterange","Boolean","sidebar","getIsMobilePortrait","getTimeframeGroups","timeFrameGroup","QuoteUrlChartTypes","cs","o","ha","hc","useChartLayoutGlobalModelAsyncModule","preventClosingUnsavedChangesAsyncModule","BackgroundInput","InputColorPicker","inputDataTestId","toLocaleLowerCase","ColorRangeRowInput","colorValue","colorTestId","rangeValue","rangeTestId","rangeLabel","rangeProps","handleRangeChange","useCallback","currentTarget","handleColorChange","RangeSlider","rightContent","BorderInput","CheckBox","Checkbox","checked","FONT_VALUES","FontInput","setFamily","setSize","setStyle","setWeight","setValue","valueSetter","Label","selected","Input","LineInput","MultilineStringInput","Textarea","placeholder","target","autoFocus","NumberInput","pattern","StringInput","Trend","valueAsNumber","VisibilityInput","isCheckboxOnly","isOff","setIsOff","setFrom","macroKey","macroLabel","charAt","INPUTS_AVAILABLE","getInitialState","visibilities","macroTimeframe","valueMacroTimeframe","getIsVisibilityOutsideAvailableTimeframes","macrotimeframe","macroRange","Visibility","initialVisibilityRef","handleChange","handleDisableSubmit","TAB_BUTTON_COMMON_PROPS","getValuesFromFormState","formState","cur","DialogTabs","ElementStyleDialog","initialFormStateRef","setFormState","selectedTab","setSelectedTab","Style","isSubmitDisabled","setIsSubmitDisabled","isDrawingElement","handleFullyOpen","CanvasElement","handleFullyClosed","onHide","handleValuesChange","shouldSubmit","shouldDismiss","hasOnSubmit","onSubmit","hasOnDismiss","onDismiss","handleValuesChangeDebounceRef","debounce","newFormState","maxWait","cancel","checkValidity","handleCloseDialog","Dialog","isDraggable","modal","backdrop","onFullyOpen","onFullyClosed","hideOnEsc","DialogHeader","onCloseClick","DialogBody","ButtonGroup","hasDivider","InputComponent","getInputForType","inputType","stateInput","DialogFooter","ElementStyleDialogContext","ElementStyleDialogWrapper","setElement","setOnSubmit","setOnDismiss","dialog","useDialogState","openDialog","DRAWINGS_SAVE_INTERVAL_MS","RETRY_LIMIT","useDrawingAutoSaveApi","postRetryCountRef","deleteRetryCountRef","fetchDrawings","fetchApi","queryParameters","throwOnStatusCodes","saveDrawings","bodyJsonString","keepalive","hi","charCodeAt","lo","getByteLengthOfString","method","contentType","ContentType","ApplicationJson","latestChangeHlc","InternalServerError","ForbiddenError","GoneError","newTicker","response","message","GenericStatusCodeError","invalidItems","deleteAllDrawings","lastLocalChange","newHlc","useDrawingAutoSaveControls","isAutoSaveActive","isInit","getIsPreserveDrawingsAndAutosaveAvailable","useIsAutoSaveActive","drawingsInternalStore","saveTimeoutRef","clearTimeout","saveLatestChanges","withDelayInMs","saveQueueExtraFilterCallback","saveQueue","latestLocalUpdateTimestamp","instanceUUID","setAutoSaveState","AutoSaveState","Unsaved","Saving","Saved","syncChartLayoutDrawings","isRemove","paneContainerType","paneInternalStoreElements","autoSaveElement","paneElement","paneDrawing","parsedElementAttrs","hasOngoingInteraction","getCanvasElementByType","create","handleAutoSaveNoteChange","note","newNoteElement","handleIdeaNoteChange","activeChart","checkDrawingUpdate","latestRemoteUpdateTimestamp","initHlc","allElements","normalizeZIndexes","activeTicker","updateInternalStoreWithElement","updateResult","deleteAllAutoSavedElements","onElementChange","elementPane","elementContainerType","elementPaneTicker","eventType","DrawingSpineOptionsEvent","Remove","useDrawingAutoSave","drawingsInternalStoreUnwatched","prevIsAutoSaveActive","ref","usePrevious","runInitialSaveAndRefetchUpdate","Off","onChartOrIndicatorChange","newTickers","newContainerTypes","ChartModel","checkDrawingUpdateSubscription","intervalCallbackOnWindowVisible","interval","unregisterListeners","willDestroy","CHANGE_UPATE_EVENTS","QUOTE_MODEL_CHANGE_EVENTS","ChangeLabel","changePoints","isTiny","classnames","DailyChangeDisplay","listenOnEvents","quoteModel","testId","DrawButton","newValue","getIsDrawingEnabled","DRAWING_COOKIE_NAME","expires","setMonth","setCookie","finally","getLayoutType","tickersCount","Search","onTickerSelected","saveToPortfolioDialogState","isSaveToPortfolioVisible","createAlertDialogState","isCreateAlertVisible","saveToPortfolioModule","isLoadingSaveToPortfolio","createAlertModule","isLoadingCreateAlert","SaveToPortfolio","CreateAlert","detailLink","formattedTicker","Futures","Forex","WebsiteSearchComponent","inputClass","isSearchIcon","isSearchItemLink","isShowAllVisible","event_category","hasRedesignEnabled","ChartControls","isQuotePage","isQuoteFinancials","handleTickerSelect","upperCaseTicker","handleCustomRangeSubmit","timeframeBarProps","canChangeTicker","hasTimeframe","editors","Heading","tools","editable","ideas","compactViewMaxBreakpointPx","grow","publish","ContextMenu","contextMenu","watchedModel","useDropdownState","shown","ContextMenuComponent","overlap","hideOnInteractOutside","callbacks","onBeforeItemClick","getAnchorRect","anchorRect","onContextMenu","stopPropagation","ready","rootEl","querySelector","ReactDOM","event","clientX","clientY","ChartEventPopoverWithState","unwatchedChartLayout","lastEventId","popoverState","isPopoverMounted","chartEventsModule","isChartEventOfThisChart","setData","clickAwayRef","isListening","refCallback","handler","contains","useClickAway","chartEvent","popoverShow","popoverHide","newData","getChartEvenBadgeType","PopoverAnchor","store","tabIndex","focusable","autoFocusOnShow","ChartEventPopoverContent","delayComponent","LoadLatestDataButton","isMountedRef","hasNewDataAvailable","setHasNewDataAvailable","getRefreshInterval","isPossibleToFetchSequentialData","hasNewData","promises","refreshData","ZOOM_CONTROLS_ACTIVE_CLASS","ZOOM_CONTROLS_IS_IN_AREA_CLASS","buttonCommonProps","getDefaultLeftOffset","ZoomControls","zoomControlsRef","isVisible","onZoomIn","onZoomOut","onZoomReset","isGoToRecentVisible","setIsGoToRecentVisible","defaultZoomFactor","isZoomResetVisible","setIsZoomResetVisible","handleGoToMostRecent","handleChartModelChangeDebounced","hidden","rafId","crossRafId","paneRef","scalerRef","zoomerRef","canvasWrapperRef","canvasRef","crossCanvasRef","paneHammer","scalerHammer","zoomerHammer","canvasWrapperHammer","lastClientX","lastClientY","currentViewRange","lastActiveTool","scalerLastY","isElementHovered","hoveredElement","isDisableTouchCrossAvailable","canvasCtx","crossCanvas","crossCanvasCtx","isIndicatorPane","hasSeenCrossNotification","localStorage","getItem","onModelUpdate","onElementCreate","onElementDestroy","onElementReplace","onElementSelect","onElementClone","immediateRecountScaleOnChartIndicatorChange","recountScale","ManualChange","onChartUpdate","activeTool","MouseModel","getIsIndicatorPane","componentDidMount","renderAll","initialStoreDrawings","Hammer","touchAction","threshold","on","onPress","onTouchMove","passive","scrollable","onScalerReset","onZoomerReset","onDoubleClick","forceUpdate","CHART_LAYOUT_CHILD_CHANGE_EVENT","componentWillUnmount","touchEventsDisabled","onPaneClick","paneIndex","getIsHammerAllowScrollActive","isChartPane","getIsChartPane","onPaneMouseMove","onMouseLeave","onPaneMouseLeave","onTouchStart","onResizerMouseDown","initialScrollable","onScalerMouseDown","onMouseEnter","onScalerMouseEnter","onScalerTouchStart","onZoomerMouseDown","onZoomerMouseMove","onZoomerTouchStart","DrawingTool","Mouse","onAddToZoomFactor","diff","shouldCalculateRightAlign","onCanvasInteractionStart","onCanvasInteractionMove","onTouchEnd","onBlur","getChartAlt","cross","isTouchCrossActive","oldElementInstance","isDrawingModeContinuousActive","setSelection","onPaneDestroy","setSelectedElement","clonedElementInstance","setCanvasSize","getArea","onMouseMoveOnScrolling","activeChartInteraction","TouchEvent","targetTouches","dif","addToLeftOffset","onScalerTouchMove","onScalerMouseMove","onScalerTouchEnd","onScalerMouseUp","setActiveChartInteraction","MouseEvent","button","originalMinMax","currentDiff","originalDiff","getBarWidthWithMargin","getMinMaxLeftOffset","newLeftOffset","fetchOlderData","getElement","openElementStyleDialog","pointerType","onCanvasPress","elementInArea","elementModel","hasProperties","isElementDrawing","onContextMenuClose","makeClone","bringToFront","sendToBack","bringForward","sendBackward","handleRemoveIndicatorPane","element_type","onContextMenuFullyOpen","updateType","requestAnimationFrame","process","_renderAll","getIsUpdatedDesign","renderPane","isCharts","isRedesignedFuturesForexCrypto","isMouseInPane","getShouldRenderCrossInPane","clearRect","isCrossDisabled","PaneModel","getIsDisabled","elementInstance","additionalData","Settings","getSettings","areaRectangle","areaRectangleCursorX","areaRectangleCursorY","chartLeftX","chartRightX","cursorX","cursorY","isCursorInChartWidthBoundaries","isChartsPage","setState","setItem","inline","_this","isMouseDownIgnored","zoomControls","paneHeight","touchEvent","setMousePosition","getMousePositionInBoundaries","isTouch","onCanvasInteractionEnd","Touch","isPrimaryClick","canvasAreaRectangle","chartLeft","chartRight","chartTop","chartBottom","getValueInRange","isSameMouseModel","isSelectionCanvas","getCanvasDOMNode","withNotificationContext","withElementStyleDialogState","ChartSpinnerOverlay","shouldDisplay","setIsVisible","timeout","DEFAULT_WRAPPER_COMPONENT","preventDefaultFunc","lastWidth","mouseWheelTimeout","setStateWithPanesTimeout","lastHeight","resizerPaneIndex","minimalPaneHeight","zoomerRightAlign","layoutModel","onLayoutModelChange","panesWrapperElement","onPaneCreate","calculateMinimalPaneHeight","handleQuoteChange","onModelChange","onOlderDataLoaded","Refetch","onDataLoaded","componentDidUpdate","isWheelZoomEnabled","handleSetPanesWrapperRef","renderChartToolbar","isChartPage","getAllValidPanes","showSettings","showTimeframe","resetMouseModel","onPinchStart","onWheel","onMouseWheel","addToZoomFactor","calcZoomerRightAlign","activePane","paneId","chartModelParam","panesHeight","newPaneHeight","newChartPaneHeight","newIsScrolled","onResizerMouseMove","onResizerMouseUp","resizePanesAccordingly","total","optiMinHeight","basePane","touches","onZoomerTouchMove","onZoomerTouchEnd","onZoomerMouseUp","getRawDistance","onPinchMove","onPinchEnd","currentLeftOffset","isIntraday","offsetDiff","shouldAlignDaysToLeftApplied","offsetBars","normalizeWheelDeltaY","deltaY","isMouseWheel","diffCoefficient","currentZoomFactor","minBarWidthInPx","maxBarWidthInPx","minZoomFactor","getZoomFactorForBarsToDisplay","chartVisibleWidth","maxZoomFactor","isNegativeDirection","newZoomFactor","newZoomFactorInRange","getZoomFactor","stretch","updateZoomAndLeftOffsetByDateRange","newQuote","shouldForceLeftOffsetUpdate","WrapperComp","gridArea","isModelDestroyedRef","initChartRef","panesConfig","getQuoteFinancialAttachmentsFromChartConfig","panesWithPerfIndicator","allSettled","paneWithPerfIndicator","prefetchPerfIndicatorAllQuotes","paneProperties","createPaneCascade","shouldResize","chartsDimensions","getChartsDimensions","handleModelBeforeDestroy","isFuturesForexCryptoPage","isModelReady","loadingStyle","hasOutline","withWatchedPanesOnChartModel","drawingCreatorsAsyncModule","drawingActions","DrawingActions","AddNote","DeleteDrawings","DeleteAutoSavedDrawings","getToolbarDrawingActions","isAddNoteAvailable","isIdea","defaultItem","isDisabled","disabledTooltip","drawingSettings","DrawingSetting","PreserveDrawings","iconActive","titleActive","DrawingModeContinuous","HideDrawings","LockDrawings","preserveDrawingsAutosaveOverride","iconAction","titleAction","getToolbarDrawingSettings","isPreserveDrawingsAndAutosaveAvailable","isAutoSaveInProgress","isInAction","drawingTools","Xabcd","toolbarDrawingTools","toolGroup","toolGroupTitle","DISABLED_ITEM_TOOLTIP_LABEL","Toolbar","isSidebar","isHorizontal","isMobileOverlay","onActiveToolChange","onDrawingActionClick","onDrawingSettingClick","onDrawingEnd","isAlternativeTheme","areToolsDisabled","ignoreRowId","drawingCreatorsModule","isDrawingCreatorsModuleLoading","autoSaveState","setIsDrawing","availableDrawingSettings","availableDrawingActions","isDrawingModeContinuous","hasData","hasHiddenDrawings","tool","drawingToolsTouchCreatorsByType","drawingToolsCreatorsByType","ToolClass","one","ToolbarComponent","isActive","isToolLoading","ToolbarItem","groupItems","groupTitle","useNativeSelect","rowId","ToolbarDivider","ceil","ChartAutoSaveNote","onNoteChange","ChartAutoSaveNotes","setTickers","unwatchedInternalStore","handleChartChange","tickerNoteMap","AutoSaveNotesDialog","isAnimating","isFullyClosed","onAction","onCancel","isAutosaveDialogContent","dialogContent","getDialogContent","ConfirmationDialogComponent","ToolbarMobile","toolbarState","hideToolbar","hideAll","urlSearchParams","setUrlSearchParams","useSearchParams","toolbarMobileElement","setToolbarMobileElement","MOBILE_TOOLBAR_DIV_ID","drawButtonProps","has","SIDEBAR_QUERY_PARAM","params","delete","handleActiveToolChange","drawingTool","handleDrawingActionClick","actionId","gutter","unmountOnHide","AutoSaveStateIndicator","setVisibilityTimeout","newIsVisible","checkIfNeededPreventLeaving","returnValue","ChartLayoutAutoSaveNote","chartLayoutModelUnwatched","ideaNoteRef","getPublishChartHtmlElements","publishChartElements","getElementsByClassName","getChartImgUrl","imgElement","PublishOldButtonClickListener","dialogConfig","setDialogConfig","isCanvas","chartImgUrl","publishModalModule","publishModalAsyncModule","PublishDialog","publishChartHtmlElements","clickHandler","dataset","indexInt","IdeaDrawingsConfirmationOptions","IdeaLeaveDialog","actionCallback","Cancel","Override","Merge","Nothing","getChartElementTypeFromQueryType","queryType","getChartElementTypeFromResponseType","TA","useChartRouteChange","isIdeasDialogOpen","dateFns","updateChartConfig","urlType","handleTypeChange","urlTicker","urlTimeframe","urlDateRange","getInstrument","newChartConfig","getRawTickerForInstrument","updateAttributesAndSync","exitIdea","defaultPeriod","defaultDateRange","handleIdeaLeave","getUuid","ChartLayoutComponentBase","orientationChangeTimeout","preserveDrawingAbortController","AbortController","prevModelWidth","prevTimeframeActiveChart","modelProperties","isHideDrawingsActive","isToolbarHorizontal","handleInitialPreserveDrawingsState","DELETE","getPaneWithSelection","keyCode","touchSize","onChartDestroy","setToolbarPosition","onWindowResize","handleOrientationChange","checkTouchEventsDisabled","quoteTimeframe","abort","throttledResize","preserveDrawings","toolsState","handlePreserveDrawingsSettings","setPreserveDrawings","URLSearchParams","tools_state","handleResize","modelAttrs","throttle","isQuoteForexFuturesCryptoPage","newIsToolbarHorizontal","innerWidth","test","getVisualViewportScale","visualViewport","handleDrawingAction","noteDialogState","toggle","handleConfirmationDialogDeleteBtn","drawingToRemove","handleDrawingsSetting","settingId","newObj","toggleHideDrawings","handleLockDrawings","renderToolbar","args","isOverlayToolbar","newCharts","useGrid","isMobilePortrait","isSidebarEnabled","getIsSidebarEnabled","ChartGrid","ChartGridCell","Sidebar","onShouldResize","horizontal","hasChartTools","renderTools","ideaTitleContainer","ideaTitle","clear","updateLayout","removeCharts","addCharts","rowStart","columnStart","rowEnd","columnEnd","numOfRowsCovered","numOfColumnsCovered","percentageOfRowsCovered","percentageOfColumnsCovered","newWidth","newHeight","settingsHeight","wantedCount","pop","ChartLayoutComponent","flowRight","checkQuoteCacheDebounce","cleanupQuoteCache","allQuotes","allChartQuotes","usedQuote","withCompleteLayoutModelInit","updateChartsTitle","defaultDocumentTitleRef","percentageChange","useChartPageTitle","handleChartsUpdate","getChartLayoutWithChartRouteChange","withQuotePolling","isWithNotifications","parentElement","Wrapper","NotificationWrapper","ChartLayoutWithGlobalState","setChartLayoutModel","getChartLayoutModelConfig","lastGlobalRerender","onRegisterChartLayoutModel","getDefaultZoomFactor","OnInitListener","setIsInit","checkIfInitIsComplete","elementIndex","hasOwnProperty","opacity","newConfig","dark","concat","isQuotePageWithDrawingsOff","getCookie","noteDrawing","ideaObject","newElements","ChartLayoutModel","getMaxDecayInterval","EliteStocksReduced","Free","pollingIntervalToCharts","setPollingIntervalToCharts","checkForChartsWithPolling","newPollingIntervalToCharts","chartRefreshInterval","intervalSubscriptions","checkForChartsWithPollingDebounced","chartsCheckerIntervalId","setInterval","clearInterval","timeoutDurations","allCharts","timeoutDurationsMin","timeoutSubscription","decay","maxDecayInterval","chartIds","quotesToUpdate","quoteToUpdate","dispatchEvent","Event","unsubscribe","getIdeaUrl","searchObject","isStockOnQute","queryString","IdeaItem","onIdeaDeleted","isDeleting","setIsDeleting","isConfirmDelete","setIsConfirmDelete","currentIdea","onDeleteIdeaClick","wasDeleted","fetch","status","newUrl","URL","searchParams","company","IdeasTabs","hasError","setHasError","hasFetched","setHasFetched","categorizedIdeas","setCategorizedIdeas","queryTickers","dateParts","processed","tickerIdeas","categorizeIdeas","fetchIdeas","handleIdeaDeleted","modifiedCategories","categoryIndex","updatedCategory","updatedAll","Tabs","TabList","category","Tab","Badge","TabPanel","toLowerCase","IdeasDialog","hasPadding","dropdownButtonClassName","tooltipState","useTooltipState","isAnyQuoteLoading","setIsAnyQuoteLoading","hideTooltip","dropdownItemProps","TooltipTrigger","checkIfAnyQuoteIsLoading","fetchingQuotes","hideOnClick","activeChartQuote","toJSON","chartId","layoutModelObjectPanes","tickersString","getChartTickers","quotesJsonString","quoteTickersTimeframes","getFormDataFromObject","ideaUrl","saveIdea","Tooltip","getIsMobileScreenSize","isDialogOpen","tour","useTour","pageTours","steps","overlayPadding","getTour","userTour","setCurrentTour","getStepsForUser","buttonTheme","hasNewTours","activeTour","startTour","once","CustomDateRangePrefixEnum","DATE_RANGE_PREFIX_DELMITER","getParsedDateRange","startInSec","getTime","endInSec","lastQuoteDateIndex","lastVisibleBarIndex","d1","d5","firstVisibleBarIndex","quoteDate","isQuoteDateInRange","numOfBarsOffset","getChartZoomAndLeftOffset","numOfBarsToRender","numberOfBarsToDraw","daysInQuote","getDaysInQuote","dateRangePrefix","dateRangeValue","Range","dateFromString","dateToString","dateFrom","dateTo","Prev","years","parseCustomDateRangeUrlParam","convertLocalToNyTime","setHours","startDateIndex","m1","m3","m6","ytd","y5","numOfBarsInView","getIntradayChartConfig","timeframeMinutes","barWidthWithMargin","hasPremarket","hasAftermarket","maxWidth","canCropChart","fullChartWidth","marketMinutesLength","getFullChartWidth","offsetInPx","shouldCropChart","chartWidthWithOffset","offsetChartAfter","shouldAlignDaysToLeft","drawDaysInOneChart","getBarsInDay","lastQuoteDate","barsToOffset","getDayToOffset","offsetChartInPx","isStockIntraday","isIntradayDateRange","isOffScreen","isOffScreenWithNoDateRange","isOffScreenIntradayDateRange","isOffScreenWithFixedBars","isQuotePageWithNoDateRange","isQuotePageIntradayDateRange","isQuotePageWithFixedBars","getShouldOffsetChartDomain","scaleType","getChartElement","perfChartInstance","numOfBars","handleDomainOffset","currentScale","scaleCreator","protectedHeightPx","minPx","extendedMin","_ref11","rounded","fromEntries","_ref12","_ref13","_ref14","_ref15","parsedRange","startQuoteDate","endQuoteDate","numOfDaysToRender","reversedDaysInQuote","reverse","startQuoteDayIndex","endQuoteDayIndex","renderDateStart","renderDateEnd","getParsedDateRangeMetaData","_ref16","shouldRenderCross","DEFAULT_WIDTHS","DEFAULT_CONTEXT","activeModule","isCloseVisible","onResize","selectModule","SidebarContext","useSidebarContext","ModuleLoadFailed","DefaultErrorBoundary","portfolioWatchlistAsyncModule","SidebarModule","sidebarModules","portfolio","content","asyncModule","withInitialLoading","isComponentReady","setIsComponentReady","sidebarModule","withModuleAsyncLoad","mobile","SidebarTabs","showTimeout","vertical","isHideOnClick","SidebarContent","defaultMobile","defaultDesktop","desktop","Resizable","enable","handleClasses","defaultSize","tabsClassName","sidebarModuleKey","setActiveModule","handleSelectModule","newUrlSearchParams","handleCloseSidebar","contextValue","ErrorBoundary","FallbackComponent","getInstrumentLabel","getResponseChartType","chartType","chartResponseType","tr","ChartEvent","getChartEventModel","chartEventModel","getXYPosition","buffer","hover","isOpenOverride","isCurrentEventActive","scaledArea","Earnings","eventItem","epsActual","epsEstimate","dateTimestamp","chartEventsByType","dividends","earnings","canvasElements","indicatorsByType","elementType","BigNumber","BIG_NUMBER_VALUES","Thousand","Million","Billion","Trillion","BIG_NUMBER_ZEROES","BIG_NUMBER_SUFFIX","dotProduct","crossProduct","pow","lineEquation","k","j","oddNodes","l2","formatBigNumber","minNumber","absNum","getString","suffix","zeroes","splitString","addZeroes","padEnd","numberByZeroesCount","isInteger","yAxisCoeficient","xAxisCoeficient","radAngle","p3","p4","denominator","ua","ub","checkLineIntersection","line1_p1","line1_p2","line2_p1","line2_p2","onLine1","onLine2","numerator1","numerator2","rayEnd","segmentStart","segmentEnd","lineIntersection","v","scalar","isSamePoint","ExponentialMovingAverage","multiplier","EMACalculation","MainCalculation","EMAConfig","calculate","onValueCalculated","_calculatedValues","ema","calculatedValues","defaultCalculatedValues","getAllCalculatedValues","lastNItems","getCalculatedValues","getDbColumnName","IndicatorBaseConfig","ShrtflConfig","shortInterest","Shrtfl","ShrtraConfig","Shrtra","ADXConfig","Adx","MAX_POSITIVE_DEFAULT_VALUE","MAX_NEGATIVE_DEFAULT_VALUE","periodInt","getParsedIntegersFromPeriodString","labelWidth","shouldUpdate","applyMinMaxPadding","compute","renderIndicator","getIsChartPageSpecificFunctionality","renderLabel","isComputeNecessary","tickTextStep","formatAxis","valueY","lastValueSuffix","indicatorCurrentText","indicatorCurrentBackground","renderLabelChartsPage","renderLabelQuotePage","indicatorLabel","roundedRect","isPerfIndicator","Perf","renderCrossTextChartsPage","renderCrossTextQuotePage","getValueLabelsAtIndex","renderCrossTextValueLabels","crossValueText","lastRenderedIndex","getValueLabel","unit","getOversoldOverboughtValueLabelsAtIndex","renderOversoldOverbought","zero","drawLines","drawInVisibleAreaProps","fromIndexOffset","getCompensatedFirstBarToRenderIndex","clipHeight","firstIndex","firstFx","renderZeroLine","tickStep","newAttrs","parsePeriodInt","setModel","areNoBarsVisible","getDomainDefaults","inputsErrorMessages","Rvol","Atr","Aro","Mfi","Rmi","Rsi","Stofu","Ult","Macd","Rwi","Trix","Wr","Aroosc","Roc","Cci","Fi","INDICATOR_DEFAULT_DOMAIN","getIsValid","getIsNumberInputValid","integerOnly","isPositiveInteger","pdi","mdi","adx","amdm","apdm","atr","deltaHigh","deltaLow","pdm","mdm","di","getLineColors","lineColors","AroConfig","aroonUp","aroonDown","oscillator","AroonCalculation","highPeriod","highestInPeriod","periodSinceHigh","lastIndexOf","lowPeriod","lowestInPeriod","periodSinceLow","COLORS","aroonCalculation","textLabels","labelSetting","ArooscConfig","ATRConfig","AverageTrueRange","CCIConfig","cci","smaCount","tp","smaSum","devCount","typicalPrice","sma","devSum","dev","COTConfig","cotQuoteCode","cot","commercialHedgers","largeTraders","smallTraders","secondarylabelX","secondarylabel","units","renderAdditionalLabels","fontSettings","FIConfig","fi","FICalculation","fiCalculation","MACDConfig","fastPeriod","slowPeriod","signalPeriod","macd","signal","histogram","MACDCalculation","emaFast","emaSlow","emaSignal","macdCount","macdCalculation","signalLine","MFIConfig","mfi","negativeMoneyFlow","mf","prevTypicalPrice","positiveMoneyFlow","moneyFlow","oldMF","NoneConfig","OBVConfig","Obv","obv","currentObv","PerfConfig","indicatorLabelWidth","hasCachedData","getTickersAndTimeframe","quoteSettings","getFromCacheSync","fetchedData","getAll","firstVisibleBar","lastVisibleBar","lastValueIndex","lastTickerTimestamp","canUseCustomMinMax","domainDefaults","getTickers","getTickerColor","hasBackground","tickerValue","textPosX","textPosY","measuredWidth","isVertical","labelBottom","canFitItemsVertically","tickerTextWidth","performanceIndicatorLabel","crossText","allTickers","hasPatterns","chartUuid","canBeEmptyQuote","getSanitizedTicker","RMIConfig","momentum","rmi","u","ad","au","sumu","sumd","rs","ROCConfig","roc","RSIConfig","rsi","RsiCalculation","rsiCalculation","RVOLConfig","baseLine","DEFAULT_PARAMETERS","rvol","periodStr","parsePeriod","baseLineY","RWIConfig","rwiHi","rwiLo","trSum","atrWeight","maxHi","maxLo","getComputedValuesAtDateIndex","financialAttachmentsData","computedValues","getLastValue","getValueAtDataIndex","vals","shouldShowDate","isBeforeData","valueLabel","FinancialIndicator","dateIndex","timestampToFinancialsIndexesMap","alignedFinancialAttachmentsData","timestampKey","sourceIndexes","alignedData","lastBeforeDateFinancialsDataIndex","si","sharesFloat","sourceIndex","averageVolume","StofaConfig","Stofa","dPeriod","StofuConfig","kPeriod","k1","dCount","dSum","kSum","kCount","highestHigh","lowestLow","Stochastics","StoslConfig","Stosl","TRIXConfig","trix","TrixCalculation","trippleEmaPeriod","ema1","ema2","ema3","ema1Count","ema2Count","ema3Count","trixCalculation","UltConfig","period1","period2","period3","ult","bp","bpSum2","bpSum3","count2","count3","trSum2","trSum3","avg2","avg3","bpSum1","trSum1","count1","avg1","VolConfig","WRConfig","none","aro","aroosc","rwi","stofa","stofu","stosl","vol","wr","shrtfl","shrtra","financialIndicators","getWatchedPropValue","watchedProp","spineObject","getIsSpineObject","hasToObject","getJSONReplacerFunc","getWatchedProps","getAreWatchedPropsEqual","currentValue","previousValue","DEFAULT_SPINE_EVENTS","DefaultSpineEvents","stringifiedOptions","useForceUpdate","watchedPropertiesRef","handleModelChange","isArray","spineEvents","hasMany","getChartType","defaultRefreshInterval","Default","customRefreshInterval","Elite","isStockFastRefreshAvailable","omitKeys","getIsScrollable","perfQuotes","quotePerfTickers","quotePerf","chartOrIndicator","attrsInSync","ChartPartToAttrsSyncMap","modelAttr","chartParts","isInSync","chartPart","isFinancialIndicator","quoteFinancialAttachments","quoteFinancialAttachment","shouldClear","allChartEvents","Crosshair","drawingsInternalStoreModel","chartPartsToSync","newSyncedChartParts","normalizeHexAlpha","hexString","customColors","customColorKeys","defaultColors","chartLightTheme","chartDarkTheme","aftermarketFade","crossTextBackground","gridSecondary","negativeChange","overlayTransparentBackground","positiveChange","premarketFade","indicatorLightTheme","indicatorDarkTheme","elementLightTheme","elementDarkTheme","generalColors","newAutoSaveState","generateUuid","getElementZIndexRange","oldInstance","pane_id","clonedObj","cloned","moveToZIndex","currentZIndex","directionCoef","newZIndex","elementsBelowZero","elementsAboveZero","getBelowAboveZeroElements","changeElementZIndexes","elementsArray","addElement","oldZIndex","isBelowZero","getIsChartType","isOverlay","refreshElementId","MARKET_START","END_OF_DAY","roundTimeForSyncedPane","sourceChart","targetChart","dateToReturn","sourceChartHasPremarket","targetChartHasPremarket","setDate","lastDayOfMonth","lastDayOfWeek","weekStartsOn","endOfDay","getIsDateBeforeMarketStart","getIsCrossSyncOn","getIsMouseInChartOfPane","paneOfMouse","mouseInChart","currentPaneChart","mousePositionTimestamp","currentPanePositionX","getPriceForPane","mousePaneIndex","getIndexInChart","mouse","CHART_EVENT_BADGE_TYPE_ORDER","chartEventElementModel","move","chartPanes","targetPane","currentChartPaneRecords","records","chart_id","ohterChartPaneRecords","targetRecordIndex","arrayWithoutTargetRecord","chartRecordIndex","panesAbove","panesBelow","getNumericId","isSorted","resetHeight","allPaneElements","rebuildElementZIndexes","hoveredChartEvent","openedChartEvent","hoveredTypeChartEventElements","openedTypeChartEventElements","nonActiveChartEventElements","chartEventsOnSameXPoint","chartEvent_B","isOpened","isHoveredType","isOpenType","quoteCache","getCachedQuote","cachedAt","setCachedQuote","computableKeys","tickerRaw","doesQuoteAndFetchParamsMatch","isSameOrNoChartUuid","is404","isNotEmptyQuote","isCacheAllowed","financialAttachment","doesQuoteAndOptionsMatch","shouldUseCache","getResolvedFetchingPromise","numberOfRefreshChecks","premarketLengthMinutes","aftermarketLengthMinutes","patternsMinRange","patternsMaxRange","dataId","maxBars","tickersAndTimeframes","accumulator","fetchRequest","QuoteFetchTypeUrlOption","New","fetchingPromise","getUrl","NotFoundError","getIsAbortError","shouldUseEmptyQuote","Newer","noNewData","newQuoteData","lastTime","afterTime","AIndex","BIndex","mergeIndex","ADate","BDate","prevAIndex","prevDate","newDate","isSameWeek","isSameMonth","warn","thisDateLength","dataDateLength","atts","drawDays","getBarIndexes","alignAllFinancialAttachmentsDataWithQuoteDates","getChartEventsWithId","alignFinancialAttachmentsDataWithQuoteDates","lastDateIndex","firstDate","matchingQuoteTimestamp","parsedDate","convertedDateToNyTimestamp","dateDate","isSameDay","clearCachedData","deleteCachedQuote","cachedHeikinAshiData","HAClose","heikAshiData","cachedDayToOffset","dayToOffset","lastDay","dateStringFromDate","yyyy","mm","dd","padStart","cachedDateToIndex","getTimestampFromPositionX","host","env","BE_API_URL","rev","clearData","largeChartFontSize","INTERACTIVE_CHART_SETTINGS","tickerTimeframeChangeHeight","chartSettings","colorsOverride","settingColors","isLight","getNormalizedZIndex","BaseConfig","Ema","OverlayBaseConfig","BBConfig","Bb","deviations","topColor","bottomColor","upperBand","lowerBand","BbCalculation","stdDev","initialPeriodIndex","stdDevSum","OverlayConfig","getFreeColor","periods","getRGBAValueFromValidColorString","BB_COLORS","TOP","BOTTOM","MIDDLE","BollingerBands","scaledTop","scaledBottom","firstBarToRender","lastBarToRender","bbCalculation","DchConfig","Dch","channelStrokeColor","channelFillColor","medianBandColor","DonchianChannels","medianBand","EMA","EMA2Config","Ema2","EMA2","HILOConfig","Hilo","highColor","lowColor","HighLow","prevHigh","prevLow","prevBar","HLineConfig","Hline","isPositiveFloat","ICConfig","Ic","conversion","spanB","spanAStrokeColor","spanAFillColor","spanBStrokeColor","spanBFillColor","conversionLineColor","baseLineColor","laggingSpanColor","Stroke","Fill","Conversion","Base","SpanB","IchimokuCloud","renderFull","outsideBar","conversionLine","senkouSpanA","senkouSpanB","conversionStartIndex","baseStartIndex","spanBIndex","highestHi","lowestLo","lastSpanAX","lastSpanBX","cloudStartingX","toIndexOffset","fxOverride","ICFConfig","Icf","KCHConfig","Kch","emaPeriod","atrPeriod","strokeColor","fillColor","KeltnerChannel","middleLine","PatternsConfig","Patterns","supportColor","resistColor","originalScale","barsInDay","aboveBelow","textHS","above","below","kind","Calculation","PPConfig","Pp","calculationType","PivotPeriod","PivotPoints","getPeriodType","week","getIsEnoughData","startIndex","endIndex","periodType","dayGap","startDay","beforeDay","calculatedX","fromX","toX","currentDate","previousTradingDay","previousNYMidnightTimestamp","currentMidnight","currentNYMidnightTimestamp","isNonStockFullDay","isStockFullDay","firstDayCurrentWeek","firstDayCurrentWeekTimestamp","firstDayPreviousWeek","firstDayPreviousWeekTimestamp","firstDayCurrentMonth","firstDayCurrentMonthTimestamp","firstDayPreviousMonth","firstDayPreviousMonthTimestamp","firstDayCurrentYear","firstDayCurrentYearTimestamp","firstDayPreviousYear","firstDayPreviousYearTimestamp","pivot","sup1","sup2","sup3","res1","res2","res3","previousHigh","previousLow","pivotPoint","currentX","toBars","nextDate","SARConfig","Sar","maxStep","risingColor","fallingColor","SAR","isLong","sar","ep","newHigh","newLow","af","sarToDraw","customizable","SMAConfig","Sma","SMACalculation","SMA","SMA2Config","Sma2","SMA2","StrConfig","Str","uptrendColor","downtrendColor","Supertrend","finalUpperBand","finalLowerBand","supertrend","avg","VPConfig","Vp","upColor","downColor","VP_COLORS","applyOpacityToColor","VolumeProfile","minClose","maxClose","segment","segments","up","down","segmentIndex","isInSegment","volumeTrend","volumeFX","segmentHeightRaw","segmentHeight","upSegmentWidth","downSegmentWidth","VWAPConfig","Vwap","vwap","VWapCalculation","cumulativePV","cumulativeVolume","second","datesAreOnSameDay","VWAP","bb","dch","hilo","hline","ic","icf","kch","pp","sma2","vp","arg","_len2","_key2","_len3","_key3","devicePixelRatio","getQuoteDateTimestampOffsetInSeconds","referenceDate","dayNumber","monthIndex","previousSunday","getDay","getIsDstInNy","getUTCFullYear","getUTCMonth","getUTCDate","getUTCHours","getUTCMinutes","getUTCSeconds","addOffset","quoteDateTimeOffsetInMs","localTimeOffsetInMs","getTimezoneOffset","offsetDirectionCoefficient","setTime","bufferMinutes","dayOfWeek","currentDayMinutes","premarketMinutes","aftermarketMinutes","isWeekend","isClosed","setUTCSeconds","dateFromDateString","testTouchPoints","isMobileOs","navigator","userAgent","createEvent","match","msMaxTouchPoints","maxTouchPoints","matchesIPad","matchesIPhone","matchesIPod","re","RegExp","cookie","toUTCString","fullscreenElement","webkitFullscreenElement","mozFullScreenElement","msFullscreenElement","webkitRequestFullScreen","mozRequestFullScreen","msRequestFullscreen","webkitExitFullscreen","mozExitFullScreen","msExitFullscreen","fn","readyState","chartElementId","box","matchingPages","requestsAbortControllersCache","abortRequest","controller","websiteShared","shouldUseCPUOnly","matchesAndroid","matchesWebOS","matchesiPad","matchesBlackBerry","matchesWindowsPhone","matchesIOSLike","isMobileDevice","isFirefoxDesktop","getContext","willReadFrequently","_cache","_restore","CanvasRenderingContext2D","getChartEventBadgeColors","outerStroke","innerStroke","innerFill","textFill","getFormattedEventDate","exdate","hasEarningsDateSuffix","formattedDate","formatDateToStringUS","getEarningsDateSuffix","getFormattedValue","bigNumberUnit","maxDecimalPlaces","numberString","bigNumber","substring","wholeNumber","decimalNumber","formattedDecimalNumber","getChartEventBageColors","twColors","chartLayoutSettings","isXPointVisible","renderXAxisLabels","labels","allowedOverflow","sortedLabels","renderedLabelRanges","newLabel","hasPriority","halfOfTextWidth","overflowLeft","overflowRight","labelX","getIsOverlapping","getSize","paddingX","paddingY","render15MinXAxis","startBarIndex","endBarIndex","indexOffset","SMALL_INDEX_CHART_LABEL_BUFFER","renderIntradayXAxis","marketStartHour","marketEndHour","dayIndex","roundedX","renderTimeframeXAxisProps","lastHours","renderIntradayXAxisFutures","renderDailyXAxis","isYearLabel","renderWeeklyXAxis","lastYear","isJanuary","renderMonthlyXAxis","n0","n1","x0","DAY_IN_SECONDS","TWO_MIN_IN_MS","virtualDatesCache","areTimestampsFromSameDay","ts1","ts2","ts1Utc","ts2Utc","getVirtualDatesCacheId","idRevision","setCachedVirtualDates","fromSeconds","toSeconds","virtualDates","virtualDatesCacheId","lastUsed","checkVirtualCacheSize","MAX_BAR_BORDER_WIDTH","MIN_BAR_MARGIN_WIDTH","MAX_BAR_MARGIN_WIDTH","settingsCenter","barMarginWidth","shouldRound","roundDecimalPlaces","halfBarWidthRaw","DEFAULT_ZOOM_GUESS_INCREMENT","zoomFactorForBarsToDisplayCache","zoomFactorForBarsToDisplayCacheKeys","getZoomFactorFromCache","setZoomFactorToCache","poppedKey","defaultBarWidthWithMargin","zoomIncrement","finalZoomFactor","iteration","barWidthDiff","getTimeframeSeconds","lowerIndex","upperIndex","isWithinRangeOfQuoteDate","commonVirtualCacheProps","cachedDates","virtualDateSeconds","getCachedVirtualDates","timeframeSeconds","numOfDatesBefore","numOfDatesAfter","virtualTradedDays","dateStartSeconds","dateEndSeconds","datesSeconds","isStartBeforeDates","isEndAfterDates","dateTime","getVirtualTradedDays","marketStartSeconds","barTimeframeSeconds","quoteDatesTimestampOffset","dayStartSeconds","barSeconds","virtualTimeframeTradedDates","isLowerBounded","isOneBeforeLowerBoundStarts","isLookingBack","averageBarDate","numOfSecondsOutOfBounds","perfIndicatorElement","getPerfIndicatorTickerAndTimeframes","resolve","_ref17","isXAxisInView","domainRange","priceFy","YAxisLeftMargin","firstBarClose","_ref18","_ref19","_ref20","changePercent","changePercentString","_ref21","isForexFuturesCryptoPage","_ref22","isForexFuturesCrypto","isOffscreenChartWithNarrowBars","_ref23","_ref24","hexStringToRGBA","hexColor","removeHashSymbol","g","rgbaToHexString","alpha","alphaToHex","rgbaToHSVA","hsvaToRGBA","rgbaToRGBAString","rgbaStringToObject","colorParts","exec","red","green","strColor","allowAlpha","getIsRgb","rgbKeys","output","canSelectAlpha","hsvaToHEXString","dataBarIndex","isBarVisible","object","formData","append","FormData","statusCode","throwOnPredicate","url","credentials","headers","responseContentType","Html","responseData","ApplicationJsonUTF","FormUrlEncoded","parseResponseForContentType","getStatusCodeError","forceUpdateKey","increment","precision","periodString","part","parsedNumber","MAX_SAFE_INTEGER","visited","WeakSet","toLocaleDateString","crypto","randomUUID","getRandomValues","Uint8Array","two","local","remote","useChartLayoutGlobalModelModule","useChartLayoutGlobalModel"],"sourceRoot":""}