Skip to content

Commit 4c1f7a2

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

File tree

4 files changed

+94
-17
lines changed

4 files changed

+94
-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: 14 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,9 @@ 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, {
82+
subscriptZeros: false,
83+
});
8284

8385
const didResetVisibleRange = useRef(false);
8486
const didLoadInitialData = useRef(false);
@@ -370,6 +372,17 @@ const useChartElem = (symbol: string, feedId: string) => {
370372
});
371373
}, [quickSelectWindow, resolution, fetchHistoricalData]);
372374

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

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: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,45 @@
11
import { useCallback, useMemo } from "react";
22
import { useNumberFormatter } from "react-aria";
33

4-
export const usePriceFormatter = () => {
4+
export const usePriceFormatter = (
5+
exponent?: number,
6+
{ subscriptZeros = true }: { subscriptZeros?: boolean } = {},
7+
) => {
8+
// Calculate the number of decimal places based on the exponent
9+
// The exponent represents the power of 10, so -8 means 8 decimal places
10+
const decimals = exponent === undefined ? undefined : Math.abs(exponent);
11+
512
const bigNumberFormatter = useNumberFormatter({ maximumFractionDigits: 2 });
613
const smallNumberFormatter = useNumberFormatter({
714
maximumSignificantDigits: 6,
815
});
16+
const exponentBasedFormatter = useNumberFormatter({
17+
minimumFractionDigits: decimals,
18+
maximumFractionDigits: decimals,
19+
});
20+
921
const format = useCallback(
10-
(n: number) =>
11-
n >= 1000
12-
? bigNumberFormatter.format(n)
13-
: formatToSubscriptNumber(smallNumberFormatter.format(n)),
14-
[bigNumberFormatter, smallNumberFormatter],
22+
(n: number) => {
23+
// If we have an exponent, use exponent-based formatting
24+
if (decimals !== undefined) {
25+
const formatted = exponentBasedFormatter.format(n);
26+
return subscriptZeros ? formatToSubscriptNumber(formatted) : formatted;
27+
}
28+
// Otherwise, fall back to the old behavior
29+
if (n >= 1000) {
30+
const formatted = bigNumberFormatter.format(n);
31+
return subscriptZeros ? formatToSubscriptNumber(formatted) : formatted;
32+
}
33+
const formatted = smallNumberFormatter.format(n);
34+
return subscriptZeros ? formatToSubscriptNumber(formatted) : formatted;
35+
},
36+
[
37+
bigNumberFormatter,
38+
smallNumberFormatter,
39+
exponentBasedFormatter,
40+
decimals,
41+
subscriptZeros,
42+
],
1543
);
1644
return useMemo(() => ({ format }), [format]);
1745
};

0 commit comments

Comments
 (0)