{"version":3,"file":"255.15fd83e0.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/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/modules/create-alert/async-modules.ts","webpack://@finviz/website/./js/main/modules/save-to-portfolio/async-modules.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/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/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/atr.ts","webpack://@finviz/website/../charts/app/indicator-calculation/ema.ts","webpack://@finviz/website/../charts/app/indicator-calculation/main.ts","webpack://@finviz/website/../charts/app/indicator-calculation/sma.ts","webpack://@finviz/website/../charts/app/indicators/configs/atr.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/indicator-calculation/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/atr.ts","webpack://@finviz/website/../charts/app/indicators/configs/cci.ts","webpack://@finviz/website/../charts/app/indicator-calculation/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/indicator-calculation/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/indicator-calculation/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/indicator-calculation/rmi.ts","webpack://@finviz/website/../charts/app/indicators/rmi.ts","webpack://@finviz/website/../charts/app/indicators/configs/roc.ts","webpack://@finviz/website/../charts/app/indicator-calculation/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/indicator-calculation/rvol.ts","webpack://@finviz/website/../charts/app/indicators/rvol.ts","webpack://@finviz/website/../charts/app/indicators/configs/rwi.ts","webpack://@finviz/website/../charts/app/indicator-calculation/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/indicator-calculation/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/indicator-calculation/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/indicator-calculation/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/sma.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/indicator-calculation/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/indicator-calculation/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/indicator-calculation/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/indicator-calculation/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/indicator-calculation/pp.ts","webpack://@finviz/website/../charts/app/overlays/pp.ts","webpack://@finviz/website/../charts/app/overlays/configs/sar.ts","webpack://@finviz/website/../charts/app/indicator-calculation/sar.ts","webpack://@finviz/website/../charts/app/overlays/sar.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/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/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 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 './main/modules/create-alert/async-modules'\r\nexport { saveToPortfolioAsyncModule } from './main/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\nexport { getCurrency } from './app/crypto/currencyUtils'\r\n\r\nexport const assets = { logo, logo_light }\r\n","export const createAlertAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"create-alert\" */ './DialogContent'),\r\n cacheKey: 'create-alert',\r\n}\r\n","export const saveToPortfolioAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"save-to-portfolio\" */ './DialogContent'),\r\n cacheKey: 'save-to-portfolio',\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

(Component: React.ComponentType

, fallback: React.ReactNode = null) {\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, weight: '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, weight: '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, weight: '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, weight: '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?: 'normal' | 'italic'\r\n weight?: 'normal' | 'bold' | '900'\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 TextAttrs,\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 { IChartSettings, 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 initTickerText(chartSettings: IChartSettings) {\r\n const { Colors } = chartSettings.general\r\n const text = this.data.name || this.data.ticker\r\n const isSmallIndexChart = getIsSmallIndexChart(this.specificChartFunctionality)\r\n const font: TextAttrs['font'] = isSmallIndexChart\r\n ? { size: FONT_SIZE.L, weight: 'bold' }\r\n : Text.getMergedPropsWithDefaults('font', chartSettings.top.ticker.font)\r\n this.tickerText = new Text(\r\n {\r\n text,\r\n x: chartSettings.top.ticker.margin.left,\r\n y: chartSettings.top.ticker.margin.top,\r\n fillStyle: Colors.text,\r\n font,\r\n ...(!isSmallIndexChart ? { textBaseline: chartSettings.top.baseline } : {}),\r\n },\r\n this.paneModel\r\n )\r\n }\r\n\r\n renderText(context: CanvasRenderingContext2D) {\r\n const { ChartSettings, isOurSiteRequest } = this.getChartLayoutSettings()\r\n context.save()\r\n context.translate(ChartSettings.left.width, 0)\r\n\r\n this.initTickerText(ChartSettings)\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, weight: '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, weight: '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 const volumes = areNoBarsVisible\r\n ? [this.data.volume[firstBarToRenderIndex.dataIndex], this.data.volume[lastBarToRenderIndex.dataIndex]]\r\n : this.data.volume.slice(firstBarToRenderIndex.dataIndex, lastBarToRenderIndex.dataIndex + 1)\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.dataIndex]\r\n max = this.data.high[lastBarToRenderIndex.dataIndex]\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.dataIndex]\r\n } else {\r\n for (let i = firstBarToRenderIndex.dataIndex; i <= lastBarToRenderIndex.dataIndex; 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.dataIndex]\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, weight: '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, weight: '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, weight: '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","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 TickerSearch,\r\n createAlertAsyncModule,\r\n getCurrency,\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}&c=${getCurrency(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(model, 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 } 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 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 PaneModel from '../models/pane'\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(paneModel: PaneModel, quoteModel: QuoteModel) {\r\n const element = paneModel.getChartOrIndicatorElement()\r\n let altText = `${quoteModel.name || quoteModel.ticker} - `\r\n if (element?.isIndicator()) {\r\n altText += `${element.instance.seoLabel} Indicator`\r\n } else {\r\n altText += `${getInstrumentLabel(quoteModel.instrument)} Price Chart`\r\n }\r\n return altText\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 { 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 { ATRConfig, Options } from '../indicators/configs/atr'\r\nimport utils from '../utils'\r\nimport { MainCalculation } from './main'\r\n\r\nexport function getTrueRange(high: number, low: number, prevClose?: number) {\r\n return prevClose !== undefined\r\n ? utils.max([high - low, Math.abs(high - prevClose), Math.abs(low - prevClose)])\r\n : high - low\r\n}\r\n\r\nexport class 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 = getTrueRange(high, 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\ntype DefaultCalculatedValuesType = {\r\n atr: number[]\r\n}\r\n\r\nexport class ATRCalculation extends MainCalculation {\r\n static config = ATRConfig\r\n\r\n calculate() {\r\n const { period } = this.options\r\n const { close, high, low } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n if (close.length < period) return\r\n\r\n const atr = new AverageTrueRange(period)\r\n for (let i = 0; i < close.length; i++) {\r\n atr.add(high[i], low[i], close[i - 1])\r\n\r\n if (i < period - 1) continue\r\n\r\n this._calculatedValues.atr[i] = atr.value\r\n }\r\n }\r\n}\r\n","import { EMAConfig, Options } from '../overlays/configs/ema'\r\nimport { MainCalculation } 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() {\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 }\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 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() {\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 { Options, SMAConfig } from '../overlays/configs/sma'\r\nimport { MainCalculation } from './main'\r\n\r\nexport class SimpleMovingAverage {\r\n period: number\r\n sum: number\r\n count: number\r\n value: number\r\n trailingValues: 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 this.trailingValues = []\r\n }\r\n\r\n add(value: number) {\r\n if (this.count < this.period) {\r\n this.sum += value\r\n this.count++\r\n this.trailingValues.push(value)\r\n if (this.count === this.period) this.value = this.sum / this.period\r\n } else {\r\n const firstTrailingValue = this.trailingValues.shift() ?? 0\r\n this.sum = this.sum - firstTrailingValue + value\r\n this.value = this.sum / this.period\r\n this.trailingValues.push(value)\r\n }\r\n }\r\n}\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() {\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 const sma = new SimpleMovingAverage(period)\r\n for (let i = 0; i < close.length; i++) {\r\n sma.add(close[i])\r\n if (i >= period - 1) {\r\n this._calculatedValues.sma[i] = sma.value\r\n }\r\n }\r\n }\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 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 static calculatedValuesOrder = ['atr'] as const\r\n static calculatedValuesLabels = { atr: 'ATR' }\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 { 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 seoLabel: string | null = null\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 seoLabel = 'Short Interest, 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 seoLabel = 'Short Interest, 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 static calculatedValuesOrder = ['adx', 'pdi', 'mdi'] as const\r\n static calculatedValuesLabels = { adx: 'ADX', pdi: '+DI', mdi: '-DI' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { ADXConfig, Attrs } from '../indicators/configs/adx'\r\nimport { getTrueRange } from './atr'\r\nimport { MainCalculation } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n /**\r\n * Average Directional Index\r\n */\r\n adx: number[]\r\n /**\r\n * Plus Directional Indicator\r\n */\r\n pdi: number[]\r\n /**\r\n * Minus Directional Indicator\r\n */\r\n mdi: number[]\r\n}\r\n\r\nfunction getDX(pdi: number, mdi: number) {\r\n return (Math.abs(pdi - mdi) / Math.abs(pdi + mdi)) * 100\r\n}\r\n\r\nexport class ADXCalculation extends MainCalculation {\r\n static config = ADXConfig\r\n\r\n calculate() {\r\n const { period } = this.options\r\n const { high, low, close } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n /**\r\n * Smoothed Average True Range\r\n */\r\n const sATR: number[] = []\r\n let firstAtrAccumulator = 0\r\n /**\r\n * Smoothed Plus Directional Movement\r\n */\r\n const sPDM: number[] = []\r\n let firstPdmAccumulator = 0\r\n /**\r\n * Smoothed Minus Directional Movement\r\n */\r\n const sMDM: number[] = []\r\n let firstMdmAccumulator = 0\r\n /**\r\n * Directional Index\r\n */\r\n const dx: number[] = []\r\n\r\n /**\r\n * First ADX: Sum of n periods of TR\r\n */\r\n let firstAdxAccumulator = 0\r\n\r\n // Not enough data for calculation\r\n if (close.length < period + 1) return\r\n\r\n for (let i = 1; i < close.length; i++) {\r\n const tr = getTrueRange(high[i], low[i], close[i - 1])\r\n\r\n const upMove = high[i] - high[i - 1]\r\n const downMove = low[i - 1] - low[i]\r\n\r\n const plusDM = upMove > downMove && upMove > 0 ? upMove : 0\r\n const minusDM = downMove > upMove && downMove > 0 ? downMove : 0\r\n\r\n if (i <= period) {\r\n firstAtrAccumulator += tr\r\n firstPdmAccumulator += plusDM\r\n firstMdmAccumulator += minusDM\r\n if (i === period) {\r\n // First value of smoothed ATR/PDM/MDM is just SUM of n periods\r\n sATR[i] = firstAtrAccumulator\r\n sPDM[i] = firstPdmAccumulator\r\n sMDM[i] = firstMdmAccumulator\r\n this._calculatedValues.pdi[period] = (sPDM[i] / sATR[i]) * 100\r\n this._calculatedValues.mdi[period] = (sMDM[i] / sATR[i]) * 100\r\n dx[i] = getDX(this._calculatedValues.pdi[i], this._calculatedValues.mdi[i])\r\n firstAdxAccumulator = dx[i]\r\n }\r\n continue\r\n }\r\n\r\n sATR[i] = sATR[i - 1] - sATR[i - 1] / period + tr\r\n sPDM[i] = sPDM[i - 1] - sPDM[i - 1] / period + plusDM\r\n sMDM[i] = sMDM[i - 1] - sMDM[i - 1] / period + minusDM\r\n\r\n this._calculatedValues.pdi[i] = (sPDM[i] / sATR[i]) * 100\r\n this._calculatedValues.mdi[i] = (sMDM[i] / sATR[i]) * 100\r\n\r\n dx[i] =\r\n (Math.abs(this._calculatedValues.pdi[i] - this._calculatedValues.mdi[i]) /\r\n Math.abs(this._calculatedValues.pdi[i] + this._calculatedValues.mdi[i])) *\r\n 100\r\n\r\n // Because ADX is double smoothed adx valus start at \"double period index\",\r\n // whole calculation is starting at index 1 because we always compare current with previous\r\n // eg. for period 5:\r\n // first smoothing is from index 1 to 5 becuase 1 to 5 is 5 indexes\r\n // then second smooting is from index 5 to 9 becuase again it is 5 indexes\r\n // thus (period * 2 - 1) === (5 * 2 - 1) => 9\r\n if (i <= period * 2 - 1) {\r\n firstAdxAccumulator += dx[i]\r\n if (i === period * 2 - 1) {\r\n // First ADX is n period average of DX\r\n this._calculatedValues.adx[period * 2 - 1] = firstAdxAccumulator / period\r\n }\r\n continue\r\n }\r\n\r\n this._calculatedValues.adx[i] = (this._calculatedValues.adx[i - 1] * (period - 1) + dx[i]) / period\r\n }\r\n }\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 seoLabel() {\r\n return (this.constructor as typeof Indicator).config.seoLabel ?? this.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 weight: '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.dataIndex; i <= lastBarToRenderIndex.dataIndex; 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 { ADXCalculation } from '../indicator-calculation/adx'\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 declare adxCalculation: ADXCalculation\r\n\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.adxCalculation = new ADXCalculation({\r\n quote: this.data,\r\n options: { period: this.period },\r\n })\r\n\r\n this.adxCalculation.calculate()\r\n this.lastValue = this.adxCalculation.calculatedValues.adx.last() ?? null\r\n }\r\n const { min, max } =\r\n this.adxCalculation.calculatedValues.pdi.length > 0 ||\r\n this.adxCalculation.calculatedValues.mdi.length > 0 ||\r\n this.adxCalculation.calculatedValues.adx.length > 0\r\n ? this.computeVisibleMinMax(\r\n this.adxCalculation.calculatedValues.pdi,\r\n this.adxCalculation.calculatedValues.mdi,\r\n this.adxCalculation.calculatedValues.adx\r\n )\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.adxCalculation.calculatedValues.pdi[dataIndex]) },\r\n { color: lineColors.mdi, text: this.getValueLabel(this.adxCalculation.calculatedValues.mdi[dataIndex]) },\r\n { color: lineColors.adx, text: this.getValueLabel(this.adxCalculation.calculatedValues.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.adxCalculation.calculatedValues.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.adxCalculation.calculatedValues.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.adxCalculation.calculatedValues.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 } 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() {\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 }\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 { ATRCalculation } from '../indicator-calculation/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 declare atrCalculation: ATRCalculation\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.atrCalculation === null) {\r\n this.atrCalculation = new ATRCalculation({\r\n quote: this.data,\r\n options: { period: this.period },\r\n })\r\n\r\n this.atrCalculation.calculate()\r\n this.lastValue = this.atrCalculation.calculatedValues.atr.last() ?? null\r\n }\r\n const { min, max } =\r\n this.atrCalculation.calculatedValues.atr.length > 0\r\n ? this.computeVisibleMinMax(this.atrCalculation.calculatedValues.atr)\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 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.atrCalculation.calculatedValues.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.atrCalculation.calculatedValues.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 static calculatedValuesOrder = ['cci'] as const\r\n static calculatedValuesLabels = {\r\n cci: 'CCI',\r\n }\r\n\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { Attrs, CCIConfig } from '../indicators/configs/cci'\r\nimport { MainCalculation } from './main'\r\nimport { SimpleMovingAverage } from './sma'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n cci: number[]\r\n}\r\nconst constant = 0.015\r\n\r\nexport class CCICalculation extends MainCalculation {\r\n static config = CCIConfig\r\n\r\n calculate() {\r\n const { period } = this.options\r\n const { high, low, close } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n if (close.length < period) return\r\n\r\n const typicalPrice = []\r\n const tpSma = new SimpleMovingAverage(period)\r\n\r\n for (let i = 0; i < close.length; i++) {\r\n typicalPrice[i] = (close[i] + low[i] + high[i]) / 3\r\n\r\n tpSma.add(typicalPrice[i])\r\n\r\n if (i < period - 1) {\r\n continue\r\n }\r\n\r\n let devSum = 0\r\n for (let j = i - period + 1; j <= i; j++) {\r\n devSum += Math.abs(typicalPrice[j] - tpSma.value)\r\n }\r\n\r\n const dev = devSum / period\r\n this._calculatedValues.cci[i] = 0\r\n if (dev > 0) {\r\n this._calculatedValues.cci[i] = (typicalPrice[i] - tpSma.value) / (constant * dev)\r\n }\r\n }\r\n }\r\n}\r\n","import { CCICalculation } from '../indicator-calculation/cci'\r\nimport { Attrs, CCIConfig } from './configs/cci'\r\nimport Indicator from './indicator'\r\n\r\nclass CommodityChannelIndex extends Indicator {\r\n static config = CCIConfig\r\n\r\n declare cciCalculation: CCICalculation\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.cciCalculation = new CCICalculation({\r\n quote: this.data,\r\n options: { period: this.period },\r\n })\r\n\r\n this.cciCalculation.calculate()\r\n this.lastValue = this.cciCalculation.calculatedValues.cci.last() ?? null\r\n }\r\n\r\n const { min, max } =\r\n this.cciCalculation.calculatedValues.cci.length > 0\r\n ? this.computeVisibleMinMax(this.cciCalculation.calculatedValues.cci)\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 return this.getOversoldOverboughtValueLabelsAtIndex(index, this.cciCalculation.calculatedValues.cci)\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.cciCalculation.calculatedValues.cci, this.period - 1, -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, weight: '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 weight: '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, weight: '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 } 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() {\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 }\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 } 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() {\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 }\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 static calculatedValuesOrder = ['mfi'] as const\r\n static calculatedValuesLabels = { mfi: 'MFI' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { Attrs, MFIConfig } from '../indicators/configs/mfi'\r\nimport { MainCalculation } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n mfi: number[]\r\n}\r\n\r\nexport class MFICalculation extends MainCalculation {\r\n static config = MFIConfig\r\n\r\n calculate() {\r\n const { period } = this.options\r\n const { high, low, close, volume } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n if (close.length <= period) return\r\n\r\n const typicalPrice: number[] = []\r\n const moneyFlow: number[] = []\r\n // + && - rolling sum means sum of money flows in interval (i-period, i)\r\n let positiveMoneyFlowRollingSum = 0\r\n let negativeMoneyFlowRollingSum = 0\r\n for (let i = 0; i < close.length; i++) {\r\n typicalPrice[i] = (close[i] + low[i] + high[i]) / 3\r\n\r\n if (i === 0) continue\r\n\r\n const currentMoneyFlow = typicalPrice[i] * volume[i]\r\n\r\n // while i < period increment money flow period sums\r\n if (typicalPrice[i] > typicalPrice[i - 1]) {\r\n positiveMoneyFlowRollingSum += currentMoneyFlow\r\n moneyFlow[i] = currentMoneyFlow\r\n } else if (typicalPrice[i] < typicalPrice[i - 1]) {\r\n negativeMoneyFlowRollingSum += currentMoneyFlow\r\n moneyFlow[i] = -currentMoneyFlow\r\n }\r\n\r\n if (i < period) continue\r\n\r\n // from the point when we have n = period data calculated\r\n // we keep sum as period rolling sum\r\n const oldMoneyFlow = moneyFlow[i - period]\r\n if (oldMoneyFlow > 0) {\r\n positiveMoneyFlowRollingSum -= oldMoneyFlow\r\n } else if (oldMoneyFlow < 0) {\r\n negativeMoneyFlowRollingSum += oldMoneyFlow\r\n }\r\n\r\n // and are able to calculate first mfi value\r\n this._calculatedValues.mfi[i] = 100 - 100 / (1 + positiveMoneyFlowRollingSum / negativeMoneyFlowRollingSum)\r\n }\r\n }\r\n}\r\n","import { MFICalculation } from '../indicator-calculation/mfi'\r\nimport { 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 declare mfiCalculation: MFICalculation\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 this.mfiCalculation = new MFICalculation({\r\n quote: this.data,\r\n options: { period: this.period },\r\n })\r\n\r\n this.mfiCalculation.calculate()\r\n\r\n this.lastValue = this.mfiCalculation.calculatedValues.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.mfiCalculation.calculatedValues.mfi)\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.mfiCalculation.calculatedValues.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 static calculatedValuesOrder = ['obv'] as const\r\n static calculatedValuesLabels = { obv: 'OBV' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { OBVConfig } from '../indicators/configs/obv'\r\nimport { MainCalculation } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n obv: number[]\r\n}\r\n\r\nexport class OBVCalculation extends MainCalculation {\r\n static config = OBVConfig\r\n\r\n calculate() {\r\n const { close, volume } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n for (let i = 1; i < close.length; i++) {\r\n let currentObv = this._calculatedValues.obv[i - 1] ?? 0\r\n if (close[i] > close[i - 1]) {\r\n currentObv += volume[i]\r\n } else if (close[i] < close[i - 1]) {\r\n currentObv -= volume[i]\r\n }\r\n\r\n this._calculatedValues.obv[i] = currentObv\r\n }\r\n }\r\n}\r\n","import math from '../helpers/math'\r\nimport { OBVCalculation } from '../indicator-calculation/obv'\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 declare obvCalculation: OBVCalculation\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.obvCalculation = new OBVCalculation({\r\n quote: this.data,\r\n options: undefined,\r\n })\r\n\r\n this.obvCalculation.calculate()\r\n\r\n this.lastValue = this.obvCalculation.calculatedValues.obv.last() ?? null\r\n }\r\n const { min, max } =\r\n this.obvCalculation.calculatedValues.obv.length > 0\r\n ? this.computeVisibleMinMax(this.obvCalculation.calculatedValues.obv)\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 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.obvCalculation.calculatedValues.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.obvCalculation.calculatedValues.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 weight: '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\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 static calculatedValuesOrder = ['rmi'] as const\r\n static calculatedValuesLabels = { rmi: 'RMI' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { Attrs, RMIConfig } from '../indicators/configs/rmi'\r\nimport { MainCalculation } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n rmi: number[]\r\n}\r\n\r\nexport class RMICalculation extends MainCalculation {\r\n static config = RMIConfig\r\n\r\n calculate() {\r\n const { period, momentum } = this.options\r\n const { close } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n if (close.length < momentum + period) return\r\n\r\n let sumUp = 0\r\n let sumDown = 0\r\n let averageDown: number, averageUp: number\r\n\r\n for (let i = momentum; i < close.length; i++) {\r\n let upChange = 0\r\n let downChange = 0\r\n if (close[i] > close[i - momentum]) {\r\n upChange = close[i] - close[i - momentum]\r\n }\r\n if (close[i] < close[i - momentum]) {\r\n downChange = close[i - momentum] - close[i]\r\n }\r\n\r\n if (i - momentum < period) {\r\n sumUp += upChange\r\n sumDown += downChange\r\n averageUp = sumUp / (i - momentum + 1)\r\n averageDown = sumDown / (i - momentum + 1)\r\n } else {\r\n averageUp = (averageUp! * (period - 1) + upChange) / period\r\n averageDown = (averageDown! * (period - 1) + downChange) / period\r\n }\r\n\r\n if (i < period + momentum - 1) continue\r\n this._calculatedValues.rmi[i] =\r\n averageDown === 0 ? 100 : averageUp === 0 ? 0 : 100 - 100 / (1 + averageUp / averageDown)\r\n }\r\n }\r\n}\r\n","import { RMICalculation } from '../indicator-calculation/rmi'\r\nimport { 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 declare rmiCalculation: RMICalculation\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.rmiCalculation = new RMICalculation({\r\n quote: this.data,\r\n options: { period: this.period, momentum: this.momentum },\r\n })\r\n\r\n this.rmiCalculation.calculate()\r\n\r\n this.lastValue = this.rmiCalculation.calculatedValues.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.rmiCalculation.calculatedValues.rmi)\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(\r\n context,\r\n this.rmiCalculation.calculatedValues.rmi,\r\n this.momentum + this.period - 1,\r\n 30,\r\n 50,\r\n 70\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 ?? 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 static calculatedValuesOrder = ['roc'] as const\r\n static calculatedValuesLabels = { roc: 'ROC' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { Attrs, ROCConfig } from '../indicators/configs/roc'\r\nimport { MainCalculation } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n roc: number[]\r\n}\r\n\r\nexport class ROCCalculation extends MainCalculation {\r\n static config = ROCConfig\r\n\r\n calculate() {\r\n const { period } = this.options\r\n const { close } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n for (let i = period; i < close.length; i++) {\r\n this._calculatedValues.roc[i] = ((close[i] - close[i - period]) / close[i - period]) * 100\r\n }\r\n }\r\n}\r\n","import Line from '../canvas/line'\r\nimport { ROCCalculation } from '../indicator-calculation/roc'\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 declare rocCalculation: ROCCalculation\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.rocCalculation = new ROCCalculation({\r\n quote: this.data,\r\n options: { period: this.period },\r\n })\r\n\r\n this.rocCalculation.calculate()\r\n\r\n this.lastValue = this.rocCalculation.calculatedValues.roc.last() ?? null\r\n }\r\n const { min, max } =\r\n this.rocCalculation.calculatedValues.roc.length > 0\r\n ? this.computeVisibleMinMax(this.rocCalculation.calculatedValues.roc)\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 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.rocCalculation.calculatedValues.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 fromIndexOffset: this.period,\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.rocCalculation.calculatedValues.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 } from './main'\r\nimport { RMICalculation } from './rmi'\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() {\r\n const { period } = this.options\r\n\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n const rmiCalculation = new RMICalculation({\r\n quote: this.quote,\r\n options: { period: period, momentum: 1 },\r\n })\r\n\r\n rmiCalculation.calculate()\r\n this._calculatedValues.rsi = rmiCalculation.calculatedValues.rmi\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\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 static calculatedValuesOrder = ['rvol'] as const\r\n static calculatedValuesLabels = { rvol: 'RVOL' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { Attrs, RVOLConfig } from '../indicators/configs/rvol'\r\nimport { MainCalculation } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n rvol: number[]\r\n}\r\n\r\nexport class RVOLCalculation extends MainCalculation {\r\n static config = RVOLConfig\r\n\r\n calculate() {\r\n const { period } = this.options\r\n const { volume } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n if (volume.length < period) return\r\n\r\n let sum = 0\r\n for (let i = 0; i < volume.length; i++) {\r\n sum += volume[i] - (volume[i - period] ?? 0)\r\n if (i < period - 1) continue\r\n this._calculatedValues.rvol[i] = sum > 0 ? volume[i] / (sum / period) : 0\r\n }\r\n }\r\n}\r\n","import Line from '../canvas/line'\r\nimport { RVOLCalculation } from '../indicator-calculation/rvol'\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 declare rvolCalculation: RVOLCalculation\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.rvolCalculation = new RVOLCalculation({\r\n quote: this.data,\r\n options: { period: this.period, baseLine: this.baseLine },\r\n })\r\n\r\n this.rvolCalculation.calculate()\r\n\r\n this.lastValue = this.rvolCalculation.calculatedValues.rvol.last() ?? null\r\n }\r\n\r\n const { min, max } =\r\n this.rvolCalculation.calculatedValues.rvol.length > 0\r\n ? this.computeVisibleMinMax([...this.rvolCalculation.calculatedValues.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.rvolCalculation.calculatedValues.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.rvolCalculation.calculatedValues.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.rvolCalculation.calculatedValues.rvol[i]))\r\n\r\n context.set(\r\n 'fillStyle',\r\n this.rvolCalculation.calculatedValues.rvol[i] < this.baseLine ? Colors.volumeTrendDown : Colors.volumeTrendUp\r\n )\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 static calculatedValuesOrder = ['rwiHigh', 'rwiLow'] as const\r\n static calculatedValuesLabels = { rwiHigh: 'RWI High', rwiLow: 'RWI Low' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { Attrs, RWIConfig } from '../indicators/configs/rwi'\r\nimport { getTrueRange } from './atr'\r\nimport { MainCalculation } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n rwiHigh: number[]\r\n rwiLow: number[]\r\n}\r\n\r\nexport class RWICalculation extends MainCalculation {\r\n static config = RWIConfig\r\n\r\n calculate() {\r\n const { period } = this.options\r\n const { high, low, close } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n if (close.length <= period + 2) return\r\n\r\n const tr: number[] = []\r\n\r\n for (let i = 0; i < close.length; i++) {\r\n tr[i] = getTrueRange(high[i], low[i], close[i - 1])\r\n }\r\n\r\n for (let i = period + 2; i < close.length; i++) {\r\n const h = high[i]\r\n const l = low[i]\r\n let trSum = tr[i - 1] + tr[i - 2]\r\n let count = 2\r\n let atrWeight = (trSum / count) * Math.sqrt(count)\r\n let maxHi = atrWeight > 0 ? (h - low[i - 1]) / atrWeight : -1\r\n let maxLo = atrWeight > 0 ? (high[i - 1] - l) / atrWeight : -1\r\n for (let j = i - 1; j > i - period + 1; j--) {\r\n trSum += 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 - low[j - 1]) / atrWeight\r\n if (hi > maxHi) {\r\n maxHi = hi\r\n }\r\n\r\n const lo = (high[j - 1] - l) / atrWeight\r\n if (lo > maxLo) {\r\n maxLo = lo\r\n }\r\n }\r\n this._calculatedValues.rwiHigh[i] = maxHi\r\n this._calculatedValues.rwiLow[i] = maxLo\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 { RWICalculation } from '../indicator-calculation/rwi'\r\nimport Pane from '../models/pane'\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 declare rwiCalculation: RWICalculation\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.rwiCalculation = new RWICalculation({\r\n quote: this.data,\r\n options: { period: this.period },\r\n })\r\n\r\n this.rwiCalculation.calculate()\r\n }\r\n const { min, max } =\r\n this.rwiCalculation.calculatedValues.rwiHigh.length > 0 || this.rwiCalculation.calculatedValues.rwiLow.length > 0\r\n ? this.computeVisibleMinMax(\r\n this.rwiCalculation.calculatedValues.rwiHigh,\r\n this.rwiCalculation.calculatedValues.rwiLow\r\n )\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 rwiLow: '#c80000',\r\n rwiHigh: '#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 {\r\n color: lineColors.rwiLow,\r\n text: this.getValueLabel(this.rwiCalculation.calculatedValues.rwiLow[dataIndex]),\r\n },\r\n {\r\n color: lineColors.rwiHigh,\r\n text: this.getValueLabel(this.rwiCalculation.calculatedValues.rwiHigh[dataIndex]),\r\n },\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.rwiCalculation.calculatedValues.rwiLow[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.rwiCalculation.calculatedValues.rwiHigh[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.rwiCalculation.calculatedValues.rwiLow.length > 0) {\r\n textLabels.push({\r\n text: this.rwiCalculation.calculatedValues.rwiLow.last()!.toFixed(2),\r\n y: Math.round(this.fy(this.rwiCalculation.calculatedValues.rwiLow.last()!)),\r\n background: '#c80000',\r\n })\r\n }\r\n if (this.rwiCalculation.calculatedValues.rwiHigh.length > 0) {\r\n textLabels.push({\r\n text: this.rwiCalculation.calculatedValues.rwiHigh.last()!.toFixed(2),\r\n y: Math.round(this.fy(this.rwiCalculation.calculatedValues.rwiHigh.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: 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 static calculatedValuesOrder = ['k', 'd'] as const\r\n static calculatedValuesLabels = { k: '%K', d: '%D' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\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 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 static calculatedValuesOrder = ['k', 'd'] as const\r\n static calculatedValuesLabels = { k: '%K', d: '%D' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { Attrs, StofuConfig } from '../indicators/configs/stofu'\r\nimport { MainCalculation } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n k: number[]\r\n d: number[]\r\n}\r\n\r\nexport function getFirstKAndDIndex({ period, dPeriod, kPeriod }: { period: number; dPeriod: number; kPeriod: number }) {\r\n const firstKIndex = period - 2 + kPeriod\r\n return { firstKIndex, firstDIndex: firstKIndex + dPeriod - 1 }\r\n}\r\n\r\nexport class StofuCalculation extends MainCalculation {\r\n static config = StofuConfig\r\n\r\n calculate() {\r\n const { period, dPeriod, kPeriod } = this.options\r\n const { high, low, close } = this.quote\r\n\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n const { firstKIndex, firstDIndex } = getFirstKAndDIndex({ period: period, kPeriod, dPeriod })\r\n\r\n if (firstDIndex < firstKIndex || [period, dPeriod, kPeriod].some((i) => i > close.length - 1)) return\r\n\r\n let dCount, dSum, k\r\n const k1Arr = []\r\n const dArr = []\r\n const kArr = []\r\n\r\n let kSum = (dSum = 0)\r\n let kCount = (dCount = 0)\r\n for (let i = 0; i < close.length; i++) {\r\n let highestHigh = high[i]\r\n let lowestLow = low[i]\r\n\r\n for (let j = i - period + 1; j <= i; j++) {\r\n if (high[j] > highestHigh) {\r\n highestHigh = high[j]\r\n }\r\n if (low[j] < lowestLow) {\r\n lowestLow = low[j]\r\n }\r\n }\r\n\r\n k = ((close[i] - lowestLow) / (highestHigh - lowestLow)) * 100\r\n if (highestHigh === lowestLow) {\r\n k = 100\r\n }\r\n k1Arr[i] = k\r\n if (kPeriod > 1) {\r\n kSum += k\r\n kCount++\r\n if (kCount > kPeriod) {\r\n kSum -= k1Arr[i - 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 > dPeriod) {\r\n dSum -= kArr[i - dPeriod]\r\n dCount--\r\n }\r\n\r\n kArr[i] = k\r\n dArr[i] = dSum / dCount\r\n\r\n if (i >= firstKIndex) {\r\n this._calculatedValues.k[i] = kArr[i]\r\n if (i >= firstDIndex) {\r\n this._calculatedValues.d[i] = dArr[i]\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","import Line from '../canvas/line'\r\nimport { StofuCalculation, getFirstKAndDIndex } from '../indicator-calculation/stofu'\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 declare kPeriod: number\r\n declare period: number\r\n declare dPeriod: number\r\n declare stofuCalculation: StofuCalculation\r\n declare firstKIndex: number\r\n declare firstDIndex: number\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period = 0, dPeriod = 0, kPeriod = 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 this.stofuCalculation = new StofuCalculation({\r\n quote: this.data,\r\n options: { period: this.period, dPeriod: this.dPeriod, kPeriod: this.kPeriod },\r\n })\r\n\r\n this.stofuCalculation.calculate()\r\n\r\n const { firstKIndex, firstDIndex } = getFirstKAndDIndex({\r\n period: this.period,\r\n kPeriod: this.kPeriod,\r\n dPeriod: this.dPeriod,\r\n })\r\n this.firstKIndex = firstKIndex\r\n this.firstDIndex = firstDIndex\r\n\r\n this.lastValue = this.stofuCalculation.calculatedValues.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.stofuCalculation.calculatedValues.k[dataIndex]) },\r\n { color: lineColors.d, text: this.getValueLabel(this.stofuCalculation.calculatedValues.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 }\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n fromIndexOffset: this.firstKIndex,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.stofuCalculation.calculatedValues.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 fromIndexOffset: this.firstDIndex,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.stofuCalculation.calculatedValues.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: 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 } 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() {\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 }\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 static calculatedValuesOrder = ['ult'] as const\r\n static calculatedValuesLabels = { ult: 'Ultimate Oscillator' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { Options, UltConfig } from '../indicators/configs/ult'\r\nimport { MainCalculation } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n ult: number[]\r\n}\r\n\r\nexport class UltCalculation extends MainCalculation {\r\n static config = UltConfig\r\n\r\n calculate() {\r\n const { period1, period2, period3 } = this.options\r\n const { high, low, close } = this.quote\r\n const maxPeriod = Math.max(period1, period2, period3)\r\n\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n if (close.length - 1 < maxPeriod) return\r\n\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\r\n for (let i = 1; i < close.length; i++) {\r\n bp[i] = close[i] - Math.min(low[i], close[i - 1])\r\n tr[i] = Math.max(high[i], close[i - 1]) - Math.min(low[i], close[i - 1])\r\n\r\n bpSum1 += bp[i]\r\n trSum1 += tr[i]\r\n count1++\r\n if (count1 > period1) {\r\n bpSum1 -= bp[i - period1]\r\n trSum1 -= tr[i - period1]\r\n }\r\n\r\n bpSum2 += bp[i]\r\n trSum2 += tr[i]\r\n count2++\r\n if (count2 > period2) {\r\n bpSum2 -= bp[i - period2]\r\n trSum2 -= tr[i - period2]\r\n }\r\n\r\n bpSum3 += bp[i]\r\n trSum3 += tr[i]\r\n count3++\r\n if (count3 > period3) {\r\n bpSum3 -= bp[i - period3]\r\n trSum3 -= tr[i - 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 if (i >= maxPeriod) this._calculatedValues.ult[i] = (100 * (4 * avg1 + 2 * avg2 + avg3)) / 7\r\n }\r\n }\r\n}\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { UltCalculation } from '../indicator-calculation/ult'\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 declare ultCalculation: UltCalculation\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.ultCalculation = new UltCalculation({\r\n quote: this.data,\r\n options: { period1: this.period1, period2: this.period2, period3: this.period3 },\r\n })\r\n this.ultCalculation.calculate()\r\n\r\n this.lastValue = this.ultCalculation.calculatedValues.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.ultCalculation.calculatedValues.ult)\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(\r\n context,\r\n this.ultCalculation.calculatedValues.ult,\r\n Math.max(this.period1, this.period2, this.period3),\r\n 30,\r\n 50,\r\n 70\r\n )\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 static calculatedValuesOrder = ['r'] as const\r\n static calculatedValuesLabels = { r: '%R' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { Attrs, WRConfig } from '../indicators/configs/wr'\r\nimport { MainCalculation } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n r: number[]\r\n}\r\n\r\nexport class WRCalculation extends MainCalculation {\r\n static config = WRConfig\r\n\r\n calculate() {\r\n const { period } = this.options\r\n const { high, low, close } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n for (let i = period - 1; i < close.length; i++) {\r\n let highestHigh = high[i]\r\n let lowestLow = low[i]\r\n for (let j = i - period + 1; j <= i; j++) {\r\n if (high[j] > highestHigh) {\r\n highestHigh = high[j]\r\n }\r\n if (low[j] < lowestLow) {\r\n lowestLow = low[j]\r\n }\r\n }\r\n\r\n if (i < period - 1) continue\r\n\r\n this._calculatedValues.r[i] = 0\r\n if (highestHigh - lowestLow > 0) {\r\n this._calculatedValues.r[i] = ((highestHigh - close[i]) / (highestHigh - lowestLow)) * -100\r\n }\r\n }\r\n }\r\n}\r\n","import { WRCalculation } from '../indicator-calculation/wr'\r\nimport { 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 declare wrCalculation: WRCalculation\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.wrCalculation = new WRCalculation({\r\n quote: this.data,\r\n options: { period: this.period },\r\n })\r\n this.wrCalculation.calculate()\r\n\r\n this.lastValue = this.wrCalculation.calculatedValues.r.last() ?? null\r\n }\r\n const { min, max } =\r\n this.wrCalculation.calculatedValues.r.length > 0\r\n ? this.computeVisibleMinMax(this.wrCalculation.calculatedValues.r)\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 return this.getOversoldOverboughtValueLabelsAtIndex(index, this.wrCalculation.calculatedValues.r)\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.wrCalculation.calculatedValues.r, this.period - 1, -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 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 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?.isIndicator() && mainElement.instance.type === IndicatorType.Cot) {\r\n return cotKeys.includes(mainElement.instance.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 (element.isChart()) {\r\n return element.instance.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((indicatorElement) => indicatorElement.instance.config.quoteFinancialAttachments)\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 { 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.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 BaseChart from '../charts/base_chart'\r\nimport { CanvasElementType, ChartElementType, IndicatorType } from '../constants/common'\r\nimport IndicatorElement from '../indicators/indicator'\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 | IndicatorElement) {\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(): this is { instance: InstanceType } & BaseChart {\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(): this is { instance: InstanceType } & IndicatorElement {\r\n return this.isIndicator() && financialIndicators.includes(this.instance!.type as IndicatorType)\r\n }\r\n\r\n isIndicator(): this is { instance: InstanceType } & IndicatorElement {\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 // Only intraday quotes have afterhours\r\n (!quote.isIntraday || (!quote.premarket === !options?.premarket && !quote.aftermarket === !options?.aftermarket)) &&\r\n (!options?.patterns || !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 weight: '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 weight: '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 weight: '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 weight: '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 weight: '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 = { 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 { 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 } 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() {\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 }\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 fetchedAt = -1\r\n shouldUpdate = true\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 set(obj: Partial) {\r\n super.set(obj)\r\n this.shouldUpdate = true\r\n\r\n return this\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 isComputeNecessary() {\r\n // if quote was updated (this.fetchedAt !== this.data.fetchedAt)\r\n // or overlay setting was changed (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 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 { drawInVisibleArea } from '../utils/draw_in_visible_area'\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 declare bbCalculation: BbCalculation\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 firstBarToRenderIndex: number | undefined\r\n let lastBarToRenderIndex = 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 if (this.isComputeNecessary()) {\r\n this.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 this.bbCalculation.calculate()\r\n }\r\n\r\n drawInVisibleArea({\r\n fromIndexOffset: period - 1,\r\n leftOffset,\r\n width,\r\n quote: this.data,\r\n paneModel: this.model,\r\n drawBarCallback: (i, x) => {\r\n const smaValue = this.bbCalculation.calculatedValues.sma[i]\r\n if (Number.isFinite(smaValue)) {\r\n firstBarToRenderIndex ??= i\r\n context.lineTo(x, Math.round(this.fy(smaValue)))\r\n lastBarToRenderIndex = i\r\n }\r\n },\r\n })\r\n\r\n if (firstBarToRenderIndex === 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(\r\n this.fx(firstBarToRenderIndex),\r\n Math.round(this.fy(this.bbCalculation.calculatedValues.upperBand[firstBarToRenderIndex]))\r\n )\r\n context.set('strokeStyle', BB_COLORS[theme].TOP)\r\n for (let i = firstBarToRenderIndex; i <= lastBarToRenderIndex; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(this.bbCalculation.calculatedValues.upperBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRenderIndex), scaledTop)\r\n context.lineTo(this.fx(firstBarToRenderIndex), scaledTop)\r\n context.fill()\r\n\r\n // bottom line\r\n context.beginPath()\r\n context.moveTo(\r\n this.fx(firstBarToRenderIndex),\r\n Math.round(this.fy(this.bbCalculation.calculatedValues.lowerBand[firstBarToRenderIndex]))\r\n )\r\n context.set('strokeStyle', BB_COLORS[theme].BOTTOM)\r\n for (let i = firstBarToRenderIndex; i <= lastBarToRenderIndex; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(this.bbCalculation.calculatedValues.lowerBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRenderIndex), scaledBottom)\r\n context.lineTo(this.fx(firstBarToRenderIndex), 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 static calculatedValuesOrder = ['upperBand', 'lowerBand', 'medianBand'] as const\r\n static calculatedValuesLabels = {\r\n upperBand: 'Upper Band',\r\n lowerBand: 'Lower Band',\r\n medianBand: 'Median',\r\n }\r\n\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { DchConfig, Options } from '../overlays/configs/dch'\r\nimport utils from '../utils'\r\nimport { MainCalculation } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n upperBand: number[]\r\n lowerBand: number[]\r\n medianBand: number[]\r\n}\r\n\r\nexport class DchCalculation extends MainCalculation {\r\n static config = DchConfig\r\n\r\n calculate() {\r\n const { period } = this.options\r\n const { high, low, close } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n if (close.length < period) return\r\n const startingIndex = period - 1\r\n for (let i = startingIndex; i < close.length; i++) {\r\n this._calculatedValues.upperBand[i] = utils.max(high.slice(Math.max(0, i - startingIndex), i + 1))\r\n this._calculatedValues.lowerBand[i] = utils.min(low.slice(Math.max(0, i - startingIndex), i + 1))\r\n this._calculatedValues.medianBand[i] =\r\n (this._calculatedValues.upperBand[i] + this._calculatedValues.lowerBand[i]) / 2\r\n }\r\n }\r\n}\r\n","import { DchCalculation } from '../indicator-calculation/dch'\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 declare dchCalculation: DchCalculation\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 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 if (this.isComputeNecessary()) {\r\n this.dchCalculation = new DchCalculation({\r\n quote: this.data,\r\n options: { period: this.attrs.period },\r\n })\r\n\r\n this.dchCalculation.calculate()\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 fromIndexOffset: this.attrs.period - 1,\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 context.lineTo(x, Math.round(this.fy(this.dchCalculation?.calculatedValues.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(this.dchCalculation?.calculatedValues.lowerBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), 0)\r\n context.lineTo(this.fx(firstBarToRender), 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(this.dchCalculation?.calculatedValues.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 { drawInVisibleArea } from '../utils/draw_in_visible_area'\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 declare emaCalculation: EMACalculation\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\r\n if (this.isComputeNecessary()) {\r\n this.emaCalculation = new EMACalculation({\r\n quote: this.data,\r\n options: { period: this.attrs.period },\r\n })\r\n\r\n this.emaCalculation.calculate()\r\n }\r\n\r\n drawInVisibleArea({\r\n fromIndexOffset: this.attrs.period - 1,\r\n leftOffset,\r\n width,\r\n quote: this.data,\r\n paneModel: this.model,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.emaCalculation.calculatedValues.ema[i])))\r\n },\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.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 static calculatedValuesOrder = ['highestHigh', 'lowestLow'] as const\r\n static calculatedValuesLabels = {\r\n highestHigh: 'Highest high',\r\n lowestLow: 'Lowest low',\r\n }\r\n\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { HILOConfig, Options } from '../overlays/configs/hilo'\r\nimport utils from '../utils'\r\nimport { MainCalculation } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n highestHigh: number[]\r\n lowestLow: number[]\r\n}\r\n\r\nexport class HILOCalculation extends MainCalculation {\r\n static config = HILOConfig\r\n\r\n calculate() {\r\n const { period } = this.options\r\n const { high, low, close } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n if (close.length < period) return\r\n const startingIndex = period - 1\r\n for (let i = startingIndex; i < close.length; i++) {\r\n this._calculatedValues.highestHigh[i] = utils.max(high.slice(Math.max(0, i - startingIndex), i + 1))\r\n this._calculatedValues.lowestLow[i] = utils.min(low.slice(Math.max(0, i - startingIndex), i + 1))\r\n }\r\n }\r\n}\r\n","import { HILOCalculation } from '../indicator-calculation/hilo'\r\nimport PaneModel from '../models/pane'\r\nimport { getBarWidthWithMargin } from '../utils/chart'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\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 declare hiloCalculation: HILOCalculation\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: undefined | number\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\r\n if (this.isComputeNecessary()) {\r\n this.hiloCalculation = new HILOCalculation({\r\n quote: this.data,\r\n options: { period },\r\n })\r\n\r\n this.hiloCalculation.calculate()\r\n }\r\n\r\n let prevHigh = -1\r\n drawInVisibleArea({\r\n leftOffset,\r\n width,\r\n quote: this.data,\r\n paneModel: this.model,\r\n drawBarCallback: (i, x) => {\r\n firstBarToRender ??= i\r\n const highestHigh =\r\n this.hiloCalculation.calculatedValues.highestHigh[i] ||\r\n (prevHigh !== -1 ? prevHigh : undefined) ||\r\n this.hiloCalculation.calculatedValues.highestHigh[\r\n this.hiloCalculation.calculatedValues.highestHigh.findIndex((item) => item !== undefined)\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 const y = Math.round(this.fy(highestHigh))\r\n context.lineTo(Math.round(x - halfWidth), y)\r\n context.lineTo(Math.round(x + halfWidth), y)\r\n\r\n prevHigh = highestHigh\r\n lastBarToRender = i\r\n },\r\n })\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(Math.round(this.fx(lastBarToRender)) + halfWidth, 0)\r\n context.lineTo(Math.round(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 const lowestLow =\r\n this.hiloCalculation.calculatedValues.lowestLow[i] ||\r\n (prevLow !== -1 ? prevLow : undefined) ||\r\n this.hiloCalculation.calculatedValues.lowestLow[\r\n this.hiloCalculation.calculatedValues.lowestLow.findIndex((item) => item !== undefined)\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 const y = Math.round(this.fy(lowestLow))\r\n context.lineTo(Math.round(x - halfWidth), y)\r\n context.lineTo(Math.round(x + halfWidth), y)\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(Math.round(this.fx(lastBarToRender)) + halfWidth, context.canvas.height)\r\n context.lineTo(Math.round(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 static calculatedValuesOrder = ['baseLine', 'conversionLine', 'senkouSpanA', 'senkouSpanB'] as const\r\n static calculatedValuesLabels = {\r\n baseLine: 'Base Line',\r\n conversionLine: 'Conversion Line',\r\n senkouSpanA: 'Leading Span A',\r\n senkouSpanB: 'Leading Span B',\r\n }\r\n\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { ICConfig, Options } from '../overlays/configs/ic'\r\nimport utils from '../utils'\r\nimport { MainCalculation } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n conversionLine: number[]\r\n baseLine: number[]\r\n senkouSpanA: number[]\r\n senkouSpanB: number[]\r\n}\r\n\r\ntype CalculationSupportValues = {\r\n conversionStartIndex: number\r\n baseStartIndex: number\r\n spanBIndex: number\r\n start: number\r\n end: number\r\n}\r\n\r\nexport class ICCalculation extends MainCalculation {\r\n static config = ICConfig\r\n declare options: Options\r\n protected _calculationSupportValues = {} as CalculationSupportValues\r\n\r\n get calculationSupportValues() {\r\n return this._calculationSupportValues\r\n }\r\n\r\n calculate() {\r\n const { conversion, base, spanB } = this.options\r\n const { close, high, low } = this.quote\r\n\r\n this._calculationSupportValues.conversionStartIndex = conversion - 1\r\n this._calculationSupportValues.baseStartIndex = base - 1\r\n this._calculationSupportValues.spanBIndex = spanB - 1\r\n this._calculationSupportValues.start = Math.min(\r\n this._calculationSupportValues.baseStartIndex,\r\n this._calculationSupportValues.conversionStartIndex\r\n )\r\n this._calculationSupportValues.end = close.length + this._calculationSupportValues.baseStartIndex\r\n\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n for (let i = this._calculationSupportValues.start; i < this._calculationSupportValues.end; i++) {\r\n if (i >= this._calculationSupportValues.conversionStartIndex && i < close.length) {\r\n const highestHi = utils.max(high.slice(i - this._calculationSupportValues.conversionStartIndex, i + 1))\r\n const lowestLo = utils.min(low.slice(i - this._calculationSupportValues.conversionStartIndex, i + 1))\r\n this._calculatedValues.conversionLine[i] = (highestHi + lowestLo) / 2\r\n }\r\n\r\n if (i >= this._calculationSupportValues.baseStartIndex && i < close.length) {\r\n const highestHi = utils.max(high.slice(i - this._calculationSupportValues.baseStartIndex, i + 1))\r\n const lowestLo = utils.min(low.slice(i - this._calculationSupportValues.baseStartIndex, i + 1))\r\n this._calculatedValues.baseLine[i] = (highestHi + lowestLo) / 2\r\n\r\n this._calculatedValues.senkouSpanA[i + this._calculationSupportValues.baseStartIndex] =\r\n (this._calculatedValues.baseLine[i] + this._calculatedValues.conversionLine[i]) / 2 // + baseStart because it needs to be shifted to the future\r\n }\r\n\r\n if (i >= this._calculationSupportValues.spanBIndex) {\r\n const highestHi = utils.max(high.slice(i - this._calculationSupportValues.spanBIndex, i + 1))\r\n const lowestLo = utils.min(low.slice(i - this._calculationSupportValues.spanBIndex, i + 1))\r\n this._calculatedValues.senkouSpanB[i + this._calculationSupportValues.baseStartIndex] =\r\n (highestHi + lowestLo) / 2 // + baseStart because it needs to be shifted to the future\r\n }\r\n }\r\n }\r\n}\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { ICCalculation } from '../indicator-calculation/ic'\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 declare icCalculation: ICCalculation\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\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 if (this.data.close.length === 0) return\r\n\r\n // Calculation\r\n if (this.isComputeNecessary()) {\r\n this.icCalculation = new ICCalculation({\r\n quote: this.data,\r\n options: {\r\n conversion,\r\n base,\r\n spanB,\r\n },\r\n })\r\n this.icCalculation.calculate()\r\n }\r\n\r\n let lastSpanAX = 0\r\n let lastSpanBX = 0\r\n const cloudStartingX = this.fx(\r\n this.icCalculation.calculationSupportValues.spanBIndex +\r\n this.icCalculation.calculationSupportValues.baseStartIndex\r\n )\r\n\r\n const drawInVisibleAreaProps = {\r\n toIndexOffset: this.icCalculation.calculationSupportValues.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\r\n let firstBarToRenderIndex: number | undefined\r\n let lastBarToRenderIndex = 0\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n firstBarToRenderIndex ??= i\r\n context.lineTo(x, Math.round(this.fy(this.icCalculation.calculatedValues.senkouSpanA[i])))\r\n lastSpanAX = x\r\n lastBarToRenderIndex = i\r\n },\r\n })\r\n context.stroke()\r\n\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\r\n // 1.3 Fill\r\n if (firstBarToRenderIndex === undefined) return\r\n context.beginPath()\r\n for (let i = firstBarToRenderIndex; i <= lastBarToRenderIndex; i++) {\r\n if (i >= this.icCalculation.calculatedValues.senkouSpanA.length) continue\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(this.icCalculation.calculatedValues.senkouSpanB[i])))\r\n lastSpanBX = x\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 for (let i = firstBarToRenderIndex; i <= lastBarToRenderIndex; i++) {\r\n if (i >= this.icCalculation.calculatedValues.senkouSpanA.length) continue\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(this.icCalculation.calculatedValues.senkouSpanB[i])))\r\n }\r\n context.stroke()\r\n\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\r\n // 2.3 Fill\r\n context.beginPath()\r\n for (let i = firstBarToRenderIndex; i <= lastBarToRenderIndex; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(this.icCalculation.calculatedValues.senkouSpanA[i])))\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 for (let i = firstBarToRenderIndex; i <= lastBarToRenderIndex; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(this.icCalculation.calculatedValues.conversionLine[i])))\r\n }\r\n context.stroke()\r\n\r\n // base line\r\n context.set('strokeStyle', baseLineColor)\r\n context.beginPath()\r\n for (let i = firstBarToRenderIndex; i <= lastBarToRenderIndex; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(this.icCalculation.calculatedValues.baseLine[i])))\r\n }\r\n context.stroke()\r\n\r\n // lagging span\r\n context.set('strokeStyle', laggingSpanColor)\r\n context.beginPath()\r\n for (let i = firstBarToRenderIndex; i <= lastBarToRenderIndex; i++) {\r\n context.lineTo(this.fx(i - (base - 1)), Math.round(this.fy(this.data.close[i])))\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 static calculatedValuesOrder = ['upperBand', 'middleLine', 'lowerBand'] as const\r\n static calculatedValuesLabels = {\r\n upperBand: 'Upper Band',\r\n middleLine: 'Middle Line',\r\n lowerBand: 'Lower Band',\r\n }\r\n\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[1]\r\n}\r\n","import { KCHConfig, Options } from '../overlays/configs/kch'\r\nimport { AverageTrueRange } from './atr'\r\nimport { ExponentialMovingAverage } from './ema'\r\nimport { MainCalculation } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n upperBand: number[]\r\n middleLine: number[]\r\n lowerBand: number[]\r\n}\r\n\r\nexport class KCHCalculation extends MainCalculation {\r\n static config = KCHConfig\r\n declare options: Options\r\n\r\n calculate() {\r\n const { emaPeriod, multiplier, atrPeriod } = this.options\r\n const { close, high, low } = this.quote\r\n const start = Math.max(emaPeriod, atrPeriod)\r\n\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n const ema = new ExponentialMovingAverage(emaPeriod)\r\n const atr = new AverageTrueRange(atrPeriod)\r\n\r\n for (let i = 0; i < close.length; i++) {\r\n ema.add(close[i])\r\n atr.add(high[i], low[i], close[i - 1])\r\n if (i < start - 1) {\r\n continue\r\n }\r\n this._calculatedValues.middleLine[i] = ema.value\r\n this._calculatedValues.upperBand[i] = ema.value + multiplier * atr.value\r\n this._calculatedValues.lowerBand[i] = ema.value - multiplier * atr.value\r\n }\r\n }\r\n}\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { KCHCalculation } from '../indicator-calculation/kch'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\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 declare kchCalculation: KCHCalculation\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\r\n let firstBarToRenderIndex: number | undefined\r\n let lastBarToRenderIndex = 0\r\n\r\n if (this.isComputeNecessary()) {\r\n this.kchCalculation = new KCHCalculation({\r\n quote: this.data,\r\n options: {\r\n emaPeriod,\r\n multiplier,\r\n atrPeriod,\r\n },\r\n })\r\n this.kchCalculation.calculate()\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', strokeColor)\r\n context.set('fillStyle', fillColor)\r\n\r\n //top line + clip\r\n context.beginPath()\r\n\r\n drawInVisibleArea({\r\n fromIndexOffset: Math.max(emaPeriod, atrPeriod) - 1,\r\n leftOffset,\r\n width,\r\n quote: this.data,\r\n paneModel: this.model,\r\n drawBarCallback: (i, x) => {\r\n const upperBandValue = this.kchCalculation?.calculatedValues.upperBand[i]\r\n if (Number.isFinite(upperBandValue)) {\r\n firstBarToRenderIndex ??= i\r\n context.lineTo(x, Math.round(this.fy(upperBandValue)))\r\n lastBarToRenderIndex = i\r\n }\r\n },\r\n })\r\n\r\n if (firstBarToRenderIndex === undefined) {\r\n context.restore()\r\n return\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRenderIndex), context.canvas.height)\r\n context.lineTo(this.fx(firstBarToRenderIndex), context.canvas.height)\r\n context.clip()\r\n\r\n // bottom line + fill\r\n context.beginPath()\r\n for (let i = firstBarToRenderIndex; i <= lastBarToRenderIndex; i++) {\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(this.kchCalculation?.calculatedValues.lowerBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRenderIndex), 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 = firstBarToRenderIndex; i <= lastBarToRenderIndex; i++) {\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(this.kchCalculation?.calculatedValues.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, weight: '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, weight: '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 PPCalculationTypeEnum {\r\n standard,\r\n fibonacci,\r\n}\r\n\r\nexport const PPCalculationTypeLabels = {\r\n [PPCalculationTypeEnum.standard]: 'Standard',\r\n [PPCalculationTypeEnum.fibonacci]: 'Fibonacci',\r\n}\r\n\r\nexport type Options = {\r\n calculationType: PPCalculationTypeEnum\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 static calculatedValuesOrder = ['pivot', 'res1', 'res2', 'res3', 'sup1', 'sup2', 'sup3'] as const\r\n\r\n static calculatedValuesLabels = {\r\n pivot: 'Pivot',\r\n res1: 'Resistance 1',\r\n res2: 'Resistance 2',\r\n res3: 'Resistance 3',\r\n sup1: 'Support 1',\r\n sup2: 'Support 2',\r\n sup3: 'Support 3',\r\n }\r\n\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import * as dateFns from 'date-fns'\r\n\r\nimport { TIMEFRAME } from '../constants/common'\r\nimport { Options, PPCalculationTypeEnum, PPConfig } from '../overlays/configs/pp'\r\nimport Utils from '../utils'\r\nimport { MainCalculation } from './main'\r\n\r\nexport enum PivotPeriod {\r\n day,\r\n week,\r\n month,\r\n year,\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\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\ntype CalculatedPivotPoint = {\r\n pivot: number\r\n sup1: number\r\n sup2: number\r\n sup3: number\r\n res1: number\r\n res2: number\r\n res3: number\r\n}\r\n\r\ntype CalculatedValuesForRender = {\r\n pivotPointsByPeriodKey: {\r\n [key: string]: CalculatedPivotPoint\r\n }\r\n}\r\n\r\nconst FIB_LVL_1 = 0.382\r\nconst FIB_LVL_2 = 0.618\r\n\r\nexport class PPCalculation extends MainCalculation {\r\n static config = PPConfig\r\n declare options: Options\r\n\r\n protected _calculatedValuesForRender = { pivotPointsByPeriodKey: {} } as CalculatedValuesForRender\r\n\r\n get calculatedValuesForRender() {\r\n return this._calculatedValuesForRender\r\n }\r\n\r\n calculate() {\r\n const { calculationType } = this.options\r\n const { close, date, timeframe, low, high } = this.quote\r\n\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n if (close.length === 0) return\r\n\r\n const periodType = getPeriodType(timeframe)\r\n const periodKeyFormat = getPeriodKeyFormat(periodType)\r\n\r\n let currentPeriodDate = Utils.dateFromUnixTimestamp(date[0])\r\n let previousPeriodDate = currentPeriodDate\r\n let previousHigh = Number.MIN_VALUE\r\n let previousLow = Number.MAX_VALUE\r\n let previousClose = 0\r\n let calculatedPivotPoint: CalculatedPivotPoint | undefined\r\n\r\n for (let i = 0; i < close.length; i++) {\r\n currentPeriodDate = Utils.dateFromUnixTimestamp(date[i])\r\n const isCurrentPeriodDateSameAsPrevioud = getIsSameDateInPeriod(previousPeriodDate, currentPeriodDate, periodType)\r\n\r\n // if date is in current period date, set previous HLC and skip rest of the loop\r\n if (isCurrentPeriodDateSameAsPrevioud) {\r\n previousHigh = Math.max(previousHigh, high[i])\r\n previousLow = Math.min(previousLow, low[i])\r\n previousClose = close[i]\r\n // if there are calculated pp, assign them to current index, it's because at this point in loop\r\n // calculatedPivotPoints available are calculated from previous period for current period\r\n if (calculatedPivotPoint !== undefined) this._setCalculatedValues(i, calculatedPivotPoint)\r\n continue\r\n }\r\n\r\n // Prev period HLC are ready for use\r\n // Calculate pivot points\r\n\r\n calculatedPivotPoint = getPivotPoints(previousHigh, previousLow, previousClose, calculationType)\r\n // assign pp to current period indexes\r\n this._setCalculatedValues(i, calculatedPivotPoint)\r\n\r\n // because of way we render pp, having to lookup for pp by index isn't suitable\r\n // it is much better to look for pp for specific period by periodKey,\r\n // thus we have and aditional format of pp just for rendering purposes\r\n this._setSupportValues(dateFns.format(currentPeriodDate, periodKeyFormat), calculatedPivotPoint)\r\n\r\n // All calculations/usage of previous period values are done\r\n // current values are first values from new period,\r\n // assign previous HLC so first day of new period is included\r\n previousHigh = high[i]\r\n previousLow = low[i]\r\n previousClose = close[i]\r\n\r\n previousPeriodDate = currentPeriodDate\r\n }\r\n }\r\n\r\n private _setCalculatedValues(index: number, calculatedPivotPoint: CalculatedPivotPoint) {\r\n this._calculatedValues.pivot[index] = calculatedPivotPoint.pivot\r\n this._calculatedValues.res1[index] = calculatedPivotPoint.res1\r\n this._calculatedValues.res2[index] = calculatedPivotPoint.res2\r\n this._calculatedValues.res3[index] = calculatedPivotPoint.res3\r\n this._calculatedValues.sup1[index] = calculatedPivotPoint.sup1\r\n this._calculatedValues.sup2[index] = calculatedPivotPoint.sup2\r\n this._calculatedValues.sup3[index] = calculatedPivotPoint.sup3\r\n }\r\n\r\n private _setSupportValues(periodKey: string, calculatedPivotPoint: CalculatedPivotPoint) {\r\n this._calculatedValuesForRender.pivotPointsByPeriodKey[periodKey] = { ...calculatedPivotPoint }\r\n }\r\n}\r\n\r\nexport function getPeriodType(timeframe: TIMEFRAME) {\r\n switch (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\nexport function getIsSameDateInPeriod(previousPeriodDate: Date, currentPeriodDate: Date, periodType: PivotPeriod) {\r\n switch (periodType) {\r\n case PivotPeriod.day:\r\n return dateFns.isSameDay(previousPeriodDate, currentPeriodDate)\r\n case PivotPeriod.week:\r\n return dateFns.isSameWeek(previousPeriodDate, currentPeriodDate, { weekStartsOn: 1 })\r\n case PivotPeriod.month:\r\n return dateFns.isSameMonth(previousPeriodDate, currentPeriodDate)\r\n case PivotPeriod.year:\r\n return dateFns.isSameYear(previousPeriodDate, currentPeriodDate)\r\n }\r\n}\r\n\r\nfunction getPivotPoints(\r\n previousHigh: number,\r\n previousLow: number,\r\n previousClose: number,\r\n calculationType: PPCalculationTypeEnum\r\n) {\r\n const pivot = (previousHigh + previousLow + previousClose) / 3\r\n if (calculationType === PPCalculationTypeEnum.standard) {\r\n return {\r\n pivot,\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 }\r\n }\r\n\r\n return {\r\n pivot,\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\r\nexport function getPeriodKeyFormat(periodType: PivotPeriod) {\r\n switch (periodType) {\r\n case PivotPeriod.day:\r\n return 'yyyy-MM-dd'\r\n case PivotPeriod.week:\r\n return 'yyyy-MM-w'\r\n case PivotPeriod.month:\r\n return 'yyyy-MM'\r\n case PivotPeriod.year:\r\n return 'yyyy'\r\n }\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 {\r\n PPCalculation,\r\n PivotPeriod,\r\n getIsSameDateInPeriod,\r\n getPeriodKeyFormat,\r\n getPeriodType,\r\n} from '../indicator-calculation/pp'\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, PPCalculationTypeEnum, PPCalculationTypeLabels, PPConfig } from './configs/pp'\r\nimport Overlay from './overlay'\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n CalculationType: PPCalculationTypeEnum.standard,\r\n Color: '#FFA75F',\r\n}\r\nconst MINUTES_PER_DAY = 1440\r\n\r\nfunction getCalculationType(period: string) {\r\n // standard & fibonacci were legacy values, kept in parsing for backward compatability purposes\r\n switch (period) {\r\n case 'fibonacci':\r\n case '1':\r\n return PPCalculationTypeEnum.fibonacci\r\n case 'standard':\r\n case '0':\r\n default:\r\n return PPCalculationTypeEnum.standard\r\n }\r\n}\r\n\r\nclass PivotPoints extends Overlay {\r\n static config = PPConfig\r\n\r\n declare ppCalculation: PPCalculation\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 = getCalculationType(period)\r\n this.trigger('change')\r\n }\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 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\r\n if (this.isComputeNecessary()) {\r\n this.ppCalculation = new PPCalculation({\r\n quote: this.data,\r\n options: {\r\n calculationType: this.attrs.calculationType,\r\n },\r\n })\r\n this.ppCalculation.calculate()\r\n }\r\n\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 const isStock = this.data.instrument === Instrument.Stock\r\n const periodType = getPeriodType(this.data.timeframe)\r\n const periodKeyFormat = getPeriodKeyFormat(periodType)\r\n let currentDate = new Date()\r\n let lastDate = new Date()\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.dataIndex; index <= lastBarToRender.dataIndex; index++) {\r\n currentDate = Utils.dateFromUnixTimestamp(this.data.date[index])\r\n\r\n // check if new calculation/render is necessary\r\n if (getIsSameDateInPeriod(lastDate, currentDate, periodType)) continue\r\n lastDate = currentDate\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.dataIndex; 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.dataIndex; 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.dataIndex; 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.dataIndex; 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.dataIndex; 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.dataIndex; 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 // get pivotPoint for current date from calculation\r\n const currentPeriodKey = dateFns.format(currentDate, periodKeyFormat)\r\n const pivotPoint = this.ppCalculation.calculatedValuesForRender.pivotPointsByPeriodKey[currentPeriodKey]\r\n if (!pivotPoint) continue\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: PPCalculationTypeEnum.standard,\r\n label: PPCalculationTypeLabels[PPCalculationTypeEnum.standard],\r\n },\r\n {\r\n value: PPCalculationTypeEnum.fibonacci,\r\n label: PPCalculationTypeLabels[PPCalculationTypeEnum.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 return Object.values(PPCalculationTypeEnum).includes(this.attrs[key])\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} (${PPCalculationTypeLabels[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 static calculatedValuesOrder = ['sar'] as const\r\n static calculatedValuesLabels = { sar: 'SAR' }\r\n static defaultCalculatedValueOption = this.calculatedValuesOrder[0]\r\n}\r\n","import { Options, SARConfig } from '../overlays/configs/sar'\r\nimport { MainCalculation } from './main'\r\n\r\ntype DefaultCalculatedValuesType = {\r\n sar: number[]\r\n}\r\n\r\ntype CalculationSupportValues = {\r\n isLong: boolean[]\r\n}\r\n\r\nexport class SARCalculation extends MainCalculation {\r\n static config = SARConfig\r\n declare options: Options\r\n protected _calculationSupportValues: CalculationSupportValues = { isLong: [] }\r\n\r\n get calculationSupportValues() {\r\n return this._calculationSupportValues\r\n }\r\n\r\n calculate() {\r\n const { step, maxStep } = this.options\r\n const { high, low, close } = this.quote\r\n\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n const deltaHigh = high[1] - high[0]\r\n const deltaLow = low[0] - low[1]\r\n const plusDirectionalMovement = deltaHigh > 0 && deltaHigh > deltaLow ? deltaHigh : 0\r\n const minusDirectionalMovement = deltaLow > 0 && deltaLow > deltaHigh ? deltaLow : 0\r\n // Trend direction long = up, short = down\r\n let isLong = plusDirectionalMovement >= minusDirectionalMovement\r\n\r\n let sar = isLong ? low[0] : high[0]\r\n let extremePrice = isLong ? high[1] : low[1]\r\n let accelerationFactor = step\r\n\r\n for (let i = 1; i < close.length; i++) {\r\n const prevHigh = high[i - 1]\r\n const prevLow = low[i - 1]\r\n const newHigh = high[i]\r\n const newLow = low[i]\r\n\r\n if (isLong) {\r\n // Switch to short if the low penetrates the SAR value.\r\n if (newLow <= sar) {\r\n // Switch and Overide the SAR with the extremePrice\r\n isLong = false\r\n sar = extremePrice\r\n\r\n // Make sure the overide SAR is within yesterday's and today's range.\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 // Output the overide SAR\r\n this._calculatedValues.sar[i] = sar\r\n\r\n // Adjust accelerationFactor and extremePrice\r\n accelerationFactor = step\r\n extremePrice = newLow\r\n\r\n // Calculate the new SAR\r\n sar = sar + accelerationFactor * (extremePrice - sar)\r\n\r\n // Make sure the new SAR is within yesterday's and today's range\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 // No switch\r\n\r\n // Output the SAR (was calculated in the previous iteration)\r\n this._calculatedValues.sar[i] = sar\r\n\r\n // Adjust accelerationFactor and extremePrice\r\n if (newHigh > extremePrice) {\r\n extremePrice = newHigh\r\n accelerationFactor += step\r\n if (accelerationFactor > maxStep) {\r\n accelerationFactor = maxStep\r\n }\r\n }\r\n\r\n // Calculate the new SAR\r\n sar = sar + accelerationFactor * (extremePrice - sar)\r\n\r\n // Make sure the new SAR is within yesterday's and today's range\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 // Switch to long if the high penetrates the SAR value\r\n if (newHigh >= sar) {\r\n // Switch and Overide the SAR with the extremePrice\r\n isLong = true\r\n sar = extremePrice\r\n\r\n // Make sure the overide SAR is within yesterday's and today's range\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 // Output the overide SAR\r\n this._calculatedValues.sar[i] = sar\r\n\r\n // Adjust accelerationFactor and extremePrice\r\n accelerationFactor = step\r\n extremePrice = newHigh\r\n\r\n // Calculate the new SAR\r\n sar = sar + accelerationFactor * (extremePrice - sar)\r\n\r\n // Make sure the overide SAR is within yesterday's and today's range\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 // No switch\r\n\r\n // Output the SAR (was calculated in the previous iteration)\r\n this._calculatedValues.sar[i] = sar\r\n\r\n // Adjust accelerationFactor and extremePrice\r\n if (newLow < extremePrice) {\r\n extremePrice = newLow\r\n accelerationFactor += step\r\n if (accelerationFactor > maxStep) {\r\n accelerationFactor = maxStep\r\n }\r\n }\r\n\r\n // Calculate the new SAR\r\n sar = sar + accelerationFactor * (extremePrice - sar)\r\n\r\n // Make sure the overide SAR is within yesterday's and today's range\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 this._calculationSupportValues.isLong[i] = isLong\r\n }\r\n }\r\n}\r\n","import { SARCalculation } from '../indicator-calculation/sar'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { Attrs, SARConfig } from './configs/sar'\r\nimport Overlay from './overlay'\r\n\r\nconst RECTANGLE_WIDTH = 3\r\nconst RECTANGLE_HALF_WIDTH = 3 / 2\r\n\r\nclass SAR extends Overlay {\r\n static config = SARConfig\r\n declare sarCalculation: SARCalculation\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 { leftOffset, width } = this.model.chart()\r\n const { step, maxStep } = this.attrs\r\n\r\n if (this.isComputeNecessary()) {\r\n this.sarCalculation = new SARCalculation({\r\n quote: this.data,\r\n options: { step, maxStep },\r\n })\r\n\r\n this.sarCalculation.calculate()\r\n }\r\n\r\n drawInVisibleArea({\r\n leftOffset,\r\n width,\r\n quote: this.data,\r\n paneModel: this.model,\r\n drawBarCallback: (i, x) => {\r\n const rectX = Math.round(x - RECTANGLE_HALF_WIDTH)\r\n const rectY = Math.round(this.fy(this.sarCalculation.calculatedValues.sar[i]) - RECTANGLE_HALF_WIDTH)\r\n context.set(\r\n 'fillStyle',\r\n this.sarCalculation.calculationSupportValues.isLong[i] ? this.attrs.risingColor : this.attrs.fallingColor\r\n )\r\n context.fillRect(rectX, rectY, RECTANGLE_WIDTH, RECTANGLE_WIDTH)\r\n },\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 { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { SMACalculation } from '../indicator-calculation/sma'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\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 declare smaCalculation: SMACalculation\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 if (this.isComputeNecessary()) {\r\n this.smaCalculation = new SMACalculation({\r\n quote: this.data,\r\n options: { period },\r\n })\r\n\r\n this.smaCalculation.calculate()\r\n }\r\n\r\n drawInVisibleArea({\r\n fromIndexOffset: period - 1,\r\n leftOffset,\r\n width,\r\n quote: this.data,\r\n paneModel: this.model,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.smaCalculation.calculatedValues.sma[i])))\r\n },\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 '../indicator-calculation/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(\r\n this.data.close.slice(firstBarToRender.dataIndex, lastBarToRender.dataIndex + 1)\r\n )\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.dataIndex; i <= lastBarToRender.dataIndex; 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 } 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() {\r\n const { date, close, low, high, volume } = this.quote\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 < date.length; 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 }\r\n}\r\n","import { VWapCalculation } from '../indicator-calculation/vwap'\r\nimport PaneModel from '../models/pane'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\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 declare vwapCalculation: VWapCalculation\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 if (this.isComputeNecessary()) {\r\n this.vwapCalculation = new VWapCalculation({\r\n quote: this.data,\r\n options: { period: this.attrs.period },\r\n })\r\n\r\n this.vwapCalculation.calculate()\r\n }\r\n\r\n drawInVisibleArea({\r\n leftOffset,\r\n width,\r\n quote: this.data,\r\n paneModel: this.model,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.vwapCalculation.calculatedValues.vwap[i])))\r\n },\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 { 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 }).dataIndex - 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 }).dataIndex + 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, weight: '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\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 is 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 // barIndex & dataIndex match for non-intraday timeframes,\r\n // however intraday timeframes have pre-derminated count of bars per certain timeframe eg. trading day\r\n // so count of data doesn't have to match with count of bars that are displayed,\r\n // if bar doesn't have data, we call that a bar gap\r\n\r\n // barIndex is index of bar at the edge of visible chart area, either first or last\r\n const barIndex = Math.round(paneModel.scale.x.invert(-leftOffset + (chartWidth !== undefined ? chartWidth : 0)))\r\n // dataIndex is index of actual real data\r\n // not all the time there is data 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 const dataIndex = quote.barToDataIndex[Math.min(Math.max(barIndex, 0), quote.barToDataIndex.length - 1)]\r\n const halfBarWidth = getHalfBarWidth(chartModel, false)\r\n\r\n // if barIndex doesn't match barIndex value at the dataIndex we know that that bar index doesn't have data\r\n const haveBarIndexData = barIndex === quote.barIndex[dataIndex]\r\n const isDataIndexVisible = Math.round(paneModel.scale.x(quote.barIndex[dataIndex]) + halfBarWidth) + leftOffset > 0\r\n\r\n const barToRenderObject = {\r\n barIndex,\r\n dataIndex,\r\n isDataIndexVisible,\r\n haveBarIndexData,\r\n }\r\n\r\n // If chartWidth isn't provided we are getting firstVisibleBarToRender\r\n if (chartWidth === undefined) {\r\n // If bar isn't visible we do dataIndex + 1 because we want to get next real bar as we know current isn't visible,\r\n // this doesn't mean that next is as we might be on view where there are none bars visible,\r\n // if that is the case, then firstVisibleBarToRender.index > lastVisibleBarToRender.index || none bars are visible\r\n barToRenderObject.dataIndex = isDataIndexVisible\r\n ? dataIndex\r\n : Math.max(Math.min(dataIndex + 1, quote.barIndex.length - 1), 0)\r\n return barToRenderObject\r\n }\r\n\r\n // If chartWidth is provided we are getting lastVisibleBarToRender\r\n return barToRenderObject\r\n\r\n /**\r\n * Setup:\r\n * firstBarToRender (fb), lastBarToRender (lb), both variables contain index and dataIndex in format (index, dataIndex)\r\n * on intraday charts where we can have bar gaps so each bar have index value and dataIndex value,\r\n * as it is best for edge cases we would use that for our cases\r\n * we would refer to that like eg. (0,0) - (index, dataIndex), if index value doesn't match dataIndex\r\n * it means that there is bar gap, in that case dataIndex would have value of most recent existing bar with data\r\n * eg. (0,0),(1,1),(2,1),(3,2)...\r\n * for ilustrating what is visible chart area we would use square brackets []\r\n * eg. (0,0),(1,1),(2,2) [ (3,3),(4,4),(5,5),(6,6),(7,7) ] (8,8),(9,9),(10,10)\r\n * visible bars in example are bars 3 to 7\r\n *\r\n * Cases:\r\n * 1: first and last bars are in place - (0,0),(1,1),(2,2) [ (3,3),(4,4),(5,5),(6,6),(7,7) ] (8,8),(9,9),(10,10)\r\n * 2: first bar visible last bar not - (0,0),(1,1),(2,2) [ (3,3),(4,3),(5,3),(6,3),(7,3) ] (8,4),(9,5),(10,6)\r\n * 3: first bar not visible last bar visible - (0,0),(1,1),(2,2) [ (3,2),(4,2),(5,2),(6,2),(7,3) ] (8,4),(9,5),(10,6)\r\n * 4: first and last bar not visible (no bars visible) - (0,0),(1,1),(2,2) [ (3,2),(4,2),(5,2),(6,2),(7,2) ] (8,3),(9,4),(10,5)\r\n * 5: first and last bar not visible (bars in the middle) - (0,0),(1,1),(2,2) [ (3,2),(4,3),(5,4),(6,5),(7,5) ] (8,6),(9,7),(10,8)\r\n * 6: first bar not visible but no previous bar existing, last bar visible - [ (0,-),(1,-),(2,-),(3,0),(4,1) ] (5,2),(6,3),(7,4), (8,5),(9,6),(10,7) // in reality it would be [ (0,0),(1,0),(2,0),(3,0),(4,1) ] (5,2),(6,3),(7,4), (8,5),(9,6),(10,7)\r\n * 7: first bar visible last bar not visible but no later bars exists - (0,0),(1,1),(2,2),(3,3),(4,4),(5,5),(6,6) [ (7,7),(8,8),(9,-),(10,-) ] // in reality it would be (0,0),(1,1),(2,2),(3,3),(4,4),(5,5),(6,6) [ (7,7),(8,8),(9,8),(10,8) ]\r\n *\r\n * Current behaviour:\r\n *\r\n * Case: 1 - fb(3,3), lb(7,7)\r\n * Case: 2 - fb(3,3), lb(7,3)\r\n * Case: 3 - fb(3,3), lb(7,3)\r\n * Case: 4 - fb(3,3), lb(7,2)\r\n * Case: 5 - fb(3,3), lb(7,5)\r\n * Case: 6 - fb(0,0), lb(4,1)\r\n * Case: 7 - fb(7,7), lb(10,8)\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 }).dataIndex - 1, fromIndexOffset)\r\n}\r\n\r\ntype IBarToRender = ReturnType\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.isDataIndexVisible && !lastBarToRenderIndex.isDataIndexVisible\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","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\nimport type Quote from '../app/models/quote'\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?: 'normal' | 'italic'\r\n weight?: 'normal' | 'bold' | '900'\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 quoteData?: Quote[]\r\n // Idea properties\r\n idea?: IIdea\r\n ideaQuotes?: Quote[]\r\n barWidth: number\r\n barMargin: number\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","portfolioWatchlistTableAsyncModule","assets","logo","logo_light","createAlertAsyncModule","saveToPortfolioAsyncModule","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","replace","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","initTickerText","chartSettings","isSmallIndexChart","L","isOurSiteRequest","SpecificChartFunctionality","offScreen","XS","M","blue","renderChange","getOHLC","directRender","changePercentage","lastDate","renderOHLC","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","dataIndex","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","lastMonth","monthsInData","availableTickSpots","monthsToAvail","renderMonth","chartsByType","candleStick","heikinAshi","hollowCandleStick","lineChart","marketSentiment","multiLineCharts","ohlcChart","perfChart","getContainerTypeFromPaneConfig","indicatorElement","getContainerType","mainElement","indicatorType","None","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","FinvizSettings","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","pathname","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","CHART_ELEMENT_ID","clientHeight","Popover","minHeight","CHART_SETTINGS_DIALOG_TEST_ID","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","minutes","hours","days","weeks","INPUTS_AVAILABLE","getInitialState","visibilities","macroTimeframe","valueMacroTimeframe","getIsVisibilityOutsideAvailableTimeframes","macrotimeframe","macroRange","MicroTimeframeRange","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","getCurrency","TickerSearch","inputClass","hasSearchIcon","isSearchItemLink","isShowAllVisible","event_category","hasUserPremium","hasRedesignEnabled","ChartControls","isQuotePage","isQuoteFinancials","handleTickerSelect","upperCaseTicker","handleCustomRangeSubmit","timeframeBarProps","canChangeTicker","hasTimeframe","editors","ChartEditorEnum","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","rows","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","QuotePageQueryChartTypes","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","columns","ChartGridCell","gridAreas","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","MOBILE_VIEW_BREAKPOINT_WIDTH","MOBILE_BARS_TO_VIEW","OnInitListener","setIsInit","checkIfInitIsComplete","elementIndex","hasOwnProperty","opacity","newConfig","dark","concat","isQuotePageWithDrawingsOff","getCookie","noteDrawing","ideaObject","newElements","ChartLayoutModel","getMaxDecayInterval","QuotePollingIntervalInMs","EliteStocksReduced","Free","pollingIntervalToCharts","setPollingIntervalToCharts","checkForChartsWithPolling","newPollingIntervalToCharts","chartRefreshInterval","intervalSubscriptions","checkForChartsWithPollingDebounced","chartsCheckerIntervalId","setInterval","EXTRA_MARKET_BUFFER_MINUTES","clearInterval","timeoutDurations","allCharts","timeoutDurationsMin","timeoutSubscription","decay","maxDecayInterval","chartIds","quotesToUpdate","quoteToUpdate","dispatchEvent","Event","QUOTE_FETCH_EVENT","unsubscribe","getIdeaUrl","searchObject","isStockOnQute","queryString","IdeaItem","onIdeaDeleted","isDeleting","setIsDeleting","isConfirmDelete","setIsConfirmDelete","currentIdea","onDeleteIdeaClick","wasDeleted","fetch","status","newUrl","URL","searchParams","company","TimeframeLabelShort","IdeasTabs","hasError","setHasError","hasFetched","setHasFetched","categorizedIdeas","setCategorizedIdeas","queryTickers","dateParts","processed","tickerIdeas","categorizeIdeas","fetchIdeas","handleIdeaDeleted","prev","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","LayoutType","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","DateRangeType","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","PREMARKET_AFTERMARKET_HOURS","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","altText","seoLabel","getInstrumentLabel","getResponseChartType","chartType","chartResponseType","ChartEvent","ChartEventType","Dividends","Split","EarningsNeutral","getChartEventModel","chartEventModel","getXYPosition","buffer","hover","isOpenOverride","isCurrentEventActive","scaledArea","ChartEventLabels","Earnings","eventItem","epsActual","epsEstimate","dateTimestamp","EarningsFuture","EarningsNegative","EarningsPositive","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","getTrueRange","AverageTrueRange","tr","ATRCalculation","MainCalculation","ATRConfig","calculate","_calculatedValues","atr","ExponentialMovingAverage","multiplier","EMACalculation","EMAConfig","ema","calculatedValues","defaultCalculatedValues","getAllCalculatedValues","lastNItems","getCalculatedValues","getDbColumnName","SimpleMovingAverage","trailingValues","firstTrailingValue","shift","SMACalculation","SMAConfig","sma","IndicatorBaseConfig","Atr","curr","ShrtflConfig","QuoteFinancialAttachment","shortInterest","Shrtfl","ShrtraConfig","Shrtra","ADXConfig","Adx","adx","pdi","mdi","ADXCalculation","sATR","firstAtrAccumulator","sPDM","firstPdmAccumulator","sMDM","firstMdmAccumulator","firstAdxAccumulator","upMove","downMove","plusDM","minusDM","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","INDICATOR_LABEL_HEIGHT","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","Aro","Mfi","Rmi","Rsi","Stofu","Ult","Macd","Rwi","Trix","Wr","Aroosc","Roc","Cci","Fi","INDICATOR_DEFAULT_DOMAIN","getIsValid","getIsNumberInputValid","integerOnly","isPositiveInteger","adxCalculation","getLineColors","lineColors","AroConfig","aroonUp","aroonDown","oscillator","AroonCalculation","highPeriod","highestInPeriod","periodSinceHigh","lastIndexOf","lowPeriod","lowestInPeriod","periodSinceLow","COLORS","aroonCalculation","textLabels","labelSetting","ArooscConfig","ATR","atrCalculation","CCIConfig","cci","CCICalculation","typicalPrice","tpSma","devSum","dev","cciCalculation","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","MFICalculation","moneyFlow","positiveMoneyFlowRollingSum","negativeMoneyFlowRollingSum","currentMoneyFlow","oldMoneyFlow","mfiCalculation","NoneConfig","OBVConfig","Obv","obv","OBVCalculation","currentObv","obvCalculation","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","RMICalculation","averageDown","averageUp","sumUp","sumDown","upChange","downChange","rmiCalculation","ROCConfig","roc","ROCCalculation","rocCalculation","RSIConfig","rsi","RsiCalculation","rsiCalculation","RVOLConfig","baseLine","rvol","RVOLCalculation","DEFAULT_PARAMETERS","periodStr","parsePeriod","rvolCalculation","baseLineY","RWIConfig","rwiHigh","rwiLow","RWICalculation","trSum","atrWeight","maxHi","maxLo","rwiCalculation","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","getFirstKAndDIndex","firstKIndex","firstDIndex","StofuCalculation","dCount","dSum","k1Arr","dArr","kArr","kSum","kCount","highestHigh","lowestLow","stofuCalculation","Stochastics","StoslConfig","Stosl","TRIXConfig","trix","TrixCalculation","trippleEmaPeriod","ema1","ema2","ema3","ema1Count","ema2Count","ema3Count","trixCalculation","UltConfig","period1","period2","period3","ult","UltCalculation","maxPeriod","bpSum2","bpSum3","count2","count3","trSum2","trSum3","bp","avg2","avg3","bpSum1","trSum1","count1","avg1","ultCalculation","VolConfig","WRConfig","WRCalculation","wrCalculation","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","IntradayTimeframeInterval","drawDays","getBarIndexes","alignAllFinancialAttachmentsDataWithQuoteDates","ChartEventDbType","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","XXXL","INTERACTIVE_CHART_SETTINGS","SETTINGS_HEIGHT","tickerTimeframeChangeHeight","TICKER_TIMEFRAME_CHANGE_HEIGHT","XL","colorsOverride","settingColors","isLight","getNormalizedZIndex","BaseConfig","OverlayType","Ema","OverlayBaseConfig","Sma","BBConfig","Bb","deviations","topColor","bottomColor","upperBand","lowerBand","BbCalculation","stdDev","initialPeriodIndex","stdDevSum","OverlayConfig","getFreeColor","periods","getRGBAValueFromValidColorString","BB_COLORS","TOP","BOTTOM","MIDDLE","BollingerBands","scaledTop","scaledBottom","bbCalculation","smaValue","DchConfig","Dch","channelStrokeColor","channelFillColor","medianBandColor","medianBand","DchCalculation","startingIndex","DonchianChannels","firstBarToRender","lastBarToRender","dchCalculation","EMA","emaCalculation","EMA2Config","Ema2","EMA2","HILOConfig","Hilo","highColor","lowColor","HILOCalculation","HighLow","hiloCalculation","prevHigh","prevLow","prevBar","HLineConfig","Hline","isPositiveFloat","ICConfig","Ic","conversion","spanB","spanAStrokeColor","spanAFillColor","spanBStrokeColor","spanBFillColor","conversionLineColor","baseLineColor","laggingSpanColor","conversionLine","senkouSpanA","senkouSpanB","ICCalculation","_calculationSupportValues","calculationSupportValues","conversionStartIndex","baseStartIndex","spanBIndex","highestHi","lowestLo","Stroke","Fill","Conversion","Base","SpanB","IchimokuCloud","renderFull","outsideBar","icCalculation","lastSpanAX","lastSpanBX","cloudStartingX","toIndexOffset","fxOverride","ICFConfig","Icf","KCHConfig","Kch","emaPeriod","atrPeriod","strokeColor","fillColor","middleLine","KCHCalculation","KeltnerChannel","kchCalculation","upperBandValue","PatternsConfig","Patterns","supportColor","resistColor","originalScale","barsInDay","aboveBelow","textHS","above","below","kind","PPCalculationTypeEnum","PPCalculationTypeLabels","standard","PPConfig","Pp","calculationType","pivot","res1","res2","res3","sup1","sup2","sup3","PivotPeriod","PPCalculation","_calculatedValuesForRender","pivotPointsByPeriodKey","calculatedValuesForRender","periodType","getPeriodType","periodKeyFormat","getPeriodKeyFormat","calculatedPivotPoint","currentPeriodDate","previousPeriodDate","previousHigh","previousLow","getIsSameDateInPeriod","_setCalculatedValues","getPivotPoints","_setSupportValues","periodKey","week","CalculationType","Color","PivotPoints","getCalculationType","ppCalculation","calculatedX","fromX","toX","currentDate","currentX","toBars","nextDate","currentPeriodKey","pivotPoint","SARConfig","Sar","maxStep","risingColor","fallingColor","sar","SARCalculation","isLong","deltaHigh","deltaLow","extremePrice","accelerationFactor","newHigh","newLow","SAR","sarCalculation","rectX","rectY","customizable","SMA","smaCalculation","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","vwapCalculation","bb","dch","hilo","hline","ic","icf","kch","pp","sma2","vp","requestsAbortControllersCache","abortRequest","controller","websiteShared","shouldUseCPUOnly","matchesAndroid","navigator","userAgent","match","matchesWebOS","matchesIPhone","matchesiPad","matchesIPod","matchesBlackBerry","matchesWindowsPhone","matchesIOSLike","maxTouchPoints","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","dateFromDateString","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","TIMEFRAME_SECONDS","isWithinRangeOfQuoteDate","commonVirtualCacheProps","cachedDates","virtualDateSeconds","getCachedVirtualDates","timeframeSeconds","numOfDatesBefore","numOfDatesAfter","virtualTradedDays","dateStartSeconds","dateEndSeconds","datesSeconds","isStartBeforeDates","isEndAfterDates","getTimezoneOffset","dateTime","getQuoteDateTimestampOffsetInSeconds","getVirtualTradedDays","marketStartSeconds","barTimeframeSeconds","quoteDatesTimestampOffset","dayStartSeconds","barSeconds","virtualTimeframeTradedDates","isLowerBounded","isOneBeforeLowerBoundStarts","isLookingBack","averageBarDate","numOfSecondsOutOfBounds","CRYPTOS","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","haveBarIndexData","isDataIndexVisible","barToRenderObject","object","formData","append","FormData","statusCode","throwOnPredicate","url","credentials","headers","responseContentType","Html","responseData","ApplicationJsonUTF","FormUrlEncoded","parseResponseForContentType","getStatusCodeError","forceUpdateKey","increment","two","local","remote","useChartLayoutGlobalModelModule","useChartLayoutGlobalModel"],"sourceRoot":""}