summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanglewood <85772166+deeleeramone@users.noreply.github.com>2024-04-17 07:53:45 -0700
committerGitHub <noreply@github.com>2024-04-17 14:53:45 +0000
commit779708a3a4112901739e3cd2d42c2a371ec5d1ad (patch)
treedd5416f21604c1a30bbcba0d66fefc952af887fe
parent326f239d0142a250a31128f148d7b8802c395298 (diff)
[BugFix] Charts: Fix Legend & Title Crowding in Jupyter (#6316)
* better jupyter legend * add that to the commit
-rw-r--r--openbb_platform/obbject_extensions/charting/openbb_charting/__init__.py17
-rw-r--r--openbb_platform/obbject_extensions/charting/openbb_charting/charting_router.py58
-rw-r--r--openbb_platform/obbject_extensions/charting/openbb_charting/core/openbb_figure.py2
-rw-r--r--openbb_platform/obbject_extensions/charting/openbb_charting/core/plotly.html12
-rw-r--r--openbb_platform/obbject_extensions/charting/openbb_charting/core/plotly_ta/ta_class.py3
-rw-r--r--openbb_platform/obbject_extensions/charting/openbb_charting/utils/generic_charts.py28
6 files changed, 71 insertions, 49 deletions
diff --git a/openbb_platform/obbject_extensions/charting/openbb_charting/__init__.py b/openbb_platform/obbject_extensions/charting/openbb_charting/__init__.py
index ac64c497fae..6f34a96d27e 100644
--- a/openbb_platform/obbject_extensions/charting/openbb_charting/__init__.py
+++ b/openbb_platform/obbject_extensions/charting/openbb_charting/__init__.py
@@ -264,6 +264,7 @@ class Charting:
orientation: Literal["h", "v"] = "v",
colors: Optional[List[str]] = None,
layout_kwargs: Optional[Dict[str, Any]] = None,
+ bar_kwargs: Optional[Dict[str, Any]] = None,
render: bool = True,
**kwargs,
) -> Union[OpenBBFigure, Figure, None]:
@@ -281,19 +282,18 @@ class Charting:
The bar mode, by default "group".
xtype : Literal["category", "multicategory", "date", "log", "linear"], optional
The x-axis type, by default "category".
- title : Optional[str], optional
+ title : str, optional
The title of the chart, by default None.
- xtitle : Optional[str], optional
+ xtitle : str, optional
The x-axis title, by default None.
- ytitle : Optional[str], optional
+ ytitle : str, optional
The y-axis title, by default None.
- orientation : Literal["h", "v"], optional
- The orientation of the chart, by default "v".
- colors: Optional[List[str]], optional
+ colors: List[str], optional
Manually set the colors to cycle through for each column in 'y', by default None.
- layout_kwargs : Optional[Dict[str, Any]], optional
+ bar_kwargs : Dict[str, Any], optional
+ Additional keyword arguments to apply with figure.add_bar(), by default None.
+ layout_kwargs : Dict[str, Any], optional
Additional keyword arguments to apply with figure.update_layout(), by default None.
-
Returns
-------
OpenBBFigure
@@ -311,6 +311,7 @@ class Charting:
ytitle=ytitle,
orientation=orientation,
colors=colors,
+ bar_kwargs=bar_kwargs,
layout_kwargs=layout_kwargs,
)
diff --git a/openbb_platform/obbject_extensions/charting/openbb_charting/charting_router.py b/openbb_platform/obbject_extensions/charting/openbb_charting/charting_router.py
index b261da67a3d..b13bf0d5a05 100644
--- a/openbb_platform/obbject_extensions/charting/openbb_charting/charting_router.py
+++ b/openbb_platform/obbject_extensions/charting/openbb_charting/charting_router.py
@@ -289,21 +289,20 @@ def equity_price_historical( # noqa: PLR0912
)
if _volume is True and "atr" in indicators: # type: ignore
fig.add_inchart_volume(data)
- fig.set_title(title)
fig.update_layout(
paper_bgcolor="rgba(0,0,0,0)",
plot_bgcolor="rgba(0,0,0,0)",
font=dict(color=text_color),
showlegend=True,
legend=dict(
- orientation="h",
- yanchor="bottom",
- xanchor="auto",
- y=1.02,
- x=0.95,
+ orientation="v",
+ yanchor="top",
+ xanchor="right",
+ y=0.95,
+ x=-0.01,
xref="paper",
- bgcolor="rgba(0,0,0,0)",
font=dict(size=12),
+ bgcolor="rgba(0,0,0,0)",
),
xaxis=dict(
ticklen=0,
@@ -328,6 +327,7 @@ def equity_price_historical( # noqa: PLR0912
zeroline=True,
mirror=True,
showline=True,
+ tickfont=dict(size=14),
),
yaxis2=dict(
ticklen=0,
@@ -341,6 +341,10 @@ def equity_price_historical( # noqa: PLR0912
hovermode="x",
)
+ if kwargs.get("title"):
+ title = kwargs["title"]
+ fig.update_layout(title=dict(text=title, x=0.5))
+
content = fig.to_plotly_json()
return fig, content
@@ -353,7 +357,7 @@ def equity_price_historical( # noqa: PLR0912
if "symbol" in data.columns:
data = data.pivot(columns="symbol", values=target)
- title: str = kwargs.get("title") if "title" in kwargs else title if title else "Historical Prices" # type: ignore
+ title: str = kwargs.get("title", "Historical Prices") # type: ignore
y1title = data.iloc[:, 0].name
y2title = ""
@@ -374,8 +378,6 @@ def equity_price_historical( # noqa: PLR0912
fig = OpenBBFigure()
- fig.update_layout(ChartStyle().plotly_template.get("layout", {}))
-
for i, col in enumerate(data.columns):
hovertemplate = f"{data[col].name}: %{{y}}<extra></extra>"
@@ -416,23 +418,34 @@ def equity_price_historical( # noqa: PLR0912
y2title = None # type: ignore
fig.update_layout(
- title=dict(text=title, x=0.5, font=dict(size=16)),
paper_bgcolor="rgba(0,0,0,0)",
plot_bgcolor="rgba(0,0,0,0)",
- font=dict(color=text_color),
- legend=dict(
- orientation="h",
- yanchor="bottom",
- xanchor="right",
- y=1.02,
- x=1,
- bgcolor="rgba(0,0,0,0)",
+ legend=(
+ dict(
+ orientation="v",
+ yanchor="top",
+ xanchor="right",
+ y=0.95,
+ x=-0.01,
+ bgcolor="rgba(0,0,0,0)",
+ )
+ if len(data.columns) > 2
+ else dict(
+ orientation="h",
+ yanchor="bottom",
+ xanchor="right",
+ y=1.02,
+ x=0.98,
+ bgcolor="rgba(0,0,0,0)",
+ )
),
yaxis1=(
dict(
side="right",
ticklen=0,
showgrid=True,
+ showline=True,
+ gridcolor="rgba(128,128,128,0.3)",
title=dict(
text=y1title if y1title else None, standoff=20, font=dict(size=20)
),
@@ -458,11 +471,16 @@ def equity_price_historical( # noqa: PLR0912
xaxis=dict(
ticklen=0,
showgrid=True,
+ showline=True,
+ gridcolor="rgba(128,128,128,0.3)",
),
- margin=dict(l=20, r=20, b=20),
+ margin=dict(l=20, r=20, b=20, t=20),
dragmode="pan",
hovermode="x",
)
+ if kwargs.get("title"):
+ title = kwargs["title"]
+ fig.update_layout(title=dict(text=title, x=0.5))
content = fig.show(external=True).to_plotly_json()
diff --git a/openbb_platform/obbject_extensions/charting/openbb_charting/core/openbb_figure.py b/openbb_platform/obbject_extensions/charting/openbb_charting/core/openbb_figure.py
index d6864a4f5f7..6d3315feee3 100644
--- a/openbb_platform/obbject_extensions/charting/openbb_charting/core/openbb_figure.py
+++ b/openbb_platform/obbject_extensions/charting/openbb_charting/core/openbb_figure.py
@@ -42,6 +42,8 @@ if TYPE_CHECKING:
TimeSeriesT = TypeVar("TimeSeriesT", bound="TimeSeries")
+pio.default_renderers = "notebook"
+
class OpenBBFigure(go.Figure):
"""Custom Figure class for OpenBB Terminal.
diff --git a/openbb_platform/obbject_extensions/charting/openbb_charting/core/plotly.html b/openbb_platform/obbject_extensions/charting/openbb_charting/core/plotly.html
index ad42aacf3d7..6912deac3b6 100644
--- a/openbb_platform/obbject_extensions/charting/openbb_charting/core/plotly.html
+++ b/openbb_platform/obbject_extensions/charting/openbb_charting/core/plotly.html
@@ -4008,7 +4008,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
l-51.45-160.536h39.787l19.526,67.894c5.479,19.046,10.479,37.386,14.299,57.397h0.709c4.048-19.298,9.045-38.352,14.526-56.693
l20.487-68.598h38.599L427.518,380.583z`, width: 550, height: 550, transform: "translate(4, 0)"
}, downloadImage: { path: "M22.71,6.29a1,1,0,0,0-1.42,0L20,7.59V2a1,1,0,0,0-2,0V7.59l-1.29-1.3a1,1,0,0,0-1.42,1.42l3,3a1,1,0,0,0,.33.21.94.94,0,0,0,.76,0,1,1,0,0,0,.33-.21l3-3A1,1,0,0,0,22.71,6.29ZM19,13a1,1,0,0,0-1,1v.38L16.52,12.9a2.79,2.79,0,0,0-3.93,0l-.7.7L9.41,11.12a2.85,2.85,0,0,0-3.93,0L4,12.6V7A1,1,0,0,1,5,6h8a1,1,0,0,0,0-2H5A3,3,0,0,0,2,7V19a3,3,0,0,0,3,3H17a3,3,0,0,0,3-3V14A1,1,0,0,0,19,13ZM5,20a1,1,0,0,1-1-1V15.43l2.9-2.9a.79.79,0,0,1,1.09,0l3.17,3.17,0,0L15.46,20Zm13-1a.89.89,0,0,1-.18.53L13.31,15l.7-.7a.77.77,0,0,1,1.1,0L18,17.21Z", width: 21, height: 21, transform: "translate(-2, -2)" }
- }, $7 = { data: { candlestick: [{ decreasing: { fillcolor: "#e4003a", line: { color: "#e4003a" } }, increasing: { fillcolor: "#00ACFF", line: { color: "#00ACFF" } }, type: "candlestick" }] }, layout: { annotationdefaults: { showarrow: !1 }, autotypenumbers: "strict", colorway: ["#ffed00", "#ef7d00", "#e4003a", "#c13246", "#822661", "#48277c", "#005ca9", "#00aaff", "#9b30d9", "#af005f", "#5f00af", "#af87ff"], dragmode: "pan", font: { family: "Fira Code", size: 18 }, hoverlabel: { align: "left" }, mapbox: { style: "dark" }, hovermode: "x", legend: { bgcolor: "rgba(0, 0, 0, 0)", x: .01, xanchor: "left", y: .99, yanchor: "top", font: { size: 15 } }, paper_bgcolor: "#000000", plot_bgcolor: "#000000", xaxis: { automargin: !0, autorange: !0, rangeslider: { visible: !1 }, showgrid: !0, showline: !0, tickfont: { size: 14 }, zeroline: !1, tick0: 1, title: { standoff: 20 }, linecolor: "#F5EFF3", mirror: !0, ticks: "outside" }, yaxis: { anchor: "x", automargin: !0, fixedrange: !1, zeroline: !1, showgrid: !0, showline: !0, side: "right", tick0: .5, title: { standoff: 20 }, gridcolor: "#283442", linecolor: "#F5EFF3", mirror: !0, ticks: "outside" } } }, K7 = { data: { barpolar: [{ marker: { line: { color: "white", width: .5 }, pattern: { fillmode: "overlay", size: 10, solidity: .2 } }, type: "barpolar" }], bar: [{ error_x: { color: "#2a3f5f" }, error_y: { color: "#2a3f5f" }, marker: { line: { color: "white", width: .5 }, pattern: { fillmode: "overlay", size: 10, solidity: .2 } }, type: "bar" }], carpet: [{ aaxis: { endlinecolor: "#2a3f5f", gridcolor: "#C8D4E3", linecolor: "#C8D4E3", minorgridcolor: "#C8D4E3", startlinecolor: "#2a3f5f" }, baxis: { endlinecolor: "#2a3f5f", gridcolor: "#C8D4E3", linecolor: "#C8D4E3", minorgridcolor: "#C8D4E3", startlinecolor: "#2a3f5f" }, type: "carpet" }], choropleth: [{ colorbar: { outlinewidth: 0, ticks: "" }, type: "choropleth" }], contourcarpet: [{ colorbar: { outlinewidth: 0, ticks: "" }, type: "contourcarpet" }], contour: [{ colorbar: { outlinewidth: 0, ticks: "" }, colorscale: [[0, "#0d0887"], [.1111111111111111, "#46039f"], [.2222222222222222, "#7201a8"], [.3333333333333333, "#9c179e"], [.4444444444444444, "#bd3786"], [.5555555555555556, "#d8576b"], [.6666666666666666, "#ed7953"], [.7777777777777778, "#fb9f3a"], [.8888888888888888, "#fdca26"], [1, "#f0f921"]], type: "contour" }], heatmapgl: [{ colorbar: { outlinewidth: 0, ticks: "" }, colorscale: [[0, "#0d0887"], [.1111111111111111, "#46039f"], [.2222222222222222, "#7201a8"], [.3333333333333333, "#9c179e"], [.4444444444444444, "#bd3786"], [.5555555555555556, "#d8576b"], [.6666666666666666, "#ed7953"], [.7777777777777778, "#fb9f3a"], [.8888888888888888, "#fdca26"], [1, "#f0f921"]], type: "heatmapgl" }], heatmap: [{ colorbar: { outlinewidth: 0, ticks: "" }, colorscale: [[0, "#0d0887"], [.1111111111111111, "#46039f"], [.2222222222222222, "#7201a8"], [.3333333333333333, "#9c179e"], [.4444444444444444, "#bd3786"], [.5555555555555556, "#d8576b"], [.6666666666666666, "#ed7953"], [.7777777777777778, "#fb9f3a"], [.8888888888888888, "#fdca26"], [1, "#f0f921"]], type: "heatmap" }], histogram2dcontour: [{ colorbar: { outlinewidth: 0, ticks: "" }, colorscale: [[0, "#0d0887"], [.1111111111111111, "#46039f"], [.2222222222222222, "#7201a8"], [.3333333333333333, "#9c179e"], [.4444444444444444, "#bd3786"], [.5555555555555556, "#d8576b"], [.6666666666666666, "#ed7953"], [.7777777777777778, "#fb9f3a"], [.8888888888888888, "#fdca26"], [1, "#f0f921"]], type: "histogram2dcontour" }], histogram2d: [{ colorbar: { outlinewidth: 0, ticks: "" }, colorscale: [[0, "#0d0887"], [.1111111111111111, "#46039f"], [.2222222222222222, "#7201a8"], [.3333333333333333, "#9c179e"], [.4444444444444444, "#bd3786"], [.5555555555555556, "#d8576b"], [.6666666666666666, "#ed7953"], [.7777777777777778, "#fb9f3a"], [.8888888888888888, "#fdca26"], [1, "#f0f921"]], type: "histogram2d" }], histogram: [{ marker: { pattern: { fillmode: "overlay", size: 10, solidity: .2 } }, type: "histogram" }], mesh3d: [{ colorbar: { outlinewidth: 0, ticks: "" }, type: "mesh3d" }], parcoords: [{ line: { colorbar: { outlinewidth: 0, ticks: "" } }, type: "parcoords" }], pie: [{ automargin: !0, type: "pie" }], scatter3d: [{ line: { colorbar: { outlinewidth: 0, ticks: "" } }, marker: { colorbar: { outlinewidth: 0, ticks: "" } }, type: "scatter3d" }], scattercarpet: [{ marker: { colorbar: { outlinewidth: 0, ticks: "" } }, type: "scattercarpet" }], scattergeo: [{ marker: { colorbar: { outlinewidth: 0, ticks: "" } }, type: "scattergeo" }], scattergl: [{ marker: { colorbar: { outlinewidth: 0, ticks: "" } }, type: "scattergl" }], scattermapbox: [{ marker: { colorbar: { outlinewidth: 0, ticks: "" } }, type: "scattermapbox" }], scatterpolargl: [{ marker: { colorbar: { outlinewidth: 0, ticks: "" } }, type: "scatterpolargl" }], scatterpolar: [{ marker: { colorbar: { outlinewidth: 0, ticks: "" } }, type: "scatterpolar" }], scatter: [{ fillpattern: { fillmode: "overlay", size: 10, solidity: .2 }, type: "scatter" }], scatterternary: [{ marker: { colorbar: { outlinewidth: 0, ticks: "" } }, type: "scatterternary" }], surface: [{ colorbar: { outlinewidth: 0, ticks: "" }, colorscale: [[0, "#0d0887"], [.1111111111111111, "#46039f"], [.2222222222222222, "#7201a8"], [.3333333333333333, "#9c179e"], [.4444444444444444, "#bd3786"], [.5555555555555556, "#d8576b"], [.6666666666666666, "#ed7953"], [.7777777777777778, "#fb9f3a"], [.8888888888888888, "#fdca26"], [1, "#f0f921"]], type: "surface" }], table: [{ cells: { fill: { color: "#EBF0F8" }, line: { color: "white" } }, header: { fill: { color: "#C8D4E3" }, line: { color: "white" } }, type: "table" }], candlestick: [{ decreasing: { fillcolor: "#e4003a", line: { color: "#990000" } }, increasing: { fillcolor: "#00ACFF", line: { color: "#007500" } }, type: "candlestick" }] }, layout: { annotationdefaults: { arrowcolor: "#2a3f5f", arrowhead: 0, arrowwidth: 1, showarrow: !1 }, autotypenumbers: "strict", coloraxis: { colorbar: { outlinewidth: 0, ticks: "" } }, colorscale: { diverging: [[0, "#8e0152"], [.1, "#c51b7d"], [.2, "#de77ae"], [.3, "#f1b6da"], [.4, "#fde0ef"], [.5, "#f7f7f7"], [.6, "#e6f5d0"], [.7, "#b8e186"], [.8, "#7fbc41"], [.9, "#4d9221"], [1, "#276419"]], sequential: [[0, "#0d0887"], [.1111111111111111, "#46039f"], [.2222222222222222, "#7201a8"], [.3333333333333333, "#9c179e"], [.4444444444444444, "#bd3786"], [.5555555555555556, "#d8576b"], [.6666666666666666, "#ed7953"], [.7777777777777778, "#fb9f3a"], [.8888888888888888, "#fdca26"], [1, "#f0f921"]], sequentialminus: [[0, "#0d0887"], [.1111111111111111, "#46039f"], [.2222222222222222, "#7201a8"], [.3333333333333333, "#9c179e"], [.4444444444444444, "#bd3786"], [.5555555555555556, "#d8576b"], [.6666666666666666, "#ed7953"], [.7777777777777778, "#fb9f3a"], [.8888888888888888, "#fdca26"], [1, "#f0f921"]] }, colorway: ["#254495", "#c13246", "#48277c", "#e4003a", "#ef7d00", "#822661", "#ffed00", "#00aaff", "#9b30d9", "#af005f", "#5f00af", "#af87ff"], font: { color: "#2a3f5f" }, geo: { bgcolor: "white", lakecolor: "white", landcolor: "white", showlakes: !0, showland: !0, subunitcolor: "#C8D4E3" }, hoverlabel: { align: "left" }, hovermode: "x", mapbox: { style: "light" }, paper_bgcolor: "white", plot_bgcolor: "white", polar: { angularaxis: { gridcolor: "#EBF0F8", linecolor: "#EBF0F8", ticks: "" }, bgcolor: "white", radialaxis: { gridcolor: "#EBF0F8", linecolor: "#EBF0F8", ticks: "" } }, scene: { xaxis: { backgroundcolor: "white", gridcolor: "#DFE8F3", gridwidth: 2, linecolor: "#EBF0F8", showbackground: !0, ticks: "", zerolinecolor: "#EBF0F8" }, yaxis: { backgroundcolor: "white", gridcolor: "#DFE8F3", gridwidth: 2, linecolor: "#EBF0F8", showbackground: !0, ticks: "", zerolinecolor: "#EBF0F8" }, zaxis: { backgroundcolor: "white", gridcolor: "#DFE8F3", gridwidth: 2, linecolor: "#EBF0F8", showbackground: !0, ticks: "", zerolinecolor: "#EBF0F8" } }, shapedefaults: { line: { color: "#2a3f5f" } }, ternary: { aaxis: { gridcolor: "#DFE8F3", linecolor: "#A2B1C6", ticks: "" }, baxis: { gridcolor: "#DFE8F3", linecolor: "#A2B1C6", ticks: "" }, bgcolor: "white", caxis: { gridcolor: "#DFE8F3", linecolor: "#A2B1C6", ticks: "" } }, title: { x: .05 }, xaxis: { automargin: !0, ticks: "outside", zerolinewidth: 2, rangeslider: { visible: !1 }, showgrid: !0, showline: !0, tickfont: { size: 15 }, title: { standoff: 20 }, mirror: !0, zeroline: !1 }, yaxis: { automargin: !0, ticks: "outside", tickfont: { size: 15 }, zerolinewidth: 2, fixedrange: !1, title: { standoff: 20 }, nticks: 8, showgrid: !0, showline: !0, side: "right", mirror: !0, zeroline: !1 }, dragmode: "pan", legend: { bgcolor: "rgba(0, 0, 0, 0)", x: 1.03, xanchor: "left", y: .99, yanchor: "top" } } }; function zo() { return zo = Object.assign ? Object.assign.bind() : function (L) { for (var I = 1; I < arguments.length; I++) { var $ = arguments[I]; for (var se in $) Object.prototype.hasOwnProperty.call($, se) && (L[se] = $[se]) } return L }, zo.apply(this, arguments) } function wf(L, I, { checkForDefaultPrevented: $ = !0 } = {}) { return function (Pe) { if (L == null || L(Pe), $ === !1 || !Pe.defaultPrevented) return I == null ? void 0 : I(Pe) } } function J7(L, I) { typeof L == "function" ? L(I) : L != null && (L.current = I) } function S5(...L) { return I => L.forEach($ => J7($, I)) } function pd(...L) { return In.useCallback(S5(...L), L) } function Q7(L, I = []) { let $ = []; function se(R, E) { const e = In.createContext(E), w = $.length; $ = [...$, E]; function k(_) { const { scope: y, children: h, ...l } = _, t = (y == null ? void 0 : y[L][w]) || e, o = In.useMemo(() => l, Object.values(l)); return In.createElement(t.Provider, { value: o }, h) } function i(_, y) { const h = (y == null ? void 0 : y[L][w]) || e, l = In.useContext(h); if (l) return l; if (E !== void 0) return E; throw new Error(`\`${_}\` must be used within \`${R}\``) } return k.displayName = R + "Provider", [k, i] } const Pe = () => { const R = $.map(E => In.createContext(E)); return function (e) { const w = (e == null ? void 0 : e[L]) || R; return In.useMemo(() => ({ [`__scope${L}`]: { ...e, [L]: w } }), [e, w]) } }; return Pe.scopeName = L, [se, eA(Pe, ...I)] } function eA(...L) { const I = L[0]; if (L.length === 1) return I; const $ = () => { const se = L.map(Pe => ({ useScope: Pe(), scopeName: Pe.scopeName })); return function (R) { const E = se.reduce((e, { useScope: w, scopeName: k }) => { const _ = w(R)[`__scope${k}`]; return { ...e, ..._ } }, {}); return In.useMemo(() => ({ [`__scope${I.scopeName}`]: E }), [E]) } }; return $.scopeName = I.scopeName, $ } const Tm = globalThis != null && globalThis.document ? In.useLayoutEffect : () => { }, tA = Z6["useId".toString()] || (() => { }); let nA = 0; function sv(L) { const [I, $] = In.useState(tA()); return Tm(() => { L || $(se => se ?? String(nA++)) }, [L]), L || (I ? `radix-${I}` : "") } function Cf(L) { const I = In.useRef(L); return In.useEffect(() => { I.current = L }), In.useMemo(() => (...$) => { var se; return (se = I.current) === null || se === void 0 ? void 0 : se.call(I, ...$) }, []) } function rA({ prop: L, defaultProp: I, onChange: $ = () => { } }) { const [se, Pe] = iA({ defaultProp: I, onChange: $ }), R = L !== void 0, E = R ? L : se, e = Cf($), w = In.useCallback(k => { if (R) { const _ = typeof k == "function" ? k(L) : k; _ !== L && e(_) } else Pe(k) }, [R, L, Pe, e]); return [E, w] } function iA({ defaultProp: L, onChange: I }) { const $ = In.useState(L), [se] = $, Pe = In.useRef(se), R = Cf(I); return In.useEffect(() => { Pe.current !== se && (R(se), Pe.current = se) }, [se, Pe, R]), $ } const Fy = In.forwardRef((L, I) => { const { children: $, ...se } = L, Pe = In.Children.toArray($), R = Pe.find(oA); if (R) { const E = R.props.children, e = Pe.map(w => w === R ? In.Children.count(E) > 1 ? In.Children.only(null) : In.isValidElement(E) ? E.props.children : null : w); return In.createElement(Am, zo({}, se, { ref: I }), In.isValidElement(E) ? In.cloneElement(E, void 0, e) : null) } return In.createElement(Am, zo({}, se, { ref: I }), $) }); Fy.displayName = "Slot"; const Am = In.forwardRef((L, I) => { const { children: $, ...se } = L; return In.isValidElement($) ? In.cloneElement($, { ...sA(se, $.props), ref: I ? S5(I, $.ref) : $.ref }) : In.Children.count($) > 1 ? In.Children.only(null) : null }); Am.displayName = "SlotClone"; const aA = ({ children: L }) => In.createElement(In.Fragment, null, L); function oA(L) { return In.isValidElement(L) && L.type === aA } function sA(L, I) { const $ = { ...I }; for (const se in I) { const Pe = L[se], R = I[se]; /^on[A-Z]/.test(se) ? Pe && R ? $[se] = (...e) => { R(...e), Pe(...e) } : Pe && ($[se] = Pe) : se === "style" ? $[se] = { ...Pe, ...R } : se === "className" && ($[se] = [Pe, R].filter(Boolean).join(" ")) } return { ...L, ...$ } } const lA = ["a", "button", "div", "form", "h2", "h3", "img", "input", "label", "li", "nav", "ol", "p", "span", "svg", "ul"], Nh = lA.reduce((L, I) => { const $ = In.forwardRef((se, Pe) => { const { asChild: R, ...E } = se, e = R ? Fy : I; return In.useEffect(() => { window[Symbol.for("radix-ui")] = !0 }, []), In.createElement(e, zo({}, E, { ref: Pe })) }); return $.displayName = `Primitive.${I}`, { ...L, [I]: $ } }, {}); function uA(L, I) { L && Ay.flushSync(() => L.dispatchEvent(I)) } function cA(L, I = globalThis == null ? void 0 : globalThis.document) { const $ = Cf(L); In.useEffect(() => { const se = Pe => { Pe.key === "Escape" && $(Pe) }; return I.addEventListener("keydown", se), () => I.removeEventListener("keydown", se) }, [$, I]) } const Mm = "dismissableLayer.update", fA = "dismissableLayer.pointerDownOutside", hA = "dismissableLayer.focusOutside"; let f_; const pA = In.createContext({ layers: new Set, layersWithOutsidePointerEventsDisabled: new Set, branches: new Set }), dA = In.forwardRef((L, I) => { var $; const { disableOutsidePointerEvents: se = !1, onEscapeKeyDown: Pe, onPointerDownOutside: R, onFocusOutside: E, onInteractOutside: e, onDismiss: w, ...k } = L, i = In.useContext(pA), [_, y] = In.useState(null), h = ($ = _ == null ? void 0 : _.ownerDocument) !== null && $ !== void 0 ? $ : globalThis == null ? void 0 : globalThis.document, [, l] = In.useState({}), t = pd(I, b => y(b)), o = Array.from(i.layers), [r] = [...i.layersWithOutsidePointerEventsDisabled].slice(-1), n = o.indexOf(r), a = _ ? o.indexOf(_) : -1, s = i.layersWithOutsidePointerEventsDisabled.size > 0, u = a >= n, p = gA(b => { const g = b.target, f = [...i.branches].some(v => v.contains(g)); !u || f || (R == null || R(b), e == null || e(b), b.defaultPrevented || w == null || w()) }, h), c = vA(b => { const g = b.target;[...i.branches].some(v => v.contains(g)) || (E == null || E(b), e == null || e(b), b.defaultPrevented || w == null || w()) }, h); return cA(b => { a === i.layers.size - 1 && (Pe == null || Pe(b), !b.defaultPrevented && w && (b.preventDefault(), w())) }, h), In.useEffect(() => { if (_) return se && (i.layersWithOutsidePointerEventsDisabled.size === 0 && (f_ = h.body.style.pointerEvents, h.body.style.pointerEvents = "none"), i.layersWithOutsidePointerEventsDisabled.add(_)), i.layers.add(_), h_(), () => { se && i.layersWithOutsidePointerEventsDisabled.size === 1 && (h.body.style.pointerEvents = f_) } }, [_, h, se, i]), In.useEffect(() => () => { _ && (i.layers.delete(_), i.layersWithOutsidePointerEventsDisabled.delete(_), h_()) }, [_, i]), In.useEffect(() => { const b = () => l({}); return document.addEventListener(Mm, b), () => document.removeEventListener(Mm, b) }, []), In.createElement(Nh.div, zo({}, k, { ref: t, style: { pointerEvents: s ? u ? "auto" : "none" : void 0, ...L.style }, onFocusCapture: wf(L.onFocusCapture, c.onFocusCapture), onBlurCapture: wf(L.onBlurCapture, c.onBlurCapture), onPointerDownCapture: wf(L.onPointerDownCapture, p.onPointerDownCapture) })) }); function gA(L, I = globalThis == null ? void 0 : globalThis.document) { const $ = Cf(L), se = In.useRef(!1), Pe = In.useRef(() => { }); return In.useEffect(() => { const R = e => { if (e.target && !se.current) { let i = function () { E5(fA, $, k, { discrete: !0 }) }; var w = i; const k = { originalEvent: e }; e.pointerType === "touch" ? (I.removeEventListener("click", Pe.current), Pe.current = i, I.addEventListener("click", Pe.current, { once: !0 })) : i() } se.current = !1 }, E = window.setTimeout(() => { I.addEventListener("pointerdown", R) }, 0); return () => { window.clearTimeout(E), I.removeEventListener("pointerdown", R), I.removeEventListener("click", Pe.current) } }, [I, $]), { onPointerDownCapture: () => se.current = !0 } } function vA(L, I = globalThis == null ? void 0 : globalThis.document) { const $ = Cf(L), se = In.useRef(!1); return In.useEffect(() => { const Pe = R => { R.target && !se.current && E5(hA, $, { originalEvent: R }, { discrete: !1 }) }; return I.addEventListener("focusin", Pe), () => I.removeEventListener("focusin", Pe) }, [I, $]), { onFocusCapture: () => se.current = !0, onBlurCapture: () => se.current = !1 } } function h_() { const L = new CustomEvent(Mm); document.dispatchEvent(L) } function E5(L, I, $, { discrete: se }) { const Pe = $.originalEvent.target, R = new CustomEvent(L, { bubbles: !1, cancelable: !0, detail: $ }); I && Pe.addEventListener(L, I, { once: !0 }), se ? uA(Pe, R) : Pe.dispatchEvent(R) } const lv = "focusScope.autoFocusOnMount", uv = "focusScope.autoFocusOnUnmount", p_ = { bubbles: !1, cancelable: !0 }, mA = In.forwardRef((L, I) => { const { loop: $ = !1, trapped: se = !1, onMountAutoFocus: Pe, onUnmountAutoFocus: R, ...E } = L, [e, w] = In.useState(null), k = Cf(Pe), i = Cf(R), _ = In.useRef(null), y = pd(I, t => w(t)), h = In.useRef({ paused: !1, pause() { this.paused = !0 }, resume() { this.paused = !1 } }).current; In.useEffect(() => { if (se) { let n = function (p) { if (h.paused || !e) return; const c = p.target; e.contains(c) ? _.current = c : kc(_.current, { select: !0 }) }, a = function (p) { if (h.paused || !e) return; const c = p.relatedTarget; c !== null && (e.contains(c) || kc(_.current, { select: !0 })) }, s = function (p) { const c = document.activeElement; for (const b of p) b.removedNodes.length > 0 && (e != null && e.contains(c) || kc(e)) }; var t = n, o = a, r = s; document.addEventListener("focusin", n), document.addEventListener("focusout", a); const u = new MutationObserver(s); return e && u.observe(e, { childList: !0, subtree: !0 }), () => { document.removeEventListener("focusin", n), document.removeEventListener("focusout", a), u.disconnect() } } }, [se, e, h.paused]), In.useEffect(() => { if (e) { g_.add(h); const t = document.activeElement; if (!e.contains(t)) { const r = new CustomEvent(lv, p_); e.addEventListener(lv, k), e.dispatchEvent(r), r.defaultPrevented || (yA(kA(C5(e)), { select: !0 }), document.activeElement === t && kc(e)) } return () => { e.removeEventListener(lv, k), setTimeout(() => { const r = new CustomEvent(uv, p_); e.addEventListener(uv, i), e.dispatchEvent(r), r.defaultPrevented || kc(t ?? document.body, { select: !0 }), e.removeEventListener(uv, i), g_.remove(h) }, 0) } } }, [e, k, i, h]); const l = In.useCallback(t => { if (!$ && !se || h.paused) return; const o = t.key === "Tab" && !t.altKey && !t.ctrlKey && !t.metaKey, r = document.activeElement; if (o && r) { const n = t.currentTarget, [a, s] = xA(n); a && s ? !t.shiftKey && r === s ? (t.preventDefault(), $ && kc(a, { select: !0 })) : t.shiftKey && r === a && (t.preventDefault(), $ && kc(s, { select: !0 })) : r === n && t.preventDefault() } }, [$, se, h.paused]); return In.createElement(Nh.div, zo({ tabIndex: -1 }, E, { ref: y, onKeyDown: l })) }); function yA(L, { select: I = !1 } = {}) { const $ = document.activeElement; for (const se of L) if (kc(se, { select: I }), document.activeElement !== $) return } function xA(L) { const I = C5(L), $ = d_(I, L), se = d_(I.reverse(), L); return [$, se] } function C5(L) { const I = [], $ = document.createTreeWalker(L, NodeFilter.SHOW_ELEMENT, { acceptNode: se => { const Pe = se.tagName === "INPUT" && se.type === "hidden"; return se.disabled || se.hidden || Pe ? NodeFilter.FILTER_SKIP : se.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP } }); for (; $.nextNode();)I.push($.currentNode); return I } function d_(L, I) { for (const $ of L) if (!bA($, { upTo: I })) return $ } function bA(L, { upTo: I }) { if (getComputedStyle(L).visibility === "hidden") return !0; for (; L;) { if (I !== void 0 && L === I) return !1; if (getComputedStyle(L).display === "none") return !0; L = L.parentElement } return !1 } function _A(L) { return L instanceof HTMLInputElement && "select" in L } function kc(L, { select: I = !1 } = {}) { if (L && L.focus) { const $ = document.activeElement; L.focus({ preventScroll: !0 }), L !== $ && _A(L) && I && L.select() } } const g_ = wA(); function wA() { let L = []; return { add(I) { const $ = L[0]; I !== $ && ($ == null || $.pause()), L = v_(L, I), L.unshift(I) }, remove(I) { var $; L = v_(L, I), ($ = L[0]) === null || $ === void 0 || $.resume() } } } function v_(L, I) { const $ = [...L], se = $.indexOf(I); return se !== -1 && $.splice(se, 1), $ } function kA(L) { return L.filter(I => I.tagName !== "A") } function TA(L, I) { return In.useReducer(($, se) => { const Pe = I[$][se]; return Pe ?? $ }, L) } const By = L => { const { present: I, children: $ } = L, se = AA(I), Pe = typeof $ == "function" ? $({ present: se.isPresent }) : In.Children.only($), R = pd(se.ref, Pe.ref); return typeof $ == "function" || se.isPresent ? In.cloneElement(Pe, { ref: R }) : null }; By.displayName = "Presence"; function AA(L) { const [I, $] = In.useState(), se = In.useRef({}), Pe = In.useRef(L), R = In.useRef("none"), E = L ? "mounted" : "unmounted", [e, w] = TA(E, { mounted: { UNMOUNT: "unmounted", ANIMATION_OUT: "unmountSuspended" }, unmountSuspended: { MOUNT: "mounted", ANIMATION_END: "unmounted" }, unmounted: { MOUNT: "mounted" } }); return In.useEffect(() => { const k = b0(se.current); R.current = e === "mounted" ? k : "none" }, [e]), Tm(() => { const k = se.current, i = Pe.current; if (i !== L) { const y = R.current, h = b0(k); L ? w("MOUNT") : h === "none" || (k == null ? void 0 : k.display) === "none" ? w("UNMOUNT") : w(i && y !== h ? "ANIMATION_OUT" : "UNMOUNT"), Pe.current = L } }, [L, w]), Tm(() => { if (I) { const k = _ => { const h = b0(se.current).includes(_.animationName); _.target === I && h && Ay.flushSync(() => w("ANIMATION_END")) }, i = _ => { _.target === I && (R.current = b0(se.current)) }; return I.addEventListener("animationstart", i), I.addEventListener("animationcancel", k), I.addEventListener("animationend", k), () => { I.removeEventListener("animationstart", i), I.removeEventListener("animationcancel", k), I.removeEventListener("animationend", k) } } else w("ANIMATION_END") }, [I, w]), { isPresent: ["mounted", "unmountSuspended"].includes(e), ref: In.useCallback(k => { k && (se.current = getComputedStyle(k)), $(k) }, []) } } function b0(L) { return (L == null ? void 0 : L.animationName) || "none" } let cv = 0; function MA() { In.useEffect(() => { var L, I; const $ = document.querySelectorAll("[data-radix-focus-guard]"); return document.body.insertAdjacentElement("afterbegin", (L = $[0]) !== null && L !== void 0 ? L : m_()), document.body.insertAdjacentElement("beforeend", (I = $[1]) !== null && I !== void 0 ? I : m_()), cv++, () => { cv === 1 && document.querySelectorAll("[data-radix-focus-guard]").forEach(se => se.remove()), cv-- } }, []) } function m_() { const L = document.createElement("span"); return L.setAttribute("data-radix-focus-guard", ""), L.tabIndex = 0, L.style.cssText = "outline: none; opacity: 0; position: fixed; pointer-events: none", L } var ku = function () { return ku = Object.assign || function (I) { for (var $, se = 1, Pe = arguments.length; se < Pe; se++) { $ = arguments[se]; for (var R in $) Object.prototype.hasOwnProperty.call($, R) && (I[R] = $[R]) } return I }, ku.apply(this, arguments) }; function L5(L, I) { var $ = {}; for (var se in L) Object.prototype.hasOwnProperty.call(L, se) && I.indexOf(se) < 0 && ($[se] = L[se]); if (L != null && typeof Object.getOwnPropertySymbols == "function") for (var Pe = 0, se = Object.getOwnPropertySymbols(L); Pe < se.length; Pe++)I.indexOf(se[Pe]) < 0 && Object.prototype.propertyIsEnumerable.call(L, se[Pe]) && ($[se[Pe]] = L[se[Pe]]); return $ } function SA(L, I, $) { if ($ || arguments.length === 2) for (var se = 0, Pe = I.length, R; se < Pe; se++)(R || !(se in I)) && (R || (R = Array.prototype.slice.call(I, 0, se)), R[se] = I[se]); return L.concat(R || Array.prototype.slice.call(I)) } var H0 = "right-scroll-bar-position", q0 = "width-before-scroll-bar", EA = "with-scroll-bars-hidden", CA = "--removed-body-scroll-bar-size"; function LA(L, I) { return typeof L == "function" ? L(I) : L && (L.current = I), L } function PA(L, I) { var $ = In.useState(function () { return { value: L, callback: I, facade: { get current() { return $.value }, set current(se) { var Pe = $.value; Pe !== se && ($.value = se, $.callback(se, Pe)) } } } })[0]; return $.callback = I, $.facade } function OA(L, I) { return PA(I || null, function ($) { return L.forEach(function (se) { return LA(se, $) }) }) } function IA(L) { return L } function RA(L, I) { I === void 0 && (I = IA); var $ = [], se = !1, Pe = { read: function () { if (se) throw new Error("Sidecar: could not `read` from an `assigned` medium. `read` could be used only with `useMedium`."); return $.length ? $[$.length - 1] : L }, useMedium: function (R) { var E = I(R, se); return $.push(E), function () { $ = $.filter(function (e) { return e !== E }) } }, assignSyncMedium: function (R) { for (se = !0; $.length;) { var E = $; $ = [], E.forEach(R) } $ = { push: function (e) { return R(e) }, filter: function () { return $ } } }, assignMedium: function (R) { se = !0; var E = []; if ($.length) { var e = $; $ = [], e.forEach(R), E = $ } var w = function () { var i = E; E = [], i.forEach(R) }, k = function () { return Promise.resolve().then(w) }; k(), $ = { push: function (i) { E.push(i), k() }, filter: function (i) { return E = E.filter(i), $ } } } }; return Pe } function zA(L) { L === void 0 && (L = {}); var I = RA(null); return I.options = ku({ async: !0, ssr: !1 }, L), I } var P5 = function (L) { var I = L.sideCar, $ = L5(L, ["sideCar"]); if (!I) throw new Error("Sidecar: please provide `sideCar` property to import the right car"); var se = I.read(); if (!se) throw new Error("Sidecar medium not found"); return In.createElement(se, ku({}, $)) }; P5.isSideCarExport = !0; function DA(L, I) { return L.useMedium(I), P5 } var O5 = zA(), fv = function () { }, B1 = In.forwardRef(function (L, I) { var $ = In.useRef(null), se = In.useState({ onScrollCapture: fv, onWheelCapture: fv, onTouchMoveCapture: fv }), Pe = se[0], R = se[1], E = L.forwardProps, e = L.children, w = L.className, k = L.removeScrollBar, i = L.enabled, _ = L.shards, y = L.sideCar, h = L.noIsolation, l = L.inert, t = L.allowPinchZoom, o = L.as, r = o === void 0 ? "div" : o, n = L5(L, ["forwardProps", "children", "className", "removeScrollBar", "enabled", "shards", "sideCar", "noIsolation", "inert", "allowPinchZoom", "as"]), a = y, s = OA([$, I]), u = ku(ku({}, n), Pe); return In.createElement(In.Fragment, null, i && In.createElement(a, { sideCar: O5, removeScrollBar: k, shards: _, noIsolation: h, inert: l, setCallbacks: R, allowPinchZoom: !!t, lockRef: $ }), E ? In.cloneElement(In.Children.only(e), ku(ku({}, u), { ref: s })) : In.createElement(r, ku({}, u, { className: w, ref: s }), e)) }); B1.defaultProps = { enabled: !0, removeScrollBar: !0, inert: !1 }; B1.classNames = { fullWidth: q0, zeroRight: H0 }; var y_, FA = function () { if (y_) return y_; if (typeof __webpack_nonce__ < "u") return __webpack_nonce__ }; function BA() { if (!document) return null; var L = document.createElement("style"); L.type = "text/css"; var I = FA(); return I && L.setAttribute("nonce", I), L } function NA(L, I) { L.styleSheet ? L.styleSheet.cssText = I : L.appendChild(document.createTextNode(I)) } function jA(L) { var I = document.head || document.getElementsByTagName("head")[0]; I.appendChild(L) } var UA = function () { var L = 0, I = null; return { add: function ($) { L == 0 && (I = BA()) && (NA(I, $), jA(I)), L++ }, remove: function () { L--, !L && I && (I.parentNode && I.parentNode.removeChild(I), I = null) } } }, VA = function () { var L = UA(); return function (I, $) { In.useEffect(function () { return L.add(I), function () { L.remove() } }, [I && $]) } }, I5 = function () { var L = VA(), I = function ($) { var se = $.styles, Pe = $.dynamic; return L(se, Pe), null }; return I }, HA = { left: 0, top: 0, right: 0, gap: 0 }, hv = function (L) { return parseInt(L || "", 10) || 0 }, qA = function (L) { var I = window.getComputedStyle(document.body), $ = I[L === "padding" ? "paddingLeft" : "marginLeft"], se = I[L === "padding" ? "paddingTop" : "marginTop"], Pe = I[L === "padding" ? "paddingRight" : "marginRight"]; return [hv($), hv(se), hv(Pe)] }, GA = function (L) { if (L === void 0 && (L = "margin"), typeof window > "u") return HA; var I = qA(L), $ = document.documentElement.clientWidth, se = window.innerWidth; return { left: I[0], top: I[1], right: I[2], gap: Math.max(0, se - $ + I[2] - I[0]) } }, WA = I5(), ZA = function (L, I, $, se) {
+ }, $7 = { data: { candlestick: [{ decreasing: { fillcolor: "#e4003a", line: { color: "#e4003a" } }, increasing: { fillcolor: "#00ACFF", line: { color: "#00ACFF" } }, type: "candlestick" }] }, layout: { annotationdefaults: { showarrow: !1 }, autotypenumbers: "strict", colorway: ["#ffed00", "#ef7d00", "#e4003a", "#c13246", "#822661", "#48277c", "#005ca9", "#00aaff", "#9b30d9", "#af005f", "#5f00af", "#af87ff"], dragmode: "pan", font: { family: "Arial", size: 18 }, hoverlabel: { align: "left" }, mapbox: { style: "dark" }, hovermode: "x", legend: { bgcolor: "rgba(0, 0, 0, 0)", x: .01, xanchor: "left", y: .99, yanchor: "top", font: { size: 15 } }, paper_bgcolor: "#000000", plot_bgcolor: "#000000", xaxis: { automargin: !0, autorange: !0, rangeslider: { visible: !1 }, showgrid: !0, showline: !0, tickfont: { size: 14 }, zeroline: !1, tick0: 1, title: { standoff: 20 }, linecolor: "#F5EFF3", mirror: !0, ticks: "outside" }, yaxis: { anchor: "x", automargin: !0, fixedrange: !1, zeroline: !1, showgrid: !0, showline: !0, side: "right", tick0: .5, title: { standoff: 20 }, gridcolor: "#283442", linecolor: "#F5EFF3", mirror: !0, ticks: "outside" } } }, K7 = { data: { barpolar: [{ marker: { line: { color: "white", width: .5 }, pattern: { fillmode: "overlay", size: 10, solidity: .2 } }, type: "barpolar" }], bar: [{ error_x: { color: "#2a3f5f" }, error_y: { color: "#2a3f5f" }, marker: { line: { color: "white", width: .5 }, pattern: { fillmode: "overlay", size: 10, solidity: .2 } }, type: "bar" }], carpet: [{ aaxis: { endlinecolor: "#2a3f5f", gridcolor: "#C8D4E3", linecolor: "#C8D4E3", minorgridcolor: "#C8D4E3", startlinecolor: "#2a3f5f" }, baxis: { endlinecolor: "#2a3f5f", gridcolor: "#C8D4E3", linecolor: "#C8D4E3", minorgridcolor: "#C8D4E3", startlinecolor: "#2a3f5f" }, type: "carpet" }], choropleth: [{ colorbar: { outlinewidth: 0, ticks: "" }, type: "choropleth" }], contourcarpet: [{ colorbar: { outlinewidth: 0, ticks: "" }, type: "contourcarpet" }], contour: [{ colorbar: { outlinewidth: 0, ticks: "" }, colorscale: [[0, "#0d0887"], [.1111111111111111, "#46039f"], [.2222222222222222, "#7201a8"], [.3333333333333333, "#9c179e"], [.4444444444444444, "#bd3786"], [.5555555555555556, "#d8576b"], [.6666666666666666, "#ed7953"], [.7777777777777778, "#fb9f3a"], [.8888888888888888, "#fdca26"], [1, "#f0f921"]], type: "contour" }], heatmapgl: [{ colorbar: { outlinewidth: 0, ticks: "" }, colorscale: [[0, "#0d0887"], [.1111111111111111, "#46039f"], [.2222222222222222, "#7201a8"], [.3333333333333333, "#9c179e"], [.4444444444444444, "#bd3786"], [.5555555555555556, "#d8576b"], [.6666666666666666, "#ed7953"], [.7777777777777778, "#fb9f3a"], [.8888888888888888, "#fdca26"], [1, "#f0f921"]], type: "heatmapgl" }], heatmap: [{ colorbar: { outlinewidth: 0, ticks: "" }, colorscale: [[0, "#0d0887"], [.1111111111111111, "#46039f"], [.2222222222222222, "#7201a8"], [.3333333333333333, "#9c179e"], [.4444444444444444, "#bd3786"], [.5555555555555556, "#d8576b"], [.6666666666666666, "#ed7953"], [.7777777777777778, "#fb9f3a"], [.8888888888888888, "#fdca26"], [1, "#f0f921"]], type: "heatmap" }], histogram2dcontour: [{ colorbar: { outlinew