Skip to content

Commit 8bfb8ae

Browse files
committed
feat: make price formatting feed-exponent aware
1 parent 29e2fe1 commit 8bfb8ae

File tree

4 files changed

+89
-17
lines changed

4 files changed

+89
-17
lines changed

apps/insights/src/components/LivePrices/index.tsx

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,17 @@ const LiveAggregatePrice = ({
4343
if (current === undefined) {
4444
return <Price />;
4545
} else if (current.status === PriceStatus.Trading) {
46-
return <Price current={current.price} prev={prev?.price} />;
46+
return (
47+
<Price
48+
current={current.price}
49+
prev={prev?.price}
50+
exponent={current.exponent}
51+
/>
52+
);
4753
} else {
48-
return <Price current={current.previousPrice} />;
54+
return (
55+
<Price current={current.previousPrice} exponent={current.exponent} />
56+
);
4957
}
5058
};
5159

@@ -58,20 +66,28 @@ const LiveComponentPrice = ({
5866
publisherKey: string;
5967
cluster: Cluster;
6068
}) => {
61-
const { prev, current } = useLivePriceComponent(
69+
const { prev, current, exponent } = useLivePriceComponent(
6270
cluster,
6371
feedKey,
6472
publisherKey,
6573
);
66-
return <Price current={current?.latest.price} prev={prev?.latest.price} />;
74+
return (
75+
<Price
76+
current={current?.latest.price}
77+
prev={prev?.latest.price}
78+
exponent={exponent}
79+
/>
80+
);
6781
};
6882

6983
const Price = ({
7084
prev,
7185
current,
86+
exponent,
7287
}: {
7388
prev?: number | undefined;
7489
current?: number | undefined;
90+
exponent?: number | undefined;
7591
}) =>
7692
current === undefined ? (
7793
<Skeleton width={SKELETON_WIDTH} />
@@ -80,7 +96,7 @@ const Price = ({
8096
className={styles.price}
8197
data-direction={prev ? getChangeDirection(prev, current) : "flat"}
8298
>
83-
<FormattedPriceValue n={current} />
99+
<FormattedPriceValue n={current} exponent={exponent} />
84100
</span>
85101
);
86102

@@ -114,6 +130,7 @@ const LiveAggregateConfidence = ({
114130
? current.confidence
115131
: current.previousConfidence)
116132
}
133+
exponent={current?.exponent}
117134
/>
118135
);
119136
};
@@ -128,24 +145,42 @@ const LiveComponentConfidence = ({
128145
cluster: Cluster;
129146
}) => {
130147
const { current } = useLivePriceComponent(cluster, feedKey, publisherKey);
131-
return <Confidence confidence={current?.latest.confidence} />;
148+
const { current: priceData } = useLivePriceData(cluster, feedKey);
149+
return (
150+
<Confidence
151+
confidence={current?.latest.confidence}
152+
exponent={priceData?.exponent}
153+
/>
154+
);
132155
};
133156

134-
const Confidence = ({ confidence }: { confidence?: number | undefined }) => (
157+
const Confidence = ({
158+
confidence,
159+
exponent,
160+
}: {
161+
confidence?: number | undefined;
162+
exponent?: number | undefined;
163+
}) => (
135164
<span className={styles.confidence}>
136165
<PlusMinus className={styles.plusMinus} />
137166
{confidence === undefined ? (
138167
<Skeleton width={SKELETON_WIDTH} />
139168
) : (
140169
<span>
141-
<FormattedPriceValue n={confidence} />
170+
<FormattedPriceValue n={confidence} exponent={exponent} />
142171
</span>
143172
)}
144173
</span>
145174
);
146175

147-
const FormattedPriceValue = ({ n }: { n: number }) => {
148-
const formatter = usePriceFormatter();
176+
const FormattedPriceValue = ({
177+
n,
178+
exponent,
179+
}: {
180+
n: number;
181+
exponent?: number | undefined;
182+
}) => {
183+
const formatter = usePriceFormatter(exponent);
149184

150185
return useMemo(() => formatter.format(n), [n, formatter]);
151186
};

apps/insights/src/components/PriceFeed/Chart/chart.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ const useChartElem = (symbol: string, feedId: string) => {
6969
const chartContainerRef = useRef<HTMLDivElement | null>(null);
7070
const chartRef = useRef<ChartRefContents | undefined>(undefined);
7171
const isBackfilling = useRef(false);
72-
const priceFormatter = usePriceFormatter();
7372
const abortControllerRef = useRef<AbortController | undefined>(undefined);
7473
// Lightweight charts has [a
7574
// bug](https://github.com/tradingview/lightweight-charts/issues/1649) where
@@ -79,6 +78,7 @@ const useChartElem = (symbol: string, feedId: string) => {
7978
const whitespaceData = useRef<Set<WhitespaceData>>(new Set());
8079

8180
const { current: livePriceData } = useLivePriceData(Cluster.Pythnet, feedId);
81+
const priceFormatter = usePriceFormatter(livePriceData?.exponent);
8282

8383
const didResetVisibleRange = useRef(false);
8484
const didLoadInitialData = useRef(false);
@@ -370,6 +370,17 @@ const useChartElem = (symbol: string, feedId: string) => {
370370
});
371371
}, [quickSelectWindow, resolution, fetchHistoricalData]);
372372

373+
// Update the chart's price formatter when the exponent becomes available
374+
useEffect(() => {
375+
if (chartRef.current && livePriceData?.exponent !== undefined) {
376+
chartRef.current.chart.applyOptions({
377+
localization: {
378+
priceFormatter: priceFormatter.format,
379+
},
380+
});
381+
}
382+
}, [livePriceData?.exponent, priceFormatter]);
383+
373384
return { chartRef, chartContainerRef };
374385
};
375386

apps/insights/src/hooks/use-live-price-data.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export const useLivePriceComponent = (
7272
prev: prev?.priceComponents.find((component) =>
7373
component.publisher.equals(publisherKey),
7474
),
75+
exponent: current?.exponent,
7576
};
7677
};
7778

apps/insights/src/hooks/use-price-formatter.ts

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,42 @@
11
import { useCallback, useMemo } from "react";
22
import { useNumberFormatter } from "react-aria";
33

4-
export const usePriceFormatter = () => {
4+
export const usePriceFormatter = (exponent?: number, { subscript }: { subscript?: boolean } = {}) => {
5+
// Calculate the number of decimal places based on the exponent
6+
// The exponent represents the power of 10, so -8 means 8 decimal places
7+
const decimals = exponent === undefined ? undefined : Math.abs(exponent);
8+
59
const bigNumberFormatter = useNumberFormatter({ maximumFractionDigits: 2 });
610
const smallNumberFormatter = useNumberFormatter({
711
maximumSignificantDigits: 6,
812
});
13+
const exponentBasedFormatter = useNumberFormatter({
14+
minimumFractionDigits: decimals,
15+
maximumFractionDigits: decimals,
16+
});
17+
918
const format = useCallback(
10-
(n: number) =>
11-
n >= 1000
12-
? bigNumberFormatter.format(n)
13-
: formatToSubscriptNumber(smallNumberFormatter.format(n)),
14-
[bigNumberFormatter, smallNumberFormatter],
19+
(n: number) => {
20+
// If we have an exponent, use exponent-based formatting
21+
if (decimals !== undefined) {
22+
const formatted = exponentBasedFormatter.format(n);
23+
return subscript ? formatToSubscriptNumber(formatted) : formatted;
24+
}
25+
// Otherwise, fall back to the old behavior
26+
if (n >= 1000) {
27+
const formatted = bigNumberFormatter.format(n);
28+
return subscript ? formatToSubscriptNumber(formatted) : formatted;
29+
}
30+
const formatted = smallNumberFormatter.format(n);
31+
return subscript ? formatToSubscriptNumber(formatted) : formatted;
32+
},
33+
[
34+
bigNumberFormatter,
35+
smallNumberFormatter,
36+
exponentBasedFormatter,
37+
decimals,
38+
subscript,
39+
],
1540
);
1641
return useMemo(() => ({ format }), [format]);
1742
};

0 commit comments

Comments
 (0)