diff --git a/apps/insights/src/components/LivePrices/index.tsx b/apps/insights/src/components/LivePrices/index.tsx
index a590679047..fc5248172c 100644
--- a/apps/insights/src/components/LivePrices/index.tsx
+++ b/apps/insights/src/components/LivePrices/index.tsx
@@ -43,9 +43,17 @@ const LiveAggregatePrice = ({
if (current === undefined) {
return ;
} else if (current.status === PriceStatus.Trading) {
- return ;
+ return (
+
+ );
} else {
- return ;
+ return (
+
+ );
}
};
@@ -58,20 +66,28 @@ const LiveComponentPrice = ({
publisherKey: string;
cluster: Cluster;
}) => {
- const { prev, current } = useLivePriceComponent(
+ const { prev, current, exponent } = useLivePriceComponent(
cluster,
feedKey,
publisherKey,
);
- return ;
+ return (
+
+ );
};
const Price = ({
prev,
current,
+ exponent,
}: {
prev?: number | undefined;
current?: number | undefined;
+ exponent?: number | undefined;
}) =>
current === undefined ? (
@@ -80,7 +96,7 @@ const Price = ({
className={styles.price}
data-direction={prev ? getChangeDirection(prev, current) : "flat"}
>
-
+
);
@@ -114,6 +130,7 @@ const LiveAggregateConfidence = ({
? current.confidence
: current.previousConfidence)
}
+ exponent={current?.exponent}
/>
);
};
@@ -128,24 +145,42 @@ const LiveComponentConfidence = ({
cluster: Cluster;
}) => {
const { current } = useLivePriceComponent(cluster, feedKey, publisherKey);
- return ;
+ const { current: priceData } = useLivePriceData(cluster, feedKey);
+ return (
+
+ );
};
-const Confidence = ({ confidence }: { confidence?: number | undefined }) => (
+const Confidence = ({
+ confidence,
+ exponent,
+}: {
+ confidence?: number | undefined;
+ exponent?: number | undefined;
+}) => (
{confidence === undefined ? (
) : (
-
+
)}
);
-const FormattedPriceValue = ({ n }: { n: number }) => {
- const formatter = usePriceFormatter();
+const FormattedPriceValue = ({
+ n,
+ exponent,
+}: {
+ n: number;
+ exponent?: number | undefined;
+}) => {
+ const formatter = usePriceFormatter(exponent);
return useMemo(() => formatter.format(n), [n, formatter]);
};
diff --git a/apps/insights/src/components/PriceFeed/Chart/chart.tsx b/apps/insights/src/components/PriceFeed/Chart/chart.tsx
index e807c99d0a..7a4690d369 100644
--- a/apps/insights/src/components/PriceFeed/Chart/chart.tsx
+++ b/apps/insights/src/components/PriceFeed/Chart/chart.tsx
@@ -69,7 +69,6 @@ const useChartElem = (symbol: string, feedId: string) => {
const chartContainerRef = useRef(null);
const chartRef = useRef(undefined);
const isBackfilling = useRef(false);
- const priceFormatter = usePriceFormatter();
const abortControllerRef = useRef(undefined);
// Lightweight charts has [a
// bug](https://github.com/tradingview/lightweight-charts/issues/1649) where
@@ -79,6 +78,9 @@ const useChartElem = (symbol: string, feedId: string) => {
const whitespaceData = useRef>(new Set());
const { current: livePriceData } = useLivePriceData(Cluster.Pythnet, feedId);
+ const priceFormatter = usePriceFormatter(livePriceData?.exponent, {
+ subscriptZeros: false,
+ });
const didResetVisibleRange = useRef(false);
const didLoadInitialData = useRef(false);
@@ -370,6 +372,17 @@ const useChartElem = (symbol: string, feedId: string) => {
});
}, [quickSelectWindow, resolution, fetchHistoricalData]);
+ // Update the chart's price formatter when the exponent becomes available
+ useEffect(() => {
+ if (chartRef.current && livePriceData?.exponent !== undefined) {
+ chartRef.current.chart.applyOptions({
+ localization: {
+ priceFormatter: priceFormatter.format,
+ },
+ });
+ }
+ }, [livePriceData?.exponent, priceFormatter]);
+
return { chartRef, chartContainerRef };
};
diff --git a/apps/insights/src/hooks/use-live-price-data.tsx b/apps/insights/src/hooks/use-live-price-data.tsx
index 9a57a5262c..2ebbb2169f 100644
--- a/apps/insights/src/hooks/use-live-price-data.tsx
+++ b/apps/insights/src/hooks/use-live-price-data.tsx
@@ -72,6 +72,7 @@ export const useLivePriceComponent = (
prev: prev?.priceComponents.find((component) =>
component.publisher.equals(publisherKey),
),
+ exponent: current?.exponent,
};
};
diff --git a/apps/insights/src/hooks/use-price-formatter.ts b/apps/insights/src/hooks/use-price-formatter.ts
index f51bbdd446..7e4c594829 100644
--- a/apps/insights/src/hooks/use-price-formatter.ts
+++ b/apps/insights/src/hooks/use-price-formatter.ts
@@ -1,17 +1,45 @@
import { useCallback, useMemo } from "react";
import { useNumberFormatter } from "react-aria";
-export const usePriceFormatter = () => {
+export const usePriceFormatter = (
+ exponent?: number,
+ { subscriptZeros = true }: { subscriptZeros?: boolean } = {},
+) => {
+ // Calculate the number of decimal places based on the exponent
+ // The exponent represents the power of 10, so -8 means 8 decimal places
+ const decimals = exponent === undefined ? undefined : Math.abs(exponent);
+
const bigNumberFormatter = useNumberFormatter({ maximumFractionDigits: 2 });
const smallNumberFormatter = useNumberFormatter({
maximumSignificantDigits: 6,
});
+ const exponentBasedFormatter = useNumberFormatter({
+ minimumFractionDigits: decimals,
+ maximumFractionDigits: decimals,
+ });
+
const format = useCallback(
- (n: number) =>
- n >= 1000
- ? bigNumberFormatter.format(n)
- : formatToSubscriptNumber(smallNumberFormatter.format(n)),
- [bigNumberFormatter, smallNumberFormatter],
+ (n: number) => {
+ // If we have an exponent, use exponent-based formatting
+ if (decimals !== undefined) {
+ const formatted = exponentBasedFormatter.format(n);
+ return subscriptZeros ? formatToSubscriptNumber(formatted) : formatted;
+ }
+ // Otherwise, fall back to the old behavior
+ if (n >= 1000) {
+ const formatted = bigNumberFormatter.format(n);
+ return subscriptZeros ? formatToSubscriptNumber(formatted) : formatted;
+ }
+ const formatted = smallNumberFormatter.format(n);
+ return subscriptZeros ? formatToSubscriptNumber(formatted) : formatted;
+ },
+ [
+ bigNumberFormatter,
+ smallNumberFormatter,
+ exponentBasedFormatter,
+ decimals,
+ subscriptZeros,
+ ],
);
return useMemo(() => ({ format }), [format]);
};